Initial version of new evp_test program.
[openssl.git] / crypto / evp / evp_test.c
1 /* evp_test.c */
2 /*
3  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4  * project.
5  */
6 /* ====================================================================
7  * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  */
54
55 #include <stdio.h>
56 #include <string.h>
57 #include <stdlib.h>
58 #include <ctype.h>
59 #include <openssl/evp.h>
60 #include <openssl/err.h>
61 #include <openssl/x509v3.h>
62
63 /* Remove spaces from beginning and end of a string */
64
65 static void remove_space(char **pval)
66 {
67     unsigned char *p = (unsigned char *)*pval;
68
69     while (isspace(*p))
70         p++;
71
72     *pval = (char *)p;
73
74     p = p + strlen(*pval) - 1;
75
76     /* Remove trailing space */
77     while (isspace(*p))
78         *p-- = 0;
79 }
80
81 /*
82  * Given a line of the form:
83  *      name = value # comment
84  * extract name and value. NB: modifies passed buffer.
85  */
86
87 static int parse_line(char **pkw, char **pval, char *linebuf)
88 {
89     char *p;
90
91     p = linebuf + strlen(linebuf) - 1;
92
93     if (*p != '\n') {
94         fprintf(stderr, "FATAL: missing EOL\n");
95         exit(1);
96     }
97
98     /* Look for # */
99
100     p = strchr(linebuf, '#');
101
102     if (p)
103         *p = '\0';
104
105     /* Look for = sign */
106     p = strchr(linebuf, '=');
107
108     /* If no '=' exit */
109     if (!p)
110         return 0;
111
112     *p++ = '\0';
113
114     *pkw = linebuf;
115     *pval = p;
116
117     /* Remove spaces from keyword and value */
118     remove_space(pkw);
119     remove_space(pval);
120
121     return 1;
122 }
123
124 /* For a hex string "value" convert to a binary allocated buffer */
125 static int test_bin(const char *value, unsigned char **buf, size_t *buflen)
126 {
127     long len;
128     if (!*value) {
129         /* Don't return NULL for zero length buffer */
130         *buf = OPENSSL_malloc(1);
131         if (!*buf)
132             return 0;
133         **buf = 0;
134         *buflen = 0;
135         return 1;
136     }
137     *buf = string_to_hex(value, &len);
138     if (!*buf) {
139         fprintf(stderr, "Value=%s\n", value);
140         ERR_print_errors_fp(stderr);
141         return -1;
142     }
143     /* Size of input buffer means we'll never overflow */
144     *buflen = len;
145     return 1;
146 }
147
148 /* Structure holding test information */
149 struct evp_test {
150     /* method for this test */
151     const struct evp_test_method *meth;
152     /* current line being processed */
153     unsigned int line;
154     /* start line of current test */
155     unsigned int start_line;
156     /* Error string for test */
157     const char *err;
158     /* Expected error value of test */
159     char *expected_err;
160     /* Number of tests */
161     int ntests;
162     /* Error count */
163     int errors;
164     /* test specific data */
165     void *data;
166 };
167 /* Test method structure */
168 struct evp_test_method {
169     /* Name of test as it appears in file */
170     const char *name;
171     /* Initialise test for "alg" */
172     int (*init) (struct evp_test * t, const char *alg);
173     /* Clean up method */
174     void (*cleanup) (struct evp_test * t);
175     /* Test specific name value pair processing */
176     int (*parse) (struct evp_test * t, const char *name, const char *value);
177     /* Run the test itself */
178     int (*run_test) (struct evp_test * t);
179 };
180
181 static const struct evp_test_method digest_test_method, cipher_test_method;
182 static const struct evp_test_method aead_test_method;
183
184 static const struct evp_test_method *evp_test_list[] = {
185     &digest_test_method,
186     &cipher_test_method,
187     NULL,
188 };
189
190 static const struct evp_test_method *evp_find_test(const char *name)
191 {
192     const struct evp_test_method **tt;
193     for (tt = evp_test_list; *tt; tt++) {
194         if (!strcmp(name, (*tt)->name))
195             return *tt;
196     }
197     return NULL;
198 }
199
200 static int check_test_error(struct evp_test *t)
201 {
202     if (!t->err && !t->expected_err)
203         return 1;
204     if (t->err && !t->expected_err) {
205         fprintf(stderr, "Test line %d: unexpected error %s\n",
206                 t->start_line, t->err);
207         return 0;
208     }
209     if (!t->err && t->expected_err) {
210         fprintf(stderr, "Test line %d: succeeded expecting %s\n",
211                 t->start_line, t->expected_err);
212         return 0;
213     }
214     if (!strcmp(t->err, t->expected_err))
215         return 1;
216
217     fprintf(stderr, "Test line %d: expecting %s got %s\n",
218             t->start_line, t->expected_err, t->err);
219     return 0;
220 }
221
222 /* Setup a new test, run any existing test */
223
224 static int setup_test(struct evp_test *t, const struct evp_test_method *tmeth)
225 {
226     /* If we already have a test set up run it */
227     if (t->meth) {
228         t->ntests++;
229         t->err = NULL;
230         if (t->meth->run_test(t) != 1) {
231             fprintf(stderr, "%s test error line %d\n",
232                     t->meth->name, t->start_line);
233             return 0;
234         }
235         if (!check_test_error(t)) {
236             if (t->err)
237                 ERR_print_errors_fp(stderr);
238             t->errors++;
239         }
240         ERR_clear_error();
241         t->meth->cleanup(t);
242         /* If new test type free old data */
243         if (tmeth != t->meth && t->data) {
244             OPENSSL_free(t->data);
245             t->data = NULL;
246         }
247         if (t->expected_err) {
248             OPENSSL_free(t->expected_err);
249             t->expected_err = NULL;
250         }
251     }
252     t->meth = tmeth;
253     return 1;
254 }
255
256 static int process_test(struct evp_test *t, char *buf, int verbose)
257 {
258     char *keyword, *value;
259     int rv = 0;
260     const struct evp_test_method *tmeth;
261     if (verbose)
262         fputs(buf, stdout);
263     if (!parse_line(&keyword, &value, buf))
264         return 1;
265     /* See if keyword corresponds to a test start */
266     tmeth = evp_find_test(keyword);
267     if (tmeth) {
268         if (!setup_test(t, tmeth))
269             return 0;
270         t->start_line = t->line;
271         if (!tmeth->init(t, value)) {
272             fprintf(stderr, "Unknown %s: %s\n", keyword, value);
273             return 0;
274         }
275         return 1;
276     } else if (!strcmp(keyword, "Result")) {
277         if (t->expected_err) {
278             fprintf(stderr, "Line %d: multiple result lines\n", t->line);
279             return 0;
280         }
281         t->expected_err = BUF_strdup(value);
282         if (!t->expected_err)
283             return 0;
284     } else {
285         /* Must be test specific line: try to parse it */
286         if (t->meth)
287             rv = t->meth->parse(t, keyword, value);
288
289         if (rv == 0)
290             fprintf(stderr, "line %d: unexpected keyword %s\n",
291                     t->line, keyword);
292
293         if (rv < 0)
294             fprintf(stderr, "line %d: error processing keyword %s\n",
295                     t->line, keyword);
296         if (rv <= 0)
297             return 0;
298     }
299     return 1;
300 }
301
302 int main(int argc, char **argv)
303 {
304     FILE *in = NULL;
305     char buf[10240];
306     struct evp_test t;
307
308     ERR_load_crypto_strings();
309     OpenSSL_add_all_algorithms();
310     t.meth = NULL;
311     t.err = NULL;
312     t.line = 0;
313     t.start_line = -1;
314     t.errors = 0;
315     t.ntests = 0;
316     in = fopen(argv[1], "r");
317     while (fgets(buf, sizeof(buf), in)) {
318         t.line++;
319         if (!process_test(&t, buf, 0))
320             exit(1);
321     }
322     /* Run any final test we have */
323     if (!setup_test(&t, NULL))
324         exit(1);
325     fprintf(stderr, "%d tests completed with %d errors\n",
326             t.ntests, t.errors);
327     fclose(in);
328     return 0;
329 }
330
331 static void test_free(void *d)
332 {
333     if (d)
334         OPENSSL_free(d);
335 }
336
337 /* Message digest tests */
338
339 struct digest_data {
340     /* Digest this test is for */
341     const EVP_MD *digest;
342     /* Input to digest */
343     unsigned char *input;
344     size_t input_len;
345     /* Expected output */
346     unsigned char *output;
347     size_t output_len;
348 };
349
350 static int digest_test_init(struct evp_test *t, const char *alg)
351 {
352     const EVP_MD *digest;
353     struct digest_data *mdat = t->data;
354     digest = EVP_get_digestbyname(alg);
355     if (!digest)
356         return 0;
357     mdat = OPENSSL_malloc(sizeof(struct digest_data));
358     mdat->digest = digest;
359     mdat->input = NULL;
360     mdat->output = NULL;
361     t->data = mdat;
362     return 1;
363 }
364
365 static void digest_test_cleanup(struct evp_test *t)
366 {
367     struct digest_data *mdat = t->data;
368     test_free(mdat->input);
369     test_free(mdat->output);
370 }
371
372 static int digest_test_parse(struct evp_test *t,
373                              const char *keyword, const char *value)
374 {
375     struct digest_data *mdata = t->data;
376     if (!strcmp(keyword, "Input"))
377         return test_bin(value, &mdata->input, &mdata->input_len);
378     if (!strcmp(keyword, "Output"))
379         return test_bin(value, &mdata->output, &mdata->output_len);
380     return 0;
381 }
382
383 static int digest_test_run(struct evp_test *t)
384 {
385     struct digest_data *mdata = t->data;
386     const char *err = "INTERNAL_ERROR";
387     EVP_MD_CTX *mctx;
388     unsigned char md[EVP_MAX_MD_SIZE];
389     unsigned int md_len;
390     mctx = EVP_MD_CTX_create();
391     if (!mctx)
392         goto err;
393     err = "DIGESTINIT_ERROR";
394     if (!EVP_DigestInit_ex(mctx, mdata->digest, NULL))
395         goto err;
396     err = "DIGESTUPDATE_ERROR";
397     if (!EVP_DigestUpdate(mctx, mdata->input, mdata->input_len))
398         goto err;
399     err = "DIGESTFINAL_ERROR";
400     if (!EVP_DigestFinal(mctx, md, &md_len))
401         goto err;
402     err = "DIGEST_LENGTH_MISMATCH";
403     if (md_len != mdata->output_len)
404         goto err;
405     err = "DIGEST_MISMATCH";
406     if (memcmp(mdata->output, md, md_len))
407         goto err;
408     err = NULL;
409  err:
410     if (mctx)
411         EVP_MD_CTX_destroy(mctx);
412     t->err = err;
413     return err ? 0 : 1;
414 }
415
416 static const struct evp_test_method digest_test_method = {
417     "Digest",
418     digest_test_init,
419     digest_test_cleanup,
420     digest_test_parse,
421     digest_test_run
422 };
423
424 /* Cipher tests */
425 struct cipher_data {
426     const EVP_CIPHER *cipher;
427     int enc;
428     /* Set to EVP_CIPH_GCM_MODE or EVP_CIPH_CCM_MODE if AEAD */
429     int aead;
430     unsigned char *key;
431     size_t key_len;
432     unsigned char *iv;
433     size_t iv_len;
434     unsigned char *plaintext;
435     size_t plaintext_len;
436     unsigned char *ciphertext;
437     size_t ciphertext_len;
438     /* GCM, CCM only */
439     unsigned char *aad;
440     size_t aad_len;
441     unsigned char *tag;
442     size_t tag_len;
443 };
444
445 static int cipher_test_init(struct evp_test *t, const char *alg)
446 {
447     const EVP_CIPHER *cipher;
448     struct cipher_data *cdat = t->data;
449     cipher = EVP_get_cipherbyname(alg);
450     if (!cipher)
451         return 0;
452     cdat = OPENSSL_malloc(sizeof(struct cipher_data));
453     cdat->cipher = cipher;
454     cdat->enc = -1;
455     cdat->key = NULL;
456     cdat->iv = NULL;
457     cdat->ciphertext = NULL;
458     cdat->plaintext = NULL;
459     cdat->aad = NULL;
460     cdat->tag = NULL;
461     t->data = cdat;
462     if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE
463         || EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE)
464         cdat->aead = EVP_CIPHER_mode(cipher);
465     else
466         cdat->aead = 0;
467
468     return 1;
469 }
470
471 static void cipher_test_cleanup(struct evp_test *t)
472 {
473     struct cipher_data *cdat = t->data;
474     test_free(cdat->key);
475     test_free(cdat->iv);
476     test_free(cdat->ciphertext);
477     test_free(cdat->plaintext);
478     test_free(cdat->aad);
479     test_free(cdat->tag);
480 }
481
482 static int cipher_test_parse(struct evp_test *t, const char *keyword,
483                              const char *value)
484 {
485     struct cipher_data *cdat = t->data;
486     if (!strcmp(keyword, "Key"))
487         return test_bin(value, &cdat->key, &cdat->key_len);
488     if (!strcmp(keyword, "IV"))
489         return test_bin(value, &cdat->iv, &cdat->iv_len);
490     if (!strcmp(keyword, "Plaintext"))
491         return test_bin(value, &cdat->plaintext, &cdat->plaintext_len);
492     if (!strcmp(keyword, "Ciphertext"))
493         return test_bin(value, &cdat->ciphertext, &cdat->ciphertext_len);
494     if (cdat->aead) {
495         if (!strcmp(keyword, "AAD"))
496             return test_bin(value, &cdat->aad, &cdat->aad_len);
497         if (!strcmp(keyword, "Tag"))
498             return test_bin(value, &cdat->tag, &cdat->tag_len);
499     }
500
501     if (!strcmp(keyword, "Operation")) {
502         if (!strcmp(value, "ENCRYPT"))
503             cdat->enc = 1;
504         else if (!strcmp(value, "DECRYPT"))
505             cdat->enc = 0;
506         else
507             return 0;
508         return 1;
509     }
510     return 0;
511 }
512
513 static int cipher_test_enc(struct evp_test *t, int enc)
514 {
515     struct cipher_data *cdat = t->data;
516     unsigned char *in, *out, *tmp = NULL;
517     size_t in_len, out_len;
518     int tmplen, tmpflen;
519     EVP_CIPHER_CTX *ctx = NULL;
520     const char *err;
521     err = "INTERNAL_ERROR";
522     ctx = EVP_CIPHER_CTX_new();
523     if (!ctx)
524         goto err;
525     EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
526     if (enc) {
527         in = cdat->plaintext;
528         in_len = cdat->plaintext_len;
529         out = cdat->ciphertext;
530         out_len = cdat->ciphertext_len;
531     } else {
532         in = cdat->ciphertext;
533         in_len = cdat->ciphertext_len;
534         out = cdat->plaintext;
535         out_len = cdat->plaintext_len;
536     }
537     tmp = OPENSSL_malloc(in_len + 2 * EVP_MAX_BLOCK_LENGTH);
538     if (!tmp)
539         goto err;
540     err = "CIPHERINIT_ERROR";
541     if (!EVP_CipherInit_ex(ctx, cdat->cipher, NULL, NULL, NULL, enc))
542         goto err;
543     err = "INVALID_IV_LENGTH";
544     if (cdat->iv) {
545         if (cdat->aead == EVP_CIPH_GCM_MODE) {
546             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN,
547                                      cdat->iv_len, 0))
548                 goto err;
549         } else if (cdat->aead == EVP_CIPH_CCM_MODE) {
550             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN,
551                                      cdat->iv_len, 0))
552                 goto err;
553         } else if (cdat->iv_len != (size_t)EVP_CIPHER_CTX_iv_length(ctx))
554             goto err;
555     }
556     if (cdat->aead) {
557         unsigned char *tag;
558         /*
559          * If encrypting just set tag length. If decrypting set
560          * tag length and value.
561          */
562         if (enc) {
563             err = "TAG_LENGTH_SET_ERROR";
564             tag = NULL;
565         } else {
566             err = "TAG_SET_ERROR";
567             tag = cdat->tag;
568         }
569         if (cdat->aead == EVP_CIPH_GCM_MODE && tag) {
570             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG,
571                                      cdat->tag_len, tag))
572                 goto err;
573         } else if (cdat->aead == EVP_CIPH_CCM_MODE) {
574             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG,
575                                      cdat->tag_len, tag))
576                 goto err;
577         }
578     }
579
580     err = "INVALID_KEY_LENGTH";
581     if (!EVP_CIPHER_CTX_set_key_length(ctx, cdat->key_len))
582         goto err;
583     err = "KEY_SET_ERROR";
584     if (!EVP_CipherInit_ex(ctx, NULL, NULL, cdat->key, cdat->iv, -1))
585         goto err;
586
587     if (cdat->aead == EVP_CIPH_CCM_MODE) {
588         if (!EVP_CipherUpdate(ctx, NULL, &tmplen, NULL, out_len)) {
589             err = "CCM_PLAINTEXT_LENGTH_SET_ERROR";
590             goto err;
591         }
592     }
593     if (cdat->aad) {
594         if (!EVP_CipherUpdate(ctx, NULL, &tmplen, cdat->aad, cdat->aad_len)) {
595             err = "AAD_SET_ERROR";
596             goto err;
597         }
598     }
599     EVP_CIPHER_CTX_set_padding(ctx, 0);
600     err = "CIPHERUPDATE_ERROR";
601     if (!EVP_CipherUpdate(ctx, tmp, &tmplen, in, in_len))
602         goto err;
603     if (cdat->aead == EVP_CIPH_CCM_MODE)
604         tmpflen = 0;
605     else {
606         err = "CIPHERFINAL_ERROR";
607         if (!EVP_CipherFinal_ex(ctx, tmp + tmplen, &tmpflen))
608             goto err;
609     }
610     err = "LENGTH_MISMATCH";
611     if (out_len != (size_t)(tmplen + tmpflen))
612         goto err;
613     err = "VALUE_MISMATCH";
614     if (memcmp(out, tmp, out_len))
615         goto err;
616     if (enc && cdat->aead) {
617         unsigned char rtag[16];
618         if (cdat->tag_len > sizeof(rtag)) {
619             err = "TAG_LENGTH_INTERNAL_ERROR";
620             goto err;
621         }
622         /* EVP_CTRL_CCM_GET_TAG and EVP_CTRL_GCM_GET_TAG are equal. */
623         if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG,
624                                  cdat->tag_len, rtag)) {
625             err = "TAG_RETRIEVE_ERROR";
626             goto err;
627         }
628         if (memcmp(cdat->tag, rtag, cdat->tag_len)) {
629             err = "TAG_VALUE_MISMATCH";
630             goto err;
631         }
632     }
633     err = NULL;
634  err:
635     if (tmp)
636         OPENSSL_free(tmp);
637     EVP_CIPHER_CTX_free(ctx);
638     t->err = err;
639     return err ? 0 : 1;
640 }
641
642 static int cipher_test_run(struct evp_test *t)
643 {
644     struct cipher_data *cdat = t->data;
645     int rv;
646     if (!cdat->key) {
647         t->err = "NO_KEY";
648         return 0;
649     }
650     if (!cdat->iv && EVP_CIPHER_iv_length(cdat->cipher)) {
651         /* IV is optional and usually omitted in wrap mode */
652         if (EVP_CIPHER_mode(cdat->cipher) != EVP_CIPH_WRAP_MODE) {
653             t->err = "NO_IV";
654             return 0;
655         }
656     }
657     if (cdat->aead && !cdat->tag) {
658         t->err = "NO_TAG";
659         return 0;
660     }
661     if (cdat->enc) {
662         rv = cipher_test_enc(t, 1);
663         /* Not fatal errors: return */
664         if (rv != 1) {
665             if (rv < 0)
666                 return 0;
667             return 1;
668         }
669     }
670     if (cdat->enc != 1) {
671         rv = cipher_test_enc(t, 0);
672         /* Not fatal errors: return */
673         if (rv != 1) {
674             if (rv < 0)
675                 return 0;
676             return 1;
677         }
678     }
679     return 1;
680 }
681
682 static const struct evp_test_method cipher_test_method = {
683     "Cipher",
684     cipher_test_init,
685     cipher_test_cleanup,
686     cipher_test_parse,
687     cipher_test_run
688 };