void SHA256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len) { unsigned int block_nb; unsigned int new_len, rem_len, tmp_len; const uint8_t *shifted_data; tmp_len = SHA256_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], data, rem_len); if (ctx->len + len < SHA256_BLOCK_SIZE) { ctx->len += len; return; } new_len = len - rem_len; block_nb = new_len / SHA256_BLOCK_SIZE; shifted_data = data + rem_len; SHA256_transform(ctx, ctx->block, 1); SHA256_transform(ctx, shifted_data, block_nb); rem_len = new_len % SHA256_BLOCK_SIZE; memcpy(ctx->block, &shifted_data[block_nb << 6], rem_len); ctx->len = rem_len; ctx->tot_len += (block_nb + 1) << 6; }
void SHA256_update( SHA256_ctx* ctx, const unsigned char *data, unsigned int length) { unsigned int use; unsigned int low_bits; /* convert length to bits and add to the 64 bit word formed by lbits * and hbits */ ctx->hbits += length >> 29; low_bits = length << 3; ctx->lbits += low_bits; if ( ctx->lbits < low_bits ) { ctx->hbits++; } /* deal with first block */ use = min( 64 - ctx->mlen, length ); memcpy( ctx->M + ctx->mlen, data, use ); ctx->mlen += use; length -= use; data += use; while ( ctx->mlen == 64 ) { convert_to_bigendian( (unsigned int*)ctx->M, 64 ); SHA256_transform( ctx ); use = min( 64, length ); memcpy( ctx->M, data, use ); ctx->mlen = use; length -= use; data += use; /* was missing */ } }
void SHA256_final( SHA256_ctx* ctx ) { if ( ctx->mlen < 56 ) { ctx->M[ ctx->mlen ] = 0x80; ctx->mlen++; memset( ctx->M + ctx->mlen, 0x00, 56 - ctx->mlen ); convert_to_bigendian( ctx->M, 56 ); } else { ctx->M[ ctx->mlen ] = 0x80; ctx->mlen++; memset( ctx->M + ctx->mlen, 0x00, 64 - ctx->mlen ); convert_to_bigendian( ctx->M, 64 ); SHA256_transform( ctx ); memset( ctx->M, 0x00, 56 ); } memcpy( ctx->M + 56, (void*)(&(ctx->hbits)), 8 ); SHA256_transform( ctx ); }
uint8_t *SHA256_final(struct sha256_ctx *ctx) { unsigned int block_nb; unsigned int pm_len; unsigned int len_b; int i; block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))); len_b = (ctx->tot_len + ctx->len) << 3; pm_len = block_nb << 6; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK32(len_b, ctx->block + pm_len - 4); SHA256_transform(ctx, ctx->block, block_nb); for (i = 0; i < 8; i++) UNPACK32(ctx->h[i], &ctx->buf[i << 2]); return ctx->buf; }