1 /*
2  **********************************************************************
3  * Copyright (C) Miroslav Lichvar  2019
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  **********************************************************************
19  */
20 
21 #include <config.h>
22 #include <sysincl.h>
23 #include <logging.h>
24 #include <siv.h>
25 #include "test.h"
26 
27 #ifdef HAVE_SIV
28 
29 struct siv_test {
30   SIV_Algorithm algorithm;
31   const unsigned char key[64];
32   int key_length;
33   const unsigned char nonce[128];
34   int nonce_length;
35   const unsigned char assoc[128];
36   int assoc_length;
37   const unsigned char plaintext[128];
38   int plaintext_length;
39   const unsigned char ciphertext[128];
40   int ciphertext_length;
41 };
42 
43 void
test_unit(void)44 test_unit(void)
45 {
46   struct siv_test tests[] = {
47     { AEAD_AES_SIV_CMAC_256,
48       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
49       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
50       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 16,
51       "", 0,
52       "", 0,
53       "\x22\x3e\xb5\x94\xe0\xe0\x25\x4b\x00\x25\x8e\x21\x9a\x1c\xa4\x21", 16
54     },
55     { AEAD_AES_SIV_CMAC_256,
56       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
57       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
58       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 16,
59       "\x4c\x9d\x4f\xca\xed\x8a\xe2\xba\xad\x3f\x3e\xa6\xe9\x3c\x8c\x8b", 16,
60       "", 0,
61       "\xd7\x20\x19\x89\xc6\xdb\xc6\xd6\x61\xfc\x62\xbc\x86\x5e\xee\xef", 16
62     },
63     { AEAD_AES_SIV_CMAC_256,
64       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
65       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
66       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 16,
67       "", 0,
68       "\x4c\x9d\x4f\xca\xed\x8a\xe2\xba\xad\x3f\x3e\xa6\xe9\x3c\x8c\x8b", 16,
69       "\xb6\xc1\x60\xe9\xc2\xfd\x2a\xe8\xde\xc5\x36\x8b\x2a\x33\xed\xe1"
70       "\x14\xff\xb3\x97\x34\x5c\xcb\xe4\x4a\xa4\xde\xac\xd9\x36\x90\x46", 32
71     },
72     { AEAD_AES_SIV_CMAC_256,
73       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
74       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
75       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e", 15,
76       "\x4c\x9d\x4f\xca\xed\x8a\xe2\xba\xad\x3f\x3e\xa6\xe9\x3c\x8c", 15,
77       "\xba\x99\x79\x31\x23\x7e\x3c\x53\x58\x7e\xd4\x93\x02\xab\xe4", 15,
78       "\x03\x8c\x41\x51\xba\x7a\x8f\x77\x6e\x56\x31\x99\x42\x0b\xc7\x03"
79       "\xe7\x6c\x67\xc9\xda\xb7\x0d\x5b\x44\x06\x26\x5a\xd0\xd2\x3b", 31
80     },
81     { AEAD_AES_SIV_CMAC_256,
82       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
83       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
84       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 16,
85       "\x4c\x9d\x4f\xca\xed\x8a\xe2\xba\xad\x3f\x3e\xa6\xe9\x3c\x8c\x8b", 16,
86       "\xba\x99\x79\x31\x23\x7e\x3c\x53\x58\x7e\xd4\x93\x02\xab\xe4\xa7", 16,
87       "\x5c\x05\x23\x65\xf4\x57\x0a\xa0\xfb\x38\x3e\xce\x9b\x75\x85\xeb"
88       "\x68\x85\x19\x36\x0c\x7c\x48\x11\x40\xcb\x9b\x57\x9a\x0e\x65\x32", 32
89     },
90     { AEAD_AES_SIV_CMAC_256,
91       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
92       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
93       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
94       "\xd5", 17,
95       "\x4c\x9d\x4f\xca\xed\x8a\xe2\xba\xad\x3f\x3e\xa6\xe9\x3c\x8c\x8b"
96       "\xa0", 17,
97       "\xba\x99\x79\x31\x23\x7e\x3c\x53\x58\x7e\xd4\x93\x02\xab\xe4\xa7"
98       "\x08", 17,
99       "\xaf\x58\x4b\xe7\x82\x1e\x96\x19\x29\x91\x25\xe0\xdd\x80\x3b\x49"
100       "\xa5\x11\xcd\xb6\x08\xf3\x76\xa0\xb6\xfa\x15\x82\xf3\x95\xe1\xeb"
101       "\xbd", 33
102     },
103     { AEAD_AES_SIV_CMAC_256,
104       "\x01\x23\x45\x67\x89\xab\xcd\xef\xf0\x12\x34\x56\x78\x9a\xbc\xde"
105       "\xef\x01\x23\x45\x67\x89\xab\xcd\xde\xf0\x12\x34\x56\x78\x9a\xbc", 32,
106       "\xb0\x5a\x1b\xc7\x56\xe7\xb6\x2c\xb4\x85\xe5\x56\xa5\x28\xc0\x6c"
107       "\x2f\x3b\x0b\x9d\x1a\x0c\xdf\x69\x47\xe0\xcc\xc0\x87\xaa\x5c\x09"
108       "\x98\x48\x8d\x6a\x8e\x1e\x05\xd7\x8b\x68\x74\x83\xb5\x1d\xf1\x2c", 48,
109       "\xe5\x8b\xd2\x6a\x30\xc5\xc5\x61\xcc\xbd\x7c\x27\xbf\xfe\xf9\x06"
110       "\x00\x5b\xd7\xfc\x11\x0b\xcf\x16\x61\xef\xac\x05\xa7\xaf\xec\x27"
111       "\x41\xc8\x5e\x9e\x0d\xf9\x2f\xaf\x20\x79\x17\xe5\x17\x91\x2a\x27"
112       "\x34\x1c\xbc\xaf\xeb\xef\x7f\x52\xe7\x1e\x4c\x2a\xca\xbd\x2b\xbe"
113       "\x34\xd6\xfb\x69\xd3\x3e\x49\x59\x60\xb4\x26\xc9\xb8\xce\xba", 79,
114       "\x6c\xe7\xcf\x7e\xab\x7b\xa0\xe1\xa7\x22\xcb\x88\xde\x5e\x42\xd2"
115       "\xec\x79\xe0\xa2\xcf\x5f\x0f\x6f\x6b\x89\x57\xcd\xae\x17\xd4\xc2"
116       "\xf3\x1b\xa2\xa8\x13\x78\x23\x2f\x83\xa8\xd4\x0c\xc0\xd2\xf3\x99"
117       "\xae\x81\xa1\xca\x5b\x5f\x45\xa6\x6f\x0c\x8a\xf3\xd4\x67\x40\x81"
118       "\x26\xe2\x01\x86\xe8\x5a\xd5\xf8\x58\x80\x9f\x56\xaa\x76\x96\xbf"
119       "\x31", 81,
120       "\x9a\x06\x33\xe0\xee\x00\x6a\x9b\xc8\x20\xd5\xe2\xc2\xed\xb5\x75"
121       "\xfa\x9e\x42\x2a\x31\x6b\xda\xca\xaa\x7d\x31\x8b\x84\x7a\xb8\xd7"
122       "\x8a\x81\x25\x64\xed\x41\x9b\xa9\x77\x10\xbd\x05\x0c\x4e\xc5\x31"
123       "\x0c\xa2\x86\xec\x8a\x94\xc8\x24\x23\x3c\x13\xee\xa5\x51\xc9\xdf"
124       "\x48\xc9\x55\xc5\x2f\x40\x73\x3f\x98\xbb\x8d\x69\x78\x46\x64\x17"
125       "\x8d\x49\x2f\x14\x62\xa4\x7c\x2a\x57\x38\x87\xce\xc6\x72\xd3\x5c"
126       "\xa1", 97
127     },
128     { 0, "", 0 }
129   };
130 
131   unsigned char plaintext[sizeof (((struct siv_test *)NULL)->plaintext)];
132   unsigned char ciphertext[sizeof (((struct siv_test *)NULL)->ciphertext)];
133   SIV_Instance siv;
134   int i, j, r;
135 
136   TEST_CHECK(SIV_CreateInstance(0) == NULL);
137 
138   for (i = 0; tests[i].algorithm != 0; i++) {
139     DEBUG_LOG("testing %d (%d)", (int)tests[i].algorithm, i);
140 
141     assert(tests[i].key_length <= sizeof (tests[i].key));
142     assert(tests[i].nonce_length <= sizeof (tests[i].nonce));
143     assert(tests[i].assoc_length <= sizeof (tests[i].assoc));
144     assert(tests[i].plaintext_length <= sizeof (tests[i].plaintext));
145     assert(tests[i].ciphertext_length <= sizeof (tests[i].ciphertext));
146 
147     siv = SIV_CreateInstance(tests[i].algorithm);
148     TEST_CHECK(siv != NULL);
149 
150     TEST_CHECK(SIV_GetKeyLength(tests[i].algorithm) == tests[i].key_length);
151 
152     r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
153                     tests[i].assoc, tests[i].assoc_length,
154                     tests[i].plaintext, tests[i].plaintext_length,
155                     ciphertext, tests[i].ciphertext_length);
156     TEST_CHECK(!r);
157     r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
158                     tests[i].assoc, tests[i].assoc_length,
159                     tests[i].ciphertext, tests[i].ciphertext_length,
160                     plaintext, tests[i].plaintext_length);
161     TEST_CHECK(!r);
162 
163     for (j = -1; j < 1024; j++) {
164       r = SIV_SetKey(siv, tests[i].key, j);
165       TEST_CHECK(r == (j == tests[i].key_length));
166     }
167 
168     TEST_CHECK(SIV_GetTagLength(siv) == tests[i].ciphertext_length - tests[i].plaintext_length);
169 
170     r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
171                     tests[i].assoc, tests[i].assoc_length,
172                     tests[i].plaintext, tests[i].plaintext_length,
173                     ciphertext, tests[i].ciphertext_length);
174     TEST_CHECK(r);
175 
176 #if 0
177     for (j = 0; j < tests[i].ciphertext_length; j++) {
178       printf("\\x%02x", ciphertext[j]);
179       if (j % 16 == 15)
180         printf("\n");
181     }
182     printf("\n");
183 #endif
184     TEST_CHECK(memcmp(ciphertext, tests[i].ciphertext, tests[i].ciphertext_length) == 0);
185 
186     for (j = -1; j < tests[i].nonce_length; j++) {
187       r = SIV_Encrypt(siv, tests[i].nonce, j,
188                       tests[i].assoc, tests[i].assoc_length,
189                       tests[i].plaintext, tests[i].plaintext_length,
190                       ciphertext, tests[i].ciphertext_length);
191       if (j > 0) {
192         TEST_CHECK(r);
193         TEST_CHECK(memcmp(ciphertext, tests[i].ciphertext, tests[i].ciphertext_length) != 0);
194       } else {
195         TEST_CHECK(!r);
196       }
197     }
198 
199     for (j = -1; j < tests[i].assoc_length; j++) {
200       r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
201                       tests[i].assoc, j,
202                       tests[i].plaintext, tests[i].plaintext_length,
203                       ciphertext, tests[i].ciphertext_length);
204       if (j >= 0) {
205         TEST_CHECK(r);
206         TEST_CHECK(memcmp(ciphertext, tests[i].ciphertext, tests[i].ciphertext_length) != 0);
207       } else {
208         TEST_CHECK(!r);
209       }
210     }
211 
212     for (j = -1; j < tests[i].plaintext_length; j++) {
213       r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
214                       tests[i].assoc, tests[i].assoc_length,
215                       tests[i].plaintext, j,
216                       ciphertext, j + SIV_GetTagLength(siv));
217       if (j >= 0) {
218         TEST_CHECK(r);
219         TEST_CHECK(memcmp(ciphertext, tests[i].ciphertext, j + SIV_GetTagLength(siv)) != 0);
220       } else {
221         TEST_CHECK(!r);
222       }
223     }
224 
225     for (j = -1; j < 2 * tests[i].plaintext_length; j++) {
226       if (j == tests[i].plaintext_length)
227         continue;
228       r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
229                       tests[i].assoc, tests[i].assoc_length,
230                       tests[i].plaintext, j,
231                       ciphertext, tests[i].ciphertext_length);
232       TEST_CHECK(!r);
233     }
234 
235     for (j = -1; j < 2 * tests[i].ciphertext_length; j++) {
236       if (j == tests[i].ciphertext_length)
237         continue;
238       r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
239                       tests[i].assoc, tests[i].assoc_length,
240                       tests[i].plaintext, tests[i].plaintext_length,
241                       ciphertext, j);
242       TEST_CHECK(!r);
243     }
244 
245     r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
246                     tests[i].assoc, tests[i].assoc_length,
247                     tests[i].ciphertext, tests[i].ciphertext_length,
248                     plaintext, tests[i].plaintext_length);
249     TEST_CHECK(r);
250     TEST_CHECK(memcmp(plaintext, tests[i].plaintext, tests[i].plaintext_length) == 0);
251 
252     for (j = -1; j < tests[i].nonce_length; j++) {
253       r = SIV_Decrypt(siv, tests[i].nonce, j,
254                       tests[i].assoc, tests[i].assoc_length,
255                       tests[i].ciphertext, tests[i].ciphertext_length,
256                       plaintext, tests[i].plaintext_length);
257       TEST_CHECK(!r);
258     }
259 
260     for (j = -1; j < tests[i].assoc_length; j++) {
261       r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
262                       tests[i].assoc, j,
263                       tests[i].ciphertext, tests[i].ciphertext_length,
264                       plaintext, tests[i].plaintext_length);
265       TEST_CHECK(!r);
266     }
267 
268     for (j = -1; j < 2 * tests[i].ciphertext_length; j++) {
269       if (j == tests[i].ciphertext_length)
270         continue;
271 
272       r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
273                       tests[i].assoc, tests[i].assoc_length,
274                       tests[i].ciphertext, j,
275                       plaintext, tests[i].plaintext_length);
276       TEST_CHECK(!r);
277     }
278 
279     for (j = -1; j < tests[i].plaintext_length; j++) {
280       r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
281                       tests[i].assoc, tests[i].assoc_length,
282                       tests[i].ciphertext, tests[i].ciphertext_length,
283                       plaintext, j);
284       TEST_CHECK(!r);
285 
286       r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
287                       tests[i].assoc, tests[i].assoc_length,
288                       tests[i].ciphertext, j + SIV_GetTagLength(siv),
289                       plaintext, j);
290       TEST_CHECK(!r);
291     }
292 
293     SIV_DestroyInstance(siv);
294   }
295 
296   siv = SIV_CreateInstance(tests[0].algorithm);
297   for (i = 0; i < 1000; i++) {
298     for (j = 0; tests[j].algorithm == tests[0].algorithm; j++) {
299       r = SIV_SetKey(siv, tests[j].key, tests[j].key_length);
300       TEST_CHECK(r);
301       r = SIV_Encrypt(siv, tests[j].nonce, tests[j].nonce_length,
302                       tests[j].assoc, tests[j].assoc_length,
303                       tests[j].plaintext, tests[j].plaintext_length,
304                       ciphertext, tests[j].ciphertext_length);
305       TEST_CHECK(r);
306       r = SIV_Decrypt(siv, tests[j].nonce, tests[j].nonce_length,
307                       tests[j].assoc, tests[j].assoc_length,
308                       tests[j].ciphertext, tests[j].ciphertext_length,
309                       plaintext, tests[j].plaintext_length);
310       TEST_CHECK(r);
311     }
312   }
313   SIV_DestroyInstance(siv);
314 }
315 #else
316 void
test_unit(void)317 test_unit(void)
318 {
319   TEST_REQUIRE(0);
320 }
321 #endif
322