void zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp) { uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; uint8_t pad[128]; int i, padsize; for (i = 0; i < (size & ~63ULL); i += 64) SHA256Transform(H, (uint8_t *)buf + i); for (padsize = 0; i < size; i++) pad[padsize++] = *((uint8_t *)buf + i); for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) pad[padsize] = 0; for (i = 56; i >= 0; i -= 8) pad[padsize++] = (size << 3) >> i; for (i = 0; i < padsize; i += 64) SHA256Transform(H, pad + i); ZIO_SET_CHECKSUM(zcp, (uint64_t)H[0] << 32 | H[1], (uint64_t)H[2] << 32 | H[3], (uint64_t)H[4] << 32 | H[5], (uint64_t)H[6] << 32 | H[7]); }
void zio_checksum_SHA256(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, zio_cksum_t *zcp) { grub_uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; grub_uint8_t pad[128]; unsigned padsize = size & 63; unsigned i; for (i = 0; i < size - padsize; i += 64) SHA256Transform(H, (grub_uint8_t *)buf + i); for (i = 0; i < padsize; i++) pad[i] = ((grub_uint8_t *)buf)[i]; for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) pad[padsize] = 0; for (i = 0; i < 8; i++) pad[padsize++] = (size << 3) >> (56 - 8 * i); for (i = 0; i < padsize; i += 64) SHA256Transform(H, pad + i); zcp->zc_word[0] = grub_cpu_to_zfs64 ((grub_uint64_t)H[0] << 32 | H[1], endian); zcp->zc_word[1] = grub_cpu_to_zfs64 ((grub_uint64_t)H[2] << 32 | H[3], endian); zcp->zc_word[2] = grub_cpu_to_zfs64 ((grub_uint64_t)H[4] << 32 | H[5], endian); zcp->zc_word[3] = grub_cpu_to_zfs64 ((grub_uint64_t)H[6] << 32 | H[7], endian); }
void SHA256Update(SHA2_CTX *ctx, const uint8_t *data, size_t len) { size_t i = 0, j; j = (size_t)((ctx->count[0] >> 3) & (SHA256_BLOCK_LENGTH - 1)); ctx->count[0] += (len << 3); if ((j + len) > SHA256_BLOCK_LENGTH - 1) { memcpy(&ctx->buffer[j], data, (i = SHA256_BLOCK_LENGTH - j)); SHA256Transform(ctx->state.st32, ctx->buffer); for ( ; i + SHA256_BLOCK_LENGTH - 1 < len; i += SHA256_BLOCK_LENGTH) SHA256Transform(ctx->state.st32, (uint8_t *)&data[i]); j = 0; } memcpy(&ctx->buffer[j], &data[i], len - i); }
void SHA256Final(SHA256Context *ctx, unsigned char *digest) { unsigned int block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))); unsigned int len_b = (ctx->tot_len + ctx->len) << 3; unsigned int 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); SHA256Transform(ctx, ctx->block, block_nb); for (int i = 0 ; i < 8; i++) UNPACK32(ctx->h[i], &digest[i << 2]); }
void SHA256Update(SHA256Context *ctx, unsigned char *message, unsigned int len) { /* * XXX here be dragons! * After many hours of pouring over this, I think I've found the problem. * When Special created our module from the reference one, he used: * * unsigned int rem_len = SHA256_BLOCK_SIZE - ctx->len; * * instead of the reference's version of: * * unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len; * unsigned int rem_len = len < tmp_len ? len : tmp_len; * * I've changed back to the reference version of this code, and it seems to work with no errors. * So I'm inclined to believe this was the problem.. * -- w00t (January 06, 2008) */ unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len; unsigned int rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], message, rem_len); if (ctx->len + len < SHA256_BLOCK_SIZE) { ctx->len += len; return; } unsigned int new_len = len - rem_len; unsigned int block_nb = new_len / SHA256_BLOCK_SIZE; unsigned char *shifted_message = message + rem_len; SHA256Transform(ctx, ctx->block, 1); SHA256Transform(ctx, shifted_message, block_nb); rem_len = new_len % SHA256_BLOCK_SIZE; memcpy(ctx->block, &shifted_message[block_nb << 6],rem_len); ctx->len = rem_len; ctx->tot_len += (block_nb + 1) << 6; }
void SHA224Transform(uint32_t state[8], const uint8_t buffer[SHA224_BLOCK_LENGTH]) { SHA256Transform(state, buffer); }