1/* BEGIN_HEADER */
2#include "mbedtls/ccm.h"
3/* END_HEADER */
4
5/* BEGIN_DEPENDENCIES
6 * depends_on:MBEDTLS_CCM_C
7 * END_DEPENDENCIES
8 */
9
10/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */
11void mbedtls_ccm_self_test( )
12{
13    TEST_ASSERT( mbedtls_ccm_self_test( 1 ) == 0 );
14}
15/* END_CASE */
16
17/* BEGIN_CASE */
18void mbedtls_ccm_setkey( int cipher_id, int key_size, int result )
19{
20    mbedtls_ccm_context ctx;
21    unsigned char key[32];
22    int ret;
23
24    mbedtls_ccm_init( &ctx );
25
26    memset( key, 0x2A, sizeof( key ) );
27    TEST_ASSERT( (unsigned) key_size <= 8 * sizeof( key ) );
28
29    ret = mbedtls_ccm_setkey( &ctx, cipher_id, key, key_size );
30    TEST_ASSERT( ret == result );
31
32exit:
33    mbedtls_ccm_free( &ctx );
34}
35/* END_CASE */
36
37/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
38void ccm_lengths( int msg_len, int iv_len, int add_len, int tag_len, int res )
39{
40    mbedtls_ccm_context ctx;
41    unsigned char key[16];
42    unsigned char msg[10];
43    unsigned char iv[14];
44    unsigned char add[10];
45    unsigned char out[10];
46    unsigned char tag[18];
47    int decrypt_ret;
48
49    mbedtls_ccm_init( &ctx );
50
51    memset( key, 0, sizeof( key ) );
52    memset( msg, 0, sizeof( msg ) );
53    memset( iv, 0, sizeof( iv ) );
54    memset( add, 0, sizeof( add ) );
55    memset( out, 0, sizeof( out ) );
56    memset( tag, 0, sizeof( tag ) );
57
58    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
59                                 key, 8 * sizeof( key ) ) == 0 );
60
61    TEST_ASSERT( mbedtls_ccm_encrypt_and_tag( &ctx, msg_len, iv, iv_len, add, add_len,
62                                      msg, out, tag, tag_len ) == res );
63
64    decrypt_ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len, iv, iv_len, add, add_len,
65                                    msg, out, tag, tag_len );
66
67    if( res == 0 )
68        TEST_ASSERT( decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED );
69    else
70        TEST_ASSERT( decrypt_ret == res );
71
72exit:
73    mbedtls_ccm_free( &ctx );
74}
75/* END_CASE */
76
77/* BEGIN_CASE */
78void mbedtls_ccm_encrypt_and_tag( int cipher_id,
79                          char *key_hex, char *msg_hex,
80                          char *iv_hex, char *add_hex,
81                          char *result_hex )
82{
83    unsigned char key[32];
84    unsigned char msg[50];
85    unsigned char iv[13];
86    unsigned char add[32];
87    unsigned char result[50];
88    mbedtls_ccm_context ctx;
89    size_t key_len, msg_len, iv_len, add_len, tag_len, result_len;
90
91    mbedtls_ccm_init( &ctx );
92
93    memset( key, 0x00, sizeof( key ) );
94    memset( msg, 0x00, sizeof( msg ) );
95    memset( iv, 0x00, sizeof( iv ) );
96    memset( add, 0x00, sizeof( add ) );
97    memset( result, 0x00, sizeof( result ) );
98
99    key_len = unhexify( key, key_hex );
100    msg_len = unhexify( msg, msg_hex );
101    iv_len = unhexify( iv, iv_hex );
102    add_len = unhexify( add, add_hex );
103    result_len = unhexify( result, result_hex );
104    tag_len = result_len - msg_len;
105
106    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );
107
108    /* Test with input == output */
109    TEST_ASSERT( mbedtls_ccm_encrypt_and_tag( &ctx, msg_len, iv, iv_len, add, add_len,
110                 msg, msg, msg + msg_len, tag_len ) == 0 );
111
112    TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
113
114    /* Check we didn't write past the end */
115    TEST_ASSERT( msg[result_len] == 0 && msg[result_len + 1] == 0 );
116
117exit:
118    mbedtls_ccm_free( &ctx );
119}
120/* END_CASE */
121
122/* BEGIN_CASE */
123void mbedtls_ccm_auth_decrypt( int cipher_id,
124                       char *key_hex, char *msg_hex,
125                       char *iv_hex, char *add_hex,
126                       int tag_len, char *result_hex )
127{
128    unsigned char key[32];
129    unsigned char msg[50];
130    unsigned char iv[13];
131    unsigned char add[32];
132    unsigned char tag[16];
133    unsigned char result[50];
134    mbedtls_ccm_context ctx;
135    size_t key_len, msg_len, iv_len, add_len, result_len;
136    int ret;
137
138    mbedtls_ccm_init( &ctx );
139
140    memset( key, 0x00, sizeof( key ) );
141    memset( msg, 0x00, sizeof( msg ) );
142    memset( iv, 0x00, sizeof( iv ) );
143    memset( add, 0x00, sizeof( add ) );
144    memset( tag, 0x00, sizeof( tag ) );
145    memset( result, 0x00, sizeof( result ) );
146
147    key_len = unhexify( key, key_hex );
148    msg_len = unhexify( msg, msg_hex );
149    iv_len = unhexify( iv, iv_hex );
150    add_len = unhexify( add, add_hex );
151    msg_len -= tag_len;
152    memcpy( tag, msg + msg_len, tag_len );
153
154    if( strcmp( "FAIL", result_hex ) == 0 )
155    {
156        ret = MBEDTLS_ERR_CCM_AUTH_FAILED;
157        result_len = -1;
158    }
159    else
160    {
161        ret = 0;
162        result_len = unhexify( result, result_hex );
163    }
164
165    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );
166
167    /* Test with input == output */
168    TEST_ASSERT( mbedtls_ccm_auth_decrypt( &ctx, msg_len, iv, iv_len, add, add_len,
169                 msg, msg, msg + msg_len, tag_len ) == ret );
170
171    if( ret == 0 )
172    {
173        TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
174    }
175    else
176    {
177        size_t i;
178
179        for( i = 0; i < msg_len; i++ )
180            TEST_ASSERT( msg[i] == 0 );
181    }
182
183    /* Check we didn't write past the end (where the original tag is) */
184    TEST_ASSERT( memcmp( msg + msg_len, tag, tag_len ) == 0 );
185
186exit:
187    mbedtls_ccm_free( &ctx );
188}
189/* END_CASE */
190