]>
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 | |
10 | * notice, this list of conditions and the following disclaimer. | |
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 |
0e360199 | 58 | #include <openssl/engine.h> |
0b13e9f0 RL |
59 | #endif |
60 | #include <openssl/err.h> | |
9dd5ae65 | 61 | #include <openssl/conf.h> |
0e360199 BL |
62 | |
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 | { | |
70 | if((n%16) == 0) | |
71 | fprintf(f,"\n%04x",n); | |
72 | fprintf(f," %02x",s[n]); | |
73 | } | |
74 | fprintf(f,"\n"); | |
75 | } | |
76 | ||
77 | static int convert(unsigned char *s) | |
78 | { | |
79 | unsigned char *d; | |
80 | ||
81 | for(d=s ; *s ; s+=2,++d) | |
82 | { | |
236be532 | 83 | unsigned int n; |
0e360199 BL |
84 | |
85 | if(!s[1]) | |
86 | { | |
87 | fprintf(stderr,"Odd number of hex digits!"); | |
55f78baf | 88 | EXIT(4); |
0e360199 BL |
89 | } |
90 | sscanf((char *)s,"%2x",&n); | |
91 | *d=(unsigned char)n; | |
92 | } | |
93 | return s-d; | |
94 | } | |
95 | ||
5b46eee0 UM |
96 | static char *sstrsep(char **string, const char *delim) |
97 | { | |
98 | char isdelim[256]; | |
99 | char *token = *string; | |
100 | ||
101 | if (**string == 0) | |
102 | return NULL; | |
103 | ||
104 | memset(isdelim, 0, 256); | |
105 | isdelim[0] = 1; | |
106 | ||
107 | while (*delim) | |
108 | { | |
109 | isdelim[(unsigned char)(*delim)] = 1; | |
110 | delim++; | |
111 | } | |
112 | ||
113 | while (!isdelim[(unsigned char)(**string)]) | |
114 | { | |
115 | (*string)++; | |
116 | } | |
117 | ||
118 | if (**string) | |
119 | { | |
120 | **string = 0; | |
121 | (*string)++; | |
122 | } | |
123 | ||
124 | return token; | |
125 | } | |
126 | ||
8716dbea | 127 | static unsigned char *ustrsep(char **p,const char *sep) |
6631a7e7 | 128 | { return (unsigned char *)sstrsep(p,sep); } |
0e360199 | 129 | |
848f735a RL |
130 | static int test1_exit(int ec) |
131 | { | |
132 | EXIT(ec); | |
3dda0dd2 | 133 | return(0); /* To keep some compilers quiet */ |
848f735a RL |
134 | } |
135 | ||
0d263d2a DSH |
136 | /* Test copying of contexts */ |
137 | static void test_ctx_replace(EVP_CIPHER_CTX **pctx) | |
138 | { | |
139 | /* Make copy of context and replace original */ | |
140 | EVP_CIPHER_CTX *ctx_copy; | |
141 | ctx_copy = EVP_CIPHER_CTX_new(); | |
142 | EVP_CIPHER_CTX_copy(ctx_copy, *pctx); | |
143 | EVP_CIPHER_CTX_free(*pctx); | |
144 | *pctx = ctx_copy; | |
145 | } | |
146 | ||
0e360199 BL |
147 | static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn, |
148 | const unsigned char *iv,int in, | |
149 | const unsigned char *plaintext,int pn, | |
e6bd5e8a | 150 | const unsigned char *ciphertext,int cn, |
15652f98 DSH |
151 | const unsigned char *aad,int an, |
152 | const unsigned char *tag,int tn, | |
e6bd5e8a | 153 | int encdec) |
0e360199 | 154 | { |
0d263d2a | 155 | EVP_CIPHER_CTX *ctx = NULL; |
0e360199 | 156 | unsigned char out[4096]; |
15652f98 | 157 | int outl,outl2,mode; |
0e360199 | 158 | |
e6bd5e8a RL |
159 | printf("Testing cipher %s%s\n",EVP_CIPHER_name(c), |
160 | (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); | |
0e360199 BL |
161 | hexdump(stdout,"Key",key,kn); |
162 | if(in) | |
163 | hexdump(stdout,"IV",iv,in); | |
164 | hexdump(stdout,"Plaintext",plaintext,pn); | |
165 | hexdump(stdout,"Ciphertext",ciphertext,cn); | |
15652f98 DSH |
166 | if (an) |
167 | hexdump(stdout,"AAD",aad,an); | |
168 | if (tn) | |
169 | hexdump(stdout,"Tag",tag,tn); | |
170 | mode = EVP_CIPHER_mode(c); | |
171 | if(kn != EVP_CIPHER_key_length(c)) | |
0e360199 | 172 | { |
70d71f61 | 173 | fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn, |
15652f98 | 174 | (unsigned long)EVP_CIPHER_key_length(c)); |
848f735a | 175 | test1_exit(5); |
0e360199 | 176 | } |
0d263d2a DSH |
177 | ctx = EVP_CIPHER_CTX_new(); |
178 | EVP_CIPHER_CTX_set_flags(ctx,EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); | |
e6bd5e8a RL |
179 | if (encdec != 0) |
180 | { | |
d827c5ed | 181 | if ((mode == EVP_CIPH_GCM_MODE) || (mode == EVP_CIPH_OCB_MODE)) |
15652f98 | 182 | { |
0d263d2a | 183 | if(!EVP_EncryptInit_ex(ctx,c,NULL,NULL,NULL)) |
15652f98 DSH |
184 | { |
185 | fprintf(stderr,"EncryptInit failed\n"); | |
186 | ERR_print_errors_fp(stderr); | |
187 | test1_exit(10); | |
188 | } | |
d827c5ed | 189 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_IVLEN, in, NULL)) |
15652f98 DSH |
190 | { |
191 | fprintf(stderr,"IV length set failed\n"); | |
192 | ERR_print_errors_fp(stderr); | |
193 | test1_exit(11); | |
194 | } | |
d827c5ed MC |
195 | if((mode == EVP_CIPH_OCB_MODE) && |
196 | !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_OCB_SET_TAGLEN, tn, NULL)) | |
197 | { | |
198 | fprintf(stderr,"Tag length set failed\n"); | |
199 | ERR_print_errors_fp(stderr); | |
200 | test1_exit(15); | |
201 | } | |
0d263d2a | 202 | if(!EVP_EncryptInit_ex(ctx,NULL,NULL,key,iv)) |
15652f98 DSH |
203 | { |
204 | fprintf(stderr,"Key/IV set failed\n"); | |
205 | ERR_print_errors_fp(stderr); | |
206 | test1_exit(12); | |
207 | } | |
0d263d2a | 208 | if (an && !EVP_EncryptUpdate(ctx,NULL,&outl,aad,an)) |
15652f98 DSH |
209 | { |
210 | fprintf(stderr,"AAD set failed\n"); | |
211 | ERR_print_errors_fp(stderr); | |
212 | test1_exit(13); | |
213 | } | |
214 | } | |
215 | else if (mode == EVP_CIPH_CCM_MODE) | |
216 | { | |
0d263d2a | 217 | if(!EVP_EncryptInit_ex(ctx,c,NULL,NULL,NULL)) |
15652f98 DSH |
218 | { |
219 | fprintf(stderr,"EncryptInit failed\n"); | |
220 | ERR_print_errors_fp(stderr); | |
221 | test1_exit(10); | |
222 | } | |
0d263d2a | 223 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) |
15652f98 DSH |
224 | { |
225 | fprintf(stderr,"IV length set failed\n"); | |
226 | ERR_print_errors_fp(stderr); | |
227 | test1_exit(11); | |
228 | } | |
0d263d2a | 229 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) |
15652f98 DSH |
230 | { |
231 | fprintf(stderr,"Tag length set failed\n"); | |
232 | ERR_print_errors_fp(stderr); | |
233 | test1_exit(11); | |
234 | } | |
0d263d2a | 235 | if(!EVP_EncryptInit_ex(ctx,NULL,NULL,key,iv)) |
15652f98 DSH |
236 | { |
237 | fprintf(stderr,"Key/IV set failed\n"); | |
238 | ERR_print_errors_fp(stderr); | |
239 | test1_exit(12); | |
240 | } | |
0d263d2a | 241 | if (!EVP_EncryptUpdate(ctx,NULL,&outl,NULL,pn)) |
15652f98 DSH |
242 | { |
243 | fprintf(stderr,"Plaintext length set failed\n"); | |
244 | ERR_print_errors_fp(stderr); | |
245 | test1_exit(12); | |
246 | } | |
0d263d2a | 247 | if (an && !EVP_EncryptUpdate(ctx,NULL,&outl,aad,an)) |
15652f98 DSH |
248 | { |
249 | fprintf(stderr,"AAD set failed\n"); | |
250 | ERR_print_errors_fp(stderr); | |
251 | test1_exit(13); | |
252 | } | |
253 | } | |
97cf1f6c DSH |
254 | else if (mode == EVP_CIPH_WRAP_MODE) |
255 | { | |
0d263d2a | 256 | if(!EVP_EncryptInit_ex(ctx,c,NULL,key,in ? iv : NULL)) |
97cf1f6c DSH |
257 | { |
258 | fprintf(stderr,"EncryptInit failed\n"); | |
259 | ERR_print_errors_fp(stderr); | |
260 | test1_exit(10); | |
261 | } | |
262 | } | |
0d263d2a | 263 | else if(!EVP_EncryptInit_ex(ctx,c,NULL,key,iv)) |
e6bd5e8a RL |
264 | { |
265 | fprintf(stderr,"EncryptInit failed\n"); | |
5906e8d5 | 266 | ERR_print_errors_fp(stderr); |
848f735a | 267 | test1_exit(10); |
e6bd5e8a | 268 | } |
0d263d2a | 269 | EVP_CIPHER_CTX_set_padding(ctx,0); |
0e360199 | 270 | |
0d263d2a DSH |
271 | test_ctx_replace(&ctx); |
272 | ||
273 | if(!EVP_EncryptUpdate(ctx,out,&outl,plaintext,pn)) | |
e6bd5e8a RL |
274 | { |
275 | fprintf(stderr,"Encrypt failed\n"); | |
5906e8d5 | 276 | ERR_print_errors_fp(stderr); |
848f735a | 277 | test1_exit(6); |
e6bd5e8a | 278 | } |
0d263d2a | 279 | if(!EVP_EncryptFinal_ex(ctx,out+outl,&outl2)) |
e6bd5e8a RL |
280 | { |
281 | fprintf(stderr,"EncryptFinal failed\n"); | |
5906e8d5 | 282 | ERR_print_errors_fp(stderr); |
848f735a | 283 | test1_exit(7); |
e6bd5e8a | 284 | } |
0e360199 | 285 | |
e6bd5e8a RL |
286 | if(outl+outl2 != cn) |
287 | { | |
288 | fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n", | |
289 | outl+outl2,cn); | |
848f735a | 290 | test1_exit(8); |
e6bd5e8a | 291 | } |
0e360199 | 292 | |
e6bd5e8a RL |
293 | if(memcmp(out,ciphertext,cn)) |
294 | { | |
295 | fprintf(stderr,"Ciphertext mismatch\n"); | |
296 | hexdump(stderr,"Got",out,cn); | |
297 | hexdump(stderr,"Expected",ciphertext,cn); | |
848f735a | 298 | test1_exit(9); |
e6bd5e8a | 299 | } |
d827c5ed MC |
300 | if ((mode == EVP_CIPH_GCM_MODE) || (mode == EVP_CIPH_OCB_MODE) |
301 | || (mode == EVP_CIPH_CCM_MODE)) | |
15652f98 DSH |
302 | { |
303 | unsigned char rtag[16]; | |
d827c5ed MC |
304 | |
305 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_TAG, tn, rtag)) | |
15652f98 DSH |
306 | { |
307 | fprintf(stderr,"Get tag failed\n"); | |
308 | ERR_print_errors_fp(stderr); | |
309 | test1_exit(14); | |
310 | } | |
311 | if (memcmp(rtag, tag, tn)) | |
312 | { | |
313 | fprintf(stderr,"Tag mismatch\n"); | |
314 | hexdump(stderr,"Got",rtag,tn); | |
315 | hexdump(stderr,"Expected",tag,tn); | |
316 | test1_exit(9); | |
317 | } | |
318 | } | |
0e360199 BL |
319 | } |
320 | ||
e6bd5e8a RL |
321 | if (encdec <= 0) |
322 | { | |
d827c5ed | 323 | if ((mode == EVP_CIPH_GCM_MODE) || (mode == EVP_CIPH_OCB_MODE)) |
15652f98 | 324 | { |
0d263d2a | 325 | if(!EVP_DecryptInit_ex(ctx,c,NULL,NULL,NULL)) |
15652f98 | 326 | { |
d827c5ed | 327 | fprintf(stderr,"DecryptInit failed\n"); |
15652f98 DSH |
328 | ERR_print_errors_fp(stderr); |
329 | test1_exit(10); | |
330 | } | |
d827c5ed | 331 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_IVLEN, in, NULL)) |
15652f98 DSH |
332 | { |
333 | fprintf(stderr,"IV length set failed\n"); | |
334 | ERR_print_errors_fp(stderr); | |
335 | test1_exit(11); | |
336 | } | |
d827c5ed MC |
337 | if((mode == EVP_CIPH_OCB_MODE) && |
338 | !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_OCB_SET_TAGLEN, tn, NULL)) | |
339 | { | |
340 | fprintf(stderr,"Tag length set failed\n"); | |
341 | ERR_print_errors_fp(stderr); | |
342 | test1_exit(15); | |
343 | } | |
0d263d2a | 344 | if(!EVP_DecryptInit_ex(ctx,NULL,NULL,key,iv)) |
15652f98 DSH |
345 | { |
346 | fprintf(stderr,"Key/IV set failed\n"); | |
347 | ERR_print_errors_fp(stderr); | |
348 | test1_exit(12); | |
349 | } | |
d827c5ed | 350 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_TAG, tn, (void *)tag)) |
15652f98 DSH |
351 | { |
352 | fprintf(stderr,"Set tag failed\n"); | |
353 | ERR_print_errors_fp(stderr); | |
354 | test1_exit(14); | |
355 | } | |
0d263d2a | 356 | if (an && !EVP_DecryptUpdate(ctx,NULL,&outl,aad,an)) |
15652f98 DSH |
357 | { |
358 | fprintf(stderr,"AAD set failed\n"); | |
359 | ERR_print_errors_fp(stderr); | |
360 | test1_exit(13); | |
361 | } | |
362 | } | |
363 | else if (mode == EVP_CIPH_CCM_MODE) | |
364 | { | |
0d263d2a | 365 | if(!EVP_DecryptInit_ex(ctx,c,NULL,NULL,NULL)) |
15652f98 DSH |
366 | { |
367 | fprintf(stderr,"DecryptInit failed\n"); | |
368 | ERR_print_errors_fp(stderr); | |
369 | test1_exit(10); | |
370 | } | |
0d263d2a | 371 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) |
15652f98 DSH |
372 | { |
373 | fprintf(stderr,"IV length set failed\n"); | |
374 | ERR_print_errors_fp(stderr); | |
375 | test1_exit(11); | |
376 | } | |
0d263d2a | 377 | if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) |
15652f98 DSH |
378 | { |
379 | fprintf(stderr,"Tag length set failed\n"); | |
380 | ERR_print_errors_fp(stderr); | |
381 | test1_exit(11); | |
382 | } | |
0d263d2a | 383 | if(!EVP_DecryptInit_ex(ctx,NULL,NULL,key,iv)) |
15652f98 DSH |
384 | { |
385 | fprintf(stderr,"Key/Nonce set failed\n"); | |
386 | ERR_print_errors_fp(stderr); | |
387 | test1_exit(12); | |
388 | } | |
0d263d2a | 389 | if (!EVP_DecryptUpdate(ctx,NULL,&outl,NULL,pn)) |
15652f98 DSH |
390 | { |
391 | fprintf(stderr,"Plaintext length set failed\n"); | |
392 | ERR_print_errors_fp(stderr); | |
393 | test1_exit(12); | |
394 | } | |
0d263d2a | 395 | if (an && !EVP_EncryptUpdate(ctx,NULL,&outl,aad,an)) |
15652f98 DSH |
396 | { |
397 | fprintf(stderr,"AAD set failed\n"); | |
398 | ERR_print_errors_fp(stderr); | |
399 | test1_exit(13); | |
400 | } | |
401 | } | |
97cf1f6c DSH |
402 | else if (mode == EVP_CIPH_WRAP_MODE) |
403 | { | |
0d263d2a | 404 | if(!EVP_DecryptInit_ex(ctx,c,NULL,key,in ? iv : NULL)) |
97cf1f6c DSH |
405 | { |
406 | fprintf(stderr,"EncryptInit failed\n"); | |
407 | ERR_print_errors_fp(stderr); | |
408 | test1_exit(10); | |
409 | } | |
410 | } | |
0d263d2a | 411 | else if(!EVP_DecryptInit_ex(ctx,c,NULL,key,iv)) |
e6bd5e8a RL |
412 | { |
413 | fprintf(stderr,"DecryptInit failed\n"); | |
5906e8d5 | 414 | ERR_print_errors_fp(stderr); |
848f735a | 415 | test1_exit(11); |
e6bd5e8a | 416 | } |
0d263d2a DSH |
417 | EVP_CIPHER_CTX_set_padding(ctx,0); |
418 | ||
419 | test_ctx_replace(&ctx); | |
0e360199 | 420 | |
0d263d2a | 421 | if(!EVP_DecryptUpdate(ctx,out,&outl,ciphertext,cn)) |
e6bd5e8a RL |
422 | { |
423 | fprintf(stderr,"Decrypt failed\n"); | |
5906e8d5 | 424 | ERR_print_errors_fp(stderr); |
848f735a | 425 | test1_exit(6); |
e6bd5e8a | 426 | } |
0d263d2a | 427 | if(mode != EVP_CIPH_CCM_MODE && !EVP_DecryptFinal_ex(ctx,out+outl,&outl2)) |
e6bd5e8a RL |
428 | { |
429 | fprintf(stderr,"DecryptFinal failed\n"); | |
5906e8d5 | 430 | ERR_print_errors_fp(stderr); |
848f735a | 431 | test1_exit(7); |
e6bd5e8a | 432 | } |
0e360199 | 433 | |
2121f15d | 434 | if(outl+outl2 != pn) |
e6bd5e8a RL |
435 | { |
436 | fprintf(stderr,"Plaintext length mismatch got %d expected %d\n", | |
2121f15d | 437 | outl+outl2,pn); |
848f735a | 438 | test1_exit(8); |
e6bd5e8a | 439 | } |
0e360199 | 440 | |
2121f15d | 441 | if(memcmp(out,plaintext,pn)) |
e6bd5e8a RL |
442 | { |
443 | fprintf(stderr,"Plaintext mismatch\n"); | |
2121f15d BL |
444 | hexdump(stderr,"Got",out,pn); |
445 | hexdump(stderr,"Expected",plaintext,pn); | |
848f735a | 446 | test1_exit(9); |
e6bd5e8a | 447 | } |
0e360199 BL |
448 | } |
449 | ||
0d263d2a | 450 | EVP_CIPHER_CTX_free(ctx); |
544a2aea | 451 | |
0e360199 BL |
452 | printf("\n"); |
453 | } | |
454 | ||
4897dc40 BL |
455 | static int test_cipher(const char *cipher,const unsigned char *key,int kn, |
456 | const unsigned char *iv,int in, | |
457 | const unsigned char *plaintext,int pn, | |
e6bd5e8a | 458 | const unsigned char *ciphertext,int cn, |
15652f98 DSH |
459 | const unsigned char *aad,int an, |
460 | const unsigned char *tag,int tn, | |
e6bd5e8a | 461 | int encdec) |
4897dc40 BL |
462 | { |
463 | const EVP_CIPHER *c; | |
4897dc40 | 464 | |
3feb6305 MC |
465 | #ifdef OPENSSL_NO_OCB |
466 | if(strstr(cipher, "ocb") != NULL) | |
467 | return 1; | |
468 | #endif | |
4897dc40 BL |
469 | c=EVP_get_cipherbyname(cipher); |
470 | if(!c) | |
471 | return 0; | |
472 | ||
15652f98 | 473 | test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,aad,an,tag,tn,encdec); |
4897dc40 | 474 | |
4897dc40 BL |
475 | return 1; |
476 | } | |
477 | ||
478 | static int test_digest(const char *digest, | |
479 | const unsigned char *plaintext,int pn, | |
b83eddc5 | 480 | const unsigned char *ciphertext, unsigned int cn) |
4897dc40 BL |
481 | { |
482 | const EVP_MD *d; | |
483 | EVP_MD_CTX ctx; | |
484 | unsigned char md[EVP_MAX_MD_SIZE]; | |
485 | unsigned int mdn; | |
486 | ||
487 | d=EVP_get_digestbyname(digest); | |
488 | if(!d) | |
489 | return 0; | |
490 | ||
491 | printf("Testing digest %s\n",EVP_MD_name(d)); | |
492 | hexdump(stdout,"Plaintext",plaintext,pn); | |
493 | hexdump(stdout,"Digest",ciphertext,cn); | |
494 | ||
495 | EVP_MD_CTX_init(&ctx); | |
20d2186c | 496 | if(!EVP_DigestInit_ex(&ctx,d, NULL)) |
4897dc40 BL |
497 | { |
498 | fprintf(stderr,"DigestInit failed\n"); | |
5906e8d5 | 499 | ERR_print_errors_fp(stderr); |
55f78baf | 500 | EXIT(100); |
4897dc40 BL |
501 | } |
502 | if(!EVP_DigestUpdate(&ctx,plaintext,pn)) | |
503 | { | |
504 | fprintf(stderr,"DigestUpdate failed\n"); | |
5906e8d5 | 505 | ERR_print_errors_fp(stderr); |
55f78baf | 506 | EXIT(101); |
4897dc40 | 507 | } |
20d2186c | 508 | if(!EVP_DigestFinal_ex(&ctx,md,&mdn)) |
4897dc40 | 509 | { |
997a54c9 | 510 | fprintf(stderr,"DigestFinal failed\n"); |
5906e8d5 | 511 | ERR_print_errors_fp(stderr); |
55f78baf | 512 | EXIT(101); |
4897dc40 | 513 | } |
997a54c9 | 514 | EVP_MD_CTX_cleanup(&ctx); |
4897dc40 BL |
515 | |
516 | if(mdn != cn) | |
517 | { | |
518 | fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn); | |
55f78baf | 519 | EXIT(102); |
4897dc40 BL |
520 | } |
521 | ||
522 | if(memcmp(md,ciphertext,cn)) | |
523 | { | |
524 | fprintf(stderr,"Digest mismatch\n"); | |
525 | hexdump(stderr,"Got",md,cn); | |
526 | hexdump(stderr,"Expected",ciphertext,cn); | |
55f78baf | 527 | EXIT(103); |
4897dc40 BL |
528 | } |
529 | ||
530 | printf("\n"); | |
531 | ||
544a2aea DSH |
532 | EVP_MD_CTX_cleanup(&ctx); |
533 | ||
4897dc40 BL |
534 | return 1; |
535 | } | |
536 | ||
0e360199 BL |
537 | int main(int argc,char **argv) |
538 | { | |
539 | const char *szTestFile; | |
540 | FILE *f; | |
541 | ||
542 | if(argc != 2) | |
543 | { | |
544 | fprintf(stderr,"%s <test file>\n",argv[0]); | |
55f78baf | 545 | EXIT(1); |
0e360199 | 546 | } |
997a54c9 GT |
547 | CRYPTO_malloc_debug_init(); |
548 | CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); | |
549 | CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); | |
0e360199 BL |
550 | |
551 | szTestFile=argv[1]; | |
552 | ||
553 | f=fopen(szTestFile,"r"); | |
554 | if(!f) | |
555 | { | |
556 | perror(szTestFile); | |
55f78baf | 557 | EXIT(2); |
0e360199 | 558 | } |
97cf1f6c | 559 | ERR_load_crypto_strings(); |
cb78486d | 560 | /* Load up the software EVP_CIPHER and EVP_MD definitions */ |
0e360199 | 561 | OpenSSL_add_all_ciphers(); |
4897dc40 | 562 | OpenSSL_add_all_digests(); |
0b13e9f0 | 563 | #ifndef OPENSSL_NO_ENGINE |
cb78486d | 564 | /* Load all compiled-in ENGINEs */ |
0e360199 | 565 | ENGINE_load_builtin_engines(); |
0b13e9f0 | 566 | #endif |
6cc37003 | 567 | #if 0 |
9dd5ae65 | 568 | OPENSSL_config(); |
6cc37003 | 569 | #endif |
0b13e9f0 | 570 | #ifndef OPENSSL_NO_ENGINE |
11a57c7b GT |
571 | /* Register all available ENGINE implementations of ciphers and digests. |
572 | * This could perhaps be changed to "ENGINE_register_all_complete()"? */ | |
573 | ENGINE_register_all_ciphers(); | |
574 | ENGINE_register_all_digests(); | |
575 | /* If we add command-line options, this statement should be switchable. | |
576 | * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if | |
577 | * they weren't already initialised. */ | |
578 | /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ | |
0b13e9f0 | 579 | #endif |
0e360199 BL |
580 | |
581 | for( ; ; ) | |
582 | { | |
a8a00498 | 583 | char line[4096]; |
0e360199 BL |
584 | char *p; |
585 | char *cipher; | |
15652f98 | 586 | unsigned char *iv,*key,*plaintext,*ciphertext,*aad,*tag; |
e6bd5e8a | 587 | int encdec; |
282a480a BL |
588 | int kn,in,pn,cn; |
589 | int an = 0; | |
590 | int tn = 0; | |
0e360199 | 591 | |
a8a00498 | 592 | if(!fgets((char *)line,sizeof line,f)) |
0e360199 | 593 | break; |
a8a00498 | 594 | if(line[0] == '#' || line[0] == '\n') |
0e360199 | 595 | continue; |
a8a00498 | 596 | p=line; |
5b46eee0 | 597 | cipher=sstrsep(&p,":"); |
0e360199 BL |
598 | key=ustrsep(&p,":"); |
599 | iv=ustrsep(&p,":"); | |
600 | plaintext=ustrsep(&p,":"); | |
e6bd5e8a RL |
601 | ciphertext=ustrsep(&p,":"); |
602 | if (p[-1] == '\n') { | |
e6bd5e8a | 603 | encdec = -1; |
15652f98 DSH |
604 | p[-1] = '\0'; |
605 | tag=aad=NULL; | |
606 | an=tn=0; | |
e6bd5e8a | 607 | } else { |
15652f98 DSH |
608 | aad=ustrsep(&p,":"); |
609 | tag=ustrsep(&p,":"); | |
610 | if (tag == NULL) { | |
611 | p = (char *)aad; | |
612 | tag=aad=NULL; | |
613 | an=tn=0; | |
614 | } | |
615 | if (p [-1] == '\n') { | |
616 | encdec = -1; | |
617 | p[-1] = '\0'; | |
618 | } else | |
619 | encdec = atoi(sstrsep(&p,"\n")); | |
e6bd5e8a | 620 | } |
0e360199 | 621 | |
0e360199 BL |
622 | kn=convert(key); |
623 | in=convert(iv); | |
624 | pn=convert(plaintext); | |
625 | cn=convert(ciphertext); | |
15652f98 DSH |
626 | if (aad) { |
627 | an=convert(aad); | |
628 | tn=convert(tag); | |
629 | } | |
0e360199 | 630 | |
15652f98 | 631 | if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,aad,an,tag,tn,encdec) |
4897dc40 | 632 | && !test_digest(cipher,plaintext,pn,ciphertext,cn)) |
0e360199 | 633 | { |
63d74075 NL |
634 | #ifdef OPENSSL_NO_AES |
635 | if (strstr(cipher, "AES") == cipher) | |
636 | { | |
637 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
638 | continue; | |
639 | } | |
640 | #endif | |
641 | #ifdef OPENSSL_NO_DES | |
642 | if (strstr(cipher, "DES") == cipher) | |
643 | { | |
644 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
645 | continue; | |
646 | } | |
647 | #endif | |
648 | #ifdef OPENSSL_NO_RC4 | |
649 | if (strstr(cipher, "RC4") == cipher) | |
650 | { | |
651 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
652 | continue; | |
653 | } | |
f3dea9a5 BM |
654 | #endif |
655 | #ifdef OPENSSL_NO_CAMELLIA | |
656 | if (strstr(cipher, "CAMELLIA") == cipher) | |
657 | { | |
658 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
659 | continue; | |
660 | } | |
96afc1cf BM |
661 | #endif |
662 | #ifdef OPENSSL_NO_SEED | |
663 | if (strstr(cipher, "SEED") == cipher) | |
664 | { | |
665 | fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); | |
666 | continue; | |
667 | } | |
63d74075 | 668 | #endif |
4897dc40 | 669 | fprintf(stderr,"Can't find %s\n",cipher); |
55f78baf | 670 | EXIT(3); |
0e360199 BL |
671 | } |
672 | } | |
d77a9706 | 673 | fclose(f); |
0e360199 | 674 | |
0b13e9f0 | 675 | #ifndef OPENSSL_NO_ENGINE |
997a54c9 | 676 | ENGINE_cleanup(); |
0b13e9f0 | 677 | #endif |
997a54c9 GT |
678 | EVP_cleanup(); |
679 | CRYPTO_cleanup_all_ex_data(); | |
4c329696 | 680 | ERR_remove_thread_state(NULL); |
997a54c9 GT |
681 | ERR_free_strings(); |
682 | CRYPTO_mem_leaks_fp(stderr); | |
0e360199 BL |
683 | |
684 | return 0; | |
685 | } |