/*ARGSUSED*/ void zio_checksum_SHA512_native(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { SHA2_CTX ctx; SHA2Init(SHA512_256, &ctx); SHA2Update(&ctx, buf, size); SHA2Final(zcp, &ctx); }
/*ARGSUSED*/ void abd_checksum_SHA512_native(abd_t *abd, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { SHA2_CTX ctx; SHA2Init(SHA512_256, &ctx); (void) abd_iterate_func(abd, 0, size, sha_incremental, &ctx); SHA2Final(zcp, &ctx); }
/* * Like pkcs11:mac_init_ctx() */ static int smb2_hmac_sha256_init(sha2_hc_ctx_t *hc, uint8_t *key, uint_t key_len) { uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK]; uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK]; sha2_mech_type_t mech = SHA256_HMAC_MECH_INFO_TYPE; int i; bzero(sha_ipad, sizeof (sha_ipad)); bzero(sha_opad, sizeof (sha_opad)); if (key_len > SHA256_HMAC_BLOCK_SIZE) { /* * Digest the key when it is longer than 64 bytes. * (Not needed for SMB2 signing.) */ return (-1); } (void) memcpy(sha_ipad, key, key_len); (void) memcpy(sha_opad, key, key_len); /* XOR key with ipad (0x36) and opad (0x5c) */ for (i = 0; i < SHA256_HMAC_INTS_PER_BLOCK; i ++) { sha_ipad[i] ^= 0x3636363636363636ULL; sha_opad[i] ^= 0x5c5c5c5c5c5c5c5cULL; } /* perform SHA2 on ipad */ SHA2Init(mech, &hc->hc_icontext); SHA2Update(&hc->hc_icontext, (uint8_t *)sha_ipad, sizeof (sha_ipad)); /* perform SHA2 on opad */ SHA2Init(mech, &hc->hc_ocontext); SHA2Update(&hc->hc_ocontext, (uint8_t *)sha_opad, sizeof (sha_opad)); return (0); }
/* * Initialize a SHA2-HMAC context. */ static void sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes) { uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)]; uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)]; int i, block_size, blocks_per_int64; /* Determine the block size */ if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) { block_size = SHA256_HMAC_BLOCK_SIZE; blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t); } else { block_size = SHA512_HMAC_BLOCK_SIZE; blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t); } (void) bzero(ipad, block_size); (void) bzero(opad, block_size); (void) bcopy(keyval, ipad, length_in_bytes); (void) bcopy(keyval, opad, length_in_bytes); /* XOR key with ipad (0x36) and opad (0x5c) */ for (i = 0; i < blocks_per_int64; i ++) { ipad[i] ^= 0x3636363636363636; opad[i] ^= 0x5c5c5c5c5c5c5c5c; } /* perform SHA2 on ipad */ SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext); SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size); /* perform SHA2 on opad */ SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext); SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size); }
static int sha2_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, crypto_req_handle_t req) { /* * Allocate and initialize SHA2 context. */ ctx->cc_provider_private = kmem_alloc(sizeof (sha2_ctx_t), crypto_kmflag(req)); if (ctx->cc_provider_private == NULL) return (CRYPTO_HOST_MEMORY); PROV_SHA2_CTX(ctx)->sc_mech_type = mechanism->cm_type; SHA2Init(mechanism->cm_type, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx); return (CRYPTO_SUCCESS); }
/*ARGSUSED*/ void zio_checksum_SHA256(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { SHA2_CTX ctx; zio_cksum_t tmp; SHA2Init(SHA256, &ctx); SHA2Update(&ctx, buf, size); SHA2Final(&tmp, &ctx); /* * A prior implementation of this function had a * private SHA256 implementation always wrote things out in * Big Endian and there wasn't a byteswap variant of it. * To preseve on disk compatibility we need to force that * behaviour. */ zcp->zc_word[0] = BE_64(tmp.zc_word[0]); zcp->zc_word[1] = BE_64(tmp.zc_word[1]); zcp->zc_word[2] = BE_64(tmp.zc_word[2]); zcp->zc_word[3] = BE_64(tmp.zc_word[3]); }
/* ARGSUSED */ static int sha2_digest_atomic(crypto_provider_handle_t provider, crypto_session_id_t session_id, crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_data_t *digest, crypto_req_handle_t req) { int ret = CRYPTO_SUCCESS; SHA2_CTX sha2_ctx; uint32_t sha_digest_len; /* * Do the SHA inits. */ SHA2Init(mechanism->cm_type, &sha2_ctx); switch (data->cd_format) { case CRYPTO_DATA_RAW: SHA2Update(&sha2_ctx, (uint8_t *)data-> cd_raw.iov_base + data->cd_offset, data->cd_length); break; case CRYPTO_DATA_UIO: ret = sha2_digest_update_uio(&sha2_ctx, data); break; case CRYPTO_DATA_MBLK: ret = sha2_digest_update_mblk(&sha2_ctx, data); break; default: ret = CRYPTO_ARGUMENTS_BAD; } /* * Do the SHA updates on the specified input data. */ if (ret != CRYPTO_SUCCESS) { /* the update failed, bail */ digest->cd_length = 0; return (ret); } if (mechanism->cm_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) sha_digest_len = SHA256_DIGEST_LENGTH; else sha_digest_len = SHA512_DIGEST_LENGTH; /* * Do a SHA2 final, must be done separately since the digest * type can be different than the input data type. */ switch (digest->cd_format) { case CRYPTO_DATA_RAW: SHA2Final((unsigned char *)digest->cd_raw.iov_base + digest->cd_offset, &sha2_ctx); break; case CRYPTO_DATA_UIO: ret = sha2_digest_final_uio(&sha2_ctx, digest, sha_digest_len, NULL); break; case CRYPTO_DATA_MBLK: ret = sha2_digest_final_mblk(&sha2_ctx, digest, sha_digest_len, NULL); break; default: ret = CRYPTO_ARGUMENTS_BAD; } if (ret == CRYPTO_SUCCESS) digest->cd_length = sha_digest_len; else digest->cd_length = 0; return (ret); }