1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-29 11:41:15 +03:00

Implement ChaCha20 and ChaCha20-Poly1305

Smoke tests: test data for ChaCha20 calculated with PyCryptodome; test
vector from RFC 7539 for ChaCha20-Poly1305.
This commit is contained in:
Gilles Peskine
2019-05-06 15:25:00 +02:00
parent 3e79c8ecfd
commit 26869f2d9b
2 changed files with 123 additions and 0 deletions

View File

@ -51,6 +51,8 @@
#include "mbedtls/bignum.h"
#include "mbedtls/blowfish.h"
#include "mbedtls/camellia.h"
#include "mbedtls/chacha20.h"
#include "mbedtls/chachapoly.h"
#include "mbedtls/cipher.h"
#include "mbedtls/ccm.h"
#include "mbedtls/cmac.h"
@ -179,6 +181,14 @@ static psa_status_t mbedtls_to_psa_error( int ret )
case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
return( PSA_ERROR_HARDWARE_FAILURE );
case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
return( PSA_ERROR_INVALID_ARGUMENT );
case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
return( PSA_ERROR_BAD_STATE );
case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
return( PSA_ERROR_INVALID_SIGNATURE );
case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
return( PSA_ERROR_NOT_SUPPORTED );
case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
@ -465,6 +475,12 @@ static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
if( bits < 8 || bits > 2048 )
return( PSA_ERROR_INVALID_ARGUMENT );
break;
#endif
#if defined(MBEDTLS_CHACHA20_C)
case PSA_KEY_TYPE_CHACHA20:
if( bits != 256 )
return( PSA_ERROR_INVALID_ARGUMENT );
break;
#endif
default:
return( PSA_ERROR_NOT_SUPPORTED );
@ -2026,6 +2042,7 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
switch( alg )
{
case PSA_ALG_ARC4:
case PSA_ALG_CHACHA20:
mode = MBEDTLS_MODE_STREAM;
break;
case PSA_ALG_CTR:
@ -2049,6 +2066,9 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
mode = MBEDTLS_MODE_GCM;
break;
case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
mode = MBEDTLS_MODE_CHACHAPOLY;
break;
default:
return( NULL );
}
@ -2084,6 +2104,9 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
case PSA_KEY_TYPE_ARC4:
cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
break;
case PSA_KEY_TYPE_CHACHA20:
cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
break;
default:
return( NULL );
}
@ -3318,6 +3341,11 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
{
operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
}
#if defined(MBEDTLS_CHACHA20_C)
else
if( alg == PSA_ALG_CHACHA20 )
operation->iv_size = 12;
#endif
exit:
if( status == 0 )
@ -3631,6 +3659,9 @@ typedef struct
#if defined(MBEDTLS_GCM_C)
mbedtls_gcm_context gcm;
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
mbedtls_chachapoly_context chachapoly;
#endif /* MBEDTLS_CHACHAPOLY_C */
} ctx;
psa_algorithm_t core_alg;
uint8_t full_tag_length;
@ -3715,6 +3746,22 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation,
break;
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
operation->full_tag_length = 16;
/* We only support the default tag length. */
if( alg != PSA_ALG_CHACHA20_POLY1305 )
return( PSA_ERROR_NOT_SUPPORTED );
mbedtls_chachapoly_init( &operation->ctx.chachapoly );
status = mbedtls_to_psa_error(
mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
operation->slot->data.raw.data ) );
if( status != 0 )
goto cleanup;
break;
#endif /* MBEDTLS_CHACHAPOLY_C */
default:
return( PSA_ERROR_NOT_SUPPORTED );
}
@ -3792,6 +3839,26 @@ psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
}
else
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
{
if( nonce_length != 12 || operation.tag_length != 16 )
{
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
status = mbedtls_to_psa_error(
mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
plaintext_length,
nonce,
additional_data,
additional_data_length,
plaintext,
ciphertext,
tag ) );
}
else
#endif /* MBEDTLS_CHACHAPOLY_C */
{
return( PSA_ERROR_NOT_SUPPORTED );
}
@ -3883,6 +3950,26 @@ psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
}
else
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
{
if( nonce_length != 12 || operation.tag_length != 16 )
{
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
status = mbedtls_to_psa_error(
mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
ciphertext_length - operation.tag_length,
nonce,
additional_data,
additional_data_length,
tag,
ciphertext,
plaintext ) );
}
else
#endif /* MBEDTLS_CHACHAPOLY_C */
{
return( PSA_ERROR_NOT_SUPPORTED );
}