static SANE_Status usb_send_command (struct scanner *s, struct cmd *c, struct response *r, void *buf) { SANE_Status st; struct bulk_header *h = (struct bulk_header *) buf; u8 resp[sizeof (*h) + STATUS_SIZE]; size_t sz = sizeof (*h) + MAX_CMD_SIZE; memset (h, 0, sz); h->length = cpu2be32 (sz); h->type = cpu2be16 (COMMAND_BLOCK); h->code = cpu2be16 (COMMAND_CODE); memcpy (h + 1, c->cmd, c->cmd_size); st = sanei_usb_write_bulk (s->file, (const SANE_Byte *) h, &sz); if (st) return st; if (sz != sizeof (*h) + MAX_CMD_SIZE) return SANE_STATUS_IO_ERROR; if (c->dir == CMD_IN) { sz = sizeof (*h) + c->data_size; st = sanei_usb_read_bulk (s->file, (SANE_Byte *) h, &sz); c->data = h + 1; c->data_size = sz - sizeof (*h); if (st || sz < sizeof (*h)) { st = sanei_usb_release_interface (s->file, 0); if (st) return st; st = sanei_usb_claim_interface (s->file, 0); if (st) return st; r->status = CHECK_CONDITION; return SANE_STATUS_GOOD; } } else if (c->dir == CMD_OUT) { sz = sizeof (*h) + c->data_size; memset (h, 0, sizeof (*h)); h->length = cpu2be32 (sizeof (*h) + c->data_size); h->type = cpu2be16 (DATA_BLOCK); h->code = cpu2be16 (DATA_CODE); memcpy (h + 1, c->data, c->data_size); st = sanei_usb_write_bulk (s->file, (const SANE_Byte *) h, &sz); if (st) return st; } sz = sizeof (resp); st = sanei_usb_read_bulk (s->file, resp, &sz); if (st || sz != sizeof (resp)) return SANE_STATUS_IO_ERROR; r->status = be2cpu32 (*((u32 *) (resp + sizeof (*h)))); return st; }
/* ======================================================================== Routine Description: 1. Append bit 1 to end of the message 2. Append the length of message in rightmost 64 bits 3. Transform the Hash Value to digest message Arguments: pSHA_CTX Pointer to SHA256_CTX_STRUC Return Value: digestMessage Digest message Note: None ======================================================================== */ VOID RT_SHA256_End ( IN SHA256_CTX_STRUC *pSHA_CTX, OUT UINT8 DigestMessage[]) { UINT index; uint64_t message_length_bits; /* Append bit 1 to end of the message */ NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80); /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ if (pSHA_CTX->BlockLen > 55) RT_SHA256_Hash(pSHA_CTX); /* End of if */ /* Append the length of message in rightmost 64 bits */ message_length_bits = pSHA_CTX->MessageLen*8; message_length_bits = cpu2be64(message_length_bits); memmove(&pSHA_CTX->Block[56], &message_length_bits, 8); RT_SHA256_Hash(pSHA_CTX); /* Return message digest, transform the uint32_t hash value to bytes */ for (index = 0; index < 8;index++) pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]); /* End of for */ memmove(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE); } /* End of RT_SHA256_End */
/* ======================================================================== Routine Description: SHA256 computation for one block (512 bits) Arguments: pSHA_CTX Pointer to SHA256_CTX_STRUC Return Value: None Note: None ======================================================================== */ VOID RT_SHA256_Hash ( IN SHA256_CTX_STRUC *pSHA_CTX) { uint32_t W_i,t; uint32_t W[64]; uint32_t a,b,c,d,e,f,g,h,T1,T2; /* Prepare the message schedule, {W_i}, 0 < t < 15 */ memmove(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE); for (W_i = 0; W_i < 16; W_i++) W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ /* End of for */ /* SHA256 hash computation */ /* Initialize the working variables */ a = pSHA_CTX->HashValue[0]; b = pSHA_CTX->HashValue[1]; c = pSHA_CTX->HashValue[2]; d = pSHA_CTX->HashValue[3]; e = pSHA_CTX->HashValue[4]; f = pSHA_CTX->HashValue[5]; g = pSHA_CTX->HashValue[6]; h = pSHA_CTX->HashValue[7]; /* 64 rounds */ for (t = 0;t < 64;t++) { if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */ W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16]; /* End of if */ T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t]; T2 = Zsigma_256_0(a) + Maj(a,b,c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } /* End of for */ /* Compute the i^th intermediate hash value H^(i) */ pSHA_CTX->HashValue[0] += a; pSHA_CTX->HashValue[1] += b; pSHA_CTX->HashValue[2] += c; pSHA_CTX->HashValue[3] += d; pSHA_CTX->HashValue[4] += e; pSHA_CTX->HashValue[5] += f; pSHA_CTX->HashValue[6] += g; pSHA_CTX->HashValue[7] += h; memset(pSHA_CTX->Block, 0, SHA256_BLOCK_SIZE); pSHA_CTX->BlockLen = 0; } /* End of RT_SHA256_Hash */
void kvs40xx_init_window (struct scanner *s, struct window *wnd, int wnd_id) { int paper = str_index (paper_list, s->val[PAPER_SIZE].s), i; memset (wnd, 0, sizeof (struct window)); copy16 (wnd->window_descriptor_block_length, cpu2be16 (66)); wnd->window_identifier = wnd_id; copy16 (wnd->x_resolution, cpu2be16 (s->val[RESOLUTION].w)); copy16 (wnd->y_resolution, cpu2be16 (s->val[RESOLUTION].w)); if (!paper) { copy32 (wnd->upper_left_x, cpu2be32 (mm2scanner_units (s->val[TL_X].w))); copy32 (wnd->upper_left_y, cpu2be32 (mm2scanner_units (s->val[TL_Y].w))); copy32 (wnd->document_width, cpu2be32 (mm2scanner_units (s->val[BR_X].w))); copy32 (wnd->width, cpu2be32 (mm2scanner_units (s->val[BR_X].w - s->val[TL_X].w))); copy32 (wnd->document_length, cpu2be32 (mm2scanner_units (s->val[BR_Y].w))); copy32 (wnd->length, cpu2be32 (mm2scanner_units (s->val[BR_Y].w - s->val[TL_Y].w))); } else { u32 w = cpu2be32 (mm2scanner_units (paper_sizes[paper].width)); u32 h = cpu2be32 (mm2scanner_units (paper_sizes[paper].height)); copy32 (wnd->upper_left_x, cpu2be32 (mm2scanner_units (0))); copy32 (wnd->upper_left_y, cpu2be32 (mm2scanner_units (0))); if (!s->val[LANDSCAPE].b) { copy32 (wnd->width, w); copy32 (wnd->length, h); copy32 (wnd->document_width, w); copy32 (wnd->document_length, h); } else { copy32 (wnd->width, h); copy32 (wnd->length, w); copy32 (wnd->document_width, h); copy32 (wnd->document_length, w); } } wnd->brightness = s->val[BRIGHTNESS].w; wnd->threshold = s->val[THRESHOLD].w; wnd->contrast = s->val[CONTRAST].w; wnd->image_composition = mode_val[str_index (mode_list, s->val[MODE].s)]; wnd->bit_per_pixel = bps_val[str_index (mode_list, s->val[MODE].s)]; copy16 (wnd->halftone_pattern, cpu2be16 (str_index (halftone_pattern, s->val[HALFTONE_PATTERN].s))); wnd->rif_padding = s->val[INVERSE].b << 7; copy16 (wnd->bit_ordering, cpu2be16 (BIT_ORDERING)); wnd->compression_type = s->val[COMPRESSION].b ? 0x81 : 0; wnd->compression_argument = s->val[COMPRESSION_PAR].w; wnd->vendor_unique_identifier = 0; wnd->nobuf_fstspeed_dfstop = str_index (source_list, s->val[SOURCE].s) << 7 | str_index (stapeled_list, s->val[STAPELED_DOC].s) << 5 | s->val[STOP_SKEW].b << 4 | s->val[CROP].b << 3 | s->val[DFSTOP].b << 0; wnd->mirror_image = s->val[MIRROR].b << 7 | s->val[DFEED_L].b << 2 | s->val[DFEED_C].b << 1 | s->val[DFEED_R].b << 0; wnd->image_emphasis = str_index (image_emphasis_list, s->val[IMAGE_EMPHASIS].s); wnd->gamma_correction = gamma_val[str_index (gamma_list, s->val[GAMMA_CORRECTION].s)]; wnd->mcd_lamp_dfeed_sens = str_index (lamp_list, s->val[LAMP].s) << 4 | str_index (dfeed_sence_list, s->val[DFEED_SENCE].s); wnd->document_size = (paper != 0) << 7 | s->val[LENGTHCTL].b << 6 | s->val[LONG_PAPER].b << 5 | s->val[LANDSCAPE].b << 4 | paper_val[paper]; wnd->ahead_deskew_dfeed_scan_area_fspeed_rshad = (s->val[DESKEW].b || s->val[CROP].b ? 2 : 0) << 5 | /*XXX*/ s->val[DBLFEED].b << 4 | s->val[FIT_TO_PAGE].b << 2; wnd->continuous_scanning_pages = str_index (feeder_mode_list, s->val[FEEDER_MODE].s) ? 0xff : 0; wnd->automatic_threshold_mode = automatic_threshold_val [str_index (automatic_threshold_list, s->val[AUTOMATIC_THRESHOLD].s)]; wnd->automatic_separation_mode = 0; /*Does not supported */ wnd->standard_white_level_mode = white_level_val[str_index (white_level_list, s->val[WHITE_LEVEL].s)]; wnd->b_wnr_noise_reduction = str_index (noise_reduction_list, s->val[NOISE_REDUCTION].s); i = str_index (manual_feed_list, s->val[MANUALFEED].s); wnd->mfeed_toppos_btmpos_dsepa_hsepa_dcont_rstkr = i << 6 | s->val[TOPPOS].b << 5 | s->val[BTMPOS].b << 4; wnd->stop_mode = 1; wnd->red_chroma = s->val[RED_CHROMA].w; wnd->blue_chroma = s->val[BLUE_CHROMA].w; }
/* ======================================================================== Routine Description: SHA1 computation for one block (512 bits) Arguments: pSHA_CTX Pointer to SHA1_CTX_STRUC Return Value: None Note: None ======================================================================== */ VOID RT_SHA1_Hash ( IN SHA1_CTX_STRUC *pSHA_CTX) { uint32_t W_i,t; uint32_t W[80]; uint32_t a,b,c,d,e,T,f_t = 0; /* Prepare the message schedule, {W_i}, 0 < t < 15 */ memmove(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE); for (W_i = 0; W_i < 16; W_i++) { W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ } /* End of for */ for (W_i = 16; W_i < 80; W_i++) { W[W_i] = ROTL32((W[W_i - 3] ^ W[W_i - 8] ^ W[W_i - 14] ^ W[W_i - 16]),1); } /* End of for */ /* SHA256 hash computation */ /* Initialize the working variables */ a = pSHA_CTX->HashValue[0]; b = pSHA_CTX->HashValue[1]; c = pSHA_CTX->HashValue[2]; d = pSHA_CTX->HashValue[3]; e = pSHA_CTX->HashValue[4]; /* 80 rounds */ for (t = 0;t < 20;t++) { f_t = Ch(b,c,d); T = ROTL32(a,5) + f_t + e + SHA1_K[0] + W[t]; e = d; d = c; c = ROTL32(b,30); b = a; a = T; } /* End of for */ for (t = 20;t < 40;t++) { f_t = Parity(b,c,d); T = ROTL32(a,5) + f_t + e + SHA1_K[1] + W[t]; e = d; d = c; c = ROTL32(b,30); b = a; a = T; } /* End of for */ for (t = 40;t < 60;t++) { f_t = Maj(b,c,d); T = ROTL32(a,5) + f_t + e + SHA1_K[2] + W[t]; e = d; d = c; c = ROTL32(b,30); b = a; a = T; } /* End of for */ for (t = 60;t < 80;t++) { f_t = Parity(b,c,d); T = ROTL32(a,5) + f_t + e + SHA1_K[3] + W[t]; e = d; d = c; c = ROTL32(b,30); b = a; a = T; } /* End of for */ /* Compute the i^th intermediate hash value H^(i) */ pSHA_CTX->HashValue[0] += a; pSHA_CTX->HashValue[1] += b; pSHA_CTX->HashValue[2] += c; pSHA_CTX->HashValue[3] += d; pSHA_CTX->HashValue[4] += e; memset(pSHA_CTX->Block, 0, SHA1_BLOCK_SIZE); pSHA_CTX->BlockLen = 0; } /* End of RT_SHA1_Hash */