/* * Update the message digest with the contents of BUF with length LEN. */ void sha1_update(struct sha1_context *ctx, const byte *buf, uint len) { if (ctx->count) { /* Fill rest of internal buffer */ for (; len && ctx->count < SHA1_BLOCK_SIZE; len--) ctx->buf[ctx->count++] = *buf++; if (ctx->count < SHA1_BLOCK_SIZE) return; /* Process data from internal buffer */ sha1_transform(ctx, ctx->buf); ctx->nblocks++; ctx->count = 0; } if (!len) return; /* Process data from input buffer */ while (len >= SHA1_BLOCK_SIZE) { sha1_transform(ctx, buf); ctx->nblocks++; buf += SHA1_BLOCK_SIZE; len -= SHA1_BLOCK_SIZE; } /* Copy remaining data to internal buffer */ memcpy(ctx->buf, buf, len); ctx->count = len; }
/* hash more data */ EXPORT void sha1_update(struct sha1_context *ctx, const char *data, size_t len) { uint8_t offset = ctx->length & (SHA1_BLOCKSIZE - 1); ctx->length += len; if (offset + len >= SHA1_BLOCKSIZE) { uint8_t n = SHA1_BLOCKSIZE - offset; memcpy(ctx->buf + offset, data, n); sha1_transform(ctx->state, ctx->buf); data += n; len -= n; while (len >= SHA1_BLOCKSIZE) { memcpy(ctx->buf, data, SHA1_BLOCKSIZE); sha1_transform(ctx->state, ctx->buf); data += SHA1_BLOCKSIZE; len -= SHA1_BLOCKSIZE; } memcpy(ctx->buf, data, len); } else memcpy(ctx->buf + offset, data, len); }
/* end hashing and return the final hash */ EXPORT void sha1_final(struct sha1_context *ctx, char out[SHA1_DIGEST_LENGTH]) { uint8_t offset = ctx->length & (SHA1_BLOCKSIZE - 1); uint8_t i; /* append the '1' bit */ ctx->buf[offset++] = 0x80; /* if there are less than 8 bytes of the buffer free * for the bitsize, append zeros and transform */ if (offset > SHA1_BLOCKSIZE - 8) { while (offset < SHA1_BLOCKSIZE) ctx->buf[offset++] = 0; sha1_transform(ctx->state, ctx->buf); offset = 0; } /* pad with zeroes until we add the bitsize */ while (offset < SHA1_BLOCKSIZE - sizeof(ctx->length)) ctx->buf[offset++] = 0; /* store bitsize big-endian and do the final transform */ #ifdef WORD_BIGENDIAN memcpy(ctx->buf + offset, &ctx->length, sizeof(ctx->length)); #else /* ctx->buf[offset++] = (ctx->length >> 53) & 0xff; ctx->buf[offset++] = (ctx->length >> 45) & 0xff; ctx->buf[offset++] = (ctx->length >> 37) & 0xff; ctx->buf[offset++] = (ctx->length >> 29) & 0xff; ctx->buf[offset++] = (ctx->length >> 21) & 0xff; ctx->buf[offset++] = (ctx->length >> 13) & 0xff; */ ctx->buf[offset++] = (ctx->length >> 5) & 0xff; ctx->buf[offset++] = (ctx->length << 3) & 0xff; #endif sha1_transform(ctx->state, ctx->buf); /* copy output */ #ifdef WORD_BIGENDAN memcpy(out, ctx->state, SHA1_DIGEST_LENGTH); #else for (i = 0; i < 5; i++) { *out++ = (ctx->state[i] >> 24) & 0xff; *out++ = (ctx->state[i] >> 16) & 0xff; *out++ = (ctx->state[i] >> 8) & 0xff; *out++ = ctx->state[i] & 0xff; } #endif }
/* * The routine final terminates the computation and returns the digest. The * handle is prepared for a new cycle, but adding bytes to the handle will the * destroy the returned buffer. * * Returns: 20 bytes representing the digest. */ byte * sha1_final(struct sha1_context *ctx) { u32 t, msb, lsb; sha1_update(ctx, NULL, 0); /* flush */ t = ctx->nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; if ((lsb += ctx->count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; if (ctx->count < 56) { /* enough room */ ctx->buf[ctx->count++] = 0x80; /* pad */ while (ctx->count < 56) ctx->buf[ctx->count++] = 0; /* pad */ } else { /* need one extra block */ ctx->buf[ctx->count++] = 0x80; /* pad character */ while (ctx->count < 64) ctx->buf[ctx->count++] = 0; sha1_update(ctx, NULL, 0); /* flush */ memset(ctx->buf, 0, 56); /* fill next block with zeroes */ } /* append the 64 bit count */ ctx->buf[56] = msb >> 24; ctx->buf[57] = msb >> 16; ctx->buf[58] = msb >> 8; ctx->buf[59] = msb; ctx->buf[60] = lsb >> 24; ctx->buf[61] = lsb >> 16; ctx->buf[62] = lsb >> 8; ctx->buf[63] = lsb; sha1_transform(ctx, ctx->buf); byte *p = ctx->buf; #define X(a) do { put_u32(p, ctx->h##a); p += 4; } while(0) X(0); X(1); X(2); X(3); X(4); #undef X return ctx->buf; }
static void sha1oracle_consume (struct mdblock *mp, const u_char block[64]) { sha1oracle_ctx *soc = (sha1oracle_ctx *) mp; size_t i; if (soc->firstblock) { u_char wblock[64]; memcpy (wblock, block, sizeof (wblock)); for (i = 0; i < soc->nstate; i++) { puthyper (wblock, i); sha1_transform (soc->state[i], wblock); } soc->firstblock = 0; return; } for (i = 0; i < soc->nstate; i++) sha1_transform (soc->state[i], block); }
int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) { u8 xkey[64]; u32 t[5], _t[5]; int i, j, m, k; u8 *xpos = x; u32 carry; if (seed_len < sizeof(xkey)) os_memset(xkey + seed_len, 0, sizeof(xkey) - seed_len); else seed_len = sizeof(xkey); /* FIPS 186-2 + change notice 1 */ os_memcpy(xkey, seed, seed_len); t[0] = 0x67452301; t[1] = 0xEFCDAB89; t[2] = 0x98BADCFE; t[3] = 0x10325476; t[4] = 0xC3D2E1F0; m = xlen / 40; for (j = 0; j < m; j++) { /* XSEED_j = 0 */ for (i = 0; i < 2; i++) { /* XVAL = (XKEY + XSEED_j) mod 2^b */ /* w_i = G(t, XVAL) */ os_memcpy(_t, t, 20); sha1_transform((u8 *) _t, xkey); _t[0] = host_to_be32(_t[0]); _t[1] = host_to_be32(_t[1]); _t[2] = host_to_be32(_t[2]); _t[3] = host_to_be32(_t[3]); _t[4] = host_to_be32(_t[4]); os_memcpy(xpos, _t, 20); /* XKEY = (1 + XKEY + w_i) mod 2^b */ carry = 1; for (k = 19; k >= 0; k--) { carry += xkey[k] + xpos[k]; xkey[k] = carry & 0xff; carry >>= 8; } xpos += 20; } /* x_j = w_0|w_1 */ } return 0; }
void sha1_update(SHA1 *sha1, const uint8_t *data, size_t length) { size_t i, j; j = (size_t)((sha1->count >> 3) & 63); sha1->count += (uint64_t)length << 3; if ((j + length) > 63) { i = 64 - j; memcpy(&sha1->buffer[j], data, i); sha1_transform(sha1, sha1->buffer); for (; i + 63 < length; i += 64) { sha1_transform(sha1, &data[i]); } j = 0; } else { i = 0; } memcpy(&sha1->buffer[j], &data[i], length - i); }