mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
icp: brutally remove unused AES modes
Still retaining the struture, for now. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #16209
This commit is contained in:
committed by
Brian Behlendorf
parent
4185179190
commit
57249bcddc
+24
-360
@@ -40,18 +40,6 @@
|
||||
* Mechanism info structure passed to KCF during registration.
|
||||
*/
|
||||
static const crypto_mech_info_t aes_mech_info_tab[] = {
|
||||
/* AES_ECB */
|
||||
{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
|
||||
CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
|
||||
CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC},
|
||||
/* AES_CBC */
|
||||
{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
|
||||
CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
|
||||
CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC},
|
||||
/* AES_CTR */
|
||||
{SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
|
||||
CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
|
||||
CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC},
|
||||
/* AES_CCM */
|
||||
{SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
|
||||
CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
|
||||
@@ -60,11 +48,6 @@ static const crypto_mech_info_t aes_mech_info_tab[] = {
|
||||
{SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
|
||||
CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
|
||||
CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC},
|
||||
/* AES_GMAC */
|
||||
{SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
|
||||
CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
|
||||
CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
|
||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||
};
|
||||
|
||||
static int aes_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
|
||||
@@ -103,20 +86,6 @@ static const crypto_cipher_ops_t aes_cipher_ops = {
|
||||
.decrypt_atomic = aes_decrypt_atomic
|
||||
};
|
||||
|
||||
static int aes_mac_atomic(crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
|
||||
crypto_data_t *, crypto_spi_ctx_template_t);
|
||||
static int aes_mac_verify_atomic(crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t);
|
||||
|
||||
static const crypto_mac_ops_t aes_mac_ops = {
|
||||
.mac_init = NULL,
|
||||
.mac = NULL,
|
||||
.mac_update = NULL,
|
||||
.mac_final = NULL,
|
||||
.mac_atomic = aes_mac_atomic,
|
||||
.mac_verify_atomic = aes_mac_verify_atomic
|
||||
};
|
||||
|
||||
static int aes_create_ctx_template(crypto_mechanism_t *, crypto_key_t *,
|
||||
crypto_spi_ctx_template_t *, size_t *);
|
||||
static int aes_free_context(crypto_ctx_t *);
|
||||
@@ -129,7 +98,7 @@ static const crypto_ctx_ops_t aes_ctx_ops = {
|
||||
static const crypto_ops_t aes_crypto_ops = {
|
||||
NULL,
|
||||
&aes_cipher_ops,
|
||||
&aes_mac_ops,
|
||||
NULL,
|
||||
&aes_ctx_ops,
|
||||
};
|
||||
|
||||
@@ -141,7 +110,6 @@ static const crypto_provider_info_t aes_prov_info = {
|
||||
};
|
||||
|
||||
static crypto_kcf_provider_handle_t aes_prov_handle = 0;
|
||||
static crypto_data_t null_crypto_data = { CRYPTO_DATA_RAW };
|
||||
|
||||
int
|
||||
aes_mod_init(void)
|
||||
@@ -181,18 +149,6 @@ aes_check_mech_param(crypto_mechanism_t *mechanism, aes_ctx_t **ctx)
|
||||
int rv = CRYPTO_SUCCESS;
|
||||
|
||||
switch (mechanism->cm_type) {
|
||||
case AES_ECB_MECH_INFO_TYPE:
|
||||
param_required = B_FALSE;
|
||||
alloc_fun = ecb_alloc_ctx;
|
||||
break;
|
||||
case AES_CBC_MECH_INFO_TYPE:
|
||||
param_len = AES_BLOCK_LEN;
|
||||
alloc_fun = cbc_alloc_ctx;
|
||||
break;
|
||||
case AES_CTR_MECH_INFO_TYPE:
|
||||
param_len = sizeof (CK_AES_CTR_PARAMS);
|
||||
alloc_fun = ctr_alloc_ctx;
|
||||
break;
|
||||
case AES_CCM_MECH_INFO_TYPE:
|
||||
param_len = sizeof (CK_AES_CCM_PARAMS);
|
||||
alloc_fun = ccm_alloc_ctx;
|
||||
@@ -201,13 +157,8 @@ aes_check_mech_param(crypto_mechanism_t *mechanism, aes_ctx_t **ctx)
|
||||
param_len = sizeof (CK_AES_GCM_PARAMS);
|
||||
alloc_fun = gcm_alloc_ctx;
|
||||
break;
|
||||
case AES_GMAC_MECH_INFO_TYPE:
|
||||
param_len = sizeof (CK_AES_GMAC_PARAMS);
|
||||
alloc_fun = gmac_alloc_ctx;
|
||||
break;
|
||||
default:
|
||||
rv = CRYPTO_MECHANISM_INVALID;
|
||||
return (rv);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
if (param_required && mechanism->cm_param != NULL &&
|
||||
mechanism->cm_param_len != param_len) {
|
||||
@@ -282,22 +233,6 @@ aes_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
aes_copy_block64(uint8_t *in, uint64_t *out)
|
||||
{
|
||||
if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
|
||||
/* LINTED: pointer alignment */
|
||||
out[0] = *(uint64_t *)&in[0];
|
||||
/* LINTED: pointer alignment */
|
||||
out[1] = *(uint64_t *)&in[8];
|
||||
} else {
|
||||
uint8_t *iv8 = (uint8_t *)&out[0];
|
||||
|
||||
AES_COPY_BLOCK(in, iv8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
|
||||
crypto_data_t *ciphertext)
|
||||
@@ -310,35 +245,21 @@ aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
|
||||
ASSERT(ctx->cc_provider_private != NULL);
|
||||
aes_ctx = ctx->cc_provider_private;
|
||||
|
||||
/*
|
||||
* For block ciphers, plaintext must be a multiple of AES block size.
|
||||
* This test is only valid for ciphers whose blocksize is a power of 2.
|
||||
*/
|
||||
if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE))
|
||||
== 0) && (plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
|
||||
ASSERT(ciphertext != NULL);
|
||||
|
||||
/*
|
||||
* We need to just return the length needed to store the output.
|
||||
* We should not destroy the context for the following case.
|
||||
*/
|
||||
switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) {
|
||||
switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE)) {
|
||||
case CCM_MODE:
|
||||
length_needed = plaintext->cd_length + aes_ctx->ac_mac_len;
|
||||
break;
|
||||
case GCM_MODE:
|
||||
length_needed = plaintext->cd_length + aes_ctx->ac_tag_len;
|
||||
break;
|
||||
case GMAC_MODE:
|
||||
if (plaintext->cd_length != 0)
|
||||
return (CRYPTO_ARGUMENTS_BAD);
|
||||
|
||||
length_needed = aes_ctx->ac_tag_len;
|
||||
break;
|
||||
default:
|
||||
length_needed = plaintext->cd_length;
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
if (ciphertext->cd_length < length_needed) {
|
||||
@@ -382,7 +303,7 @@ aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
|
||||
ciphertext->cd_offset - saved_offset;
|
||||
}
|
||||
ciphertext->cd_offset = saved_offset;
|
||||
} else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx->ac_flags & GCM_MODE) {
|
||||
/*
|
||||
* gcm_encrypt_final() will compute the MAC and append
|
||||
* it to existing ciphertext. So, need to adjust the left over
|
||||
@@ -426,15 +347,6 @@ aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
|
||||
ASSERT(ctx->cc_provider_private != NULL);
|
||||
aes_ctx = ctx->cc_provider_private;
|
||||
|
||||
/*
|
||||
* For block ciphers, plaintext must be a multiple of AES block size.
|
||||
* This test is only valid for ciphers whose blocksize is a power of 2.
|
||||
*/
|
||||
if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE))
|
||||
== 0) && (ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0) {
|
||||
return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
|
||||
}
|
||||
|
||||
ASSERT(plaintext != NULL);
|
||||
|
||||
/*
|
||||
@@ -443,23 +355,16 @@ aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
|
||||
*
|
||||
* CCM: plaintext is MAC len smaller than cipher text
|
||||
* GCM: plaintext is TAG len smaller than cipher text
|
||||
* GMAC: plaintext length must be zero
|
||||
*/
|
||||
switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) {
|
||||
switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE)) {
|
||||
case CCM_MODE:
|
||||
length_needed = aes_ctx->ac_processed_data_len;
|
||||
break;
|
||||
case GCM_MODE:
|
||||
length_needed = ciphertext->cd_length - aes_ctx->ac_tag_len;
|
||||
break;
|
||||
case GMAC_MODE:
|
||||
if (plaintext->cd_length != 0)
|
||||
return (CRYPTO_ARGUMENTS_BAD);
|
||||
|
||||
length_needed = 0;
|
||||
break;
|
||||
default:
|
||||
length_needed = ciphertext->cd_length;
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
if (plaintext->cd_length < length_needed) {
|
||||
@@ -499,7 +404,7 @@ aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
|
||||
}
|
||||
|
||||
plaintext->cd_offset = saved_offset;
|
||||
} else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx->ac_flags & GCM_MODE) {
|
||||
/* order of following 2 lines MUST not be reversed */
|
||||
plaintext->cd_offset = plaintext->cd_length;
|
||||
plaintext->cd_length = saved_length - plaintext->cd_length;
|
||||
@@ -571,17 +476,6 @@ aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
|
||||
ret = CRYPTO_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since AES counter mode is a stream cipher, we call
|
||||
* ctr_mode_final() to pick up any remaining bytes.
|
||||
* It is an internal function that does not destroy
|
||||
* the context like *normal* final routines.
|
||||
*/
|
||||
if ((aes_ctx->ac_flags & CTR_MODE) && (aes_ctx->ac_remainder_len > 0)) {
|
||||
ret = ctr_mode_final((ctr_ctx_t *)aes_ctx,
|
||||
ciphertext, aes_encrypt_block);
|
||||
}
|
||||
|
||||
if (ret == CRYPTO_SUCCESS) {
|
||||
if (plaintext != ciphertext)
|
||||
ciphertext->cd_length =
|
||||
@@ -600,32 +494,13 @@ aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
|
||||
crypto_data_t *plaintext)
|
||||
{
|
||||
off_t saved_offset;
|
||||
size_t saved_length, out_len;
|
||||
size_t saved_length;
|
||||
int ret = CRYPTO_SUCCESS;
|
||||
aes_ctx_t *aes_ctx;
|
||||
|
||||
ASSERT(ctx->cc_provider_private != NULL);
|
||||
aes_ctx = ctx->cc_provider_private;
|
||||
|
||||
ASSERT(plaintext != NULL);
|
||||
|
||||
/*
|
||||
* Compute number of bytes that will hold the plaintext.
|
||||
* This is not necessary for CCM, GCM, and GMAC since these
|
||||
* mechanisms never return plaintext for update operations.
|
||||
*/
|
||||
if ((aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) == 0) {
|
||||
out_len = aes_ctx->ac_remainder_len;
|
||||
out_len += ciphertext->cd_length;
|
||||
out_len &= ~(AES_BLOCK_LEN - 1);
|
||||
|
||||
/* return length needed to store the output */
|
||||
if (plaintext->cd_length < out_len) {
|
||||
plaintext->cd_length = out_len;
|
||||
return (CRYPTO_BUFFER_TOO_SMALL);
|
||||
}
|
||||
}
|
||||
|
||||
saved_offset = plaintext->cd_offset;
|
||||
saved_length = plaintext->cd_length;
|
||||
|
||||
@@ -645,19 +520,6 @@ aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
|
||||
ret = CRYPTO_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since AES counter mode is a stream cipher, we call
|
||||
* ctr_mode_final() to pick up any remaining bytes.
|
||||
* It is an internal function that does not destroy
|
||||
* the context like *normal* final routines.
|
||||
*/
|
||||
if ((aes_ctx->ac_flags & CTR_MODE) && (aes_ctx->ac_remainder_len > 0)) {
|
||||
ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, plaintext,
|
||||
aes_encrypt_block);
|
||||
if (ret == CRYPTO_DATA_LEN_RANGE)
|
||||
ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
|
||||
}
|
||||
|
||||
if (ret == CRYPTO_SUCCESS) {
|
||||
if (ciphertext != plaintext)
|
||||
plaintext->cd_length =
|
||||
@@ -685,20 +547,13 @@ aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data)
|
||||
return (CRYPTO_ARGUMENTS_BAD);
|
||||
}
|
||||
|
||||
if (aes_ctx->ac_flags & CTR_MODE) {
|
||||
if (aes_ctx->ac_remainder_len > 0) {
|
||||
ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, data,
|
||||
aes_encrypt_block);
|
||||
if (ret != CRYPTO_SUCCESS)
|
||||
return (ret);
|
||||
}
|
||||
} else if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
ret = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, data,
|
||||
AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
|
||||
if (ret != CRYPTO_SUCCESS) {
|
||||
return (ret);
|
||||
}
|
||||
} else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx->ac_flags & GCM_MODE) {
|
||||
size_t saved_offset = data->cd_offset;
|
||||
|
||||
ret = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, data,
|
||||
@@ -709,16 +564,6 @@ aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data)
|
||||
}
|
||||
data->cd_length = data->cd_offset - saved_offset;
|
||||
data->cd_offset = saved_offset;
|
||||
} else {
|
||||
/*
|
||||
* There must be no unprocessed plaintext.
|
||||
* This happens if the length of the last data is
|
||||
* not a multiple of the AES block length.
|
||||
*/
|
||||
if (aes_ctx->ac_remainder_len > 0) {
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
}
|
||||
data->cd_length = 0;
|
||||
}
|
||||
|
||||
(void) aes_free_context(ctx);
|
||||
@@ -747,18 +592,8 @@ aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data)
|
||||
* This happens if the length of the last ciphertext is
|
||||
* not a multiple of the AES block length.
|
||||
*/
|
||||
if (aes_ctx->ac_remainder_len > 0) {
|
||||
if ((aes_ctx->ac_flags & CTR_MODE) == 0)
|
||||
return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
|
||||
else {
|
||||
ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, data,
|
||||
aes_encrypt_block);
|
||||
if (ret == CRYPTO_DATA_LEN_RANGE)
|
||||
ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
|
||||
if (ret != CRYPTO_SUCCESS)
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
if (aes_ctx->ac_remainder_len > 0)
|
||||
return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
|
||||
|
||||
if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
/*
|
||||
@@ -788,7 +623,7 @@ aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data)
|
||||
if (ret != CRYPTO_SUCCESS) {
|
||||
return (ret);
|
||||
}
|
||||
} else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx->ac_flags & GCM_MODE) {
|
||||
/*
|
||||
* This is where all the plaintext is returned, make sure
|
||||
* the plaintext buffer is big enough
|
||||
@@ -818,10 +653,6 @@ aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data)
|
||||
}
|
||||
|
||||
|
||||
if ((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) == 0) {
|
||||
data->cd_length = 0;
|
||||
}
|
||||
|
||||
(void) aes_free_context(ctx);
|
||||
|
||||
return (CRYPTO_SUCCESS);
|
||||
@@ -842,21 +673,6 @@ aes_encrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
|
||||
ASSERT(ciphertext != NULL);
|
||||
|
||||
/*
|
||||
* CTR, CCM, GCM, and GMAC modes do not require that plaintext
|
||||
* be a multiple of AES block size.
|
||||
*/
|
||||
switch (mechanism->cm_type) {
|
||||
case AES_CTR_MECH_INFO_TYPE:
|
||||
case AES_CCM_MECH_INFO_TYPE:
|
||||
case AES_GCM_MECH_INFO_TYPE:
|
||||
case AES_GMAC_MECH_INFO_TYPE:
|
||||
break;
|
||||
default:
|
||||
if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
}
|
||||
|
||||
if ((ret = aes_check_mech_param(mechanism, NULL)) != CRYPTO_SUCCESS)
|
||||
return (ret);
|
||||
|
||||
@@ -869,15 +685,11 @@ aes_encrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
case AES_CCM_MECH_INFO_TYPE:
|
||||
length_needed = plaintext->cd_length + aes_ctx.ac_mac_len;
|
||||
break;
|
||||
case AES_GMAC_MECH_INFO_TYPE:
|
||||
if (plaintext->cd_length != 0)
|
||||
return (CRYPTO_ARGUMENTS_BAD);
|
||||
zfs_fallthrough;
|
||||
case AES_GCM_MECH_INFO_TYPE:
|
||||
length_needed = plaintext->cd_length + aes_ctx.ac_tag_len;
|
||||
break;
|
||||
default:
|
||||
length_needed = plaintext->cd_length;
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
/* return size of buffer needed to store output */
|
||||
@@ -914,21 +726,13 @@ aes_encrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
if (ret != CRYPTO_SUCCESS)
|
||||
goto out;
|
||||
ASSERT(aes_ctx.ac_remainder_len == 0);
|
||||
} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE ||
|
||||
mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) {
|
||||
} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE) {
|
||||
ret = gcm_encrypt_final((gcm_ctx_t *)&aes_ctx,
|
||||
ciphertext, AES_BLOCK_LEN, aes_encrypt_block,
|
||||
aes_copy_block, aes_xor_block);
|
||||
if (ret != CRYPTO_SUCCESS)
|
||||
goto out;
|
||||
ASSERT(aes_ctx.ac_remainder_len == 0);
|
||||
} else if (mechanism->cm_type == AES_CTR_MECH_INFO_TYPE) {
|
||||
if (aes_ctx.ac_remainder_len > 0) {
|
||||
ret = ctr_mode_final((ctr_ctx_t *)&aes_ctx,
|
||||
ciphertext, aes_encrypt_block);
|
||||
if (ret != CRYPTO_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
ASSERT(aes_ctx.ac_remainder_len == 0);
|
||||
}
|
||||
@@ -947,7 +751,7 @@ out:
|
||||
memset(aes_ctx.ac_keysched, 0, aes_ctx.ac_keysched_len);
|
||||
kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
|
||||
}
|
||||
if (aes_ctx.ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
if (aes_ctx.ac_flags & GCM_MODE) {
|
||||
gcm_clear_ctx((gcm_ctx_t *)&aes_ctx);
|
||||
}
|
||||
return (ret);
|
||||
@@ -968,21 +772,6 @@ aes_decrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
|
||||
ASSERT(plaintext != NULL);
|
||||
|
||||
/*
|
||||
* CCM, GCM, CTR, and GMAC modes do not require that ciphertext
|
||||
* be a multiple of AES block size.
|
||||
*/
|
||||
switch (mechanism->cm_type) {
|
||||
case AES_CTR_MECH_INFO_TYPE:
|
||||
case AES_CCM_MECH_INFO_TYPE:
|
||||
case AES_GCM_MECH_INFO_TYPE:
|
||||
case AES_GMAC_MECH_INFO_TYPE:
|
||||
break;
|
||||
default:
|
||||
if ((ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
|
||||
return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
|
||||
}
|
||||
|
||||
if ((ret = aes_check_mech_param(mechanism, NULL)) != CRYPTO_SUCCESS)
|
||||
return (ret);
|
||||
|
||||
@@ -998,13 +787,8 @@ aes_decrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
case AES_GCM_MECH_INFO_TYPE:
|
||||
length_needed = ciphertext->cd_length - aes_ctx.ac_tag_len;
|
||||
break;
|
||||
case AES_GMAC_MECH_INFO_TYPE:
|
||||
if (plaintext->cd_length != 0)
|
||||
return (CRYPTO_ARGUMENTS_BAD);
|
||||
length_needed = 0;
|
||||
break;
|
||||
default:
|
||||
length_needed = ciphertext->cd_length;
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
/* return size of buffer needed to store output */
|
||||
@@ -1050,8 +834,7 @@ aes_decrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
} else {
|
||||
plaintext->cd_length = saved_length;
|
||||
}
|
||||
} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE ||
|
||||
mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) {
|
||||
} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE) {
|
||||
ret = gcm_decrypt_final((gcm_ctx_t *)&aes_ctx,
|
||||
plaintext, AES_BLOCK_LEN, aes_encrypt_block,
|
||||
aes_xor_block);
|
||||
@@ -1063,24 +846,8 @@ aes_decrypt_atomic(crypto_mechanism_t *mechanism,
|
||||
} else {
|
||||
plaintext->cd_length = saved_length;
|
||||
}
|
||||
} else if (mechanism->cm_type != AES_CTR_MECH_INFO_TYPE) {
|
||||
ASSERT(aes_ctx.ac_remainder_len == 0);
|
||||
if (ciphertext != plaintext)
|
||||
plaintext->cd_length =
|
||||
plaintext->cd_offset - saved_offset;
|
||||
} else {
|
||||
if (aes_ctx.ac_remainder_len > 0) {
|
||||
ret = ctr_mode_final((ctr_ctx_t *)&aes_ctx,
|
||||
plaintext, aes_encrypt_block);
|
||||
if (ret == CRYPTO_DATA_LEN_RANGE)
|
||||
ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
|
||||
if (ret != CRYPTO_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
if (ciphertext != plaintext)
|
||||
plaintext->cd_length =
|
||||
plaintext->cd_offset - saved_offset;
|
||||
}
|
||||
} else
|
||||
__builtin_unreachable();
|
||||
} else {
|
||||
plaintext->cd_length = saved_length;
|
||||
}
|
||||
@@ -1096,7 +863,7 @@ out:
|
||||
if (aes_ctx.ac_pt_buf != NULL) {
|
||||
vmem_free(aes_ctx.ac_pt_buf, aes_ctx.ac_data_len);
|
||||
}
|
||||
} else if (aes_ctx.ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx.ac_flags & GCM_MODE) {
|
||||
gcm_clear_ctx((gcm_ctx_t *)&aes_ctx);
|
||||
}
|
||||
|
||||
@@ -1114,12 +881,8 @@ aes_create_ctx_template(crypto_mechanism_t *mechanism, crypto_key_t *key,
|
||||
size_t size;
|
||||
int rv;
|
||||
|
||||
if (mechanism->cm_type != AES_ECB_MECH_INFO_TYPE &&
|
||||
mechanism->cm_type != AES_CBC_MECH_INFO_TYPE &&
|
||||
mechanism->cm_type != AES_CTR_MECH_INFO_TYPE &&
|
||||
mechanism->cm_type != AES_CCM_MECH_INFO_TYPE &&
|
||||
mechanism->cm_type != AES_GCM_MECH_INFO_TYPE &&
|
||||
mechanism->cm_type != AES_GMAC_MECH_INFO_TYPE)
|
||||
if (mechanism->cm_type != AES_CCM_MECH_INFO_TYPE &&
|
||||
mechanism->cm_type != AES_GCM_MECH_INFO_TYPE)
|
||||
return (CRYPTO_MECHANISM_INVALID);
|
||||
|
||||
if ((keysched = aes_alloc_keysched(&size, KM_SLEEP)) == NULL) {
|
||||
@@ -1193,22 +956,6 @@ aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
|
||||
aes_ctx->ac_keysched = keysched;
|
||||
|
||||
switch (mechanism->cm_type) {
|
||||
case AES_CBC_MECH_INFO_TYPE:
|
||||
rv = cbc_init_ctx((cbc_ctx_t *)aes_ctx, mechanism->cm_param,
|
||||
mechanism->cm_param_len, AES_BLOCK_LEN, aes_copy_block64);
|
||||
break;
|
||||
case AES_CTR_MECH_INFO_TYPE: {
|
||||
CK_AES_CTR_PARAMS *pp;
|
||||
|
||||
if (mechanism->cm_param == NULL ||
|
||||
mechanism->cm_param_len != sizeof (CK_AES_CTR_PARAMS)) {
|
||||
return (CRYPTO_MECHANISM_PARAM_INVALID);
|
||||
}
|
||||
pp = (CK_AES_CTR_PARAMS *)(void *)mechanism->cm_param;
|
||||
rv = ctr_init_ctx((ctr_ctx_t *)aes_ctx, pp->ulCounterBits,
|
||||
pp->cb, aes_copy_block);
|
||||
break;
|
||||
}
|
||||
case AES_CCM_MECH_INFO_TYPE:
|
||||
if (mechanism->cm_param == NULL ||
|
||||
mechanism->cm_param_len != sizeof (CK_AES_CCM_PARAMS)) {
|
||||
@@ -1227,17 +974,6 @@ aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
|
||||
AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
break;
|
||||
case AES_GMAC_MECH_INFO_TYPE:
|
||||
if (mechanism->cm_param == NULL ||
|
||||
mechanism->cm_param_len != sizeof (CK_AES_GMAC_PARAMS)) {
|
||||
return (CRYPTO_MECHANISM_PARAM_INVALID);
|
||||
}
|
||||
rv = gmac_init_ctx((gcm_ctx_t *)aes_ctx, mechanism->cm_param,
|
||||
AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
break;
|
||||
case AES_ECB_MECH_INFO_TYPE:
|
||||
aes_ctx->ac_flags |= ECB_MODE;
|
||||
}
|
||||
|
||||
if (rv != CRYPTO_SUCCESS) {
|
||||
@@ -1249,75 +985,3 @@ aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
process_gmac_mech(crypto_mechanism_t *mech, crypto_data_t *data,
|
||||
CK_AES_GCM_PARAMS *gcm_params)
|
||||
{
|
||||
/* LINTED: pointer alignment */
|
||||
CK_AES_GMAC_PARAMS *params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
|
||||
|
||||
if (mech->cm_type != AES_GMAC_MECH_INFO_TYPE)
|
||||
return (CRYPTO_MECHANISM_INVALID);
|
||||
|
||||
if (mech->cm_param_len != sizeof (CK_AES_GMAC_PARAMS))
|
||||
return (CRYPTO_MECHANISM_PARAM_INVALID);
|
||||
|
||||
if (params->pIv == NULL)
|
||||
return (CRYPTO_MECHANISM_PARAM_INVALID);
|
||||
|
||||
gcm_params->pIv = params->pIv;
|
||||
gcm_params->ulIvLen = AES_GMAC_IV_LEN;
|
||||
gcm_params->ulTagBits = AES_GMAC_TAG_BITS;
|
||||
|
||||
if (data == NULL)
|
||||
return (CRYPTO_SUCCESS);
|
||||
|
||||
if (data->cd_format != CRYPTO_DATA_RAW)
|
||||
return (CRYPTO_ARGUMENTS_BAD);
|
||||
|
||||
gcm_params->pAAD = (uchar_t *)data->cd_raw.iov_base;
|
||||
gcm_params->ulAADLen = data->cd_length;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
aes_mac_atomic(crypto_mechanism_t *mechanism,
|
||||
crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
|
||||
crypto_spi_ctx_template_t template)
|
||||
{
|
||||
CK_AES_GCM_PARAMS gcm_params;
|
||||
crypto_mechanism_t gcm_mech;
|
||||
int rv;
|
||||
|
||||
if ((rv = process_gmac_mech(mechanism, data, &gcm_params))
|
||||
!= CRYPTO_SUCCESS)
|
||||
return (rv);
|
||||
|
||||
gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE;
|
||||
gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
|
||||
gcm_mech.cm_param = (char *)&gcm_params;
|
||||
|
||||
return (aes_encrypt_atomic(&gcm_mech,
|
||||
key, &null_crypto_data, mac, template));
|
||||
}
|
||||
|
||||
static int
|
||||
aes_mac_verify_atomic(crypto_mechanism_t *mechanism, crypto_key_t *key,
|
||||
crypto_data_t *data, crypto_data_t *mac, crypto_spi_ctx_template_t template)
|
||||
{
|
||||
CK_AES_GCM_PARAMS gcm_params;
|
||||
crypto_mechanism_t gcm_mech;
|
||||
int rv;
|
||||
|
||||
if ((rv = process_gmac_mech(mechanism, data, &gcm_params))
|
||||
!= CRYPTO_SUCCESS)
|
||||
return (rv);
|
||||
|
||||
gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE;
|
||||
gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
|
||||
gcm_mech.cm_param = (char *)&gcm_params;
|
||||
|
||||
return (aes_decrypt_atomic(&gcm_mech,
|
||||
key, mac, &null_crypto_data, template));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user