mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-30 00:54:24 +01:00
chachapoly: split crypt_and_mac() to match GCM API
In addition to making the APIs of the various AEAD modules more consistent with each other, it's useful to have an auth_decrypt() function so that we can safely check the tag ourselves, as the user might otherwise do it in an insecure way (or even forget to do it altogether).
This commit is contained in:
parent
453cf2850f
commit
52a56d3b86
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */
|
#define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */
|
||||||
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */
|
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */
|
||||||
|
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x00049 /**< Authenticated decryption failed: data was not authentic. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -192,37 +194,64 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
|
|||||||
unsigned char mac[16] );
|
unsigned char mac[16] );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Encrypt or decrypt data, and produce a MAC with ChaCha20-Poly1305.
|
* \brief Encrypt or decrypt data, and produce a MAC (tag) with ChaCha20-Poly1305.
|
||||||
*
|
*
|
||||||
* \param key The 256-bit (32 bytes) encryption key to use.
|
* \param ctx The ChachaPoly context.
|
||||||
* \param nonce The 96-bit (12 bytes) nonce/IV to use.
|
|
||||||
* \param mode Specifies whether the data in the \p input buffer is to
|
* \param mode Specifies whether the data in the \p input buffer is to
|
||||||
* be encrypted or decrypted. If there is no data to encrypt
|
* be encrypted or decrypted. If there is no data to encrypt
|
||||||
* or decrypt (i.e. \p ilen is 0) then the value of this
|
* or decrypt (i.e. \p ilen is 0) then the value of this
|
||||||
* parameter does not matter.
|
* parameter does not matter.
|
||||||
* \param aad_len The length (in bytes) of the AAD data to process.
|
* \param length The length (in bytes) of the data to encrypt or decrypt.
|
||||||
|
* \param nonce The 96-bit (12 bytes) nonce/IV to use.
|
||||||
* \param aad Buffer containing the additional authenticated data (AAD).
|
* \param aad Buffer containing the additional authenticated data (AAD).
|
||||||
* This pointer can be NULL if aad_len == 0.
|
* This pointer can be NULL if aad_len == 0.
|
||||||
* \param ilen The length (in bytes) of the data to encrypt or decrypt.
|
* \param aad_len The length (in bytes) of the AAD data to process.
|
||||||
* \param input Buffer containing the data to encrypt or decrypt.
|
* \param input Buffer containing the data to encrypt or decrypt.
|
||||||
* This pointer can be NULL if ilen == 0.
|
* This pointer can be NULL if ilen == 0.
|
||||||
* \param output Buffer to where the encrypted or decrypted data is written.
|
* \param output Buffer to where the encrypted or decrypted data is written.
|
||||||
* This pointer can be NULL if ilen == 0.
|
* This pointer can be NULL if ilen == 0.
|
||||||
* \param mac Buffer to where the computed 128-bit (16 bytes) MAC is written.
|
* \param tag Buffer to where the computed 128-bit (16 bytes) MAC is written.
|
||||||
*
|
*
|
||||||
* \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned
|
* \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned
|
||||||
* if one or more of the required parameters are NULL.
|
* if one or more of the required parameters are NULL.
|
||||||
* Otherwise, 0 is returned to indicate success.
|
* Otherwise, 0 is returned to indicate success.
|
||||||
*/
|
*/
|
||||||
int mbedtls_chachapoly_crypt_and_mac( const unsigned char key[32],
|
int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
|
||||||
const unsigned char nonce[12],
|
|
||||||
mbedtls_chachapoly_mode_t mode,
|
mbedtls_chachapoly_mode_t mode,
|
||||||
size_t aad_len,
|
size_t length,
|
||||||
|
const unsigned char nonce[12],
|
||||||
const unsigned char *aad,
|
const unsigned char *aad,
|
||||||
size_t ilen,
|
size_t aad_len,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
unsigned char mac[16] );
|
unsigned char tag[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Decrypt data and check a MAC (tag) with ChaCha20-Poly1305.
|
||||||
|
*
|
||||||
|
* \param ctx The ChachaPoly context.
|
||||||
|
* \param length The length of the input and output data.
|
||||||
|
* \param nonce The nonce / initialization vector.
|
||||||
|
* \param aad The buffer holding the additional authenticated data.
|
||||||
|
* \param aad_len The length of the additional authenticated data.
|
||||||
|
* \param tag The buffer holding the tag.
|
||||||
|
* \param input The buffer holding the input data.
|
||||||
|
* \param output The buffer for holding the output data.
|
||||||
|
*
|
||||||
|
* \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned
|
||||||
|
* if one or more of the required parameters are NULL.
|
||||||
|
* MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED if the tag does not
|
||||||
|
* match.
|
||||||
|
* Otherwise, 0 is returned to indicate success.
|
||||||
|
*/
|
||||||
|
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char nonce[12],
|
||||||
|
const unsigned char *aad,
|
||||||
|
size_t aad_len,
|
||||||
|
const unsigned char tag[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
|
@ -295,44 +295,70 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_chachapoly_crypt_and_mac ( const unsigned char key[32],
|
int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
|
||||||
const unsigned char nonce[12],
|
|
||||||
mbedtls_chachapoly_mode_t mode,
|
mbedtls_chachapoly_mode_t mode,
|
||||||
size_t aad_len,
|
size_t length,
|
||||||
|
const unsigned char nonce[12],
|
||||||
const unsigned char *aad,
|
const unsigned char *aad,
|
||||||
size_t ilen,
|
size_t aad_len,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
unsigned char mac[16] )
|
unsigned char tag[16] )
|
||||||
{
|
{
|
||||||
mbedtls_chachapoly_context ctx;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
mbedtls_chachapoly_init( &ctx );
|
result = mbedtls_chachapoly_starts( ctx, nonce, mode );
|
||||||
|
|
||||||
result = mbedtls_chachapoly_setkey( &ctx, key );
|
|
||||||
if ( result != 0 )
|
if ( result != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
result = mbedtls_chachapoly_starts( &ctx, nonce, mode );
|
result = mbedtls_chachapoly_update_aad( ctx, aad_len, aad );
|
||||||
if ( result != 0 )
|
if ( result != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
result = mbedtls_chachapoly_update_aad( &ctx, aad_len, aad );
|
result = mbedtls_chachapoly_update( ctx, length, input, output );
|
||||||
if ( result != 0 )
|
if ( result != 0 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
result = mbedtls_chachapoly_update( &ctx, ilen, input, output );
|
result = mbedtls_chachapoly_finish( ctx, tag );
|
||||||
if ( result != 0 )
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
result = mbedtls_chachapoly_finish( &ctx, mac );
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_chachapoly_free( &ctx );
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char nonce[12],
|
||||||
|
const unsigned char *aad,
|
||||||
|
size_t aad_len,
|
||||||
|
const unsigned char tag[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char check_tag[16];
|
||||||
|
size_t i;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_chachapoly_crypt_and_tag( ctx,
|
||||||
|
MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
|
||||||
|
aad, aad_len, input, output, check_tag ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check tag in "constant-time" */
|
||||||
|
for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
|
||||||
|
diff |= tag[i] ^ check_tag[i];
|
||||||
|
|
||||||
|
if( diff != 0 )
|
||||||
|
{
|
||||||
|
mbedtls_zeroize( output, length );
|
||||||
|
return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* MBEDTLS_CHACHAPOLY_ALT */
|
#endif /* MBEDTLS_CHACHAPOLY_ALT */
|
||||||
|
|
||||||
#if defined(MBEDTLS_SELF_TEST)
|
#if defined(MBEDTLS_SELF_TEST)
|
||||||
@ -425,6 +451,7 @@ static const unsigned char test_mac[1][16] =
|
|||||||
|
|
||||||
int mbedtls_chachapoly_self_test( int verbose )
|
int mbedtls_chachapoly_self_test( int verbose )
|
||||||
{
|
{
|
||||||
|
mbedtls_chachapoly_context ctx;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int result;
|
int result;
|
||||||
unsigned char output[200];
|
unsigned char output[200];
|
||||||
@ -437,12 +464,24 @@ int mbedtls_chachapoly_self_test( int verbose )
|
|||||||
mbedtls_printf( " ChaCha20-Poly1305 test %u ", i );
|
mbedtls_printf( " ChaCha20-Poly1305 test %u ", i );
|
||||||
}
|
}
|
||||||
|
|
||||||
result = mbedtls_chachapoly_crypt_and_mac( test_key[i],
|
mbedtls_chachapoly_init( &ctx );
|
||||||
test_nonce[i],
|
|
||||||
|
result = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
|
||||||
|
if ( result != 0 )
|
||||||
|
{
|
||||||
|
if ( verbose != 0 )
|
||||||
|
{
|
||||||
|
mbedtls_printf( "setkey() error code: %i\n", result );
|
||||||
|
}
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mbedtls_chachapoly_crypt_and_tag( &ctx,
|
||||||
MBEDTLS_CHACHAPOLY_ENCRYPT,
|
MBEDTLS_CHACHAPOLY_ENCRYPT,
|
||||||
test_aad_len[i],
|
|
||||||
test_aad[i],
|
|
||||||
test_input_len[i],
|
test_input_len[i],
|
||||||
|
test_nonce[i],
|
||||||
|
test_aad[i],
|
||||||
|
test_aad_len[i],
|
||||||
test_input[i],
|
test_input[i],
|
||||||
output,
|
output,
|
||||||
mac );
|
mac );
|
||||||
@ -450,7 +489,7 @@ int mbedtls_chachapoly_self_test( int verbose )
|
|||||||
{
|
{
|
||||||
if ( verbose != 0 )
|
if ( verbose != 0 )
|
||||||
{
|
{
|
||||||
mbedtls_printf( "error code: %i\n", result );
|
mbedtls_printf( "crypt_and_tag() error code: %i\n", result );
|
||||||
}
|
}
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@ -473,6 +512,8 @@ int mbedtls_chachapoly_self_test( int verbose )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mbedtls_chachapoly_free( &ctx );
|
||||||
|
|
||||||
if ( verbose != 0 )
|
if ( verbose != 0 )
|
||||||
{
|
{
|
||||||
mbedtls_printf( "passed\n" );
|
mbedtls_printf( "passed\n" );
|
||||||
|
@ -24,6 +24,7 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char
|
|||||||
size_t key_len;
|
size_t key_len;
|
||||||
size_t nonce_len;
|
size_t nonce_len;
|
||||||
size_t mac_len;
|
size_t mac_len;
|
||||||
|
mbedtls_chachapoly_context ctx;
|
||||||
|
|
||||||
memset( key_str, 0x00, 32 );
|
memset( key_str, 0x00, 32 );
|
||||||
memset( nonce_str, 0x00, 12 );
|
memset( nonce_str, 0x00, 12 );
|
||||||
@ -43,14 +44,21 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char
|
|||||||
TEST_ASSERT( nonce_len == 12 );
|
TEST_ASSERT( nonce_len == 12 );
|
||||||
TEST_ASSERT( mac_len == 16 );
|
TEST_ASSERT( mac_len == 16 );
|
||||||
|
|
||||||
mbedtls_chachapoly_crypt_and_mac( key_str, nonce_str,
|
mbedtls_chachapoly_init( &ctx );
|
||||||
|
|
||||||
|
mbedtls_chachapoly_setkey( &ctx, key_str );
|
||||||
|
|
||||||
|
mbedtls_chachapoly_crypt_and_tag( &ctx,
|
||||||
MBEDTLS_CHACHAPOLY_ENCRYPT,
|
MBEDTLS_CHACHAPOLY_ENCRYPT,
|
||||||
aad_len, aad_str,
|
input_len, nonce_str,
|
||||||
input_len, input_str, output,
|
aad_str, aad_len,
|
||||||
mac );
|
input_str, output, mac );
|
||||||
|
|
||||||
TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 );
|
TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 );
|
||||||
TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 );
|
TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_chachapoly_free( &ctx );
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
@ -64,13 +72,14 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char
|
|||||||
unsigned char output_str[10000];
|
unsigned char output_str[10000];
|
||||||
unsigned char mac_str[16];
|
unsigned char mac_str[16];
|
||||||
unsigned char output[10000];
|
unsigned char output[10000];
|
||||||
unsigned char mac[16];
|
|
||||||
size_t input_len;
|
size_t input_len;
|
||||||
size_t output_len;
|
size_t output_len;
|
||||||
size_t aad_len;
|
size_t aad_len;
|
||||||
size_t key_len;
|
size_t key_len;
|
||||||
size_t nonce_len;
|
size_t nonce_len;
|
||||||
size_t mac_len;
|
size_t mac_len;
|
||||||
|
int ret;
|
||||||
|
mbedtls_chachapoly_context ctx;
|
||||||
|
|
||||||
memset( key_str, 0x00, 32 );
|
memset( key_str, 0x00, 32 );
|
||||||
memset( nonce_str, 0x00, 12 );
|
memset( nonce_str, 0x00, 12 );
|
||||||
@ -90,14 +99,20 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char
|
|||||||
TEST_ASSERT( nonce_len == 12 );
|
TEST_ASSERT( nonce_len == 12 );
|
||||||
TEST_ASSERT( mac_len == 16 );
|
TEST_ASSERT( mac_len == 16 );
|
||||||
|
|
||||||
mbedtls_chachapoly_crypt_and_mac( key_str, nonce_str,
|
mbedtls_chachapoly_init( &ctx );
|
||||||
MBEDTLS_CHACHAPOLY_DECRYPT,
|
|
||||||
aad_len, aad_str,
|
|
||||||
input_len, input_str, output,
|
|
||||||
mac );
|
|
||||||
|
|
||||||
|
mbedtls_chachapoly_setkey( &ctx, key_str );
|
||||||
|
|
||||||
|
ret = mbedtls_chachapoly_auth_decrypt( &ctx,
|
||||||
|
input_len, nonce_str,
|
||||||
|
aad_str, aad_len,
|
||||||
|
mac_str, input_str, output );
|
||||||
|
|
||||||
|
TEST_ASSERT( ret == 0 );
|
||||||
TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 );
|
TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 );
|
||||||
TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 );
|
|
||||||
|
exit:
|
||||||
|
mbedtls_chachapoly_free( &ctx );
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user