From 594215be6e00e1bb921497091213ed601df5e4f4 Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 14 Oct 2021 12:23:06 +0200 Subject: [PATCH] Add support for CCM*-no-tag to PSA. Signed-off-by: Mateusz Starzyk --- include/psa/crypto_sizes.h | 3 ++- include/psa/crypto_values.h | 11 +++++++++++ library/cipher.c | 35 +++++++++++++++++++++++++++++++++++ library/psa_crypto.c | 7 ++++++- library/psa_crypto_cipher.c | 3 +++ 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 4c67f10afa..e9a7a350bc 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -959,7 +959,8 @@ (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ (key_type) == PSA_KEY_TYPE_CHACHA20 && \ (alg) == PSA_ALG_STREAM_CIPHER ? 12 : \ - 0) + (alg) == PSA_ALG_CCM_STAR_NO_TAG ? 13 : \ + 0) /** The maximum IV size for all supported cipher algorithms, in bytes. * diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index daef9416cc..9f0b7517d4 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -1195,6 +1195,17 @@ */ #define PSA_ALG_CCM ((psa_algorithm_t)0x05500100) +/** The CCM* cipher mode without authentication. + * + * This is CCM* as specified in IEEE 802.15.4 ยง7, with a tag length of 0. + * For CCM* with a nonzero tag length, use the AEAD algorithm #PSA_ALG_CCM. + * + * The underlying block cipher is determined by the key type. + * + * Currently only 13-byte long IV's are supported. + */ +#define PSA_ALG_CCM_STAR_NO_TAG ((psa_algorithm_t)0x04c01300) + /** The GCM authenticated encryption algorithm. * * The underlying block cipher is determined by the key type. diff --git a/library/cipher.c b/library/cipher.c index dc801894b7..4ed6c910f0 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -424,6 +424,31 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, } #endif +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + int set_lengths_result; + int ccm_star_mode; + + set_lengths_result = mbedtls_ccm_set_lengths( + (mbedtls_ccm_context *) ctx->cipher_ctx, + 0, 0, 0 ); + if( set_lengths_result != 0 ) + return set_lengths_result; + + if( ctx->operation == MBEDTLS_DECRYPT ) + ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT; + else if( ctx->operation == MBEDTLS_ENCRYPT ) + ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT; + else + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + + return( mbedtls_ccm_starts( (mbedtls_ccm_context *) ctx->cipher_ctx, + ccm_star_mode, + iv, iv_len ) ); + } +#endif + if ( actual_iv_size != 0 ) { memcpy( ctx->iv, iv, actual_iv_size ); @@ -560,6 +585,15 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif +#if defined(MBEDTLS_CCM_C) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CCM ) + { + return( mbedtls_ccm_update( (mbedtls_ccm_context *) ctx->cipher_ctx, + input, ilen, + output, ilen, olen ) ); + } +#endif + #if defined(MBEDTLS_CHACHAPOLY_C) if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) { @@ -947,6 +981,7 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ctx->cipher_info->mode || MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_CCM == ctx->cipher_info->mode || MBEDTLS_MODE_XTS == ctx->cipher_info->mode || MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) { diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ece64b100d..67494dd249 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3587,7 +3587,12 @@ psa_status_t psa_cipher_decrypt( mbedtls_svc_key_id_t key, .core = slot->attr }; - if( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) ) + if( alg == PSA_ALG_CCM_STAR_NO_TAG && input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ) ) + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + else if ( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) ) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c index 2268fc5850..acbbd5ca6b 100644 --- a/library/psa_crypto_cipher.c +++ b/library/psa_crypto_cipher.c @@ -92,6 +92,9 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( case PSA_ALG_CBC_PKCS7: mode = MBEDTLS_MODE_CBC; break; + case PSA_ALG_CCM_STAR_NO_TAG: + mode = MBEDTLS_MODE_CCM; + break; case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ): mode = MBEDTLS_MODE_CCM; break;