int sha512_process(sha512_state * md, const unsigned char *in, unsigned long inlen) { unsigned long n; int block_size = sizeof(md->buf); if (md->curlen > block_size) return FALSE; while (inlen > 0) { if (md->curlen == 0 && inlen >= block_size) { sha512_transform(md->state, (unsigned char *)in); md->length += block_size * 8; in += block_size; inlen -= block_size; } else { n = MIN(inlen, (block_size - md->curlen)); memcpy(md->buf + md->curlen, in, (size_t)n); md->curlen += n; in += n; inlen -= n; if (md->curlen == block_size) { sha512_transform(md->state, md->buf); md->length += block_size * 8; md->curlen = 0; } } } return TRUE; }
void akmos_sha2_512_update(akmos_sha2_512_t *ctx, const uint8_t *input, size_t len) { size_t nb, new_len, rem_len, tmp_len; const uint8_t *sfi; tmp_len = AKMOS_SHA2_512_BLKLEN - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], input, rem_len); if(ctx->len + len < AKMOS_SHA2_512_BLKLEN) { ctx->len += len; return; } new_len = len - rem_len; nb = new_len / AKMOS_SHA2_512_BLKLEN; sfi = input + rem_len; sha512_transform(ctx->h, ctx->w, ctx->block, 1 & SIZE_T_MAX); sha512_transform(ctx->h, ctx->w, sfi, nb); rem_len = new_len % AKMOS_SHA2_512_BLKLEN; memcpy(ctx->block, &sfi[nb * 128], rem_len); ctx->len = rem_len; ctx->total += (nb + 1); }
static SshCryptoStatus sha512_final(void *c, unsigned char *digest, int num_64bit_words ) { SshSHA512Context *context = c; int padding, i; unsigned char temp = 0x80; unsigned int in_buffer; SshUInt32 total_low, total_high; total_low = context->total_length[0]; total_high = context->total_length[1]; ssh_sha512_update(context, &temp, 1); in_buffer = context->total_length[0] % 128; padding = (128 - (in_buffer + 17) % 128) % 128; if (in_buffer > 112) { memset(&context->u.in[in_buffer], 0, 128 - in_buffer); padding -= (128 - in_buffer); sha512_transform(context, context->u.in); in_buffer = 0; } /* Change the byte count to bit count. */ total_high <<= 3; total_high += (total_low >> 29); total_low <<= 3; SSH_PUT_32BIT(context->u.in + 120, total_high); SSH_PUT_32BIT(context->u.in + 124, total_low); /* Highest bits of length are always zero */ SSH_PUT_32BIT(context->u.in + 116, 0); SSH_PUT_32BIT(context->u.in + 112, 0); if ((128 - in_buffer - 16) > 0) { memset(&context->u.in[in_buffer], 0, 128 - in_buffer - 16); } sha512_transform(context, context->u.in); /* Copy the internal state to the digest output. */ for (i = 0; i < num_64bit_words; i++) { SSH_XUINT64_PUT(context->H[i], digest + i*8); } memset(context, 0, sizeof(SshSHA512Context)); return SSH_CRYPTO_OK; }
static void sha512_generic_block_fn(struct sha512_state *sst, u8 const *src, int blocks) { while (blocks--) { sha512_transform(sst->state, src); src += SHA512_BLOCK_SIZE; } }
int sha512_done(sha512_state * md, unsigned char *out) { int i; if (md->curlen >= sizeof(md->buf)) return FALSE; /* increase the length of the message */ md->length += md->curlen * CONST64(8); /* append the '1' bit */ md->buf[md->curlen++] = (unsigned char)0x80; /* if the length is currently above 112 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->curlen > 112) { while (md->curlen < 128) { md->buf[md->curlen++] = (unsigned char)0; } sha512_transform(md->state, md->buf); md->curlen = 0; } /* pad upto 120 bytes of zeroes * note: that from 112 to 120 is the 64 MSB of the length. We * assume that you won't hash > 2^64 bits of data... :-) */ while (md->curlen < 120) { md->buf[md->curlen++] = (unsigned char)0; } /* store length */ SILC_PUT64_MSB(md->length, md->buf + 120); sha512_transform(md->state, md->buf); /* copy output */ for (i = 0; i < 8; i += 2) { SILC_PUT64_MSB(md->state[i], out + (8 * i)); SILC_PUT64_MSB(md->state[i + 1], out + (8 * (i + 1))); } return TRUE; }
void ssh_sha512_update(void *c, const unsigned char *buf, size_t len ) { SshSHA512Context *context = c; unsigned int to_copy = 0; unsigned int in_buffer; SshUInt32 old_length = context->total_length[0]; in_buffer = old_length % 128; context->total_length[0] += len; context->total_length[0] &= 0xFFFFFFFFL; if (context->total_length[0] < old_length) /* carry */ context->total_length[1]++; while (len > 0) { if (in_buffer == 0 && len >= 128) { sha512_transform(context, buf); buf += 128; len -= 128; continue; } /* do copy? */ to_copy = 128 - in_buffer; if (to_copy > 0) { if (to_copy > len) to_copy = len; memcpy(&context->u.in[in_buffer], buf, to_copy); buf += to_copy; len -= to_copy; in_buffer += to_copy; if (in_buffer == 128) { sha512_transform(context, context->u.in); in_buffer = 0; } } } }
void sha512_final (SHA512Schedule *ctx, char *digest) { register unsigned int i = 0 ; register unsigned int pad = ctx->len % 128; ctx->buf[pad++] = 0x80 ; if (pad > 112) { byte_zero(ctx->buf + pad, 128 - pad) ; sha512_transform(ctx, ctx->buf) ; pad = 0 ; } byte_zero(ctx->buf + pad, 120 - pad) ; uint64_pack_big((char *)ctx->buf + 120, ctx->len << 3) ; sha512_transform(ctx, ctx->buf) ; for (; i < 8 ; i++) uint64_pack_big(digest + (i << 3), ctx->h[i]) ; }
void akmos_sha2_512_done(akmos_sha2_512_t *ctx, uint8_t *digest) { size_t i, nb, pm_len; uint64_t len_b; nb = (1 + ((AKMOS_SHA2_512_BLKLEN - 17) < (ctx->len % AKMOS_SHA2_512_BLKLEN))); len_b = ((ctx->total * 128) + ctx->len) * 8; pm_len = nb * 128; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK64LE(ctx->block + pm_len - 8, len_b); if(nb > 0) sha512_transform(ctx->h, ctx->w, ctx->block, nb); for(i = 0; i < ctx->diglen / (sizeof(uint64_t)); i++) UNPACK64LE(digest + (i * sizeof(uint64_t)), ctx->h[i]); }