1 /* Copyright Akamai Technologies, Inc.
2 * SPDX-License-Identifier: Apache-2.0
3 */
4
5 #define _POSIX_C_SOURCE 200112L
6 #define _ISOC99_SOURCE 1
7
8 #include "config.h"
9 #include "aes_siv.h"
10
11 #undef NDEBUG
12 #include <assert.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <string.h>
16
17 #include <openssl/crypto.h>
18 #include <openssl/evp.h>
19 #include <openssl/opensslv.h>
20
debug(const char * label,const unsigned char * hex,size_t len)21 static void debug(const char *label, const unsigned char *hex, size_t len) {
22 size_t i;
23 printf("%16s: ", label);
24 for (i = 0; i < len; i++) {
25 if (i > 0 && i % 16 == 0) {
26 printf("\n ");
27 }
28 printf("%.2x", (int)hex[i]);
29 if (i > 0 && i % 4 == 3) {
30 printf(" ");
31 }
32 }
33 printf("\n");
34 }
35
36 static int fail_allocation_counter = -1;
37
mock_malloc(size_t num)38 static void* mock_malloc(size_t num) {
39 if(fail_allocation_counter < 0) {
40 return malloc(num);
41 }
42 if(fail_allocation_counter-- == 0) {
43 return NULL;
44 }
45 return malloc(num);
46 }
47
48 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
mock_malloc_ex(size_t num,const char * file,int line)49 static void* mock_malloc_ex(size_t num, const char *file, int line) {
50 (void)file;
51 (void)line;
52 return mock_malloc(num);
53 }
54
mock_realloc_ex(void * mem,size_t num,const char * file,int line)55 static void *mock_realloc_ex(void *mem, size_t num, const char *file, int line) {
56 (void)file;
57 (void)line;
58 return realloc(mem, num);
59 }
60
mock_free_ex(void * mem,const char * file,int line)61 static void mock_free_ex(void *mem, const char* file, int line) {
62 (void)file;
63 (void)line;
64 free(mem);
65 }
66 #endif
67
68 /* This needs to be the first test case because CRYPTO_set_mem_functions()
69 will fail once any allocations have happened.
70 */
test_malloc_failure(void)71 static void test_malloc_failure(void) {
72 int ret, i=0;
73 AES_SIV_CTX *ctx;
74
75 #if OPENSSL_VERSION_NUMBER < 0x10100000L
76 ret = CRYPTO_set_mem_functions(mock_malloc, realloc, free);
77 #else
78 ret = CRYPTO_set_mem_functions(mock_malloc_ex, mock_realloc_ex, mock_free_ex);
79 #endif
80 assert(ret == 1);
81
82 printf("Test allocation failure cases:\n" );
83
84 do {
85 fail_allocation_counter = i++;
86 } while((ctx = AES_SIV_CTX_new()) == NULL);
87 assert(i > 1);
88 printf("AES_SIV_CTX_new() succeeds after %d successful allocations.\n", i-1);
89 AES_SIV_CTX_free(ctx);
90 fail_allocation_counter = -1;
91 }
92
test_cleanup_before_free(void)93 static void test_cleanup_before_free(void) {
94 printf("Test cleanup before free: ");
95 AES_SIV_CTX *ctx = AES_SIV_CTX_new();
96 assert(ctx != NULL);
97 AES_SIV_CTX_cleanup(ctx);
98 AES_SIV_CTX_free(ctx);
99 printf("OK\n");
100 }
101
test_vector_1(void)102 static void test_vector_1(void) {
103 const unsigned char key[] = {
104 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
105 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
106 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
107 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
108 };
109
110 const unsigned char ad[] = {
111 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
112 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
113 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
114 };
115
116 const unsigned char plaintext[] = {
117 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
118 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee};
119
120 const unsigned char ciphertext[] = {
121 0x85, 0x63, 0x2d, 0x07, 0xc6, 0xe8, 0xf3, 0x7f,
122 0x95, 0x0a, 0xcd, 0x32, 0x0a, 0x2e, 0xcc, 0x93,
123 0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04,
124 0xda, 0xef, 0x7f, 0x6a, 0xfe, 0x5c
125 };
126
127 unsigned char ciphertext_out[256];
128 unsigned char plaintext_out[256];
129
130 size_t plaintext_len = sizeof plaintext_out;
131 size_t ciphertext_len = sizeof ciphertext_out;
132
133 AES_SIV_CTX *ctx;
134 int ret;
135
136 printf("Test vector 1:\n");
137 debug("key", key, sizeof key);
138 debug("AD", ad, sizeof ad);
139 debug("plaintext", plaintext, sizeof plaintext);
140 debug("exp. ciphertext", ciphertext, sizeof ciphertext);
141
142 ctx = AES_SIV_CTX_new();
143 assert(ctx != NULL);
144
145 printf("Encryption:\n");
146 ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
147 sizeof key, NULL, 0, plaintext, sizeof plaintext,
148 ad, sizeof ad);
149 assert(ret == 1);
150 assert(ciphertext_len == sizeof ciphertext);
151 assert(!memcmp(ciphertext, ciphertext_out, ciphertext_len));
152
153 printf("Decryption:\n");
154 ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
155 sizeof key, NULL, 0, ciphertext_out,
156 ciphertext_len, ad, sizeof ad);
157 assert(ret == 1);
158 assert(plaintext_len == sizeof plaintext);
159 assert(!memcmp(plaintext, plaintext_out, plaintext_len));
160 AES_SIV_CTX_free(ctx);
161 }
162
test_vector_2(void)163 static void test_vector_2(void) {
164 const unsigned char key[] = {
165 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
166 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
167 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
168 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
169 };
170
171 const unsigned char ad1[] = {
172 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
173 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
174 0xde, 0xad, 0xda, 0xda, 0xde, 0xad, 0xda, 0xda,
175 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
176 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00
177 };
178
179 const unsigned char ad2[] = {
180 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
181 0x90, 0xa0
182 };
183
184 const unsigned char nonce[] = {
185 0x09, 0xf9, 0x11, 0x02, 0x9d, 0x74, 0xe3, 0x5b,
186 0xd8, 0x41, 0x56, 0xc5, 0x63, 0x56, 0x88, 0xc0
187 };
188
189 const unsigned char plaintext[] = {
190 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
191 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x6c, 0x61,
192 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74,
193 0x6f, 0x20, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
194 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20,
195 0x53, 0x49, 0x56, 0x2d, 0x41, 0x45, 0x53
196 };
197
198 const unsigned char ciphertext[] = {
199 0x7b, 0xdb, 0x6e, 0x3b, 0x43, 0x26, 0x67, 0xeb,
200 0x06, 0xf4, 0xd1, 0x4b, 0xff, 0x2f, 0xbd, 0x0f,
201 0xcb, 0x90, 0x0f, 0x2f, 0xdd, 0xbe, 0x40, 0x43,
202 0x26, 0x60, 0x19, 0x65, 0xc8, 0x89, 0xbf, 0x17,
203 0xdb, 0xa7, 0x7c, 0xeb, 0x09, 0x4f, 0xa6, 0x63,
204 0xb7, 0xa3, 0xf7, 0x48, 0xba, 0x8a, 0xf8, 0x29,
205 0xea, 0x64, 0xad, 0x54, 0x4a, 0x27, 0x2e, 0x9c,
206 0x48, 0x5b, 0x62, 0xa3, 0xfd, 0x5c, 0x0d
207 };
208
209 unsigned char ciphertext_out[256];
210 unsigned char plaintext_out[256];
211
212 AES_SIV_CTX *ctx;
213 int ret;
214
215 printf("Test vector 2:\n");
216 debug("key", key, sizeof key);
217 debug("AD1", ad1, sizeof ad1);
218 debug("AD2", ad2, sizeof ad2);
219 debug("nonce", nonce, sizeof nonce);
220 debug("plaintext", plaintext, sizeof plaintext);
221 debug("exp. ciphertext", ciphertext, sizeof ciphertext);
222
223 ctx = AES_SIV_CTX_new();
224 assert(ctx != NULL);
225
226 printf("Encryption:\n");
227 ret = AES_SIV_Init(ctx, key, sizeof key);
228 assert(ret == 1);
229 ret = AES_SIV_AssociateData(ctx, ad1, sizeof ad1);
230 assert(ret == 1);
231 ret = AES_SIV_AssociateData(ctx, ad2, sizeof ad2);
232 assert(ret == 1);
233 ret = AES_SIV_AssociateData(ctx, nonce, sizeof nonce);
234 assert(ret == 1);
235 ret = AES_SIV_EncryptFinal(ctx, ciphertext_out, ciphertext_out + 16,
236 plaintext, sizeof plaintext);
237 assert(ret == 1);
238 debug("IV || C", ciphertext_out, sizeof plaintext + 16);
239 assert(!memcmp(ciphertext_out, ciphertext, sizeof ciphertext));
240
241 printf("Decryption:\n");
242 ret = AES_SIV_Init(ctx, key, sizeof key);
243 assert(ret == 1);
244 ret = AES_SIV_AssociateData(ctx, ad1, sizeof ad1);
245 assert(ret == 1);
246 ret = AES_SIV_AssociateData(ctx, ad2, sizeof ad2);
247 assert(ret == 1);
248 ret = AES_SIV_AssociateData(ctx, nonce, sizeof nonce);
249 assert(ret == 1);
250 ret = AES_SIV_DecryptFinal(ctx, plaintext_out, ciphertext_out,
251 ciphertext_out + 16, sizeof plaintext);
252 assert(ret == 1);
253 debug("plaintext", plaintext_out, sizeof plaintext);
254 assert(!memcmp(plaintext_out, plaintext, sizeof plaintext));
255 AES_SIV_CTX_free(ctx);
256 }
257
test_384bit(void)258 static void test_384bit(void) {
259 const unsigned char key[] = {
260 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
261 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
262 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
263 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
264 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
265 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0
266 };
267
268 const unsigned char ad[] = {
269 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
270 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
271 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
272 };
273
274 const unsigned char plaintext[] = {
275 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
276 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
277 };
278
279 const unsigned char ciphertext[] = {
280 0x89, 0xe8, 0x69, 0xb9, 0x32, 0x56, 0x78, 0x51,
281 0x54, 0xf0, 0x96, 0x39, 0x62, 0xfe, 0x07, 0x40,
282 0xef, 0xf3, 0x56, 0xe4, 0x2d, 0xec, 0x1f, 0x4f,
283 0xeb, 0xde, 0xd3, 0x66, 0x42, 0xf2
284 };
285
286 unsigned char ciphertext_out[256];
287 unsigned char plaintext_out[256];
288
289 size_t plaintext_len = sizeof plaintext_out;
290 size_t ciphertext_len = sizeof ciphertext_out;
291
292 AES_SIV_CTX *ctx;
293 int ret;
294
295 printf("384-bit key test:\n");
296 debug("key", key, sizeof key);
297 debug("AD", ad, sizeof ad);
298 debug("plaintext", plaintext, sizeof plaintext);
299 debug("exp. ciphertext", ciphertext, sizeof ciphertext);
300
301 ctx = AES_SIV_CTX_new();
302 assert(ctx != NULL);
303
304 printf("Encryption:\n");
305 ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
306 sizeof key, NULL, 0, plaintext, sizeof plaintext,
307 ad, sizeof ad);
308 assert(ret == 1);
309 assert(ciphertext_len == sizeof ciphertext);
310 assert(!memcmp(ciphertext, ciphertext_out, ciphertext_len));
311
312 printf("Decryption:\n");
313 ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
314 sizeof key, NULL, 0, ciphertext_out,
315 ciphertext_len, ad, sizeof ad);
316 assert(ret == 1);
317 assert(plaintext_len == sizeof plaintext);
318 assert(!memcmp(plaintext, plaintext_out, plaintext_len));
319 AES_SIV_CTX_free(ctx);
320 }
321
test_512bit(void)322 static void test_512bit(void) {
323 const unsigned char key[] = {
324 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
325 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
326 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
327 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
328 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
329 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
330 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
331 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0
332 };
333
334 const unsigned char ad[] = {
335 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
336 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
337 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
338 };
339
340 const unsigned char plaintext[] = {
341 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
342 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
343 };
344
345 const unsigned char ciphertext[] = {
346 0x72, 0x4d, 0xfb, 0x2e, 0xaf, 0x94, 0xdb, 0xb1,
347 0x9b, 0x0b, 0xa3, 0xa2, 0x99, 0xa0, 0x80, 0x1e,
348 0xf3, 0xb0, 0x5a, 0x55, 0x49, 0x8e, 0xc2, 0x55,
349 0x26, 0x90, 0xb8, 0x98, 0x10, 0xe4
350 };
351
352 unsigned char ciphertext_out[256];
353 unsigned char plaintext_out[256];
354
355 size_t plaintext_len = sizeof plaintext_out;
356 size_t ciphertext_len = sizeof ciphertext_out;
357
358 AES_SIV_CTX *ctx;
359 int ret;
360
361 printf("512-bit key test:\n");
362 debug("key", key, sizeof key);
363 debug("AD", ad, sizeof ad);
364 debug("plaintext", plaintext, sizeof plaintext);
365 debug("exp. ciphertext", ciphertext, sizeof ciphertext);
366
367 ctx = AES_SIV_CTX_new();
368 assert(ctx != NULL);
369
370 printf("Encryption:\n");
371 ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
372 sizeof key, NULL, 0, plaintext, sizeof plaintext,
373 ad, sizeof ad);
374 assert(ret == 1);
375 assert(ciphertext_len == sizeof ciphertext);
376 assert(!memcmp(ciphertext, ciphertext_out, ciphertext_len));
377
378 printf("Decryption:\n");
379 ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
380 sizeof key, NULL, 0, ciphertext_out,
381 ciphertext_len, ad, sizeof ad);
382 assert(ret == 1);
383 assert(plaintext_len == sizeof plaintext);
384 assert(!memcmp(plaintext, plaintext_out, plaintext_len));
385 AES_SIV_CTX_free(ctx);
386 }
387
test_highlevel_with_nonce(void)388 static void test_highlevel_with_nonce(void) {
389 const unsigned char key[] = {
390 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
391 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
392 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
393 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
394 };
395
396 const unsigned char ad[] = {
397 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
398 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
399 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
400 };
401
402 const unsigned char nonce[] = {
403 0x09, 0xf9, 0x11, 0x02, 0x9d, 0x74, 0xe3, 0x5b,
404 0xd8, 0x41, 0x56, 0xc5, 0x63, 0x56, 0x88, 0xc0
405 };
406
407 const unsigned char plaintext[] = {
408 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
409 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
410 };
411
412 unsigned char ciphertext_out[256];
413 unsigned char plaintext_out[256];
414
415 size_t plaintext_len = sizeof plaintext_out;
416 size_t ciphertext_len = sizeof ciphertext_out;
417
418 AES_SIV_CTX *ctx;
419 int ret;
420
421 printf("Test high-level interface with non-NULL nonce:\n");
422 debug("key", key, sizeof key);
423 debug("AD", ad, sizeof ad);
424 debug("nonce", nonce, sizeof nonce);
425 debug("plaintext", plaintext, sizeof plaintext);
426
427 ctx = AES_SIV_CTX_new();
428 assert(ctx != NULL);
429
430 printf("Encryption:\n");
431 ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
432 sizeof key, nonce, sizeof nonce, plaintext,
433 sizeof plaintext, ad, sizeof ad);
434 assert(ret == 1);
435
436 printf("Decryption:\n");
437 ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
438 sizeof key, nonce, sizeof nonce, ciphertext_out,
439 ciphertext_len, ad, sizeof ad);
440 assert(ret == 1);
441 assert(plaintext_len == sizeof plaintext);
442 assert(!memcmp(plaintext, plaintext_out, plaintext_len));
443 AES_SIV_CTX_free(ctx);
444 }
445
test_copy(void)446 static void test_copy(void) {
447 const unsigned char key[] = {
448 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
449 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
450 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
451 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
452 };
453
454 const unsigned char ad[] = {
455 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
456 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
457 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
458 };
459
460 const unsigned char plaintext1[] = {
461 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
462 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
463 };
464
465 const unsigned char plaintext2[] = {
466 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
467 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xef
468 };
469
470 const unsigned char ciphertext[] = {
471 0x85, 0x63, 0x2d, 0x07, 0xc6, 0xe8, 0xf3, 0x7f,
472 0x95, 0x0a, 0xcd, 0x32, 0x0a, 0x2e, 0xcc, 0x93,
473 0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04,
474 0xda, 0xef, 0x7f, 0x6a, 0xfe, 0x5c
475 };
476
477 unsigned char ciphertext1_out[256], ciphertext2_out[256];
478
479 AES_SIV_CTX *ctx1, *ctx2, *ctx3;
480 int ret;
481
482 ctx1 = AES_SIV_CTX_new();
483 assert(ctx1 != NULL);
484 ctx2 = AES_SIV_CTX_new();
485 assert(ctx2 != NULL);
486 ctx3 = AES_SIV_CTX_new();
487 assert(ctx3 != NULL);
488
489 ret = AES_SIV_Init(ctx1, key, sizeof key);
490 assert(ret == 1);
491 ret = AES_SIV_CTX_copy(ctx2, ctx1);
492 assert(ret == 1);
493
494 ret = AES_SIV_AssociateData(ctx1, ad, sizeof ad);
495 assert(ret == 1);
496 ret = AES_SIV_AssociateData(ctx2, ad, sizeof ad);
497 assert(ret == 1);
498
499 ret = AES_SIV_CTX_copy(ctx3, ctx1);
500 assert(ret == 1);
501
502 ret = AES_SIV_EncryptFinal(ctx1, ciphertext1_out, ciphertext1_out + 16,
503 plaintext1, sizeof plaintext1);
504 assert(ret == 1);
505 assert(!memcmp(ciphertext, ciphertext1_out, sizeof ciphertext));
506
507 ret = AES_SIV_EncryptFinal(ctx2, ciphertext2_out, ciphertext2_out + 16,
508 plaintext1, sizeof plaintext1);
509 assert(ret == 1);
510 assert(!memcmp(ciphertext, ciphertext2_out, sizeof ciphertext));
511
512 ret = AES_SIV_EncryptFinal(ctx3, ciphertext2_out, ciphertext2_out + 16,
513 plaintext2, sizeof plaintext2);
514 assert(ret == 1);
515 assert(memcmp(ciphertext, ciphertext2_out, sizeof ciphertext));
516
517 AES_SIV_CTX_free(ctx1);
518 AES_SIV_CTX_free(ctx2);
519 AES_SIV_CTX_free(ctx3);
520 }
521
test_bad_key(void)522 static void test_bad_key(void) {
523 static const unsigned char key[40];
524 static const unsigned char ad[16];
525 static const unsigned char plaintext[16];
526
527 unsigned char ciphertext_out[256];
528 size_t ciphertext_len = sizeof ciphertext_out;
529
530 AES_SIV_CTX *ctx;
531 int ret;
532
533 printf("Test bad key size: ");
534
535 ctx = AES_SIV_CTX_new();
536 assert(ctx != NULL);
537
538 ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
539 sizeof key, NULL, 0, plaintext, sizeof plaintext,
540 ad, sizeof ad);
541 assert(ret == 0);
542
543 ret = AES_SIV_Init(ctx, key, sizeof key);
544 assert(ret == 0);
545
546 AES_SIV_CTX_free(ctx);
547 printf("OK\n");
548 }
549
test_decrypt_failure(void)550 static void test_decrypt_failure(void) {
551 static const unsigned char key[32];
552 static const unsigned char ad[16];
553 static const unsigned char ciphertext[32];
554
555 unsigned char plaintext_out[256];
556 size_t plaintext_len = sizeof plaintext_out;
557
558 AES_SIV_CTX *ctx;
559 int ret;
560
561 printf("Test decryption failure:\n");
562
563 ctx = AES_SIV_CTX_new();
564 assert(ctx != NULL);
565
566 ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
567 sizeof key, NULL, 0, ciphertext,
568 sizeof ciphertext, ad, sizeof ad);
569 assert(ret == 0);
570
571 AES_SIV_CTX_free(ctx);
572 }
573
main(void)574 int main(void) {
575 test_malloc_failure();
576 test_cleanup_before_free();
577 test_vector_1();
578 test_vector_2();
579 test_384bit();
580 test_512bit();
581 test_highlevel_with_nonce();
582 test_copy();
583 test_bad_key();
584 test_decrypt_failure();
585 return 0;
586 }
587