]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /********************************************************************** |
2 | Copyright(c) 2011-2016 Intel Corporation All rights reserved. | |
3 | ||
4 | Redistribution and use in source and binary forms, with or without | |
1e59de90 | 5 | modification, are permitted provided that the following conditions |
7c673cae FG |
6 | are met: |
7 | * Redistributions of source code must retain the above copyright | |
8 | notice, this list of conditions and the following disclaimer. | |
9 | * Redistributions in binary form must reproduce the above copyright | |
10 | notice, this list of conditions and the following disclaimer in | |
11 | the documentation and/or other materials provided with the | |
12 | distribution. | |
13 | * Neither the name of Intel Corporation nor the names of its | |
14 | contributors may be used to endorse or promote products derived | |
15 | from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | **********************************************************************/ | |
29 | ||
30 | #include <stdlib.h> | |
31 | #include <stdio.h> | |
32 | #include <stdint.h> | |
33 | #include <string.h> // for memcmp | |
34 | #include <aes_gcm.h> | |
35 | #include "gcm_vectors.h" | |
36 | #include "types.h" | |
37 | ||
38 | #ifndef TEST_SEED | |
39 | # define TEST_SEED 0x1234 | |
40 | #endif | |
41 | ||
42 | int check_data(uint8_t * test, uint8_t * expected, uint64_t len, char *data_name) | |
43 | { | |
44 | int mismatch; | |
45 | int OK = 0; | |
46 | ||
47 | mismatch = memcmp(test, expected, len); | |
48 | if (mismatch) { | |
49 | OK = 1; | |
50 | printf(" expected results don't match %s \t\t", data_name); | |
51 | { | |
52 | uint64_t a; | |
53 | for (a = 0; a < len; a++) { | |
54 | if (test[a] != expected[a]) { | |
55 | printf(" '%x' != '%x' at %lx of %lx\n", | |
56 | test[a], expected[a], a, len); | |
57 | break; | |
58 | } | |
59 | } | |
60 | } | |
61 | } | |
62 | return OK; | |
63 | } | |
64 | ||
65 | int test_gcm128_std_vectors(gcm_vector const *vector) | |
66 | { | |
1e59de90 TL |
67 | struct gcm_key_data gkey; |
68 | struct gcm_context_data gctx; | |
7c673cae FG |
69 | int OK = 0; |
70 | // Temporary array for the calculated vectors | |
71 | uint8_t *ct_test = NULL; | |
72 | uint8_t *pt_test = NULL; | |
73 | uint8_t *IV_c = NULL; | |
74 | uint8_t *T_test = NULL; | |
75 | uint8_t *T2_test = NULL; | |
7c673cae FG |
76 | uint64_t IV_alloc_len = 0; |
77 | ||
78 | // Allocate space for the calculated ciphertext | |
79 | ct_test = malloc(vector->Plen); | |
1e59de90 TL |
80 | // Allocate space for the plain text |
81 | pt_test = malloc(vector->Plen); | |
82 | if ((ct_test == NULL) || (pt_test == NULL)) { | |
83 | fprintf(stderr, "Can't allocate ciphertext or plaintext memory\n"); | |
84 | return 1; | |
85 | } | |
86 | IV_alloc_len = vector->IVlen; | |
87 | // Allocate space for the IV | |
88 | IV_c = malloc(IV_alloc_len); | |
89 | if (IV_c == NULL) { | |
90 | fprintf(stderr, "Can't allocate IV memory\n"); | |
91 | return 1; | |
92 | } | |
93 | memcpy(IV_c, vector->IV, vector->IVlen); | |
94 | ||
95 | T_test = malloc(vector->Tlen); | |
96 | T2_test = malloc(vector->Tlen); | |
97 | if ((T_test == NULL) || (T2_test == NULL)) { | |
98 | fprintf(stderr, "Can't allocate tag memory\n"); | |
7c673cae FG |
99 | return 1; |
100 | } | |
1e59de90 TL |
101 | // This is only required once for a given key |
102 | aes_gcm_pre_128(vector->K, &gkey); | |
103 | ||
104 | //// | |
105 | // ISA-l Encrypt | |
106 | //// | |
107 | aes_gcm_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, | |
108 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
109 | OK |= check_data(ct_test, vector->C, vector->Plen, "ISA-L encrypted cypher text (C)"); | |
110 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L tag (T)"); | |
111 | ||
112 | // test of in-place encrypt | |
113 | memcpy(pt_test, vector->P, vector->Plen); | |
114 | aes_gcm_enc_128(&gkey, &gctx, pt_test, pt_test, vector->Plen, IV_c, | |
115 | vector->A, vector->Alen, T_test, vector->Tlen); | |
116 | OK |= check_data(pt_test, vector->C, vector->Plen, | |
117 | "ISA-L encrypted cypher text(in-place)"); | |
118 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L encrypted tag T(in-place)"); | |
119 | memset(ct_test, 0, vector->Plen); | |
120 | memset(T_test, 0, vector->Tlen); | |
121 | ||
122 | //// | |
123 | // ISA-l Decrypt | |
124 | //// | |
125 | aes_gcm_dec_128(&gkey, &gctx, pt_test, vector->C, vector->Plen, | |
126 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
127 | OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); | |
128 | // GCM decryption outputs a 16 byte tag value that must be verified against the expected tag value | |
129 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T)"); | |
130 | ||
131 | // test in in-place decrypt | |
132 | memcpy(ct_test, vector->C, vector->Plen); | |
133 | aes_gcm_dec_128(&gkey, &gctx, ct_test, ct_test, vector->Plen, IV_c, | |
134 | vector->A, vector->Alen, T_test, vector->Tlen); | |
135 | OK |= check_data(ct_test, vector->P, vector->Plen, "ISA-L plain text (P) - in-place"); | |
136 | OK |= | |
137 | check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T) - in-place"); | |
138 | // ISA-L enc -> ISA-L dec | |
139 | aes_gcm_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, | |
140 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
141 | memset(pt_test, 0, vector->Plen); | |
142 | aes_gcm_dec_128(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, | |
143 | vector->A, vector->Alen, T2_test, vector->Tlen); | |
144 | OK |= | |
145 | check_data(pt_test, vector->P, vector->Plen, | |
146 | "ISA-L self decrypted plain text (P)"); | |
147 | OK |= check_data(T_test, T2_test, vector->Tlen, "ISA-L self decrypted tag (T)"); | |
148 | ||
149 | memset(pt_test, 0, vector->Plen); | |
150 | ||
151 | if (NULL != ct_test) | |
152 | free(ct_test); | |
153 | if (NULL != pt_test) | |
154 | free(pt_test); | |
155 | if (NULL != IV_c) | |
156 | free(IV_c); | |
157 | if (NULL != T_test) | |
158 | free(T_test); | |
159 | if (NULL != T2_test) | |
160 | free(T2_test); | |
161 | ||
162 | return OK; | |
163 | } | |
164 | ||
165 | int test_gcm256_std_vectors(gcm_vector const *vector) | |
166 | { | |
167 | struct gcm_key_data gkey; | |
168 | struct gcm_context_data gctx; | |
169 | int OK = 0; | |
170 | // Temporary array for the calculated vectors | |
171 | uint8_t *ct_test = NULL; | |
172 | uint8_t *pt_test = NULL; | |
173 | uint8_t *IV_c = NULL; | |
174 | uint8_t *T_test = NULL; | |
175 | uint8_t *T2_test = NULL; | |
176 | uint64_t IV_alloc_len = 0; | |
177 | ||
7c673cae | 178 | // Allocate space for the calculated ciphertext |
1e59de90 TL |
179 | ct_test = malloc(vector->Plen); |
180 | // Allocate space for the plain text | |
7c673cae | 181 | pt_test = malloc(vector->Plen); |
1e59de90 TL |
182 | if ((ct_test == NULL) || (pt_test == NULL)) { |
183 | fprintf(stderr, "Can't allocate ciphertext or plaintext memory\n"); | |
7c673cae FG |
184 | return 1; |
185 | } | |
1e59de90 TL |
186 | IV_alloc_len = vector->IVlen; |
187 | // Allocate space for the IV | |
188 | IV_c = malloc(IV_alloc_len); | |
189 | if (IV_c == NULL) { | |
190 | fprintf(stderr, "Can't allocate IV memory\n"); | |
191 | return 1; | |
192 | } | |
193 | memcpy(IV_c, vector->IV, vector->IVlen); | |
194 | ||
195 | T_test = malloc(vector->Tlen); | |
196 | T2_test = malloc(vector->Tlen); | |
197 | if (T_test == NULL) { | |
198 | fprintf(stderr, "Can't allocate tag memory\n"); | |
199 | return 1; | |
200 | } | |
201 | // This is only required once for a given key | |
202 | aes_gcm_pre_256(vector->K, &gkey); | |
203 | ||
204 | //// | |
205 | // ISA-l Encrypt | |
206 | //// | |
207 | memset(ct_test, 0, vector->Plen); | |
208 | aes_gcm_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, | |
209 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
210 | OK |= check_data(ct_test, vector->C, vector->Plen, "ISA-L encrypted cypher text (C)"); | |
211 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L tag (T)"); | |
212 | ||
213 | // test of in-place encrypt | |
214 | memcpy(pt_test, vector->P, vector->Plen); | |
215 | aes_gcm_enc_256(&gkey, &gctx, pt_test, pt_test, vector->Plen, IV_c, | |
216 | vector->A, vector->Alen, T_test, vector->Tlen); | |
217 | OK |= | |
218 | check_data(pt_test, vector->C, vector->Plen, | |
219 | "ISA-L encrypted cypher text(in-place)"); | |
220 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L encrypted tag T(in-place)"); | |
221 | memset(ct_test, 0, vector->Plen); | |
222 | memset(T_test, 0, vector->Tlen); | |
223 | ||
224 | //// | |
225 | // ISA-l Decrypt | |
226 | //// | |
227 | aes_gcm_dec_256(&gkey, &gctx, pt_test, vector->C, vector->Plen, | |
228 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
229 | OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); | |
230 | // GCM decryption outputs a 16 byte tag value that must be verified against the expected tag value | |
231 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T)"); | |
232 | ||
233 | // test in in-place decrypt | |
234 | memcpy(ct_test, vector->C, vector->Plen); | |
235 | aes_gcm_dec_256(&gkey, &gctx, ct_test, ct_test, vector->Plen, IV_c, | |
236 | vector->A, vector->Alen, T_test, vector->Tlen); | |
237 | OK |= check_data(ct_test, vector->P, vector->Plen, "ISA-L plain text (P) - in-place"); | |
238 | OK |= | |
239 | check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T) - in-place"); | |
240 | // ISA-L enc -> ISA-L dec | |
241 | aes_gcm_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, | |
242 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
243 | memset(pt_test, 0, vector->Plen); | |
244 | aes_gcm_dec_256(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, | |
245 | vector->A, vector->Alen, T2_test, vector->Tlen); | |
246 | OK |= | |
247 | check_data(pt_test, vector->P, vector->Plen, | |
248 | "ISA-L self decrypted plain text (P)"); | |
249 | OK |= check_data(T_test, T2_test, vector->Tlen, "ISA-L self decrypted tag (T)"); | |
250 | ||
251 | if (NULL != ct_test) | |
252 | free(ct_test); | |
253 | if (NULL != pt_test) | |
254 | free(pt_test); | |
255 | if (NULL != IV_c) | |
256 | free(IV_c); | |
257 | if (NULL != T_test) | |
258 | free(T_test); | |
259 | if (NULL != T2_test) | |
260 | free(T2_test); | |
261 | ||
262 | return OK; | |
263 | } | |
264 | ||
265 | void aes_gcm_stream_enc_128(const struct gcm_key_data *key_data, | |
266 | struct gcm_context_data *context, | |
267 | uint8_t * out, | |
268 | uint8_t const *in, | |
269 | uint64_t len, | |
270 | uint8_t * iv, | |
271 | uint8_t const *aad, | |
272 | uint64_t aad_len, uint8_t * auth_tag, uint64_t auth_tag_len) | |
273 | { | |
274 | aes_gcm_init_128(key_data, context, iv, aad, aad_len); | |
275 | uint8_t test_sequence[] = { 1, 12, 22, 0, 1, 12, 16 }; //sum(test_sequence) > max_Plen in verctors | |
276 | uint32_t i; | |
277 | uint32_t offset = 0, dist; | |
278 | ||
279 | for (i = 0; i < sizeof(test_sequence); i++) { | |
280 | dist = test_sequence[i]; | |
281 | if (offset + dist > len) | |
282 | break; | |
283 | aes_gcm_enc_128_update(key_data, context, out + offset, in + offset, dist); | |
284 | offset += dist; | |
285 | } | |
286 | ||
287 | aes_gcm_enc_128_update(key_data, context, out + offset, in + offset, len - offset); | |
288 | aes_gcm_enc_128_finalize(key_data, context, auth_tag, auth_tag_len); | |
289 | } | |
290 | ||
291 | void aes_gcm_stream_dec_128(const struct gcm_key_data *key_data, | |
292 | struct gcm_context_data *context, | |
293 | uint8_t * out, | |
294 | uint8_t const *in, | |
295 | uint64_t len, | |
296 | uint8_t * iv, | |
297 | uint8_t const *aad, | |
298 | uint64_t aad_len, uint8_t * auth_tag, uint64_t auth_tag_len) | |
299 | { | |
300 | aes_gcm_init_128(key_data, context, iv, aad, aad_len); | |
301 | uint8_t test_sequence[] = { 1, 12, 22, 0, 1, 12, 16 }; //sum(test_sequence) > max_Plen in vectors | |
302 | uint32_t i; | |
303 | uint32_t offset = 0, dist; | |
304 | ||
305 | for (i = 0; i < sizeof(test_sequence); i++) { | |
306 | dist = test_sequence[i]; | |
307 | if (offset + dist > len) | |
308 | break; | |
309 | aes_gcm_dec_128_update(key_data, context, out + offset, in + offset, dist); | |
310 | offset += dist; | |
311 | } | |
312 | aes_gcm_dec_128_update(key_data, context, out + offset, in + offset, len - offset); | |
313 | aes_gcm_dec_128_finalize(key_data, context, auth_tag, auth_tag_len); | |
314 | ||
315 | } | |
316 | ||
317 | #if !defined(NT_LD) && !defined(NT_ST) && !defined(NT_LDST) | |
318 | int test_gcm128_std_stream_vectors(gcm_vector const *vector) | |
319 | { | |
320 | struct gcm_key_data gkey; | |
321 | struct gcm_context_data gctx; | |
322 | int OK = 0; | |
323 | // Temporary array for the calculated vectors | |
324 | uint8_t *ct_test = NULL; | |
325 | uint8_t *pt_test = NULL; | |
326 | uint8_t *IV_c = NULL; | |
327 | uint8_t *T_test = NULL; | |
328 | uint8_t *T2_test = NULL; | |
329 | uint64_t IV_alloc_len = 0; | |
330 | ||
7c673cae | 331 | // Allocate space for the calculated ciphertext |
1e59de90 TL |
332 | ct_test = malloc(vector->Plen); |
333 | // Allocate space for the plain text | |
334 | pt_test = malloc(vector->Plen); | |
335 | if ((ct_test == NULL) || (pt_test == NULL)) { | |
336 | fprintf(stderr, "Can't allocate ciphertext or plaintext memory\n"); | |
337 | return 1; | |
338 | } | |
339 | IV_alloc_len = vector->IVlen; | |
340 | // Allocate space for the IV | |
7c673cae FG |
341 | IV_c = malloc(IV_alloc_len); |
342 | if (IV_c == NULL) { | |
1e59de90 | 343 | fprintf(stderr, "Can't allocate IV memory\n"); |
7c673cae FG |
344 | return 1; |
345 | } | |
7c673cae | 346 | memcpy(IV_c, vector->IV, vector->IVlen); |
7c673cae FG |
347 | |
348 | T_test = malloc(vector->Tlen); | |
349 | T2_test = malloc(vector->Tlen); | |
350 | if ((T_test == NULL) || (T2_test == NULL)) { | |
351 | fprintf(stderr, "Can't allocate tag memory\n"); | |
352 | return 1; | |
353 | } | |
354 | // This is only required once for a given key | |
1e59de90 TL |
355 | memset(gkey.expanded_keys, 0, sizeof(gkey.expanded_keys)); |
356 | aes_gcm_pre_128(vector->K, &gkey); | |
7c673cae FG |
357 | |
358 | //// | |
359 | // ISA-l Encrypt | |
360 | //// | |
1e59de90 TL |
361 | |
362 | aes_gcm_stream_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, | |
363 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
364 | OK |= check_data(ct_test, vector->C, vector->Plen, "ISA-L encrypted cypher text (C)"); |
365 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L tag (T)"); | |
366 | ||
367 | // test of in-place encrypt | |
368 | memcpy(pt_test, vector->P, vector->Plen); | |
1e59de90 TL |
369 | aes_gcm_stream_enc_128(&gkey, &gctx, pt_test, pt_test, vector->Plen, IV_c, |
370 | vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
371 | OK |= check_data(pt_test, vector->C, vector->Plen, |
372 | "ISA-L encrypted cypher text(in-place)"); | |
1e59de90 | 373 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L encrypted tag T(in-place)"); |
7c673cae FG |
374 | memset(ct_test, 0, vector->Plen); |
375 | memset(T_test, 0, vector->Tlen); | |
376 | ||
377 | //// | |
378 | // ISA-l Decrypt | |
379 | //// | |
1e59de90 TL |
380 | aes_gcm_stream_dec_128(&gkey, &gctx, pt_test, vector->C, vector->Plen, |
381 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
382 | OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); |
383 | // GCM decryption outputs a 16 byte tag value that must be verified against the expected tag value | |
384 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T)"); | |
385 | ||
386 | // test in in-place decrypt | |
387 | memcpy(ct_test, vector->C, vector->Plen); | |
1e59de90 TL |
388 | aes_gcm_stream_dec_128(&gkey, &gctx, ct_test, ct_test, vector->Plen, IV_c, |
389 | vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
390 | OK |= check_data(ct_test, vector->P, vector->Plen, "ISA-L plain text (P) - in-place"); |
391 | OK |= | |
392 | check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T) - in-place"); | |
393 | // ISA-L enc -> ISA-L dec | |
1e59de90 TL |
394 | aes_gcm_stream_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, |
395 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae | 396 | memset(pt_test, 0, vector->Plen); |
1e59de90 TL |
397 | aes_gcm_stream_dec_128(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, |
398 | vector->A, vector->Alen, T2_test, vector->Tlen); | |
7c673cae FG |
399 | OK |= |
400 | check_data(pt_test, vector->P, vector->Plen, | |
401 | "ISA-L self decrypted plain text (P)"); | |
402 | OK |= check_data(T_test, T2_test, vector->Tlen, "ISA-L self decrypted tag (T)"); | |
403 | ||
404 | memset(pt_test, 0, vector->Plen); | |
405 | ||
406 | if (NULL != ct_test) | |
407 | free(ct_test); | |
408 | if (NULL != pt_test) | |
409 | free(pt_test); | |
410 | if (NULL != IV_c) | |
411 | free(IV_c); | |
412 | if (NULL != T_test) | |
413 | free(T_test); | |
414 | if (NULL != T2_test) | |
415 | free(T2_test); | |
416 | ||
417 | return OK; | |
418 | } | |
419 | ||
1e59de90 TL |
420 | void aes_gcm_stream_enc_256(const struct gcm_key_data *key_data, |
421 | struct gcm_context_data *context, | |
422 | uint8_t * out, | |
423 | uint8_t const *in, | |
424 | uint64_t len, | |
425 | uint8_t * iv, | |
426 | uint8_t const *aad, | |
427 | uint64_t aad_len, uint8_t * auth_tag, uint64_t auth_tag_len) | |
428 | { | |
429 | aes_gcm_init_256(key_data, context, iv, aad, aad_len); | |
430 | uint8_t test_sequence[] = { 1, 12, 22, 0, 1, 12, 16 }; //sum(test_sequence) > max_Plen in vectors | |
431 | uint32_t i; | |
432 | uint32_t offset = 0, dist; | |
433 | ||
434 | for (i = 0; i < sizeof(test_sequence); i++) { | |
435 | dist = test_sequence[i]; | |
436 | if (offset + dist > len) | |
437 | break; | |
438 | aes_gcm_enc_256_update(key_data, context, out + offset, in + offset, dist); | |
439 | offset += dist; | |
440 | } | |
441 | ||
442 | aes_gcm_enc_256_update(key_data, context, out + offset, in + offset, len - offset); | |
443 | aes_gcm_enc_256_finalize(key_data, context, auth_tag, auth_tag_len); | |
444 | ||
445 | } | |
446 | ||
447 | void aes_gcm_stream_dec_256(const struct gcm_key_data *key_data, | |
448 | struct gcm_context_data *context, | |
449 | uint8_t * out, | |
450 | uint8_t const *in, | |
451 | uint64_t len, | |
452 | uint8_t * iv, | |
453 | uint8_t const *aad, | |
454 | uint64_t aad_len, uint8_t * auth_tag, uint64_t auth_tag_len) | |
455 | { | |
456 | aes_gcm_init_256(key_data, context, iv, aad, aad_len); | |
457 | uint8_t test_sequence[] = { 1, 12, 22, 0, 1, 12, 16 }; //sum(test_sequence) > max_Plen in vectors | |
458 | uint32_t i; | |
459 | uint32_t offset = 0, dist; | |
460 | ||
461 | for (i = 0; i < sizeof(test_sequence); i++) { | |
462 | dist = test_sequence[i]; | |
463 | if (offset + dist > len) | |
464 | break; | |
465 | aes_gcm_dec_256_update(key_data, context, out + offset, in + offset, dist); | |
466 | offset += dist; | |
467 | } | |
468 | ||
469 | aes_gcm_dec_256_update(key_data, context, out + offset, in + offset, len - offset); | |
470 | aes_gcm_dec_256_finalize(key_data, context, auth_tag, auth_tag_len); | |
471 | ||
472 | } | |
473 | ||
474 | int test_gcm256_std_stream_vectors(gcm_vector const *vector) | |
7c673cae | 475 | { |
1e59de90 TL |
476 | struct gcm_key_data gkey; |
477 | struct gcm_context_data gctx; | |
7c673cae FG |
478 | int OK = 0; |
479 | // Temporary array for the calculated vectors | |
480 | uint8_t *ct_test = NULL; | |
481 | uint8_t *pt_test = NULL; | |
482 | uint8_t *IV_c = NULL; | |
483 | uint8_t *T_test = NULL; | |
484 | uint8_t *T2_test = NULL; | |
7c673cae FG |
485 | uint64_t IV_alloc_len = 0; |
486 | ||
487 | // Allocate space for the calculated ciphertext | |
488 | ct_test = malloc(vector->Plen); | |
1e59de90 | 489 | // Allocate space for the plain text |
7c673cae FG |
490 | pt_test = malloc(vector->Plen); |
491 | if ((ct_test == NULL) || (pt_test == NULL)) { | |
492 | fprintf(stderr, "Can't allocate ciphertext or plaintext memory\n"); | |
493 | return 1; | |
494 | } | |
1e59de90 TL |
495 | IV_alloc_len = vector->IVlen; |
496 | // Allocate space for the IV | |
7c673cae FG |
497 | IV_c = malloc(IV_alloc_len); |
498 | if (IV_c == NULL) { | |
1e59de90 | 499 | fprintf(stderr, "Can't allocate IV memory\n"); |
7c673cae FG |
500 | return 1; |
501 | } | |
7c673cae | 502 | memcpy(IV_c, vector->IV, vector->IVlen); |
7c673cae FG |
503 | |
504 | T_test = malloc(vector->Tlen); | |
505 | T2_test = malloc(vector->Tlen); | |
506 | if (T_test == NULL) { | |
507 | fprintf(stderr, "Can't allocate tag memory\n"); | |
508 | return 1; | |
509 | } | |
510 | // This is only required once for a given key | |
1e59de90 | 511 | aes_gcm_pre_256(vector->K, &gkey); |
7c673cae FG |
512 | |
513 | //// | |
514 | // ISA-l Encrypt | |
515 | //// | |
516 | memset(ct_test, 0, vector->Plen); | |
1e59de90 TL |
517 | aes_gcm_stream_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, |
518 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
519 | OK |= check_data(ct_test, vector->C, vector->Plen, "ISA-L encrypted cypher text (C)"); |
520 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L tag (T)"); | |
521 | ||
522 | // test of in-place encrypt | |
523 | memcpy(pt_test, vector->P, vector->Plen); | |
1e59de90 TL |
524 | aes_gcm_stream_enc_256(&gkey, &gctx, pt_test, pt_test, vector->Plen, IV_c, |
525 | vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
526 | OK |= |
527 | check_data(pt_test, vector->C, vector->Plen, | |
528 | "ISA-L encrypted cypher text(in-place)"); | |
1e59de90 | 529 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L encrypted tag T(in-place)"); |
7c673cae FG |
530 | memset(ct_test, 0, vector->Plen); |
531 | memset(T_test, 0, vector->Tlen); | |
532 | ||
533 | //// | |
534 | // ISA-l Decrypt | |
535 | //// | |
1e59de90 TL |
536 | aes_gcm_stream_dec_256(&gkey, &gctx, pt_test, vector->C, vector->Plen, |
537 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
538 | OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); |
539 | // GCM decryption outputs a 16 byte tag value that must be verified against the expected tag value | |
540 | OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T)"); | |
541 | ||
542 | // test in in-place decrypt | |
543 | memcpy(ct_test, vector->C, vector->Plen); | |
1e59de90 TL |
544 | aes_gcm_stream_dec_256(&gkey, &gctx, ct_test, ct_test, vector->Plen, IV_c, |
545 | vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae FG |
546 | OK |= check_data(ct_test, vector->P, vector->Plen, "ISA-L plain text (P) - in-place"); |
547 | OK |= | |
548 | check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T) - in-place"); | |
549 | // ISA-L enc -> ISA-L dec | |
1e59de90 TL |
550 | aes_gcm_stream_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, |
551 | IV_c, vector->A, vector->Alen, T_test, vector->Tlen); | |
7c673cae | 552 | memset(pt_test, 0, vector->Plen); |
1e59de90 TL |
553 | aes_gcm_stream_dec_256(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, |
554 | vector->A, vector->Alen, T2_test, vector->Tlen); | |
7c673cae FG |
555 | OK |= |
556 | check_data(pt_test, vector->P, vector->Plen, | |
557 | "ISA-L self decrypted plain text (P)"); | |
558 | OK |= check_data(T_test, T2_test, vector->Tlen, "ISA-L self decrypted tag (T)"); | |
559 | ||
560 | if (NULL != ct_test) | |
561 | free(ct_test); | |
562 | if (NULL != pt_test) | |
563 | free(pt_test); | |
564 | if (NULL != IV_c) | |
565 | free(IV_c); | |
566 | if (NULL != T_test) | |
567 | free(T_test); | |
568 | if (NULL != T2_test) | |
569 | free(T2_test); | |
570 | ||
571 | return OK; | |
572 | } | |
1e59de90 | 573 | #endif |
7c673cae FG |
574 | |
575 | int test_gcm_std_vectors(void) | |
576 | { | |
577 | int const vectors_cnt = sizeof(gcm_vectors) / sizeof(gcm_vectors[0]); | |
578 | int vect; | |
579 | int OK = 0; | |
580 | ||
1e59de90 TL |
581 | printf("AES-GCM standard test vectors new api:\n"); |
582 | for (vect = 0; (vect < vectors_cnt); vect++) { | |
7c673cae | 583 | #ifdef DEBUG |
1e59de90 TL |
584 | printf("Standard vector new api %d/%d" |
585 | " Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", | |
586 | vect, vectors_cnt - 1, (int)gcm_vectors[vect].Klen, | |
587 | (int)gcm_vectors[vect].IVlen, (int)gcm_vectors[vect].Plen, | |
588 | (int)gcm_vectors[vect].Alen, (int)gcm_vectors[vect].Tlen); | |
7c673cae FG |
589 | #else |
590 | printf("."); | |
591 | #endif | |
1e59de90 | 592 | if (BITS_128 == gcm_vectors[vect].Klen) |
7c673cae | 593 | OK |= test_gcm128_std_vectors(&gcm_vectors[vect]); |
1e59de90 | 594 | else |
7c673cae | 595 | OK |= test_gcm256_std_vectors(&gcm_vectors[vect]); |
7c673cae FG |
596 | if (0 != OK) |
597 | return OK; | |
598 | } | |
599 | printf("\n"); | |
600 | return OK; | |
601 | } | |
602 | ||
1e59de90 TL |
603 | #if !defined(NT_LD) && !defined(NT_ST) && !defined(NT_LDST) |
604 | /** | |
605 | * Stream API test with standard vectors | |
606 | */ | |
607 | int test_gcm_std_strm_vectors(void) | |
608 | { | |
609 | int const vectors_cnt = sizeof(gcm_vectors) / sizeof(gcm_vectors[0]); | |
610 | int vect; | |
611 | int OK = 0; | |
612 | ||
613 | printf("AES-GCM standard test vectors stream api:\n"); | |
614 | for (vect = 0; (vect < vectors_cnt); vect++) { | |
615 | #ifdef DEBUG | |
616 | printf("Standard vector stream api %d/%d" | |
617 | " Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", | |
618 | vect, vectors_cnt - 1, (int)gcm_vectors[vect].Klen, | |
619 | (int)gcm_vectors[vect].IVlen, (int)gcm_vectors[vect].Plen, | |
620 | (int)gcm_vectors[vect].Alen, (int)gcm_vectors[vect].Tlen); | |
621 | #else | |
622 | printf("."); | |
623 | #endif | |
624 | if (BITS_128 == gcm_vectors[vect].Klen) | |
625 | OK |= test_gcm128_std_stream_vectors(&gcm_vectors[vect]); | |
626 | else | |
627 | OK |= test_gcm256_std_stream_vectors(&gcm_vectors[vect]); | |
628 | if (0 != OK) | |
629 | return OK; | |
630 | } | |
631 | printf("\n"); | |
632 | return OK; | |
633 | } | |
634 | #endif | |
7c673cae FG |
635 | int main(int argc, char **argv) |
636 | { | |
637 | int errors = 0; | |
638 | int seed; | |
639 | ||
640 | if (argc == 1) | |
641 | seed = TEST_SEED; | |
642 | else | |
643 | seed = atoi(argv[1]); | |
644 | ||
645 | srand(seed); | |
646 | printf("SEED: %d\n", seed); | |
647 | ||
1e59de90 TL |
648 | errors += test_gcm_std_vectors(); |
649 | #if !defined(NT_LD) && !defined(NT_ST) && !defined(NT_LDST) | |
650 | errors += test_gcm_std_strm_vectors(); | |
651 | #endif | |
7c673cae FG |
652 | |
653 | if (0 == errors) | |
654 | printf("...Pass\n"); | |
655 | else | |
656 | printf("...Fail\n"); | |
657 | ||
658 | return errors; | |
659 | } |