mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 10:55:27 +00:00
Add support for non-default-tag-size AEAD (CCM and GCM)
This commit is contained in:
parent
7da96b0d91
commit
23cc2ff9a8
|
@ -884,8 +884,34 @@ typedef uint32_t psa_algorithm_t;
|
|||
*/
|
||||
#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101)
|
||||
|
||||
#define PSA_ALG_CCM ((psa_algorithm_t)0x06000001)
|
||||
#define PSA_ALG_GCM ((psa_algorithm_t)0x06000002)
|
||||
#define PSA_ALG_CCM ((psa_algorithm_t)0x06001001)
|
||||
#define PSA_ALG_GCM ((psa_algorithm_t)0x06001002)
|
||||
|
||||
#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x00003f00)
|
||||
#define PSA_AEAD_TAG_LENGTH_OFFSET 8
|
||||
|
||||
/** Macro to build a shortened AEAD algorithm.
|
||||
*
|
||||
* A shortened AEAD algorithm is similar to the corresponding AEAD
|
||||
* algorithm, but has an authentication tag that consists of fewer bytes.
|
||||
* Depending on the algorithm, the tag length may affect the calculation
|
||||
* of the ciphertext.
|
||||
*
|
||||
* \param alg A AEAD algorithm identifier (value of type
|
||||
* #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg)
|
||||
* is true).
|
||||
* \param mac_length Desired length of the authentication tag in bytes.
|
||||
*
|
||||
* \return The corresponding AEAD algorithm with the specified
|
||||
* length.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* AEAD algorithm or if \p tag_length is not valid
|
||||
* for the specified AEAD algorithm.
|
||||
*/
|
||||
#define PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, tag_length) \
|
||||
(((alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) | \
|
||||
((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \
|
||||
PSA_ALG_AEAD_TAG_LENGTH_MASK))
|
||||
|
||||
#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000)
|
||||
/** RSA PKCS#1 v1.5 signature with hashing.
|
||||
|
@ -2432,9 +2458,9 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
|
|||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_TAG_SIZE(alg) \
|
||||
((alg) == PSA_ALG_GCM ? 16 : \
|
||||
(alg) == PSA_ALG_CCM ? 16 : \
|
||||
#define PSA_AEAD_TAG_LENGTH(alg) \
|
||||
(PSA_ALG_IS_AEAD(alg) ? \
|
||||
(((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \
|
||||
0)
|
||||
|
||||
/** Process an authenticated encryption operation.
|
||||
|
|
|
@ -188,9 +188,9 @@
|
|||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) \
|
||||
(PSA_AEAD_TAG_SIZE(alg) != 0 ? \
|
||||
(plaintext_length) + PSA_AEAD_TAG_SIZE(alg) : \
|
||||
#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) \
|
||||
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
|
||||
(plaintext_length) + PSA_AEAD_TAG_LENGTH(alg) : \
|
||||
0)
|
||||
|
||||
/** The maximum size of the output of psa_aead_decrypt(), in bytes.
|
||||
|
@ -212,9 +212,9 @@
|
|||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
|
||||
(PSA_AEAD_TAG_SIZE(alg) != 0 ? \
|
||||
(plaintext_length) - PSA_AEAD_TAG_SIZE(alg) : \
|
||||
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
|
||||
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
|
||||
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
|
||||
0)
|
||||
|
||||
/** Safe signature buffer size for psa_asymmetric_sign().
|
||||
|
|
|
@ -1224,6 +1224,9 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
|||
mbedtls_cipher_mode_t mode;
|
||||
mbedtls_cipher_id_t cipher_id_tmp;
|
||||
|
||||
if( PSA_ALG_IS_AEAD( alg ) )
|
||||
alg &= ~PSA_ALG_AEAD_TAG_LENGTH_MASK;
|
||||
|
||||
if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
|
||||
{
|
||||
switch( alg )
|
||||
|
@ -1246,10 +1249,10 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
|||
case PSA_ALG_CBC_PKCS7:
|
||||
mode = MBEDTLS_MODE_CBC;
|
||||
break;
|
||||
case PSA_ALG_CCM:
|
||||
case PSA_ALG_CCM & ~PSA_ALG_AEAD_TAG_LENGTH_MASK:
|
||||
mode = MBEDTLS_MODE_CCM;
|
||||
break;
|
||||
case PSA_ALG_GCM:
|
||||
case PSA_ALG_GCM & ~PSA_ALG_AEAD_TAG_LENGTH_MASK:
|
||||
mode = MBEDTLS_MODE_GCM;
|
||||
break;
|
||||
default:
|
||||
|
@ -2834,6 +2837,8 @@ typedef struct
|
|||
mbedtls_gcm_context gcm;
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
} ctx;
|
||||
psa_algorithm_t core_alg;
|
||||
uint8_t full_tag_length;
|
||||
uint8_t tag_length;
|
||||
} aead_operation_t;
|
||||
|
||||
|
@ -2876,11 +2881,12 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation,
|
|||
if( operation->cipher_info == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
switch( alg )
|
||||
switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
|
||||
{
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
case PSA_ALG_CCM:
|
||||
operation->tag_length = 16;
|
||||
case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
|
||||
operation->core_alg = PSA_ALG_CCM;
|
||||
operation->full_tag_length = 16;
|
||||
if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
mbedtls_ccm_init( &operation->ctx.ccm );
|
||||
|
@ -2894,8 +2900,9 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation,
|
|||
#endif /* MBEDTLS_CCM_C */
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
case PSA_ALG_GCM:
|
||||
operation->tag_length = 16;
|
||||
case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
|
||||
operation->core_alg = PSA_ALG_GCM;
|
||||
operation->full_tag_length = 16;
|
||||
if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
mbedtls_gcm_init( &operation->ctx.gcm );
|
||||
|
@ -2910,6 +2917,16 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation,
|
|||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
|
||||
{
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto cleanup;
|
||||
}
|
||||
operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
|
||||
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
|
||||
* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
|
||||
* In both cases, mbedtls_xxx will validate the tag length below. */
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
|
||||
cleanup:
|
||||
|
@ -2948,7 +2965,7 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key,
|
|||
}
|
||||
tag = ciphertext + plaintext_length;
|
||||
|
||||
if( alg == PSA_ALG_GCM )
|
||||
if( operation.core_alg == PSA_ALG_GCM )
|
||||
{
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
|
||||
|
@ -2959,7 +2976,7 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key,
|
|||
plaintext, ciphertext,
|
||||
operation.tag_length, tag ) );
|
||||
}
|
||||
else if( alg == PSA_ALG_CCM )
|
||||
else if( operation.core_alg == PSA_ALG_CCM )
|
||||
{
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
|
||||
|
@ -3028,7 +3045,7 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key,
|
|||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
if( alg == PSA_ALG_GCM )
|
||||
if( operation.core_alg == PSA_ALG_GCM )
|
||||
{
|
||||
status = psa_aead_unpadded_locate_tag( operation.tag_length,
|
||||
ciphertext, ciphertext_length,
|
||||
|
@ -3045,7 +3062,7 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key,
|
|||
tag, operation.tag_length,
|
||||
ciphertext, plaintext ) );
|
||||
}
|
||||
else if( alg == PSA_ALG_CCM )
|
||||
else if( operation.core_alg == PSA_ALG_CCM )
|
||||
{
|
||||
status = psa_aead_unpadded_locate_tag( operation.tag_length,
|
||||
ciphertext, ciphertext_length,
|
||||
|
|
|
@ -227,7 +227,7 @@ void aead_algorithm( int alg_arg, int classification_flags,
|
|||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Tag length */
|
||||
TEST_ASSERT( tag_length == PSA_AEAD_TAG_SIZE( alg ) );
|
||||
TEST_ASSERT( tag_length == PSA_AEAD_TAG_LENGTH( alg ) );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
|
Loading…
Reference in a new issue