fixing some decryption bugs in GCM128
[avr-crypto-lib.git] / test_src / main-gcm-test.c
1 /* main-gcm-test.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2014 Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 /*
22  * GCM test-suit
23  *
24 */
25
26
27 #include "main-test-common.h"
28
29 #include <gcm128.h>
30 #include <bcal_aes128.h>
31 #include <bcal_aes192.h>
32 #include <bcal_aes256.h>
33 #include "performance_test.h"
34
35 char *algo_name = "GCM-AES128";
36
37 /*****************************************************************************
38  *  additional validation-functions                                          *
39  *****************************************************************************/
40
41 #define DUMP_LEN(x, len) do { printf("%s", "\n\n" #x ":"); \
42                     cli_hexdump_block((x), (len), 4, 16); } while (0)
43
44 #define DUMP(x) DUMP_LEN(x, sizeof(x))
45
46 #define elementsof(t) (sizeof(t) / sizeof(t[0]))
47
48 /*****************************************************************************
49  *                                                                           *
50  *****************************************************************************/
51
52 const uint8_t zero_block[] PROGMEM = {
53         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
57 };
58
59 const uint8_t key_b[] PROGMEM = {
60         0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
61         0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
62         0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
63         0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
64 };
65
66
67 const uint8_t ad_block[] PROGMEM = {
68         0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
69         0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
70         0xab, 0xad, 0xda, 0xd2
71 };
72
73 const uint8_t pt_block[] PROGMEM = {
74         0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
75         0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
76         0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
77         0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
78         0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
79         0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
80         0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
81         0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
82 };
83
84 /*****************************************************************************/
85
86 const uint8_t iv_block[] PROGMEM = {
87         0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
88         0xde, 0xca, 0xf8, 0x88
89 };
90
91 /*****************************************************************************/
92
93 const uint8_t iv_6[] PROGMEM = {
94         0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
95         0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
96         0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
97         0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
98         0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
99         0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
100         0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
101         0xa6, 0x37, 0xb3, 0x9b
102 };
103
104 typedef struct {
105     const void *key;
106     uint16_t key_length_b;
107     const void *iv;
108     uint16_t iv_length_b;
109     const void *ad;
110     uint16_t ad_length_b;
111     const void *pt;
112     uint16_t pt_length_b;
113 } test_t;
114
115 const test_t test_set[] PROGMEM = {
116         { zero_block, 128, zero_block, 96, NULL, 0, NULL, 0 },
117         { zero_block, 128, zero_block, 96, NULL, 0, zero_block, 128 },
118         { key_b, 128, iv_block, 96, NULL, 0, pt_block, 512 },
119         { key_b, 128, iv_block, 96, ad_block, 160, pt_block, 480 },
120         { key_b, 128, iv_block, 64, ad_block, 160, pt_block, 480 },
121         { key_b, 128, iv_6, sizeof(iv_6) * 8, ad_block, 160, pt_block, 480 },
122
123         { zero_block, 192, zero_block, 96, NULL, 0, NULL, 0 },
124         { zero_block, 192, zero_block, 96, NULL, 0, zero_block, 128 },
125         { key_b, 192, iv_block, 96, NULL, 0, pt_block, 512 },
126         { key_b, 192, iv_block, 96, ad_block, 160, pt_block, 480 },
127         { key_b, 192, iv_block, 64, ad_block, 160, pt_block, 480 },
128         { key_b, 192, iv_6, sizeof(iv_6) * 8, ad_block, 160, pt_block, 480 },
129
130         { zero_block, 256, zero_block, 96, NULL, 0, NULL, 0 },
131         { zero_block, 256, zero_block, 96, NULL, 0, zero_block, 128 },
132         { key_b, 256, iv_block, 96, NULL, 0, pt_block, 512 },
133         { key_b, 256, iv_block, 96, ad_block, 160, pt_block, 480 },
134         { key_b, 256, iv_block, 64, ad_block, 160, pt_block, 480 },
135         { key_b, 256, iv_6, sizeof(iv_6) * 8, ad_block, 160, pt_block, 480 },
136 };
137
138 /*****************************************************************************
139  *                                                                           *
140  *****************************************************************************/
141
142
143 int8_t gcm128_simple(
144         const void *key,
145         const void *iv,
146         uint16_t iv_length_b,
147         const void * ad,
148         uint16_t ad_length_b,
149         void *dest,
150         const void *src,
151         uint16_t src_length_b,
152         void *tag,
153         uint8_t tag_length_b)
154 {
155     gcm128_ctx_t ctx;
156     DUMP_LEN(key, 16);
157     DUMP_LEN(iv, (iv_length_b + 7) / 8);
158     DUMP_LEN(ad, (ad_length_b + 7) / 8);
159     DUMP_LEN(src, (src_length_b + 7) / 8);
160     if (gcm128_init(&ctx, &aes128_desc, key, 128, iv, iv_length_b)) {
161         return -1;
162     }
163     gcm128_add_ad_final_block(&ctx, ad, ad_length_b);
164     gcm128_encrypt_final_block(&ctx, dest, src, src_length_b);
165     gcm128_finalize(&ctx, tag, tag_length_b);
166     if (dest) {
167         DUMP_LEN(dest, (src_length_b + 7) / 8);
168     }
169     DUMP_LEN(tag, (tag_length_b + 7) / 8);
170     return 0;
171 }
172
173 int8_t gcm128_simple_progmem(
174         const void *key_p,
175         uint16_t key_length_b,
176         const void *iv_p,
177         uint16_t iv_length_b,
178         const void * ad_p,
179         uint16_t ad_length_b,
180         const void *src_p,
181         uint16_t src_length_b,
182         void *tag,
183         uint8_t tag_length_b)
184 {
185     uint8_t dec_tag[16];
186     int8_t r;
187     gcm128_ctx_t ctx, dec_ctx;
188     const bcdesc_t *cipher;
189     switch (key_length_b) {
190     case 128: cipher = &aes128_desc; break;
191     case 192: cipher = &aes192_desc; break;
192     case 256: cipher = &aes256_desc; break;
193     default: return -1;
194     }
195     {
196         uint8_t key[key_length_b / 8];
197         uint8_t iv[(iv_length_b + 7) / 8];
198         memcpy_P(key, key_p, key_length_b / 8);
199         memcpy_P(iv, iv_p, (iv_length_b + 7) / 8);
200         if ((r = gcm128_init(&ctx, cipher, key, key_length_b, iv, iv_length_b))) {
201             printf_P(PSTR("DBG: (Oooops) Error: %"PRId8"\n"), r);
202             uart0_flush();
203             return -1;
204         }
205         if ((r = gcm128_init(&dec_ctx, cipher, key, key_length_b, iv, iv_length_b))) {
206             printf_P(PSTR("DBG: (Oooops) Error: %"PRId8"\n"), r);
207             uart0_flush();
208             return -1;
209         }
210
211     }
212     uint8_t tmp[GCM128_BLOCK_BYTES];
213     while (ad_length_b >= GCM128_BLOCK_BITS) {
214         memcpy_P(tmp, ad_p, GCM128_BLOCK_BYTES);
215         ad_p = &((uint8_t*)ad_p)[GCM128_BLOCK_BYTES];
216         ad_length_b -= GCM128_BLOCK_BITS;
217         gcm128_add_ad_block(&ctx, tmp);
218         gcm128_add_ad_block(&dec_ctx, tmp);
219     }
220     memcpy_P(tmp, ad_p, (ad_length_b + 7) / 8);
221     gcm128_add_ad_final_block(&ctx, tmp, ad_length_b);
222     gcm128_add_ad_final_block(&dec_ctx, tmp, ad_length_b);
223
224     while (src_length_b >= GCM128_BLOCK_BITS) {
225         memcpy_P(tmp, src_p, GCM128_BLOCK_BYTES);
226         src_length_b -= GCM128_BLOCK_BITS;
227         gcm128_encrypt_block(&ctx, tmp, tmp);
228         gcm128_decrypt_block(&dec_ctx, tmp, tmp);
229         if (memcmp_P(tmp, src_p, GCM128_BLOCK_BYTES)) {
230             printf("DBG: Error: decryption error");
231             DUMP(tmp);
232         }
233 //        DUMP(tmp);
234         src_p = &((uint8_t*)src_p)[GCM128_BLOCK_BYTES];
235     }
236     memcpy_P(tmp, src_p, (src_length_b + 7) / 8);
237     gcm128_encrypt_final_block(&ctx, tmp, tmp, src_length_b);
238     gcm128_decrypt_final_block(&dec_ctx, tmp, tmp, src_length_b);
239     if (src_length_b > 0) {
240 //        DUMP_LEN(tmp, (src_length_b + 7) / 8);
241         if (memcmp_P(tmp, src_p, (src_length_b + 7) / 8)) {
242             printf("DBG: Error: decryption error");
243             DUMP_LEN(tmp, (src_length_b + 7) / 8);
244         }
245     }
246     gcm128_finalize(&dec_ctx, dec_tag, tag_length_b);
247     gcm128_finalize(&ctx, tag, tag_length_b);
248     if (memcmp(tag, dec_tag, (tag_length_b + 7) / 8)) {
249         printf("DBG: Error: tag error");
250         DUMP_LEN(tag, (tag_length_b + 7) / 8);
251         DUMP_LEN(dec_tag, (tag_length_b + 7) / 8);
252     }
253     return 0;
254 }
255
256 void testrun_gcm128(void)
257 {
258     uint8_t key[16];
259     uint8_t iv[12];
260     uint8_t tag[16];
261     uint8_t plain[16];
262     uint8_t cipher[16];
263     memset(key, 0, sizeof(key));
264     memset(iv, 0, sizeof(iv));
265     memset(plain, 0, sizeof(plain));
266     gcm128_simple(key, iv, 96, NULL, 0, NULL, NULL, 0, tag, 128);
267     gcm128_simple(key, iv, 96, NULL, 0, cipher, plain, 128, tag, 128);
268 }
269
270
271
272 void testrun_gcm128_progmem(void)
273 {
274     test_t t;
275     uint8_t tag[16];
276     uint8_t i;
277     for (i = 0; i < elementsof(test_set); ++i) {
278         printf_P(PSTR("== Test %"PRId8" ==\n"), i + 1);
279         uart0_flush();
280         memcpy_P(&t, &test_set[i], sizeof(t));
281         gcm128_simple_progmem(
282                 t.key, t.key_length_b,
283                 t.iv, t.iv_length_b,
284                 t.ad, t.ad_length_b,
285                 t.pt, t.pt_length_b,
286                 tag, 128);
287         DUMP(tag);
288         puts("\n\n");
289         uart0_flush();
290     }
291 }
292
293 /*****************************************************************************
294  *  main                                                                     *
295  *****************************************************************************/
296
297 const char nessie_str[]      PROGMEM = "nessie";
298 const char test_str[]        PROGMEM = "test";
299 const char ftest_str[]       PROGMEM = "ftest";
300 const char gtest_str[]       PROGMEM = "gtest";
301 const char performance_str[] PROGMEM = "performance";
302 const char echo_str[]        PROGMEM = "echo";
303
304 const cmdlist_entry_t cmdlist[] PROGMEM = {
305 //    { nessie_str,      NULL, NULL },
306     { test_str,        NULL, testrun_gcm128_progmem},
307 //    { ftest_str,       NULL, testrun_f32},
308 //    { gtest_str,       NULL, testrun_g32},
309 //    { performance_str, NULL, testrun_performance_arcfour},
310     { echo_str,    (void*)1, (void_fpt)echo_ctrl},
311     { NULL,            NULL, NULL}
312 };
313
314 int main(void) {
315     main_setup();
316
317     for(;;){
318         welcome_msg(algo_name);
319         cmd_interface(cmdlist);
320     }
321
322 }
323
324