]>
Commit | Line | Data |
---|---|---|
0e360199 BL |
1 | /* Written by Ben Laurie, 2001 */ |
2 | /* | |
3 | * Copyright (c) 2001 The OpenSSL Project. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * | |
9 | * 1. Redistributions of source code must retain the above copyright | |
0f113f3e | 10 | * notice, this list of conditions and the following disclaimer. |
0e360199 BL |
11 | * |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in | |
14 | * the documentation and/or other materials provided with the | |
15 | * distribution. | |
16 | * | |
17 | * 3. All advertising materials mentioning features or use of this | |
18 | * software must display the following acknowledgment: | |
19 | * "This product includes software developed by the OpenSSL Project | |
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | |
21 | * | |
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
23 | * endorse or promote products derived from this software without | |
24 | * prior written permission. For written permission, please contact | |
25 | * openssl-core@openssl.org. | |
26 | * | |
27 | * 5. Products derived from this software may not be called "OpenSSL" | |
28 | * nor may "OpenSSL" appear in their names without prior written | |
29 | * permission of the OpenSSL Project. | |
30 | * | |
31 | * 6. Redistributions of any form whatsoever must retain the following | |
32 | * acknowledgment: | |
33 | * "This product includes software developed by the OpenSSL Project | |
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
35 | * | |
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
48 | */ | |
49 | ||
50 | #include <stdio.h> | |
51 | #include <string.h> | |
55f78baf RL |
52 | |
53 | #include "../e_os.h" | |
54 | ||
63d74075 | 55 | #include <openssl/opensslconf.h> |
0e360199 | 56 | #include <openssl/evp.h> |
0b13e9f0 | 57 | #ifndef OPENSSL_NO_ENGINE |
0f113f3e | 58 | # include <openssl/engine.h> |
0b13e9f0 RL |
59 | #endif |
60 | #include <openssl/err.h> | |
9dd5ae65 | 61 | #include <openssl/conf.h> |
0e360199 | 62 | |
0f113f3e MC |
63 | static void hexdump(FILE *f, const char *title, const unsigned char *s, int l) |
64 | { | |
65 | int n = 0; | |
66 | ||
67 | fprintf(f, "%s", title); | |
68 | for (; n < l; ++n) { | |
69 | if ((n % 16) == 0) | |
70 | fprintf(f, "\n%04x", n); | |
71 | fprintf(f, " %02x", s[n]); | |
0e360199 | 72 | } |
0f113f3e MC |
73 | fprintf(f, "\n"); |
74 | } | |
0e360199 BL |
75 | |
76 | static int convert(unsigned char *s) | |
0f113f3e | 77 | { |
0e360199 BL |
78 | unsigned char *d; |
79 | ||
0f113f3e MC |
80 | for (d = s; *s; s += 2, ++d) { |
81 | unsigned int n; | |
82 | ||
83 | if (!s[1]) { | |
84 | fprintf(stderr, "Odd number of hex digits!"); | |
85 | EXIT(4); | |
86 | } | |
87 | sscanf((char *)s, "%2x", &n); | |
88 | *d = (unsigned char)n; | |
0e360199 | 89 | } |
0f113f3e MC |
90 | return s - d; |
91 | } | |
0e360199 | 92 | |
5b46eee0 | 93 | static char *sstrsep(char **string, const char *delim) |
0f113f3e | 94 | { |
5b46eee0 UM |
95 | char isdelim[256]; |
96 | char *token = *string; | |
97 | ||
98 | if (**string == 0) | |
99 | return NULL; | |
100 | ||
101 | memset(isdelim, 0, 256); | |
102 | isdelim[0] = 1; | |
103 | ||
0f113f3e | 104 | while (*delim) { |
5b46eee0 UM |
105 | isdelim[(unsigned char)(*delim)] = 1; |
106 | delim++; | |
0f113f3e | 107 | } |
5b46eee0 | 108 | |
0f113f3e | 109 | while (!isdelim[(unsigned char)(**string)]) { |
5b46eee0 | 110 | (*string)++; |
0f113f3e | 111 | } |
5b46eee0 | 112 | |
0f113f3e | 113 | if (**string) { |
5b46eee0 UM |
114 | **string = 0; |
115 | (*string)++; | |
0f113f3e | 116 | } |
5b46eee0 UM |
117 | |
118 | return token; | |
0f113f3e | 119 | } |
5b46eee0 | 120 | |
0f113f3e MC |
121 | static unsigned char *ustrsep(char **p, const char *sep) |
122 | { | |
123 | return (unsigned char *)sstrsep(p, sep); | |
124 | } | |
0e360199 | 125 | |
848f735a | 126 | static int test1_exit(int ec) |
0f113f3e MC |
127 | { |
128 | EXIT(ec); | |
129 | return (0); /* To keep some compilers quiet */ | |
130 | } | |
848f735a | 131 | |
0d263d2a DSH |
132 | /* Test copying of contexts */ |
133 | static void test_ctx_replace(EVP_CIPHER_CTX **pctx) | |
0f113f3e MC |
134 | { |
135 | /* Make copy of context and replace original */ | |
136 | EVP_CIPHER_CTX *ctx_copy; | |
137 | ctx_copy = EVP_CIPHER_CTX_new(); | |
138 | EVP_CIPHER_CTX_copy(ctx_copy, *pctx); | |
139 | EVP_CIPHER_CTX_free(*pctx); | |
140 | *pctx = ctx_copy; | |
141 | } | |
142 | ||
143 | static void test1(const EVP_CIPHER *c, const unsigned char *key, int kn, | |
144 | const unsigned char *iv, int in, | |
145 | const unsigned char *plaintext, int pn, | |
146 | const unsigned char *ciphertext, int cn, | |
147 | const unsigned char *aad, int an, | |
148 | const unsigned char *tag, int tn, int encdec) | |
149 | { | |
0d263d2a | 150 | EVP_CIPHER_CTX *ctx = NULL; |
0e360199 | 151 | unsigned char out[4096]; |
0f113f3e MC |
152 | int outl, outl2, mode; |
153 | ||
154 | printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), | |
155 | (encdec == | |
156 | 1 ? "(encrypt)" : (encdec == | |
157 | 0 ? "(decrypt)" : "(encrypt/decrypt)"))); | |
158 | hexdump(stdout, "Key", key, kn); | |
159 | if (in) | |
160 | hexdump(stdout, "IV", iv, in); | |
161 | hexdump(stdout, "Plaintext", plaintext, pn); | |
162 | hexdump(stdout, "Ciphertext", ciphertext, cn); | |
15652f98 | 163 | if (an) |
0f113f3e | 164 | hexdump(stdout, "AAD", aad, an); |
15652f98 | 165 | if (tn) |
0f113f3e MC |
166 | hexdump(stdout, "Tag", tag, tn); |
167 | mode = EVP_CIPHER_mode(c); | |
168 | if (kn != EVP_CIPHER_key_length(c)) { | |
169 | fprintf(stderr, "Key length doesn't match, got %d expected %lu\n", kn, | |
170 | (unsigned long)EVP_CIPHER_key_length(c)); | |
171 | test1_exit(5); | |
172 | } | |
0d263d2a | 173 | ctx = EVP_CIPHER_CTX_new(); |
0f113f3e MC |
174 | EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); |
175 | if (encdec != 0) { | |
176 | if ((mode == EVP_CIPH_GCM_MODE) || (mode == EVP_CIPH_OCB_MODE)) { | |
177 | if (!EVP_EncryptInit_ex(ctx, c, NULL, NULL, NULL)) { | |
178 | fprintf(stderr, "EncryptInit failed\n"); | |
179 | ERR_print_errors_fp(stderr); | |
180 | test1_exit(10); | |
181 | } | |
182 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_IVLEN, in, NULL)) { | |
183 | fprintf(stderr, "IV length set failed\n"); | |
184 | ERR_print_errors_fp(stderr); | |
185 | test1_exit(11); | |
186 | } | |
187 | if ((mode == EVP_CIPH_OCB_MODE) && | |
188 | !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_OCB_SET_TAGLEN, tn, NULL)) | |
189 | { | |
190 | fprintf(stderr, "Tag length set failed\n"); | |
191 | ERR_print_errors_fp(stderr); | |
192 | test1_exit(15); | |
193 | } | |
194 | if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) { | |
195 | fprintf(stderr, "Key/IV set failed\n"); | |
196 | ERR_print_errors_fp(stderr); | |
197 | test1_exit(12); | |
198 | } | |
199 | if (an && !EVP_EncryptUpdate(ctx, NULL, &outl, aad, an)) { | |
200 | fprintf(stderr, "AAD set failed\n"); | |
201 | ERR_print_errors_fp(stderr); | |
202 | test1_exit(13); | |
203 | } | |
204 | } else if (mode == EVP_CIPH_CCM_MODE) { | |
205 | if (!EVP_EncryptInit_ex(ctx, c, NULL, NULL, NULL)) { | |
206 | fprintf(stderr, "EncryptInit failed\n"); | |
207 | ERR_print_errors_fp(stderr); | |
208 | test1_exit(10); | |
209 | } | |
210 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { | |
211 | fprintf(stderr, "IV length set failed\n"); | |
212 | ERR_print_errors_fp(stderr); | |
213 | test1_exit(11); | |
214 | } | |
215 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) { | |
216 | fprintf(stderr, "Tag length set failed\n"); | |
217 | ERR_print_errors_fp(stderr); | |
218 | test1_exit(11); | |
219 | } | |
220 | if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) { | |
221 | fprintf(stderr, "Key/IV set failed\n"); | |
222 | ERR_print_errors_fp(stderr); | |
223 | test1_exit(12); | |
224 | } | |
225 | if (!EVP_EncryptUpdate(ctx, NULL, &outl, NULL, pn)) { | |
226 | fprintf(stderr, "Plaintext length set failed\n"); | |
227 | ERR_print_errors_fp(stderr); | |
228 | test1_exit(12); | |
229 | } | |
230 | if (an && !EVP_EncryptUpdate(ctx, NULL, &outl, aad, an)) { | |
231 | fprintf(stderr, "AAD set failed\n"); | |
232 | ERR_print_errors_fp(stderr); | |
233 | test1_exit(13); | |
234 | } | |
235 | } else if (mode == EVP_CIPH_WRAP_MODE) { | |
236 | if (!EVP_EncryptInit_ex(ctx, c, NULL, key, in ? iv : NULL)) { | |
237 | fprintf(stderr, "EncryptInit failed\n"); | |
238 | ERR_print_errors_fp(stderr); | |
239 | test1_exit(10); | |
240 | } | |
241 | } else if (!EVP_EncryptInit_ex(ctx, c, NULL, key, iv)) { | |
242 | fprintf(stderr, "EncryptInit failed\n"); | |
243 | ERR_print_errors_fp(stderr); | |
244 | test1_exit(10); | |
245 | } | |
246 | EVP_CIPHER_CTX_set_padding(ctx, 0); | |
0e360199 | 247 | |
0f113f3e | 248 | test_ctx_replace(&ctx); |
544a2aea | 249 | |
0f113f3e MC |
250 | if (!EVP_EncryptUpdate(ctx, out, &outl, plaintext, pn)) { |
251 | fprintf(stderr, "Encrypt failed\n"); | |
252 | ERR_print_errors_fp(stderr); | |
253 | test1_exit(6); | |
254 | } | |
255 | if (!EVP_EncryptFinal_ex(ctx, out + outl, &outl2)) { | |
256 | fprintf(stderr, "EncryptFinal failed\n"); | |
257 | ERR_print_errors_fp(stderr); | |
258 | test1_exit(7); | |
259 | } | |
260 | ||
261 | if (outl + outl2 != cn) { | |
262 | fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", | |
263 | outl + outl2, cn); | |
264 | test1_exit(8); | |
265 | } | |
266 | ||
267 | if (memcmp(out, ciphertext, cn)) { | |
268 | fprintf(stderr, "Ciphertext mismatch\n"); | |
269 | hexdump(stderr, "Got", out, cn); | |
270 | hexdump(stderr, "Expected", ciphertext, cn); | |
271 | test1_exit(9); | |
272 | } | |
273 | if ((mode == EVP_CIPH_GCM_MODE) || (mode == EVP_CIPH_OCB_MODE) | |
274 | || (mode == EVP_CIPH_CCM_MODE)) { | |
275 | unsigned char rtag[16]; | |
276 | ||
277 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_TAG, tn, rtag)) { | |
278 | fprintf(stderr, "Get tag failed\n"); | |
279 | ERR_print_errors_fp(stderr); | |
280 | test1_exit(14); | |
281 | } | |
282 | if (memcmp(rtag, tag, tn)) { | |
283 | fprintf(stderr, "Tag mismatch\n"); | |
284 | hexdump(stderr, "Got", rtag, tn); | |
285 | hexdump(stderr, "Expected", tag, tn); | |
286 | test1_exit(9); | |
287 | } | |
288 | } | |
0e360199 BL |
289 | } |
290 | ||
0f113f3e MC |
291 | if (encdec <= 0) { |
292 | if ((mode == EVP_CIPH_GCM_MODE) || (mode == EVP_CIPH_OCB_MODE)) { | |
293 | if (!EVP_DecryptInit_ex(ctx, c, NULL, NULL, NULL)) { | |
294 | fprintf(stderr, "DecryptInit failed\n"); | |
295 | ERR_print_errors_fp(stderr); | |
296 | test1_exit(10); | |
297 | } | |
298 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_IVLEN, in, NULL)) { | |
299 | fprintf(stderr, "IV length set failed\n"); | |
300 | ERR_print_errors_fp(stderr); | |
301 | test1_exit(11); | |
302 | } | |
303 | if ((mode == EVP_CIPH_OCB_MODE) && | |
304 | !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_OCB_SET_TAGLEN, tn, NULL)) | |
305 | { | |
306 | fprintf(stderr, "Tag length set failed\n"); | |
307 | ERR_print_errors_fp(stderr); | |
308 | test1_exit(15); | |
309 | } | |
310 | if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) { | |
311 | fprintf(stderr, "Key/IV set failed\n"); | |
312 | ERR_print_errors_fp(stderr); | |
313 | test1_exit(12); | |
314 | } | |
315 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_TAG, tn, (void *)tag)) { | |
316 | fprintf(stderr, "Set tag failed\n"); | |
317 | ERR_print_errors_fp(stderr); | |
318 | test1_exit(14); | |
319 | } | |
320 | if (an && !EVP_DecryptUpdate(ctx, NULL, &outl, aad, an)) { | |
321 | fprintf(stderr, "AAD set failed\n"); | |
322 | ERR_print_errors_fp(stderr); | |
323 | test1_exit(13); | |
324 | } | |
325 | } else if (mode == EVP_CIPH_CCM_MODE) { | |
326 | if (!EVP_DecryptInit_ex(ctx, c, NULL, NULL, NULL)) { | |
327 | fprintf(stderr, "DecryptInit failed\n"); | |
328 | ERR_print_errors_fp(stderr); | |
329 | test1_exit(10); | |
330 | } | |
331 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { | |
332 | fprintf(stderr, "IV length set failed\n"); | |
333 | ERR_print_errors_fp(stderr); | |
334 | test1_exit(11); | |
335 | } | |
336 | if (!EVP_CIPHER_CTX_ctrl | |
337 | (ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) { | |
338 | fprintf(stderr, "Tag length set failed\n"); | |
339 | ERR_print_errors_fp(stderr); | |
340 | test1_exit(11); | |
341 | } | |
342 | if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) { | |
343 | fprintf(stderr, "Key/Nonce set failed\n"); | |
344 | ERR_print_errors_fp(stderr); | |
345 | test1_exit(12); | |
346 | } | |
347 | if (!EVP_DecryptUpdate(ctx, NULL, &outl, NULL, pn)) { | |
348 | fprintf(stderr, "Plaintext length set failed\n"); | |
349 | ERR_print_errors_fp(stderr); | |
350 | test1_exit(12); | |
351 | } | |
352 | if (an && !EVP_EncryptUpdate(ctx, NULL, &outl, aad, an)) { | |
353 | fprintf(stderr, "AAD set failed\n"); | |
354 | ERR_print_errors_fp(stderr); | |
355 | test1_exit(13); | |
356 | } | |
357 | } else if (mode == EVP_CIPH_WRAP_MODE) { | |
358 | if (!EVP_DecryptInit_ex(ctx, c, NULL, key, in ? iv : NULL)) { | |
359 | fprintf(stderr, "EncryptInit failed\n"); | |
360 | ERR_print_errors_fp(stderr); | |
361 | test1_exit(10); | |
362 | } | |
363 | } else if (!EVP_DecryptInit_ex(ctx, c, NULL, key, iv)) { | |
364 | fprintf(stderr, "DecryptInit failed\n"); | |
365 | ERR_print_errors_fp(stderr); | |
366 | test1_exit(11); | |
367 | } | |
368 | EVP_CIPHER_CTX_set_padding(ctx, 0); | |
369 | ||
370 | test_ctx_replace(&ctx); | |
371 | ||
372 | if (!EVP_DecryptUpdate(ctx, out, &outl, ciphertext, cn)) { | |
373 | fprintf(stderr, "Decrypt failed\n"); | |
374 | ERR_print_errors_fp(stderr); | |
375 | test1_exit(6); | |
376 | } | |
377 | if (mode != EVP_CIPH_CCM_MODE | |
378 | && !EVP_DecryptFinal_ex(ctx, out + outl, &outl2)) { | |
379 | fprintf(stderr, "DecryptFinal failed\n"); | |
380 | ERR_print_errors_fp(stderr); | |
381 | test1_exit(7); | |
382 | } | |
383 | ||
384 | if (outl + outl2 != pn) { | |
385 | fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", | |
386 | outl + outl2, pn); | |
387 | test1_exit(8); | |
388 | } | |
389 | ||
390 | if (memcmp(out, plaintext, pn)) { | |
391 | fprintf(stderr, "Plaintext mismatch\n"); | |
392 | hexdump(stderr, "Got", out, pn); | |
393 | hexdump(stderr, "Expected", plaintext, pn); | |
394 | test1_exit(9); | |
395 | } | |
396 | } | |
397 | ||
398 | EVP_CIPHER_CTX_free(ctx); | |
399 | ||
400 | printf("\n"); | |
401 | } | |
402 | ||
403 | static int test_cipher(const char *cipher, const unsigned char *key, int kn, | |
404 | const unsigned char *iv, int in, | |
405 | const unsigned char *plaintext, int pn, | |
406 | const unsigned char *ciphertext, int cn, | |
407 | const unsigned char *aad, int an, | |
408 | const unsigned char *tag, int tn, int encdec) | |
409 | { | |
4897dc40 | 410 | const EVP_CIPHER *c; |
4897dc40 | 411 | |
3feb6305 | 412 | #ifdef OPENSSL_NO_OCB |
0f113f3e MC |
413 | if (strstr(cipher, "ocb") != NULL) |
414 | return 1; | |
3feb6305 | 415 | #endif |
0f113f3e MC |
416 | c = EVP_get_cipherbyname(cipher); |
417 | if (!c) | |
418 | return 0; | |
4897dc40 | 419 | |
0f113f3e MC |
420 | test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, tag, tn, |
421 | encdec); | |
4897dc40 | 422 | |
4897dc40 | 423 | return 1; |
0f113f3e | 424 | } |
4897dc40 BL |
425 | |
426 | static int test_digest(const char *digest, | |
0f113f3e MC |
427 | const unsigned char *plaintext, int pn, |
428 | const unsigned char *ciphertext, unsigned int cn) | |
429 | { | |
4897dc40 BL |
430 | const EVP_MD *d; |
431 | EVP_MD_CTX ctx; | |
432 | unsigned char md[EVP_MAX_MD_SIZE]; | |
433 | unsigned int mdn; | |
434 | ||
0f113f3e MC |
435 | d = EVP_get_digestbyname(digest); |
436 | if (!d) | |
437 | return 0; | |
4897dc40 | 438 | |
0f113f3e MC |
439 | printf("Testing digest %s\n", EVP_MD_name(d)); |
440 | hexdump(stdout, "Plaintext", plaintext, pn); | |
441 | hexdump(stdout, "Digest", ciphertext, cn); | |
4897dc40 BL |
442 | |
443 | EVP_MD_CTX_init(&ctx); | |
0f113f3e MC |
444 | if (!EVP_DigestInit_ex(&ctx, d, NULL)) { |
445 | fprintf(stderr, "DigestInit failed\n"); | |
446 | ERR_print_errors_fp(stderr); | |
447 | EXIT(100); | |
448 | } | |
449 | if (!EVP_DigestUpdate(&ctx, plaintext, pn)) { | |
450 | fprintf(stderr, "DigestUpdate failed\n"); | |
451 | ERR_print_errors_fp(stderr); | |
452 | EXIT(101); | |
453 | } | |
454 | if (!EVP_DigestFinal_ex(&ctx, md, &mdn)) { | |
455 | fprintf(stderr, "DigestFinal failed\n"); | |
456 | ERR_print_errors_fp(stderr); | |
457 | EXIT(101); | |
458 | } | |
997a54c9 | 459 | EVP_MD_CTX_cleanup(&ctx); |
4897dc40 | 460 | |
0f113f3e MC |
461 | if (mdn != cn) { |
462 | fprintf(stderr, "Digest length mismatch, got %d expected %d\n", mdn, | |
463 | cn); | |
464 | EXIT(102); | |
465 | } | |
4897dc40 | 466 | |
0f113f3e MC |
467 | if (memcmp(md, ciphertext, cn)) { |
468 | fprintf(stderr, "Digest mismatch\n"); | |
469 | hexdump(stderr, "Got", md, cn); | |
470 | hexdump(stderr, "Expected", ciphertext, cn); | |
471 | EXIT(103); | |
472 | } | |
4897dc40 BL |
473 | |
474 | printf("\n"); | |
475 | ||
544a2aea DSH |
476 | EVP_MD_CTX_cleanup(&ctx); |
477 | ||
4897dc40 | 478 | return 1; |
0f113f3e | 479 | } |
4897dc40 | 480 | |
0f113f3e MC |
481 | int main(int argc, char **argv) |
482 | { | |
0e360199 BL |
483 | const char *szTestFile; |
484 | FILE *f; | |
485 | ||
0f113f3e MC |
486 | if (argc != 2) { |
487 | fprintf(stderr, "%s <test file>\n", argv[0]); | |
488 | EXIT(1); | |
489 | } | |
997a54c9 GT |
490 | CRYPTO_malloc_debug_init(); |
491 | CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); | |
492 | CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); | |
0e360199 | 493 | |
0f113f3e | 494 | szTestFile = argv[1]; |
0e360199 | 495 | |
0f113f3e MC |
496 | f = fopen(szTestFile, "r"); |
497 | if (!f) { | |
498 | perror(szTestFile); | |
499 | EXIT(2); | |
500 | } | |
97cf1f6c | 501 | ERR_load_crypto_strings(); |
cb78486d | 502 | /* Load up the software EVP_CIPHER and EVP_MD definitions */ |
0e360199 | 503 | OpenSSL_add_all_ciphers(); |
4897dc40 | 504 | OpenSSL_add_all_digests(); |
0b13e9f0 | 505 | #ifndef OPENSSL_NO_ENGINE |
cb78486d | 506 | /* Load all compiled-in ENGINEs */ |
0e360199 | 507 | ENGINE_load_builtin_engines(); |
0b13e9f0 | 508 | #endif |
6cc37003 | 509 | #if 0 |
9dd5ae65 | 510 | OPENSSL_config(); |
6cc37003 | 511 | #endif |
0b13e9f0 | 512 | #ifndef OPENSSL_NO_ENGINE |
0f113f3e MC |
513 | /* |
514 | * Register all available ENGINE implementations of ciphers and digests. | |
515 | * This could perhaps be changed to "ENGINE_register_all_complete()"? | |
516 | */ | |
11a57c7b GT |
517 | ENGINE_register_all_ciphers(); |
518 | ENGINE_register_all_digests(); | |
0f113f3e MC |
519 | /* |
520 | * If we add command-line options, this statement should be switchable. | |
521 | * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use | |
522 | * if they weren't already initialised. | |
523 | */ | |
11a57c7b | 524 | /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ |
0b13e9f0 | 525 | #endif |
0e360199 | 526 | |
0f113f3e MC |
527 | for (;;) { |
528 | char line[4096]; | |
529 | char *p; | |
530 | char *cipher; | |
531 | unsigned char *iv, *key, *plaintext, *ciphertext, *aad, *tag; | |
532 | int encdec; | |
533 | int kn, in, pn, cn; | |
534 | int an = 0; | |
535 | int tn = 0; | |
536 | ||
537 | if (!fgets((char *)line, sizeof line, f)) | |
538 | break; | |
539 | if (line[0] == '#' || line[0] == '\n') | |
540 | continue; | |
541 | p = line; | |
542 | cipher = sstrsep(&p, ":"); | |
543 | key = ustrsep(&p, ":"); | |
544 | iv = ustrsep(&p, ":"); | |
545 | plaintext = ustrsep(&p, ":"); | |
546 | ciphertext = ustrsep(&p, ":"); | |
547 | if (p[-1] == '\n') { | |
548 | encdec = -1; | |
549 | p[-1] = '\0'; | |
550 | tag = aad = NULL; | |
551 | an = tn = 0; | |
552 | } else { | |
553 | aad = ustrsep(&p, ":"); | |
554 | tag = ustrsep(&p, ":"); | |
555 | if (tag == NULL) { | |
556 | p = (char *)aad; | |
557 | tag = aad = NULL; | |
558 | an = tn = 0; | |
559 | } | |
560 | if (p[-1] == '\n') { | |
561 | encdec = -1; | |
562 | p[-1] = '\0'; | |
563 | } else | |
564 | encdec = atoi(sstrsep(&p, "\n")); | |
565 | } | |
566 | ||
567 | kn = convert(key); | |
568 | in = convert(iv); | |
569 | pn = convert(plaintext); | |
570 | cn = convert(ciphertext); | |
571 | if (aad) { | |
572 | an = convert(aad); | |
573 | tn = convert(tag); | |
574 | } | |
575 | ||
576 | if (!test_cipher | |
577 | (cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, | |
578 | tag, tn, encdec) | |
579 | && !test_digest(cipher, plaintext, pn, ciphertext, cn)) { | |
63d74075 | 580 | #ifdef OPENSSL_NO_AES |
0f113f3e MC |
581 | if (strstr(cipher, "AES") == cipher) { |
582 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
583 | continue; | |
584 | } | |
63d74075 NL |
585 | #endif |
586 | #ifdef OPENSSL_NO_DES | |
0f113f3e MC |
587 | if (strstr(cipher, "DES") == cipher) { |
588 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
589 | continue; | |
590 | } | |
63d74075 NL |
591 | #endif |
592 | #ifdef OPENSSL_NO_RC4 | |
0f113f3e MC |
593 | if (strstr(cipher, "RC4") == cipher) { |
594 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
595 | continue; | |
596 | } | |
f3dea9a5 BM |
597 | #endif |
598 | #ifdef OPENSSL_NO_CAMELLIA | |
0f113f3e MC |
599 | if (strstr(cipher, "CAMELLIA") == cipher) { |
600 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
601 | continue; | |
602 | } | |
96afc1cf BM |
603 | #endif |
604 | #ifdef OPENSSL_NO_SEED | |
0f113f3e MC |
605 | if (strstr(cipher, "SEED") == cipher) { |
606 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
607 | continue; | |
608 | } | |
63d74075 | 609 | #endif |
0f113f3e MC |
610 | fprintf(stderr, "Can't find %s\n", cipher); |
611 | EXIT(3); | |
612 | } | |
613 | } | |
614 | fclose(f); | |
0e360199 | 615 | |
0b13e9f0 | 616 | #ifndef OPENSSL_NO_ENGINE |
997a54c9 | 617 | ENGINE_cleanup(); |
0b13e9f0 | 618 | #endif |
997a54c9 GT |
619 | EVP_cleanup(); |
620 | CRYPTO_cleanup_all_ex_data(); | |
4c329696 | 621 | ERR_remove_thread_state(NULL); |
997a54c9 GT |
622 | ERR_free_strings(); |
623 | CRYPTO_mem_leaks_fp(stderr); | |
0e360199 BL |
624 | |
625 | return 0; | |
0f113f3e | 626 | } |