mbedtls/tests/suites/test_suite_cipher.function
Jaeden Amero 3ea2687053 psa: Initialize crypto in tests that need to
Don't unconditionally enable PSA Crypto for all tests. Only enable it in
tests that require it. This allows crypto tests to check that
psa_crypto_init() fails when it is supposed to fail, since we want to
perform some action in a test, and then call psa_crypto_init() and check
the result without it having been called previously.
2019-02-13 07:34:54 -05:00

1180 lines
42 KiB
Text

/* BEGIN_HEADER */
#include "mbedtls/cipher.h"
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_CIPHER_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void mbedtls_cipher_list( )
{
const int *cipher_type;
for( cipher_type = mbedtls_cipher_list(); *cipher_type != 0; cipher_type++ )
TEST_ASSERT( mbedtls_cipher_info_from_type( *cipher_type ) != NULL );
}
/* END_CASE */
/* BEGIN_CASE */
void cipher_invalid_param_unconditional( )
{
mbedtls_cipher_context_t valid_ctx;
mbedtls_cipher_context_t invalid_ctx;
mbedtls_operation_t valid_operation = MBEDTLS_ENCRYPT;
mbedtls_cipher_padding_t valid_mode = MBEDTLS_PADDING_ZEROS;
unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
int valid_size = sizeof(valid_buffer);
int valid_bitlen = valid_size * 8;
const mbedtls_cipher_info_t *valid_info = mbedtls_cipher_info_from_type(
*( mbedtls_cipher_list() ) );
size_t size_t_var;
(void)valid_mode; /* In some configurations this is unused */
mbedtls_cipher_init( &valid_ctx );
mbedtls_cipher_setup( &valid_ctx, valid_info );
mbedtls_cipher_init( &invalid_ctx );
/* mbedtls_cipher_setup() */
TEST_ASSERT( mbedtls_cipher_setup( &valid_ctx, NULL ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
/* mbedtls_cipher_get_block_size() */
TEST_ASSERT( mbedtls_cipher_get_block_size( &invalid_ctx ) == 0 );
/* mbedtls_cipher_get_cipher_mode() */
TEST_ASSERT( mbedtls_cipher_get_cipher_mode( &invalid_ctx ) ==
MBEDTLS_MODE_NONE );
/* mbedtls_cipher_get_iv_size() */
TEST_ASSERT( mbedtls_cipher_get_iv_size( &invalid_ctx ) == 0 );
/* mbedtls_cipher_get_type() */
TEST_ASSERT(
mbedtls_cipher_get_type( &invalid_ctx ) ==
MBEDTLS_CIPHER_NONE);
/* mbedtls_cipher_get_name() */
TEST_ASSERT( mbedtls_cipher_get_name( &invalid_ctx ) == 0 );
/* mbedtls_cipher_get_key_bitlen() */
TEST_ASSERT( mbedtls_cipher_get_key_bitlen( &invalid_ctx ) ==
MBEDTLS_KEY_LENGTH_NONE );
/* mbedtls_cipher_get_operation() */
TEST_ASSERT( mbedtls_cipher_get_operation( &invalid_ctx ) ==
MBEDTLS_OPERATION_NONE );
/* mbedtls_cipher_setkey() */
TEST_ASSERT(
mbedtls_cipher_setkey( &invalid_ctx,
valid_buffer,
valid_bitlen,
valid_operation ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
/* mbedtls_cipher_set_iv() */
TEST_ASSERT(
mbedtls_cipher_set_iv( &invalid_ctx,
valid_buffer,
valid_size ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
/* mbedtls_cipher_reset() */
TEST_ASSERT( mbedtls_cipher_reset( &invalid_ctx ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* mbedtls_cipher_update_ad() */
TEST_ASSERT(
mbedtls_cipher_update_ad( &invalid_ctx,
valid_buffer,
valid_size ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/* mbedtls_cipher_set_padding_mode() */
TEST_ASSERT( mbedtls_cipher_set_padding_mode( &invalid_ctx, valid_mode ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#endif
/* mbedtls_cipher_update() */
TEST_ASSERT(
mbedtls_cipher_update( &invalid_ctx,
valid_buffer,
valid_size,
valid_buffer,
&size_t_var ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
/* mbedtls_cipher_finish() */
TEST_ASSERT(
mbedtls_cipher_finish( &invalid_ctx,
valid_buffer,
&size_t_var ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* mbedtls_cipher_write_tag() */
TEST_ASSERT(
mbedtls_cipher_write_tag( &invalid_ctx,
valid_buffer,
valid_size ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
/* mbedtls_cipher_check_tag() */
TEST_ASSERT(
mbedtls_cipher_check_tag( &invalid_ctx,
valid_buffer,
valid_size ) ==
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
exit:
mbedtls_cipher_free( &invalid_ctx );
mbedtls_cipher_free( &valid_ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
void cipher_invalid_param_conditional( )
{
mbedtls_cipher_context_t valid_ctx;
mbedtls_operation_t valid_operation = MBEDTLS_ENCRYPT;
mbedtls_operation_t invalid_operation = 100;
mbedtls_cipher_padding_t valid_mode = MBEDTLS_PADDING_ZEROS;
unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
int valid_size = sizeof(valid_buffer);
int valid_bitlen = valid_size * 8;
const mbedtls_cipher_info_t *valid_info = mbedtls_cipher_info_from_type(
*( mbedtls_cipher_list() ) );
size_t size_t_var;
(void)valid_mode; /* In some configurations this is unused */
/* mbedtls_cipher_init() */
TEST_VALID_PARAM( mbedtls_cipher_init( &valid_ctx ) );
TEST_INVALID_PARAM( mbedtls_cipher_init( NULL ) );
/* mbedtls_cipher_setup() */
TEST_VALID_PARAM( mbedtls_cipher_setup( &valid_ctx, valid_info ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_setup( NULL, valid_info ) );
/* mbedtls_cipher_get_block_size() */
TEST_INVALID_PARAM_RET( 0, mbedtls_cipher_get_block_size( NULL ) );
/* mbedtls_cipher_get_cipher_mode() */
TEST_INVALID_PARAM_RET(
MBEDTLS_MODE_NONE,
mbedtls_cipher_get_cipher_mode( NULL ) );
/* mbedtls_cipher_get_iv_size() */
TEST_INVALID_PARAM_RET( 0, mbedtls_cipher_get_iv_size( NULL ) );
/* mbedtls_cipher_get_type() */
TEST_INVALID_PARAM_RET(
MBEDTLS_CIPHER_NONE,
mbedtls_cipher_get_type( NULL ) );
/* mbedtls_cipher_get_name() */
TEST_INVALID_PARAM_RET( 0, mbedtls_cipher_get_name( NULL ) );
/* mbedtls_cipher_get_key_bitlen() */
TEST_INVALID_PARAM_RET(
MBEDTLS_KEY_LENGTH_NONE,
mbedtls_cipher_get_key_bitlen( NULL ) );
/* mbedtls_cipher_get_operation() */
TEST_INVALID_PARAM_RET(
MBEDTLS_OPERATION_NONE,
mbedtls_cipher_get_operation( NULL ) );
/* mbedtls_cipher_setkey() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_setkey( NULL,
valid_buffer,
valid_bitlen,
valid_operation ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_setkey( &valid_ctx,
NULL,
valid_bitlen,
valid_operation ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_setkey( &valid_ctx,
valid_buffer,
valid_bitlen,
invalid_operation ) );
/* mbedtls_cipher_set_iv() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_set_iv( NULL,
valid_buffer,
valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_set_iv( &valid_ctx,
NULL,
valid_size ) );
/* mbedtls_cipher_reset() */
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_reset( NULL ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* mbedtls_cipher_update_ad() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_update_ad( NULL,
valid_buffer,
valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_update_ad( &valid_ctx,
NULL,
valid_size ) );
#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/* mbedtls_cipher_set_padding_mode() */
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_set_padding_mode( NULL, valid_mode ) );
#endif
/* mbedtls_cipher_update() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_update( NULL,
valid_buffer,
valid_size,
valid_buffer,
&size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_update( &valid_ctx,
NULL, valid_size,
valid_buffer,
&size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_update( &valid_ctx,
valid_buffer, valid_size,
NULL,
&size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_update( &valid_ctx,
valid_buffer, valid_size,
valid_buffer,
NULL ) );
/* mbedtls_cipher_finish() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_finish( NULL,
valid_buffer,
&size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_finish( &valid_ctx,
NULL,
&size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_finish( &valid_ctx,
valid_buffer,
NULL ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* mbedtls_cipher_write_tag() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_write_tag( NULL,
valid_buffer,
valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_write_tag( &valid_ctx,
NULL,
valid_size ) );
/* mbedtls_cipher_check_tag() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_check_tag( NULL,
valid_buffer,
valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_check_tag( &valid_ctx,
NULL,
valid_size ) );
#endif /* defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) */
/* mbedtls_cipher_crypt() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_crypt( NULL,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_crypt( &valid_ctx,
NULL, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_crypt( &valid_ctx,
valid_buffer, valid_size,
NULL, valid_size,
valid_buffer, &size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_crypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
NULL, &size_t_var ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_crypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, NULL ) );
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/* mbedtls_cipher_auth_encrypt() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( NULL,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( &valid_ctx,
NULL, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( &valid_ctx,
valid_buffer, valid_size,
NULL, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
NULL, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
NULL, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, NULL,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_encrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
NULL, valid_size ) );
/* mbedtls_cipher_auth_decrypt() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( NULL,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( &valid_ctx,
NULL, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( &valid_ctx,
valid_buffer, valid_size,
NULL, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
NULL, valid_size,
valid_buffer, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
NULL, &size_t_var,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, NULL,
valid_buffer, valid_size ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
mbedtls_cipher_auth_decrypt( &valid_ctx,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, valid_size,
valid_buffer, &size_t_var,
NULL, valid_size ) );
#endif /* defined(MBEDTLS_CIPHER_MODE_AEAD) */
/* mbedtls_cipher_free() */
TEST_VALID_PARAM( mbedtls_cipher_free( NULL ) );
exit:
TEST_VALID_PARAM( mbedtls_cipher_free( &valid_ctx ) );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
void cipher_special_behaviours( )
{
const mbedtls_cipher_info_t *cipher_info;
mbedtls_cipher_context_t ctx;
unsigned char input[32];
unsigned char output[32];
#if defined (MBEDTLS_CIPHER_MODE_CBC)
unsigned char iv[32];
#endif
size_t olen = 0;
mbedtls_cipher_init( &ctx );
memset( input, 0, sizeof( input ) );
memset( output, 0, sizeof( output ) );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
memset( iv, 0, sizeof( iv ) );
/* Check and get info structures */
cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_CBC );
TEST_ASSERT( NULL != cipher_info );
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx, cipher_info ) );
/* IV too big */
TEST_ASSERT( mbedtls_cipher_set_iv( &ctx, iv, MBEDTLS_MAX_IV_LENGTH + 1 )
== MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
/* IV too small */
TEST_ASSERT( mbedtls_cipher_set_iv( &ctx, iv, 0 )
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
mbedtls_cipher_free( &ctx );
mbedtls_cipher_init( &ctx );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
TEST_ASSERT( NULL != cipher_info );
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx, cipher_info ) );
/* Update ECB with partial block */
TEST_ASSERT( mbedtls_cipher_update( &ctx, input, 1, output, &olen )
== MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
exit:
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void enc_dec_buf( int cipher_id, char * cipher_string, int key_len,
int length_val, int pad_mode )
{
size_t length = length_val, outlen, total_len, i, block_size;
unsigned char key[64];
unsigned char iv[16];
unsigned char ad[13];
unsigned char tag[16];
unsigned char inbuf[64];
unsigned char encbuf[64];
unsigned char decbuf[64];
const mbedtls_cipher_info_t *cipher_info;
mbedtls_cipher_context_t ctx_dec;
mbedtls_cipher_context_t ctx_enc;
/*
* Prepare contexts
*/
mbedtls_cipher_init( &ctx_dec );
mbedtls_cipher_init( &ctx_enc );
memset( key, 0x2a, sizeof( key ) );
/* Check and get info structures */
cipher_info = mbedtls_cipher_info_from_type( cipher_id );
TEST_ASSERT( NULL != cipher_info );
TEST_ASSERT( mbedtls_cipher_info_from_string( cipher_string ) == cipher_info );
/* Initialise enc and dec contexts */
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_enc, cipher_info ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_dec, key, key_len, MBEDTLS_DECRYPT ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_enc, key, key_len, MBEDTLS_ENCRYPT ) );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
if( -1 != pad_mode )
{
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx_dec, pad_mode ) );
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx_enc, pad_mode ) );
}
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
/*
* Do a few encode/decode cycles
*/
for( i = 0; i < 3; i++ )
{
memset( iv , 0x00 + i, sizeof( iv ) );
memset( ad, 0x10 + i, sizeof( ad ) );
memset( inbuf, 0x20 + i, sizeof( inbuf ) );
memset( encbuf, 0, sizeof( encbuf ) );
memset( decbuf, 0, sizeof( decbuf ) );
memset( tag, 0, sizeof( tag ) );
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, sizeof( iv ) ) );
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_enc, iv, sizeof( iv ) ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, ad, sizeof( ad ) - i ) );
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, ad, sizeof( ad ) - i ) );
#endif
block_size = mbedtls_cipher_get_block_size( &ctx_enc );
TEST_ASSERT( block_size != 0 );
/* encode length number of bytes from inbuf */
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_enc, inbuf, length, encbuf, &outlen ) );
total_len = outlen;
TEST_ASSERT( total_len == length ||
( total_len % block_size == 0 &&
total_len < length &&
total_len + block_size > length ) );
TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_enc, encbuf + outlen, &outlen ) );
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_write_tag( &ctx_enc, tag, sizeof( tag ) ) );
#endif
TEST_ASSERT( total_len == length ||
( total_len % block_size == 0 &&
total_len > length &&
total_len <= length + block_size ) );
/* decode the previously encoded string */
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_dec, encbuf, total_len, decbuf, &outlen ) );
total_len = outlen;
TEST_ASSERT( total_len == length ||
( total_len % block_size == 0 &&
total_len < length &&
total_len + block_size >= length ) );
TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) );
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_check_tag( &ctx_dec, tag, sizeof( tag ) ) );
#endif
/* check result */
TEST_ASSERT( total_len == length );
TEST_ASSERT( 0 == memcmp(inbuf, decbuf, length) );
}
/*
* Done
*/
exit:
mbedtls_cipher_free( &ctx_dec );
mbedtls_cipher_free( &ctx_enc );
}
/* END_CASE */
/* BEGIN_CASE */
void enc_fail( int cipher_id, int pad_mode, int key_len, int length_val,
int ret )
{
size_t length = length_val;
unsigned char key[32];
unsigned char iv[16];
const mbedtls_cipher_info_t *cipher_info;
mbedtls_cipher_context_t ctx;
unsigned char inbuf[64];
unsigned char encbuf[64];
size_t outlen = 0;
memset( key, 0, 32 );
memset( iv , 0, 16 );
mbedtls_cipher_init( &ctx );
memset( inbuf, 5, 64 );
memset( encbuf, 0, 64 );
/* Check and get info structures */
cipher_info = mbedtls_cipher_info_from_type( cipher_id );
TEST_ASSERT( NULL != cipher_info );
/* Initialise context */
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx, cipher_info ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key, key_len, MBEDTLS_ENCRYPT ) );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx, pad_mode ) );
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv, 16 ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, NULL, 0 ) );
#endif
/* encode length number of bytes from inbuf */
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx, inbuf, length, encbuf, &outlen ) );
TEST_ASSERT( ret == mbedtls_cipher_finish( &ctx, encbuf + outlen, &outlen ) );
/* done */
exit:
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void dec_empty_buf( )
{
unsigned char key[32];
unsigned char iv[16];
mbedtls_cipher_context_t ctx_dec;
const mbedtls_cipher_info_t *cipher_info;
unsigned char encbuf[64];
unsigned char decbuf[64];
size_t outlen = 0;
memset( key, 0, 32 );
memset( iv , 0, 16 );
mbedtls_cipher_init( &ctx_dec );
memset( encbuf, 0, 64 );
memset( decbuf, 0, 64 );
/* Initialise context */
cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_CBC );
TEST_ASSERT( NULL != cipher_info);
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_dec, key, 128, MBEDTLS_DECRYPT ) );
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, 16 ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) );
#endif
/* decode 0-byte string */
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_dec, encbuf, 0, decbuf, &outlen ) );
TEST_ASSERT( 0 == outlen );
TEST_ASSERT( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED == mbedtls_cipher_finish(
&ctx_dec, decbuf + outlen, &outlen ) );
TEST_ASSERT( 0 == outlen );
exit:
mbedtls_cipher_free( &ctx_dec );
}
/* END_CASE */
/* BEGIN_CASE */
void enc_dec_buf_multipart( int cipher_id, int key_len, int first_length_val,
int second_length_val, int pad_mode,
int first_encrypt_output_len, int second_encrypt_output_len,
int first_decrypt_output_len, int second_decrypt_output_len )
{
size_t first_length = first_length_val;
size_t second_length = second_length_val;
size_t length = first_length + second_length;
size_t block_size;
unsigned char key[32];
unsigned char iv[16];
mbedtls_cipher_context_t ctx_dec;
mbedtls_cipher_context_t ctx_enc;
const mbedtls_cipher_info_t *cipher_info;
unsigned char inbuf[64];
unsigned char encbuf[64];
unsigned char decbuf[64];
size_t outlen = 0;
size_t totaloutlen = 0;
memset( key, 0, 32 );
memset( iv , 0, 16 );
mbedtls_cipher_init( &ctx_dec );
mbedtls_cipher_init( &ctx_enc );
memset( inbuf, 5, 64 );
memset( encbuf, 0, 64 );
memset( decbuf, 0, 64 );
/* Initialise enc and dec contexts */
cipher_info = mbedtls_cipher_info_from_type( cipher_id );
TEST_ASSERT( NULL != cipher_info);
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_enc, cipher_info ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_dec, key, key_len, MBEDTLS_DECRYPT ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx_enc, key, key_len, MBEDTLS_ENCRYPT ) );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
if( -1 != pad_mode )
{
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx_dec, pad_mode ) );
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx_enc, pad_mode ) );
}
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, 16 ) );
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_enc, iv, 16 ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) );
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, NULL, 0 ) );
#endif
block_size = mbedtls_cipher_get_block_size( &ctx_enc );
TEST_ASSERT( block_size != 0 );
/* encode length number of bytes from inbuf */
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_enc, inbuf, first_length, encbuf, &outlen ) );
TEST_ASSERT( (size_t)first_encrypt_output_len == outlen );
totaloutlen = outlen;
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_enc, inbuf + first_length, second_length, encbuf + totaloutlen, &outlen ) );
TEST_ASSERT( (size_t)second_encrypt_output_len == outlen );
totaloutlen += outlen;
TEST_ASSERT( totaloutlen == length ||
( totaloutlen % block_size == 0 &&
totaloutlen < length &&
totaloutlen + block_size > length ) );
TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_enc, encbuf + totaloutlen, &outlen ) );
totaloutlen += outlen;
TEST_ASSERT( totaloutlen == length ||
( totaloutlen % block_size == 0 &&
totaloutlen > length &&
totaloutlen <= length + block_size ) );
/* decode the previously encoded string */
second_length = totaloutlen - first_length;
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_dec, encbuf, first_length, decbuf, &outlen ) );
TEST_ASSERT( (size_t)first_decrypt_output_len == outlen );
totaloutlen = outlen;
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx_dec, encbuf + first_length, second_length, decbuf + totaloutlen, &outlen ) );
TEST_ASSERT( (size_t)second_decrypt_output_len == outlen );
totaloutlen += outlen;
TEST_ASSERT( totaloutlen == length ||
( totaloutlen % block_size == 0 &&
totaloutlen < length &&
totaloutlen + block_size >= length ) );
TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_dec, decbuf + totaloutlen, &outlen ) );
totaloutlen += outlen;
TEST_ASSERT( totaloutlen == length );
TEST_ASSERT( 0 == memcmp(inbuf, decbuf, length) );
exit:
mbedtls_cipher_free( &ctx_dec );
mbedtls_cipher_free( &ctx_enc );
}
/* END_CASE */
/* BEGIN_CASE */
void decrypt_test_vec( int cipher_id, int pad_mode, data_t * key,
data_t * iv, data_t * cipher,
data_t * clear, data_t * ad, data_t * tag,
int finish_result, int tag_result )
{
unsigned char output[265];
mbedtls_cipher_context_t ctx;
size_t outlen, total_len;
mbedtls_cipher_init( &ctx );
memset( output, 0x00, sizeof( output ) );
#if !defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CHACHAPOLY_C)
((void) ad);
((void) tag);
#endif
/* Prepare context */
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
mbedtls_cipher_info_from_type( cipher_id ) ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key->x, 8 * key->len, MBEDTLS_DECRYPT ) );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
if( pad_mode != -1 )
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx, pad_mode ) );
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv->x, iv->len ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, ad->x, ad->len ) );
#endif
/* decode buffer and check tag->x */
total_len = 0;
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx, cipher->x, cipher->len, output, &outlen ) );
total_len += outlen;
TEST_ASSERT( finish_result == mbedtls_cipher_finish( &ctx, output + outlen,
&outlen ) );
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
TEST_ASSERT( tag_result == mbedtls_cipher_check_tag( &ctx, tag->x, tag->len ) );
#endif
/* check plaintext only if everything went fine */
if( 0 == finish_result && 0 == tag_result )
{
TEST_ASSERT( total_len == clear->len );
TEST_ASSERT( 0 == memcmp( output, clear->x, clear->len ) );
}
exit:
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_AEAD */
void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv,
data_t * ad, data_t * cipher, data_t * tag,
char * result, data_t * clear, int use_psa )
{
/* Takes an AEAD ciphertext + tag and performs a pair
* of AEAD decryption and AEAD encryption. It checks that
* this results in the expected plaintext, and that
* decryption and encryption are inverse to one another. */
int ret;
unsigned char output[300]; /* Temporary buffer for results of
* encryption and decryption. */
unsigned char *output_tag = NULL; /* Temporary buffer for tag in the
* encryption step. */
mbedtls_cipher_context_t ctx;
size_t outlen;
unsigned char *tmp_tag = NULL;
unsigned char *tmp_cipher = NULL;
mbedtls_cipher_init( &ctx );
memset( output, 0xFF, sizeof( output ) );
/* Prepare context */
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
(void) use_psa;
#else
if( use_psa == 1 )
{
TEST_ASSERT( psa_crypto_init() == 0 );
/* PSA requires that the tag immediately follows the ciphertext. */
tmp_cipher = mbedtls_calloc( 1, cipher->len + tag->len );
TEST_ASSERT( tmp_cipher != NULL );
tmp_tag = tmp_cipher + cipher->len;
memcpy( tmp_cipher, cipher->x, cipher->len );
memcpy( tmp_tag, tag->x, tag->len );
TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( &ctx,
mbedtls_cipher_info_from_type( cipher_id ),
tag->len ) );
}
else
#endif
{
tmp_tag = tag->x;
tmp_cipher = cipher->x;
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
mbedtls_cipher_info_from_type( cipher_id ) ) );
}
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key->x, 8 * key->len,
MBEDTLS_DECRYPT ) );
/* decode buffer and check tag->x */
/* Sanity check that we don't use overly long inputs. */
TEST_ASSERT( sizeof( output ) >= cipher->len );
ret = mbedtls_cipher_auth_decrypt( &ctx, iv->x, iv->len, ad->x, ad->len,
tmp_cipher, cipher->len, output, &outlen,
tmp_tag, tag->len );
/* make sure the message is rejected if it should be */
if( strcmp( result, "FAIL" ) == 0 )
{
TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED );
goto exit;
}
/* otherwise, make sure it was decrypted properly */
TEST_ASSERT( ret == 0 );
TEST_ASSERT( outlen == clear->len );
TEST_ASSERT( memcmp( output, clear->x, clear->len ) == 0 );
/* then encrypt the clear->x and make sure we get the same ciphertext and tag->x */
memset( output, 0xFF, sizeof( output ) );
outlen = 0;
/* Sanity check that we don't use overly long inputs. */
TEST_ASSERT( sizeof( output ) >= clear->len + tag->len );
output_tag = output + clear->len;
ret = mbedtls_cipher_auth_encrypt( &ctx, iv->x, iv->len, ad->x, ad->len,
clear->x, clear->len, output, &outlen,
output_tag, tag->len );
TEST_ASSERT( ret == 0 );
TEST_ASSERT( outlen == clear->len );
TEST_ASSERT( memcmp( output, cipher->x, cipher->len ) == 0 );
TEST_ASSERT( memcmp( output_tag, tag->x, tag->len ) == 0 );
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( use_psa == 1 )
{
mbedtls_free( tmp_cipher );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void test_vec_ecb( int cipher_id, int operation, data_t * key,
data_t * input, data_t * result, int finish_result
)
{
mbedtls_cipher_context_t ctx;
unsigned char output[32];
size_t outlen;
mbedtls_cipher_init( &ctx );
memset( output, 0x00, sizeof( output ) );
/* Prepare context */
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
mbedtls_cipher_info_from_type( cipher_id ) ) );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key->x, 8 * key->len, operation ) );
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx, input->x,
mbedtls_cipher_get_block_size( &ctx ),
output, &outlen ) );
TEST_ASSERT( outlen == mbedtls_cipher_get_block_size( &ctx ) );
TEST_ASSERT( finish_result == mbedtls_cipher_finish( &ctx, output + outlen,
&outlen ) );
TEST_ASSERT( 0 == outlen );
/* check plaintext only if everything went fine */
if( 0 == finish_result )
TEST_ASSERT( 0 == memcmp( output, result->x,
mbedtls_cipher_get_block_size( &ctx ) ) );
exit:
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_WITH_PADDING */
void test_vec_crypt( int cipher_id, int operation, char *hex_key,
char *hex_iv, char *hex_input, char *hex_result,
int finish_result, int use_psa )
{
unsigned char key[50];
unsigned char input[16];
unsigned char result[16];
unsigned char iv[16];
size_t key_len, iv_len, inputlen, resultlen;
mbedtls_cipher_context_t ctx;
unsigned char output[32];
size_t outlen;
mbedtls_cipher_init( &ctx );
memset( key, 0x00, sizeof( key ) );
memset( input, 0x00, sizeof( input ) );
memset( result, 0x00, sizeof( result ) );
memset( output, 0x00, sizeof( output ) );
memset( iv, 0x00, sizeof( iv ) );
/* Prepare context */
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
(void) use_psa;
#else
if( use_psa == 1 )
{
TEST_ASSERT( psa_crypto_init() == 0 );
TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( &ctx,
mbedtls_cipher_info_from_type( cipher_id ), 0 ) );
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
mbedtls_cipher_info_from_type( cipher_id ) ) );
key_len = unhexify( key, hex_key );
inputlen = unhexify( input, hex_input );
resultlen = unhexify( result, hex_result );
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key, 8 * key_len, operation ) );
if( MBEDTLS_MODE_CBC == ctx.cipher_info->mode )
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx, MBEDTLS_PADDING_NONE ) );
iv_len = unhexify( iv, hex_iv );
TEST_ASSERT( finish_result == mbedtls_cipher_crypt( &ctx, iv_len ? iv : NULL,
iv_len, input, inputlen,
output, &outlen ) );
TEST_ASSERT( resultlen == outlen );
/* check plaintext only if everything went fine */
if( 0 == finish_result )
TEST_ASSERT( 0 == memcmp( output, result, outlen ) );
exit:
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_WITH_PADDING */
void set_padding( int cipher_id, int pad_mode, int ret )
{
const mbedtls_cipher_info_t *cipher_info;
mbedtls_cipher_context_t ctx;
mbedtls_cipher_init( &ctx );
cipher_info = mbedtls_cipher_info_from_type( cipher_id );
TEST_ASSERT( NULL != cipher_info );
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx, cipher_info ) );
TEST_ASSERT( ret == mbedtls_cipher_set_padding_mode( &ctx, pad_mode ) );
exit:
mbedtls_cipher_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
void check_padding( int pad_mode, data_t * input, int ret, int dlen_check
)
{
mbedtls_cipher_info_t cipher_info;
mbedtls_cipher_context_t ctx;
size_t dlen;
/* build a fake context just for getting access to get_padding */
mbedtls_cipher_init( &ctx );
cipher_info.mode = MBEDTLS_MODE_CBC;
ctx.cipher_info = &cipher_info;
TEST_ASSERT( 0 == mbedtls_cipher_set_padding_mode( &ctx, pad_mode ) );
TEST_ASSERT( ret == ctx.get_padding( input->x, input->len, &dlen ) );
if( 0 == ret )
TEST_ASSERT( dlen == (size_t) dlen_check );
}
/* END_CASE */