mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 12:05:38 +01:00
b17537558a
It was failing to set the key in the ENCRYPT direction before encrypting. This just happened to work for GCM and CCM. After re-encrypting, compare the length to the expected ciphertext length not the plaintext length. Again this just happens to work for GCM and CCM since they do not perform any kind of padding.
797 lines
26 KiB
Plaintext
797 lines
26 KiB
Plaintext
/* 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_null_args( )
|
|
{
|
|
mbedtls_cipher_context_t ctx;
|
|
const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type( *( mbedtls_cipher_list() ) );
|
|
unsigned char buf[1] = { 0 };
|
|
size_t olen;
|
|
|
|
mbedtls_cipher_init( &ctx );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_get_block_size( NULL ) == 0 );
|
|
TEST_ASSERT( mbedtls_cipher_get_block_size( &ctx ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_get_cipher_mode( NULL ) == MBEDTLS_MODE_NONE );
|
|
TEST_ASSERT( mbedtls_cipher_get_cipher_mode( &ctx ) == MBEDTLS_MODE_NONE );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_get_iv_size( NULL ) == 0 );
|
|
TEST_ASSERT( mbedtls_cipher_get_iv_size( &ctx ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_info_from_string( NULL ) == NULL );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_setup( &ctx, NULL )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_setup( NULL, info )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_setkey( NULL, buf, 0, MBEDTLS_ENCRYPT )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_setkey( &ctx, buf, 0, MBEDTLS_ENCRYPT )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_set_iv( NULL, buf, 0 )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_set_iv( &ctx, buf, 0 )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_reset( NULL ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_reset( &ctx ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
#if defined(MBEDTLS_GCM_C)
|
|
TEST_ASSERT( mbedtls_cipher_update_ad( NULL, buf, 0 )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_update_ad( &ctx, buf, 0 )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
#endif
|
|
|
|
TEST_ASSERT( mbedtls_cipher_update( NULL, buf, 0, buf, &olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_update( &ctx, buf, 0, buf, &olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_finish( NULL, buf, &olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_finish( &ctx, buf, &olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
#if defined(MBEDTLS_GCM_C)
|
|
TEST_ASSERT( mbedtls_cipher_write_tag( NULL, buf, olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_write_tag( &ctx, buf, olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
|
|
TEST_ASSERT( mbedtls_cipher_check_tag( NULL, buf, olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
TEST_ASSERT( mbedtls_cipher_check_tag( &ctx, buf, olen )
|
|
== MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
|
#endif
|
|
}
|
|
/* 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[32];
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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,
|
|
char *hex_key, char *hex_iv,
|
|
char *hex_cipher, char *hex_clear,
|
|
char *hex_ad, char *hex_tag,
|
|
int finish_result, int tag_result )
|
|
{
|
|
unsigned char key[50];
|
|
unsigned char iv[50];
|
|
unsigned char cipher[200];
|
|
unsigned char clear[200];
|
|
unsigned char ad[200];
|
|
unsigned char tag[20];
|
|
size_t key_len, iv_len, cipher_len, clear_len;
|
|
#if defined(MBEDTLS_GCM_C)
|
|
size_t ad_len, tag_len;
|
|
#endif
|
|
mbedtls_cipher_context_t ctx;
|
|
unsigned char output[200];
|
|
size_t outlen, total_len;
|
|
|
|
mbedtls_cipher_init( &ctx );
|
|
|
|
memset( key, 0x00, sizeof( key ) );
|
|
memset( iv, 0x00, sizeof( iv ) );
|
|
memset( cipher, 0x00, sizeof( cipher ) );
|
|
memset( clear, 0x00, sizeof( clear ) );
|
|
memset( ad, 0x00, sizeof( ad ) );
|
|
memset( tag, 0x00, sizeof( tag ) );
|
|
memset( output, 0x00, sizeof( output ) );
|
|
|
|
key_len = unhexify( key, hex_key );
|
|
iv_len = unhexify( iv, hex_iv );
|
|
cipher_len = unhexify( cipher, hex_cipher );
|
|
clear_len = unhexify( clear, hex_clear );
|
|
#if defined(MBEDTLS_GCM_C)
|
|
ad_len = unhexify( ad, hex_ad );
|
|
tag_len = unhexify( tag, hex_tag );
|
|
#else
|
|
((void) hex_ad);
|
|
((void) hex_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, 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, iv_len ) );
|
|
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) );
|
|
#if defined(MBEDTLS_GCM_C)
|
|
TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, ad, ad_len ) );
|
|
#endif
|
|
|
|
/* decode buffer and check tag */
|
|
total_len = 0;
|
|
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx, cipher, 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)
|
|
TEST_ASSERT( tag_result == mbedtls_cipher_check_tag( &ctx, tag, 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, clear_len ) );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_cipher_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_AEAD */
|
|
void auth_crypt_tv( int cipher_id, char *hex_key, char *hex_iv,
|
|
char *hex_ad, char *hex_cipher,
|
|
char *hex_tag, char *hex_clear )
|
|
{
|
|
int ret;
|
|
unsigned char key[50];
|
|
unsigned char iv[50];
|
|
unsigned char cipher[200];
|
|
unsigned char clear[200];
|
|
unsigned char ad[200];
|
|
unsigned char tag[20];
|
|
unsigned char my_tag[20];
|
|
size_t key_len, iv_len, cipher_len, clear_len, ad_len, tag_len;
|
|
mbedtls_cipher_context_t ctx;
|
|
unsigned char output[200];
|
|
size_t outlen;
|
|
|
|
mbedtls_cipher_init( &ctx );
|
|
|
|
memset( key, 0x00, sizeof( key ) );
|
|
memset( iv, 0x00, sizeof( iv ) );
|
|
memset( cipher, 0x00, sizeof( cipher ) );
|
|
memset( clear, 0x00, sizeof( clear ) );
|
|
memset( ad, 0x00, sizeof( ad ) );
|
|
memset( tag, 0x00, sizeof( tag ) );
|
|
memset( my_tag, 0xFF, sizeof( my_tag ) );
|
|
memset( output, 0xFF, sizeof( output ) );
|
|
|
|
key_len = unhexify( key, hex_key );
|
|
iv_len = unhexify( iv, hex_iv );
|
|
cipher_len = unhexify( cipher, hex_cipher );
|
|
ad_len = unhexify( ad, hex_ad );
|
|
tag_len = unhexify( tag, hex_tag );
|
|
|
|
/* Prepare context */
|
|
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
|
|
mbedtls_cipher_info_from_type( cipher_id ) ) );
|
|
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key, 8 * key_len, MBEDTLS_DECRYPT ) );
|
|
|
|
/* decode buffer and check tag */
|
|
ret = mbedtls_cipher_auth_decrypt( &ctx, iv, iv_len, ad, ad_len,
|
|
cipher, cipher_len, output, &outlen,
|
|
tag, tag_len );
|
|
|
|
/* make sure we didn't overwrite */
|
|
TEST_ASSERT( output[outlen + 0] == 0xFF );
|
|
TEST_ASSERT( output[outlen + 1] == 0xFF );
|
|
|
|
/* make sure the message is rejected if it should be */
|
|
if( strcmp( hex_clear, "FAIL" ) == 0 )
|
|
{
|
|
TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED );
|
|
goto exit;
|
|
}
|
|
|
|
/* otherwise, make sure it was decrypted properly */
|
|
TEST_ASSERT( ret == 0 );
|
|
|
|
clear_len = unhexify( clear, hex_clear );
|
|
TEST_ASSERT( outlen == clear_len );
|
|
TEST_ASSERT( memcmp( output, clear, clear_len ) == 0 );
|
|
|
|
/* then encrypt the clear and make sure we get the same ciphertext and tag */
|
|
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key, 8 * key_len,
|
|
MBEDTLS_ENCRYPT ) );
|
|
|
|
memset( output, 0xFF, sizeof( output ) );
|
|
outlen = 0;
|
|
|
|
ret = mbedtls_cipher_auth_encrypt( &ctx, iv, iv_len, ad, ad_len,
|
|
clear, clear_len, output, &outlen,
|
|
my_tag, tag_len );
|
|
TEST_ASSERT( ret == 0 );
|
|
|
|
TEST_ASSERT( outlen == cipher_len );
|
|
TEST_ASSERT( memcmp( output, cipher, cipher_len ) == 0 );
|
|
TEST_ASSERT( memcmp( my_tag, tag, tag_len ) == 0 );
|
|
|
|
/* make sure we didn't overwrite */
|
|
TEST_ASSERT( output[outlen + 0] == 0xFF );
|
|
TEST_ASSERT( output[outlen + 1] == 0xFF );
|
|
TEST_ASSERT( my_tag[tag_len + 0] == 0xFF );
|
|
TEST_ASSERT( my_tag[tag_len + 1] == 0xFF );
|
|
|
|
|
|
exit:
|
|
mbedtls_cipher_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void test_vec_ecb( int cipher_id, int operation, char *hex_key,
|
|
char *hex_input, char *hex_result,
|
|
int finish_result )
|
|
{
|
|
unsigned char key[50];
|
|
unsigned char input[16];
|
|
unsigned char result[16];
|
|
size_t key_len;
|
|
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 ) );
|
|
|
|
/* Prepare context */
|
|
TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
|
|
mbedtls_cipher_info_from_type( cipher_id ) ) );
|
|
|
|
key_len = unhexify( key, hex_key );
|
|
TEST_ASSERT( unhexify( input, hex_input ) ==
|
|
(int) mbedtls_cipher_get_block_size( &ctx ) );
|
|
TEST_ASSERT( unhexify( result, hex_result ) ==
|
|
(int) mbedtls_cipher_get_block_size( &ctx ) );
|
|
|
|
TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key, 8 * key_len, operation ) );
|
|
|
|
TEST_ASSERT( 0 == mbedtls_cipher_update( &ctx, input,
|
|
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,
|
|
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 )
|
|
{
|
|
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 */
|
|
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, char *input_str, int ret, int dlen_check )
|
|
{
|
|
mbedtls_cipher_info_t cipher_info;
|
|
mbedtls_cipher_context_t ctx;
|
|
unsigned char input[16];
|
|
size_t ilen, 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 ) );
|
|
|
|
ilen = unhexify( input, input_str );
|
|
|
|
TEST_ASSERT( ret == ctx.get_padding( input, ilen, &dlen ) );
|
|
if( 0 == ret )
|
|
TEST_ASSERT( dlen == (size_t) dlen_check );
|
|
}
|
|
/* END_CASE */
|