1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /**
5    @file gcm_test.c
6    GCM implementation, testing, by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9 
10 #ifdef LTC_GCM_MODE
11 
12 /**
13   Test the GCM code
14   @return CRYPT_OK on success
15  */
gcm_test(void)16 int gcm_test(void)
17 {
18 #ifndef LTC_TEST
19    return CRYPT_NOP;
20 #else
21    static const struct {
22        unsigned char K[32];
23        int           keylen;
24        unsigned char P[128];
25        unsigned long ptlen;
26        unsigned char A[128];
27        unsigned long alen;
28        unsigned char IV[128];
29        unsigned long IVlen;
30        unsigned char C[128];
31        unsigned char T[16];
32    } tests[] = {
33 
34 /* test case #1 */
35 {
36   /* key */
37   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
39   16,
40 
41   /* plaintext */
42   { 0 },
43   0,
44 
45   /* AAD data */
46   { 0 },
47   0,
48 
49   /* IV */
50   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51     0x00, 0x00, 0x00, 0x00 },
52   12,
53 
54   /* ciphertext  */
55   { 0 },
56 
57   /* tag */
58   { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
59     0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }
60 },
61 
62 /* test case #2 */
63 {
64   /* key */
65   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
67   16,
68 
69   /* PT */
70   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
72   16,
73 
74   /* ADATA */
75   { 0 },
76   0,
77 
78   /* IV */
79   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80     0x00, 0x00, 0x00, 0x00 },
81   12,
82 
83   /* CT */
84   { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
85     0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
86 
87   /* TAG */
88   { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
89     0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }
90 },
91 
92 /* test case #3 */
93 {
94    /* key */
95    { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
96      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
97    16,
98 
99    /* PT */
100    { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
101      0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
102      0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
103      0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
104      0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
105      0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
106      0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
107      0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, },
108   64,
109 
110   /* ADATA */
111   { 0 },
112   0,
113 
114   /* IV */
115   { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
116     0xde, 0xca, 0xf8, 0x88,  },
117   12,
118 
119   /* CT */
120   { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
121     0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
122     0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
123     0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
124     0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
125     0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
126     0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
127     0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, },
128 
129   /* TAG */
130   { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
131     0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, }
132 },
133 
134 /* test case #4 */
135 {
136    /* key */
137    { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
138      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
139    16,
140 
141    /* PT */
142    { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
143      0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
144      0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
145      0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
146      0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
147      0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
148      0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
149      0xba, 0x63, 0x7b, 0x39,  },
150    60,
151 
152    /* ADATA */
153    { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
154      0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
155      0xab, 0xad, 0xda, 0xd2,  },
156    20,
157 
158    /* IV */
159    { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
160      0xde, 0xca, 0xf8, 0x88,  },
161    12,
162 
163    /* CT */
164    { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
165      0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
166      0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
167      0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
168      0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
169      0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
170      0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
171      0x3d, 0x58, 0xe0, 0x91,  },
172 
173    /* TAG */
174    { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
175      0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, }
176 
177 },
178 
179 /* test case #5 */
180 {
181    /* key */
182    { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
183      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
184    16,
185 
186    /* PT */
187    { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
188      0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
189      0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
190      0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
191      0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
192      0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
193      0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
194      0xba, 0x63, 0x7b, 0x39,  },
195    60,
196 
197    /* ADATA */
198    { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
199      0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
200      0xab, 0xad, 0xda, 0xd2,  },
201    20,
202 
203    /* IV */
204    { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, },
205    8,
206 
207    /* CT */
208    { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
209      0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
210      0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
211      0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
212      0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
213      0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
214      0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
215      0xc2, 0x3f, 0x45, 0x98,  },
216 
217    /* TAG */
218    { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
219      0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, }
220 },
221 
222 /* test case #6 */
223 {
224    /* key */
225    { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
226      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
227    16,
228 
229    /* PT */
230    { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
231      0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
232      0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
233      0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
234      0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
235      0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
236      0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
237      0xba, 0x63, 0x7b, 0x39,  },
238    60,
239 
240    /* ADATA */
241    { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
242      0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
243      0xab, 0xad, 0xda, 0xd2,  },
244    20,
245 
246    /* IV */
247    { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
248      0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
249      0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
250      0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
251      0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
252      0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
253      0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
254      0xa6, 0x37, 0xb3, 0x9b,  },
255    60,
256 
257    /* CT */
258    { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
259      0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
260      0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
261      0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
262      0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
263      0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
264      0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
265      0x4c, 0x34, 0xae, 0xe5,  },
266 
267    /* TAG */
268    { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
269      0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, }
270 },
271 
272 /* test case #46 from BG (catches the LTC bug of v1.15) */
273 {
274    /* key */
275    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
277    16,
278 
279    /* PT */
280    { 0xa2, 0xaa, 0xb3, 0xad, 0x8b, 0x17, 0xac, 0xdd,
281      0xa2, 0x88, 0x42, 0x6c, 0xd7, 0xc4, 0x29, 0xb7,
282      0xca, 0x86, 0xb7, 0xac, 0xa0, 0x58, 0x09, 0xc7,
283      0x0c, 0xe8, 0x2d, 0xb2, 0x57, 0x11, 0xcb, 0x53,
284      0x02, 0xeb, 0x27, 0x43, 0xb0, 0x36, 0xf3, 0xd7,
285      0x50, 0xd6, 0xcf, 0x0d, 0xc0, 0xac, 0xb9, 0x29,
286      0x50, 0xd5, 0x46, 0xdb, 0x30, 0x8f, 0x93, 0xb4,
287      0xff, 0x24, 0x4a, 0xfa, 0x9d, 0xc7, 0x2b, 0xcd,
288      0x75, 0x8d, 0x2c },
289    67,
290 
291    /* ADATA */
292    { 0x68, 0x8e, 0x1a, 0xa9, 0x84, 0xde, 0x92, 0x6d,
293      0xc7, 0xb4, 0xc4, 0x7f, 0x44 },
294    13,
295 
296    /* IV */
297    { 0xb7, 0x21, 0x38, 0xb5, 0xa0, 0x5f, 0xf5, 0x07,
298      0x0e, 0x8c, 0xd9, 0x41, 0x83, 0xf7, 0x61, 0xd8 },
299    16,
300 
301    /* CT */
302    { 0xcb, 0xc8, 0xd2, 0xf1, 0x54, 0x81, 0xa4, 0xcc,
303      0x7d, 0xd1, 0xe1, 0x9a, 0xaa, 0x83, 0xde, 0x56,
304      0x78, 0x48, 0x3e, 0xc3, 0x59, 0xae, 0x7d, 0xec,
305      0x2a, 0xb8, 0xd5, 0x34, 0xe0, 0x90, 0x6f, 0x4b,
306      0x46, 0x63, 0xfa, 0xff, 0x58, 0xa8, 0xb2, 0xd7,
307      0x33, 0xb8, 0x45, 0xee, 0xf7, 0xc9, 0xb3, 0x31,
308      0xe9, 0xe1, 0x0e, 0xb2, 0x61, 0x2c, 0x99, 0x5f,
309      0xeb, 0x1a, 0xc1, 0x5a, 0x62, 0x86, 0xcc, 0xe8,
310      0xb2, 0x97, 0xa8 },
311 
312    /* TAG */
313    { 0x8d, 0x2d, 0x2a, 0x93, 0x72, 0x62, 0x6f, 0x6b,
314      0xee, 0x85, 0x80, 0x27, 0x6a, 0x63, 0x66, 0xbf }
315 }
316 
317 /* rest of test cases are the same except AES key size changes... ignored... */
318 };
319    int           idx, err;
320    unsigned long x, y;
321    unsigned char out[2][128], T[2][16];
322    gcm_state gcm;
323 
324    /* find aes */
325    idx = find_cipher("aes");
326    if (idx == -1) {
327       idx = find_cipher("rijndael");
328       if (idx == -1) {
329          return CRYPT_NOP;
330       }
331    }
332 
333    /* Special test case for empty AAD + empty PT */
334    y = sizeof(T[0]);
335    if ((err = gcm_init(&gcm, idx, tests[0].K, tests[0].keylen)) != CRYPT_OK) return err;
336    if ((err = gcm_add_iv(&gcm, tests[0].IV, tests[0].IVlen)) != CRYPT_OK)    return err;
337    /* intentionally skip gcm_add_aad + gcm_process */
338    if ((err = gcm_done(&gcm, T[0], &y)) != CRYPT_OK)                         return err;
339    if (compare_testvector(T[0], y, tests[0].T, 16, "GCM Encrypt Tag-special", 0))      return CRYPT_FAIL_TESTVECTOR;
340 
341    for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
342        y = sizeof(T[0]);
343        if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen,
344                              tests[x].IV, tests[x].IVlen,
345                              tests[x].A, tests[x].alen,
346                              (unsigned char*)tests[x].P, tests[x].ptlen,
347                              out[0], T[0], &y, GCM_ENCRYPT)) != CRYPT_OK) {
348           return err;
349        }
350 
351        if (compare_testvector(out[0], tests[x].ptlen, tests[x].C, tests[x].ptlen, "GCM CT", x)) {
352           return CRYPT_FAIL_TESTVECTOR;
353        }
354 
355        if (compare_testvector(T[0], y, tests[x].T, 16, "GCM Encrypt Tag", x)) {
356           return CRYPT_FAIL_TESTVECTOR;
357        }
358 
359        y = sizeof(T[1]);
360        XMEMCPY(T[1], tests[x].T, 16);
361        if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen,
362                              tests[x].IV, tests[x].IVlen,
363                              tests[x].A, tests[x].alen,
364                              out[1], tests[x].ptlen,
365                              out[0], T[1], &y, GCM_DECRYPT)) != CRYPT_OK) {
366           return err;
367        }
368 
369        if (compare_testvector(out[1], tests[x].ptlen, tests[x].P, tests[x].ptlen, "GCM PT", x)) {
370           return CRYPT_FAIL_TESTVECTOR;
371        }
372    }
373 
374    /* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/451 */
375    {
376       unsigned char key[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
377       unsigned char iv[]  = { 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b };
378       unsigned char valid_tag[]   = { 0xd8,0x84,0x7d,0xbc,0x32,0x6a,0x06,0xe9,0x88,0xc7,0x7a,0xd3,0x86,0x3e,0x60,0x83 };
379       unsigned char invalid_tag[] = { 0xd9,0x84,0x7d,0xbc,0x32,0x6a,0x06,0xe9,0x88,0xc7,0x7a,0xd3,0x86,0x3e,0x60,0x83 };
380       unsigned char msg[] = { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f };
381       unsigned char ct[]  = { 0xeb,0x15,0x6d,0x08,0x1e,0xd6,0xb6,0xb5,0x5f,0x46,0x12,0xf0,0x21,0xd8,0x7b,0x39 };
382       unsigned char pt[20] = { 0 };
383       unsigned long taglen;
384 
385       /* VALID tag */
386       taglen = sizeof(valid_tag);
387       err = gcm_memory(idx, key, sizeof(key), iv, sizeof(iv), NULL, 0,
388                        pt, sizeof(ct), ct, valid_tag, &taglen, GCM_DECRYPT);
389       if ((err != CRYPT_OK) || (XMEMCMP(msg, pt, sizeof(msg)) != 0)) {
390          return CRYPT_FAIL_TESTVECTOR;
391       }
392 
393       /* INVALID tag */
394       taglen = sizeof(invalid_tag);
395       err = gcm_memory(idx, key, sizeof(key), iv, sizeof(iv), NULL, 0,
396                        pt, sizeof(ct), ct, invalid_tag, &taglen, GCM_DECRYPT);
397       if (err == CRYPT_OK) {
398          return CRYPT_FAIL_TESTVECTOR; /* should fail */
399       }
400    }
401 
402    return CRYPT_OK;
403 #endif
404 }
405 
406 #endif
407 
408