1/* BEGIN_HEADER */
2#include "mbedtls/nist_kw.h"
3/* END_HEADER */
4
5/* BEGIN_DEPENDENCIES
6 * depends_on:MBEDTLS_NIST_KW_C
7 * END_DEPENDENCIES
8 */
9
10/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */
11void mbedtls_nist_kw_self_test( )
12{
13    TEST_ASSERT( mbedtls_nist_kw_self_test( 1 ) == 0 );
14}
15/* END_CASE */
16
17/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
18void mbedtls_nist_kw_mix_contexts( )
19{
20    mbedtls_nist_kw_context ctx1, ctx2;
21    unsigned char key[16];
22    unsigned char plaintext[32];
23    unsigned char ciphertext1[40];
24    unsigned char ciphertext2[40];
25    size_t output_len, i;
26
27    memset( plaintext, 0, sizeof( plaintext ) );
28    memset( ciphertext1, 0, sizeof( ciphertext1 ) );
29    memset( ciphertext2, 0, sizeof( ciphertext2 ) );
30    memset( key, 0, sizeof( key ) );
31
32    /*
33     * 1. Check wrap and unwrap with two separate contexts
34     */
35    mbedtls_nist_kw_init( &ctx1 );
36    mbedtls_nist_kw_init( &ctx2 );
37
38    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx1,
39                                         MBEDTLS_CIPHER_ID_AES,
40                                         key, sizeof( key ) * 8,
41                                         1 ) == 0 );
42
43    TEST_ASSERT( mbedtls_nist_kw_wrap( &ctx1, MBEDTLS_KW_MODE_KW,
44                                       plaintext, sizeof( plaintext ),
45                                       ciphertext1, &output_len,
46                                       sizeof( ciphertext1 ) ) == 0 );
47    TEST_ASSERT( output_len == sizeof( ciphertext1 ) );
48
49    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx2,
50                                         MBEDTLS_CIPHER_ID_AES,
51                                         key, sizeof( key ) * 8,
52                                         0 ) == 0 );
53
54    TEST_ASSERT( mbedtls_nist_kw_unwrap( &ctx2, MBEDTLS_KW_MODE_KW,
55                                         ciphertext1, output_len,
56                                         plaintext, &output_len,
57                                         sizeof( plaintext ) ) == 0 );
58
59    TEST_ASSERT( output_len == sizeof( plaintext ) );
60    for( i = 0; i < sizeof( plaintext ); i++ )
61    {
62        TEST_ASSERT( plaintext[i] == 0 );
63    }
64    mbedtls_nist_kw_free( &ctx1 );
65    mbedtls_nist_kw_free( &ctx2 );
66
67    /*
68     * 2. Check wrapping with two modes, on same context
69     */
70    mbedtls_nist_kw_init( &ctx1 );
71    mbedtls_nist_kw_init( &ctx2 );
72    output_len = sizeof( ciphertext1 );
73
74    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx1,
75                                         MBEDTLS_CIPHER_ID_AES,
76                                         key, sizeof( key ) * 8,
77                                         1 ) == 0 );
78
79    TEST_ASSERT( mbedtls_nist_kw_wrap( &ctx1, MBEDTLS_KW_MODE_KW,
80                                       plaintext, sizeof( plaintext ),
81                                       ciphertext1, &output_len,
82                                       sizeof( ciphertext1 ) ) == 0 );
83    TEST_ASSERT( output_len == sizeof( ciphertext1 ) );
84
85    TEST_ASSERT( mbedtls_nist_kw_wrap( &ctx1, MBEDTLS_KW_MODE_KWP,
86                                       plaintext, sizeof( plaintext ),
87                                       ciphertext2, &output_len,
88                                       sizeof( ciphertext2 ) ) == 0 );
89
90    TEST_ASSERT( output_len == sizeof( ciphertext2 ) );
91
92    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx2,
93                                         MBEDTLS_CIPHER_ID_AES,
94                                         key, sizeof( key ) * 8,
95                                         0 ) == 0 );
96
97    TEST_ASSERT( mbedtls_nist_kw_unwrap( &ctx2, MBEDTLS_KW_MODE_KW,
98                                         ciphertext1, sizeof( ciphertext1 ),
99                                         plaintext, &output_len,
100                                         sizeof( plaintext ) ) == 0 );
101
102    TEST_ASSERT( output_len == sizeof( plaintext ) );
103
104    for( i = 0; i < sizeof( plaintext ); i++ )
105    {
106        TEST_ASSERT( plaintext[i] == 0 );
107    }
108
109    TEST_ASSERT( mbedtls_nist_kw_unwrap( &ctx2, MBEDTLS_KW_MODE_KWP,
110                                         ciphertext2, sizeof( ciphertext2 ),
111                                         plaintext, &output_len,
112                                         sizeof( plaintext ) ) == 0 );
113
114    TEST_ASSERT( output_len == sizeof( plaintext ) );
115
116    for( i = 0; i < sizeof( plaintext ); i++ )
117    {
118        TEST_ASSERT( plaintext[i] == 0 );
119    }
120
121exit:
122    mbedtls_nist_kw_free( &ctx1 );
123    mbedtls_nist_kw_free( &ctx2 );
124}
125/* END_CASE */
126
127/* BEGIN_CASE */
128void mbedtls_nist_kw_setkey( int cipher_id, int key_size,
129                             int is_wrap, int result )
130{
131    mbedtls_nist_kw_context ctx;
132    unsigned char key[32];
133    int ret;
134
135    mbedtls_nist_kw_init( &ctx );
136
137    memset( key, 0x2A, sizeof( key ) );
138    TEST_ASSERT( (unsigned) key_size <= 8 * sizeof( key ) );
139
140    ret = mbedtls_nist_kw_setkey( &ctx, cipher_id, key, key_size, is_wrap );
141    TEST_ASSERT( ret == result );
142
143exit:
144    mbedtls_nist_kw_free( &ctx );
145}
146/* END_CASE */
147
148/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
149void nist_kw_plaintext_lengths( int in_len, int out_len, int mode, int res )
150{
151    mbedtls_nist_kw_context ctx;
152    unsigned char key[16];
153    unsigned char *plaintext = NULL;
154    unsigned char *ciphertext = NULL;
155    size_t output_len = out_len;
156
157    mbedtls_nist_kw_init( &ctx );
158
159    memset( key, 0, sizeof( key ) );
160
161    if( in_len != 0 )
162    {
163        plaintext = mbedtls_calloc( 1, in_len );
164        TEST_ASSERT( plaintext != NULL );
165    }
166
167    if( out_len != 0 )
168    {
169        ciphertext = mbedtls_calloc( 1, output_len );
170        TEST_ASSERT( ciphertext != NULL );
171    }
172
173    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
174                                         key, 8 * sizeof( key ), 1 ) == 0 );
175
176    TEST_ASSERT( mbedtls_nist_kw_wrap( &ctx, mode, plaintext, in_len,
177                                      ciphertext, &output_len,
178                                      output_len ) == res );
179    if( res == 0 )
180    {
181        if( mode == MBEDTLS_KW_MODE_KWP )
182            TEST_ASSERT( output_len == (size_t) in_len + 8 -
183                         ( in_len % 8 ) + 8 );
184        else
185            TEST_ASSERT( output_len == (size_t) in_len + 8 );
186    }
187    else
188    {
189        TEST_ASSERT( output_len == 0 );
190    }
191
192exit:
193    mbedtls_free( ciphertext );
194    mbedtls_free( plaintext );
195    mbedtls_nist_kw_free( &ctx );
196}
197/* END_CASE */
198
199/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
200void nist_kw_ciphertext_lengths( int in_len, int out_len, int mode, int res )
201{
202    mbedtls_nist_kw_context ctx;
203    unsigned char key[16];
204    unsigned char *plaintext = NULL;
205    unsigned char *ciphertext = NULL;
206    int unwrap_ret;
207    size_t output_len = out_len;
208
209    mbedtls_nist_kw_init( &ctx );
210
211    memset( key, 0, sizeof( key ) );
212
213    if( out_len != 0 )
214    {
215        plaintext = mbedtls_calloc( 1, output_len );
216        TEST_ASSERT( plaintext != NULL );
217    }
218    if( in_len != 0 )
219    {
220        ciphertext = mbedtls_calloc( 1, in_len );
221        TEST_ASSERT( ciphertext != NULL );
222    }
223
224    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
225                                         key, 8 * sizeof( key ), 0 ) == 0 );
226    unwrap_ret = mbedtls_nist_kw_unwrap( &ctx, mode, ciphertext, in_len,
227                                         plaintext, &output_len,
228                                         output_len );
229
230    if( res == 0 )
231        TEST_ASSERT( unwrap_ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED );
232    else
233        TEST_ASSERT( unwrap_ret == res );
234
235    TEST_ASSERT( output_len == 0 );
236
237exit:
238    mbedtls_free( ciphertext );
239    mbedtls_free( plaintext );
240    mbedtls_nist_kw_free( &ctx );
241}
242/* END_CASE */
243
244/* BEGIN_CASE */
245void mbedtls_nist_kw_wrap( int cipher_id, int mode, data_t *key, data_t *msg,
246                           data_t *expected_result )
247{
248    unsigned char result[528];
249    mbedtls_nist_kw_context ctx;
250    size_t result_len, i, padlen;
251
252    mbedtls_nist_kw_init( &ctx );
253
254    memset( result, '+', sizeof( result ) );
255
256    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx, cipher_id,
257                                         key->x, key->len * 8, 1 ) == 0 );
258
259    /* Test with input == output */
260    TEST_ASSERT( mbedtls_nist_kw_wrap( &ctx, mode, msg->x, msg->len,
261                 result, &result_len, sizeof( result ) ) == 0 );
262
263    TEST_ASSERT( result_len == expected_result->len );
264
265    TEST_ASSERT( memcmp( expected_result->x, result, result_len ) == 0 );
266
267    padlen = ( msg->len % 8 != 0 ) ? 8 - (msg->len % 8 ) : 0;
268    /* Check that the function didn't write beyond the end of the buffer. */
269    for( i = msg->len + 8 + padlen; i < sizeof( result ); i++ )
270    {
271        TEST_ASSERT( result[i] == '+' );
272    }
273
274exit:
275    mbedtls_nist_kw_free( &ctx );
276}
277/* END_CASE */
278
279/* BEGIN_CASE */
280void mbedtls_nist_kw_unwrap( int cipher_id, int mode, data_t *key, data_t *msg,
281                             data_t *expected_result, int expected_ret )
282{
283    unsigned char result[528];
284    mbedtls_nist_kw_context ctx;
285    size_t result_len, i;
286
287    mbedtls_nist_kw_init( &ctx );
288
289    memset( result, '+', sizeof( result ) );
290
291    TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx, cipher_id,
292                                         key->x, key->len * 8, 0 ) == 0 );
293
294    /* Test with input == output */
295    TEST_ASSERT( mbedtls_nist_kw_unwrap( &ctx, mode, msg->x, msg->len,
296                 result, &result_len, sizeof( result ) ) == expected_ret );
297    if( expected_ret == 0 )
298    {
299        TEST_ASSERT( result_len == expected_result->len );
300        TEST_ASSERT( memcmp( expected_result->x, result, result_len ) == 0 );
301    }
302    else
303    {
304        TEST_ASSERT( result_len == 0 );
305    }
306
307    /* Check that the function didn't write beyond the end of the buffer. */
308    for( i = msg->len - 8; i < sizeof( result ); i++ )
309    {
310        TEST_ASSERT( result[i] == '+' );
311    }
312
313exit:
314    mbedtls_nist_kw_free( &ctx );
315}
316/* END_CASE */
317