1fdc9976190edcdf3aa7e9deca97d52adea626b5
[openssl.git] / crypto / evp / evp_test.c
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>
52 #include <openssl/evp.h>
53 #include <openssl/engine.h>
54
55 static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
56     {
57     int n=0;
58
59     fprintf(f,"%s",title);
60     for( ; n < l ; ++n)
61         {
62         if((n%16) == 0)
63             fprintf(f,"\n%04x",n);
64         fprintf(f," %02x",s[n]);
65         }
66     fprintf(f,"\n");
67     }
68
69 static int convert(unsigned char *s)
70     {
71     unsigned char *d;
72
73     for(d=s ; *s ; s+=2,++d)
74         {
75         int n;
76
77         if(!s[1])
78             {
79             fprintf(stderr,"Odd number of hex digits!");
80             exit(4);
81             }
82         sscanf((char *)s,"%2x",&n);
83         *d=(unsigned char)n;
84         }
85     return s-d;
86     }
87
88 static unsigned char *ustrsep(char **p,const char *sep)
89     { return (unsigned char *)strsep((char **)p,sep); }
90
91 static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
92                   const unsigned char *iv,int in,
93                   const unsigned char *plaintext,int pn,
94                   const unsigned char *ciphertext,int cn)
95     {
96     EVP_CIPHER_CTX ctx;
97     unsigned char out[4096];
98     int outl,outl2;
99
100     printf("Testing cipher %s\n",EVP_CIPHER_name(c));
101     hexdump(stdout,"Key",key,kn);
102     if(in)
103         hexdump(stdout,"IV",iv,in);
104     hexdump(stdout,"Plaintext",plaintext,pn);
105     hexdump(stdout,"Ciphertext",ciphertext,cn);
106     
107     if(kn != c->key_len)
108         {
109         fprintf(stderr,"Key length doesn't match, got %d expected %d\n",kn,
110                 c->key_len);
111         exit(5);
112         }
113
114     if(!EVP_EncryptInit(&ctx,c,key,iv))
115         {
116         fprintf(stderr,"EncryptInit failed\n");
117         exit(10);
118         }
119     EVP_CIPHER_CTX_set_padding(&ctx,0);
120
121     if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
122         {
123         fprintf(stderr,"Encrypt failed\n");
124         exit(6);
125         }
126     if(!EVP_EncryptFinal(&ctx,out+outl,&outl2))
127         {
128         fprintf(stderr,"EncryptFinal failed\n");
129         exit(7);
130         }
131
132     if(outl+outl2 != cn)
133         {
134         fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
135                 outl+outl2,cn);
136         exit(8);
137         }
138
139     if(memcmp(out,ciphertext,cn))
140         {
141         fprintf(stderr,"Ciphertext mismatch\n");
142         hexdump(stderr,"Got",out,cn);
143         hexdump(stderr,"Expected",ciphertext,cn);
144         exit(9);
145         }
146
147     if(!EVP_DecryptInit(&ctx,c,key,iv))
148         {
149         fprintf(stderr,"DecryptInit failed\n");
150         exit(11);
151         }
152     EVP_CIPHER_CTX_set_padding(&ctx,0);
153
154     if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,pn))
155         {
156         fprintf(stderr,"Decrypt failed\n");
157         exit(6);
158         }
159     if(!EVP_DecryptFinal(&ctx,out+outl,&outl2))
160         {
161         fprintf(stderr,"DecryptFinal failed\n");
162         exit(7);
163         }
164
165     if(outl+outl2 != cn)
166         {
167         fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
168                 outl+outl2,cn);
169         exit(8);
170         }
171
172     if(memcmp(out,plaintext,cn))
173         {
174         fprintf(stderr,"Plaintext mismatch\n");
175         hexdump(stderr,"Got",out,cn);
176         hexdump(stderr,"Expected",plaintext,cn);
177         exit(9);
178         }
179
180     printf("\n");
181     }
182
183 static int test_cipher(const char *cipher,const unsigned char *key,int kn,
184                        const unsigned char *iv,int in,
185                        const unsigned char *plaintext,int pn,
186                        const unsigned char *ciphertext,int cn)
187     {
188     const EVP_CIPHER *c;
189     ENGINE *e;
190
191     c=EVP_get_cipherbyname(cipher);
192     if(!c)
193         return 0;
194
195     test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn);
196
197     for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
198         {
199         c=ENGINE_get_cipher_by_name(e,cipher);
200         if(!c)
201             continue;
202         printf("Testing engine %s\n",ENGINE_get_name(e));
203
204         test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn);
205         }
206
207     return 1;
208     }
209
210 static int test_digest(const char *digest,
211                        const unsigned char *plaintext,int pn,
212                        const unsigned char *ciphertext, int cn)
213     {
214     const EVP_MD *d;
215     EVP_MD_CTX ctx;
216     unsigned char md[EVP_MAX_MD_SIZE];
217     unsigned int mdn;
218
219     d=EVP_get_digestbyname(digest);
220     if(!d)
221         return 0;
222
223     printf("Testing digest %s\n",EVP_MD_name(d));
224     hexdump(stdout,"Plaintext",plaintext,pn);
225     hexdump(stdout,"Digest",ciphertext,cn);
226
227     EVP_MD_CTX_init(&ctx);
228     if(!EVP_DigestInit(&ctx,d))
229         {
230         fprintf(stderr,"DigestInit failed\n");
231         exit(100);
232         }
233     if(!EVP_DigestUpdate(&ctx,plaintext,pn))
234         {
235         fprintf(stderr,"DigestUpdate failed\n");
236         exit(101);
237         }
238     if(!EVP_DigestFinal(&ctx,md,&mdn))
239         {
240         fprintf(stderr,"DigestUpdate failed\n");
241         exit(101);
242         }
243
244     if(mdn != cn)
245         {
246         fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn);
247         exit(102);
248         }
249
250     if(memcmp(md,ciphertext,cn))
251         {
252         fprintf(stderr,"Digest mismatch\n");
253         hexdump(stderr,"Got",md,cn);
254         hexdump(stderr,"Expected",ciphertext,cn);
255         exit(103);
256         }
257
258     printf("\n");
259
260     return 1;
261     }
262
263 int main(int argc,char **argv)
264     {
265     const char *szTestFile;
266     FILE *f;
267
268     if(argc != 2)
269         {
270         fprintf(stderr,"%s <test file>\n",argv[0]);
271         exit(1);
272         }
273
274     szTestFile=argv[1];
275
276     f=fopen(szTestFile,"r");
277     if(!f)
278         {
279         perror(szTestFile);
280         exit(2);
281         }
282
283     OpenSSL_add_all_ciphers();
284     OpenSSL_add_all_digests();
285     ENGINE_load_builtin_engines();
286
287     for( ; ; )
288         {
289         char line[4096];
290         char *p;
291         char *cipher;
292         unsigned char *iv,*key,*plaintext,*ciphertext;
293         int kn,in,pn,cn;
294
295         if(!fgets((char *)line,sizeof line,f))
296             break;
297         if(line[0] == '#' || line[0] == '\n')
298             continue;
299         p=line;
300         cipher=strsep(&p,":");  
301         key=ustrsep(&p,":");
302         iv=ustrsep(&p,":");
303         plaintext=ustrsep(&p,":");
304         ciphertext=ustrsep(&p,"\n");
305
306         kn=convert(key);
307         in=convert(iv);
308         pn=convert(plaintext);
309         cn=convert(ciphertext);
310
311         if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn)
312            && !test_digest(cipher,plaintext,pn,ciphertext,cn))
313             {
314             fprintf(stderr,"Can't find %s\n",cipher);
315             exit(3);
316             }
317         }
318
319
320     return 0;
321     }