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