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        TEST_ASSERT(plaintext[i] == 0);
62    }
63    mbedtls_nist_kw_free(&ctx1);
64    mbedtls_nist_kw_free(&ctx2);
65
66    /*
67     * 2. Check wrapping with two modes, on same context
68     */
69    mbedtls_nist_kw_init(&ctx1);
70    mbedtls_nist_kw_init(&ctx2);
71    output_len = sizeof(ciphertext1);
72
73    TEST_ASSERT(mbedtls_nist_kw_setkey(&ctx1,
74                                       MBEDTLS_CIPHER_ID_AES,
75                                       key, sizeof(key) * 8,
76                                       1) == 0);
77
78    TEST_ASSERT(mbedtls_nist_kw_wrap(&ctx1, MBEDTLS_KW_MODE_KW,
79                                     plaintext, sizeof(plaintext),
80                                     ciphertext1, &output_len,
81                                     sizeof(ciphertext1)) == 0);
82    TEST_ASSERT(output_len == sizeof(ciphertext1));
83
84    TEST_ASSERT(mbedtls_nist_kw_wrap(&ctx1, MBEDTLS_KW_MODE_KWP,
85                                     plaintext, sizeof(plaintext),
86                                     ciphertext2, &output_len,
87                                     sizeof(ciphertext2)) == 0);
88
89    TEST_ASSERT(output_len == sizeof(ciphertext2));
90
91    TEST_ASSERT(mbedtls_nist_kw_setkey(&ctx2,
92                                       MBEDTLS_CIPHER_ID_AES,
93                                       key, sizeof(key) * 8,
94                                       0) == 0);
95
96    TEST_ASSERT(mbedtls_nist_kw_unwrap(&ctx2, MBEDTLS_KW_MODE_KW,
97                                       ciphertext1, sizeof(ciphertext1),
98                                       plaintext, &output_len,
99                                       sizeof(plaintext)) == 0);
100
101    TEST_ASSERT(output_len == sizeof(plaintext));
102
103    for (i = 0; i < sizeof(plaintext); i++) {
104        TEST_ASSERT(plaintext[i] == 0);
105    }
106
107    TEST_ASSERT(mbedtls_nist_kw_unwrap(&ctx2, MBEDTLS_KW_MODE_KWP,
108                                       ciphertext2, sizeof(ciphertext2),
109                                       plaintext, &output_len,
110                                       sizeof(plaintext)) == 0);
111
112    TEST_ASSERT(output_len == sizeof(plaintext));
113
114    for (i = 0; i < sizeof(plaintext); i++) {
115        TEST_ASSERT(plaintext[i] == 0);
116    }
117
118exit:
119    mbedtls_nist_kw_free(&ctx1);
120    mbedtls_nist_kw_free(&ctx2);
121}
122/* END_CASE */
123
124/* BEGIN_CASE */
125void mbedtls_nist_kw_setkey(int cipher_id, int key_size,
126                            int is_wrap, int result)
127{
128    mbedtls_nist_kw_context ctx;
129    unsigned char key[32];
130    int ret;
131
132    mbedtls_nist_kw_init(&ctx);
133
134    memset(key, 0x2A, sizeof(key));
135    TEST_ASSERT((unsigned) key_size <= 8 * sizeof(key));
136
137    ret = mbedtls_nist_kw_setkey(&ctx, cipher_id, key, key_size, is_wrap);
138    TEST_ASSERT(ret == result);
139
140exit:
141    mbedtls_nist_kw_free(&ctx);
142}
143/* END_CASE */
144
145/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
146void nist_kw_plaintext_lengths(int in_len, int out_len, int mode, int res)
147{
148    mbedtls_nist_kw_context ctx;
149    unsigned char key[16];
150    unsigned char *plaintext = NULL;
151    unsigned char *ciphertext = NULL;
152    size_t output_len = out_len;
153
154    mbedtls_nist_kw_init(&ctx);
155
156    memset(key, 0, sizeof(key));
157
158    if (in_len != 0) {
159        plaintext = mbedtls_calloc(1, in_len);
160        TEST_ASSERT(plaintext != NULL);
161    }
162
163    if (out_len != 0) {
164        ciphertext = mbedtls_calloc(1, output_len);
165        TEST_ASSERT(ciphertext != NULL);
166    }
167
168    TEST_ASSERT(mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
169                                       key, 8 * sizeof(key), 1) == 0);
170
171    TEST_ASSERT(mbedtls_nist_kw_wrap(&ctx, mode, plaintext, in_len,
172                                     ciphertext, &output_len,
173                                     output_len) == res);
174    if (res == 0) {
175        if (mode == MBEDTLS_KW_MODE_KWP) {
176            TEST_ASSERT(output_len == (size_t) in_len + 8 -
177                        (in_len % 8) + 8);
178        } else {
179            TEST_ASSERT(output_len == (size_t) in_len + 8);
180        }
181    } else {
182        TEST_ASSERT(output_len == 0);
183    }
184
185exit:
186    mbedtls_free(ciphertext);
187    mbedtls_free(plaintext);
188    mbedtls_nist_kw_free(&ctx);
189}
190/* END_CASE */
191
192/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
193void nist_kw_ciphertext_lengths(int in_len, int out_len, int mode, int res)
194{
195    mbedtls_nist_kw_context ctx;
196    unsigned char key[16];
197    unsigned char *plaintext = NULL;
198    unsigned char *ciphertext = NULL;
199    int unwrap_ret;
200    size_t output_len = out_len;
201
202    mbedtls_nist_kw_init(&ctx);
203
204    memset(key, 0, sizeof(key));
205
206    if (out_len != 0) {
207        plaintext = mbedtls_calloc(1, output_len);
208        TEST_ASSERT(plaintext != NULL);
209    }
210    if (in_len != 0) {
211        ciphertext = mbedtls_calloc(1, in_len);
212        TEST_ASSERT(ciphertext != NULL);
213    }
214
215    TEST_ASSERT(mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
216                                       key, 8 * sizeof(key), 0) == 0);
217    unwrap_ret = mbedtls_nist_kw_unwrap(&ctx, mode, ciphertext, in_len,
218                                        plaintext, &output_len,
219                                        output_len);
220
221    if (res == 0) {
222        TEST_ASSERT(unwrap_ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED);
223    } else {
224        TEST_ASSERT(unwrap_ret == res);
225    }
226
227    TEST_ASSERT(output_len == 0);
228
229exit:
230    mbedtls_free(ciphertext);
231    mbedtls_free(plaintext);
232    mbedtls_nist_kw_free(&ctx);
233}
234/* END_CASE */
235
236/* BEGIN_CASE */
237void mbedtls_nist_kw_wrap(int cipher_id, int mode, data_t *key, data_t *msg,
238                          data_t *expected_result)
239{
240    unsigned char result[528];
241    mbedtls_nist_kw_context ctx;
242    size_t result_len, i, padlen;
243
244    mbedtls_nist_kw_init(&ctx);
245
246    memset(result, '+', sizeof(result));
247
248    TEST_ASSERT(mbedtls_nist_kw_setkey(&ctx, cipher_id,
249                                       key->x, key->len * 8, 1) == 0);
250
251    /* Test with input == output */
252    TEST_ASSERT(mbedtls_nist_kw_wrap(&ctx, mode, msg->x, msg->len,
253                                     result, &result_len, sizeof(result)) == 0);
254
255    TEST_ASSERT(result_len == expected_result->len);
256
257    TEST_ASSERT(memcmp(expected_result->x, result, result_len) == 0);
258
259    padlen = (msg->len % 8 != 0) ? 8 - (msg->len % 8) : 0;
260    /* Check that the function didn't write beyond the end of the buffer. */
261    for (i = msg->len + 8 + padlen; i < sizeof(result); i++) {
262        TEST_ASSERT(result[i] == '+');
263    }
264
265exit:
266    mbedtls_nist_kw_free(&ctx);
267}
268/* END_CASE */
269
270/* BEGIN_CASE */
271void mbedtls_nist_kw_unwrap(int cipher_id, int mode, data_t *key, data_t *msg,
272                            data_t *expected_result, int expected_ret)
273{
274    unsigned char result[528];
275    mbedtls_nist_kw_context ctx;
276    size_t result_len, i;
277
278    mbedtls_nist_kw_init(&ctx);
279
280    memset(result, '+', sizeof(result));
281
282    TEST_ASSERT(mbedtls_nist_kw_setkey(&ctx, cipher_id,
283                                       key->x, key->len * 8, 0) == 0);
284
285    /* Test with input == output */
286    TEST_ASSERT(mbedtls_nist_kw_unwrap(&ctx, mode, msg->x, msg->len,
287                                       result, &result_len, sizeof(result)) == expected_ret);
288    if (expected_ret == 0) {
289        TEST_ASSERT(result_len == expected_result->len);
290        TEST_ASSERT(memcmp(expected_result->x, result, result_len) == 0);
291    } else {
292        TEST_ASSERT(result_len == 0);
293    }
294
295    /* Check that the function didn't write beyond the end of the buffer. */
296    for (i = msg->len - 8; i < sizeof(result); i++) {
297        TEST_ASSERT(result[i] == '+');
298    }
299
300exit:
301    mbedtls_nist_kw_free(&ctx);
302}
303/* END_CASE */
304