]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/evp_test.c
free null cleanup finale
[thirdparty/openssl.git] / test / evp_test.c
CommitLineData
307e3978 1/* evp_test.c */
0e360199 2/*
307e3978
DSH
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.
0e360199
BL
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
0f113f3e 14 * notice, this list of conditions and the following disclaimer.
0e360199
BL
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
307e3978 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
0e360199
BL
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
307e3978 29 * licensing@OpenSSL.org.
0e360199
BL
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
307e3978 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
0e360199
BL
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.
307e3978 52 * ====================================================================
0e360199
BL
53 */
54
55#include <stdio.h>
56#include <string.h>
307e3978
DSH
57#include <stdlib.h>
58#include <ctype.h>
0e360199 59#include <openssl/evp.h>
5824cc29 60#include <openssl/pem.h>
0b13e9f0 61#include <openssl/err.h>
307e3978 62#include <openssl/x509v3.h>
0e360199 63
307e3978
DSH
64/* Remove spaces from beginning and end of a string */
65
66static void remove_space(char **pval)
0f113f3e 67{
307e3978 68 unsigned char *p = (unsigned char *)*pval;
0f113f3e 69
307e3978
DSH
70 while (isspace(*p))
71 p++;
72
73 *pval = (char *)p;
74
75 p = p + strlen(*pval) - 1;
76
77 /* Remove trailing space */
78 while (isspace(*p))
79 *p-- = 0;
0f113f3e 80}
0e360199 81
307e3978
DSH
82/*
83 * Given a line of the form:
84 * name = value # comment
85 * extract name and value. NB: modifies passed buffer.
86 */
87
88static int parse_line(char **pkw, char **pval, char *linebuf)
0f113f3e 89{
307e3978 90 char *p;
0e360199 91
307e3978 92 p = linebuf + strlen(linebuf) - 1;
0f113f3e 93
307e3978
DSH
94 if (*p != '\n') {
95 fprintf(stderr, "FATAL: missing EOL\n");
96 exit(1);
0e360199
BL
97 }
98
307e3978 99 /* Look for # */
5b46eee0 100
307e3978 101 p = strchr(linebuf, '#');
5b46eee0 102
307e3978
DSH
103 if (p)
104 *p = '\0';
5b46eee0 105
307e3978
DSH
106 /* Look for = sign */
107 p = strchr(linebuf, '=');
5b46eee0 108
307e3978
DSH
109 /* If no '=' exit */
110 if (!p)
111 return 0;
5b46eee0 112
307e3978 113 *p++ = '\0';
5b46eee0 114
307e3978
DSH
115 *pkw = linebuf;
116 *pval = p;
5b46eee0 117
307e3978
DSH
118 /* Remove spaces from keyword and value */
119 remove_space(pkw);
120 remove_space(pval);
121
122 return 1;
0f113f3e 123}
0e360199 124
307e3978
DSH
125/* For a hex string "value" convert to a binary allocated buffer */
126static int test_bin(const char *value, unsigned char **buf, size_t *buflen)
0f113f3e 127{
307e3978
DSH
128 long len;
129 if (!*value) {
130 /* Don't return NULL for zero length buffer */
131 *buf = OPENSSL_malloc(1);
132 if (!*buf)
133 return 0;
134 **buf = 0;
135 *buflen = 0;
136 return 1;
137 }
83251f39
DSH
138 /* Check for string literal */
139 if (value[0] == '"') {
140 size_t vlen;
141 value++;
142 vlen = strlen(value);
143 if (value[vlen - 1] != '"')
144 return 0;
145 vlen--;
146 *buf = BUF_memdup(value, vlen);
147 *buflen = vlen;
148 return 1;
149 }
307e3978
DSH
150 *buf = string_to_hex(value, &len);
151 if (!*buf) {
152 fprintf(stderr, "Value=%s\n", value);
153 ERR_print_errors_fp(stderr);
154 return -1;
155 }
156 /* Size of input buffer means we'll never overflow */
157 *buflen = len;
158 return 1;
0f113f3e 159}
848f735a 160
307e3978
DSH
161/* Structure holding test information */
162struct evp_test {
5824cc29
DSH
163 /* file being read */
164 FILE *in;
165 /* List of public and private keys */
166 struct key_list *private;
167 struct key_list *public;
307e3978
DSH
168 /* method for this test */
169 const struct evp_test_method *meth;
170 /* current line being processed */
171 unsigned int line;
172 /* start line of current test */
173 unsigned int start_line;
174 /* Error string for test */
175 const char *err;
176 /* Expected error value of test */
177 char *expected_err;
178 /* Number of tests */
179 int ntests;
180 /* Error count */
181 int errors;
7a6c9792
DSH
182 /* Number of tests skipped */
183 int nskip;
b033e5d5
DSH
184 /* If output mismatch expected and got value */
185 unsigned char *out_got;
186 unsigned char *out_expected;
187 size_t out_len;
307e3978
DSH
188 /* test specific data */
189 void *data;
7a6c9792
DSH
190 /* Current test should be skipped */
191 int skip;
307e3978 192};
5824cc29
DSH
193
194struct key_list {
195 char *name;
196 EVP_PKEY *key;
197 struct key_list *next;
198};
199
307e3978
DSH
200/* Test method structure */
201struct evp_test_method {
202 /* Name of test as it appears in file */
203 const char *name;
204 /* Initialise test for "alg" */
205 int (*init) (struct evp_test * t, const char *alg);
206 /* Clean up method */
207 void (*cleanup) (struct evp_test * t);
208 /* Test specific name value pair processing */
209 int (*parse) (struct evp_test * t, const char *name, const char *value);
210 /* Run the test itself */
211 int (*run_test) (struct evp_test * t);
212};
213
214static const struct evp_test_method digest_test_method, cipher_test_method;
f9e31463 215static const struct evp_test_method mac_test_method;
5824cc29
DSH
216static const struct evp_test_method psign_test_method, pverify_test_method;
217static const struct evp_test_method pdecrypt_test_method;
218static const struct evp_test_method pverify_recover_test_method;
307e3978
DSH
219
220static const struct evp_test_method *evp_test_list[] = {
221 &digest_test_method,
222 &cipher_test_method,
83251f39 223 &mac_test_method,
5824cc29
DSH
224 &psign_test_method,
225 &pverify_test_method,
226 &pdecrypt_test_method,
227 &pverify_recover_test_method,
83251f39 228 NULL
307e3978
DSH
229};
230
231static const struct evp_test_method *evp_find_test(const char *name)
0f113f3e 232{
307e3978
DSH
233 const struct evp_test_method **tt;
234 for (tt = evp_test_list; *tt; tt++) {
235 if (!strcmp(name, (*tt)->name))
236 return *tt;
237 }
238 return NULL;
0f113f3e
MC
239}
240
b033e5d5
DSH
241static void hex_print(const char *name, const unsigned char *buf, size_t len)
242{
243 size_t i;
244 fprintf(stderr, "%s ", name);
245 for (i = 0; i < len; i++)
246 fprintf(stderr, "%02X", buf[i]);
247 fputs("\n", stderr);
248}
249
5724bd49
DSH
250static void free_expected(struct evp_test *t)
251{
b548a1f1
RS
252 OPENSSL_free(t->expected_err);
253 t->expected_err = NULL;
5724bd49
DSH
254 if (t->out_expected) {
255 OPENSSL_free(t->out_expected);
256 OPENSSL_free(t->out_got);
257 t->out_expected = NULL;
258 t->out_got = NULL;
259 }
260}
261
b033e5d5
DSH
262static void print_expected(struct evp_test *t)
263{
264 if (t->out_expected == NULL)
265 return;
266 hex_print("Expected:", t->out_expected, t->out_len);
267 hex_print("Got: ", t->out_got, t->out_len);
5724bd49 268 free_expected(t);
b033e5d5
DSH
269}
270
307e3978 271static int check_test_error(struct evp_test *t)
0f113f3e 272{
307e3978
DSH
273 if (!t->err && !t->expected_err)
274 return 1;
275 if (t->err && !t->expected_err) {
276 fprintf(stderr, "Test line %d: unexpected error %s\n",
277 t->start_line, t->err);
b033e5d5 278 print_expected(t);
307e3978 279 return 0;
0f113f3e 280 }
307e3978
DSH
281 if (!t->err && t->expected_err) {
282 fprintf(stderr, "Test line %d: succeeded expecting %s\n",
283 t->start_line, t->expected_err);
284 return 0;
285 }
286 if (!strcmp(t->err, t->expected_err))
287 return 1;
544a2aea 288
307e3978
DSH
289 fprintf(stderr, "Test line %d: expecting %s got %s\n",
290 t->start_line, t->expected_err, t->err);
291 return 0;
292}
0f113f3e 293
307e3978 294/* Setup a new test, run any existing test */
0f113f3e 295
307e3978
DSH
296static int setup_test(struct evp_test *t, const struct evp_test_method *tmeth)
297{
298 /* If we already have a test set up run it */
299 if (t->meth) {
300 t->ntests++;
7a6c9792 301 if (t->skip) {
578ce42d 302 t->meth = tmeth;
7a6c9792
DSH
303 t->nskip++;
304 return 1;
305 }
307e3978
DSH
306 t->err = NULL;
307 if (t->meth->run_test(t) != 1) {
308 fprintf(stderr, "%s test error line %d\n",
309 t->meth->name, t->start_line);
310 return 0;
0f113f3e 311 }
307e3978
DSH
312 if (!check_test_error(t)) {
313 if (t->err)
0f113f3e 314 ERR_print_errors_fp(stderr);
307e3978 315 t->errors++;
0f113f3e 316 }
307e3978
DSH
317 ERR_clear_error();
318 t->meth->cleanup(t);
d5ec8efc
DSH
319 OPENSSL_free(t->data);
320 t->data = NULL;
b548a1f1
RS
321 OPENSSL_free(t->expected_err);
322 t->expected_err = NULL;
5724bd49 323 free_expected(t);
307e3978
DSH
324 }
325 t->meth = tmeth;
326 return 1;
327}
0f113f3e 328
7a6c9792 329static int find_key(EVP_PKEY **ppk, const char *name, struct key_list *lst)
5824cc29
DSH
330{
331 for (; lst; lst = lst->next) {
7a6c9792
DSH
332 if (!strcmp(lst->name, name)) {
333 if (ppk)
334 *ppk = lst->key;
335 return 1;
336 }
5824cc29 337 }
7a6c9792 338 return 0;
5824cc29
DSH
339}
340
341static void free_key_list(struct key_list *lst)
342{
d5ec8efc 343 while (lst != NULL) {
366448ec 344 struct key_list *ltmp;
5824cc29
DSH
345 EVP_PKEY_free(lst->key);
346 OPENSSL_free(lst->name);
366448ec
DSH
347 ltmp = lst->next;
348 OPENSSL_free(lst);
349 lst = ltmp;
5824cc29
DSH
350 }
351}
352
7a6c9792
DSH
353static int check_unsupported()
354{
355 long err = ERR_peek_error();
356 if (ERR_GET_LIB(err) == ERR_LIB_EVP
366448ec 357 && ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM) {
7a6c9792
DSH
358 ERR_clear_error();
359 return 1;
360 }
361 return 0;
362}
363
307e3978
DSH
364static int process_test(struct evp_test *t, char *buf, int verbose)
365{
366 char *keyword, *value;
7a6c9792 367 int rv = 0, add_key = 0;
5824cc29
DSH
368 long save_pos;
369 struct key_list **lst, *key;
370 EVP_PKEY *pk = NULL;
307e3978
DSH
371 const struct evp_test_method *tmeth;
372 if (verbose)
373 fputs(buf, stdout);
374 if (!parse_line(&keyword, &value, buf))
375 return 1;
5824cc29
DSH
376 if (!strcmp(keyword, "PrivateKey")) {
377 save_pos = ftell(t->in);
378 pk = PEM_read_PrivateKey(t->in, NULL, 0, NULL);
7a6c9792 379 if (pk == NULL && !check_unsupported()) {
5824cc29
DSH
380 fprintf(stderr, "Error reading private key %s\n", value);
381 ERR_print_errors_fp(stderr);
382 return 0;
383 }
384 lst = &t->private;
7a6c9792 385 add_key = 1;
5824cc29
DSH
386 }
387 if (!strcmp(keyword, "PublicKey")) {
388 save_pos = ftell(t->in);
389 pk = PEM_read_PUBKEY(t->in, NULL, 0, NULL);
7a6c9792 390 if (pk == NULL && !check_unsupported()) {
5824cc29
DSH
391 fprintf(stderr, "Error reading public key %s\n", value);
392 ERR_print_errors_fp(stderr);
393 return 0;
394 }
395 lst = &t->public;
7a6c9792 396 add_key = 1;
5824cc29
DSH
397 }
398 /* If we have a key add to list */
7a6c9792 399 if (add_key) {
5824cc29 400 char tmpbuf[80];
7a6c9792 401 if (find_key(NULL, value, *lst)) {
5824cc29
DSH
402 fprintf(stderr, "Duplicate key %s\n", value);
403 return 0;
404 }
405 key = OPENSSL_malloc(sizeof(struct key_list));
406 if (!key)
407 return 0;
408 key->name = BUF_strdup(value);
409 key->key = pk;
410 key->next = *lst;
411 *lst = key;
412 /* Rewind input, read to end and update line numbers */
413 fseek(t->in, save_pos, SEEK_SET);
414 while (fgets(tmpbuf, sizeof(tmpbuf), t->in)) {
415 t->line++;
416 if (!strncmp(tmpbuf, "-----END", 8))
417 return 1;
418 }
419 fprintf(stderr, "Can't find key end\n");
420 return 0;
421 }
422
307e3978
DSH
423 /* See if keyword corresponds to a test start */
424 tmeth = evp_find_test(keyword);
425 if (tmeth) {
426 if (!setup_test(t, tmeth))
427 return 0;
428 t->start_line = t->line;
7a6c9792 429 t->skip = 0;
307e3978
DSH
430 if (!tmeth->init(t, value)) {
431 fprintf(stderr, "Unknown %s: %s\n", keyword, value);
432 return 0;
0f113f3e 433 }
307e3978 434 return 1;
7a6c9792
DSH
435 } else if (t->skip) {
436 return 1;
307e3978
DSH
437 } else if (!strcmp(keyword, "Result")) {
438 if (t->expected_err) {
439 fprintf(stderr, "Line %d: multiple result lines\n", t->line);
440 return 0;
0f113f3e 441 }
307e3978
DSH
442 t->expected_err = BUF_strdup(value);
443 if (!t->expected_err)
444 return 0;
445 } else {
446 /* Must be test specific line: try to parse it */
447 if (t->meth)
448 rv = t->meth->parse(t, keyword, value);
449
450 if (rv == 0)
451 fprintf(stderr, "line %d: unexpected keyword %s\n",
452 t->line, keyword);
453
454 if (rv < 0)
455 fprintf(stderr, "line %d: error processing keyword %s\n",
456 t->line, keyword);
457 if (rv <= 0)
458 return 0;
0f113f3e 459 }
307e3978
DSH
460 return 1;
461}
0f113f3e 462
b033e5d5
DSH
463static int check_output(struct evp_test *t, const unsigned char *expected,
464 const unsigned char *got, size_t len)
465{
466 if (!memcmp(expected, got, len))
467 return 0;
468 t->out_expected = BUF_memdup(expected, len);
469 t->out_got = BUF_memdup(got, len);
470 t->out_len = len;
471 if (t->out_expected == NULL || t->out_got == NULL) {
472 fprintf(stderr, "Memory allocation error!\n");
473 exit(1);
474 }
475 return 1;
476}
477
307e3978
DSH
478int main(int argc, char **argv)
479{
480 FILE *in = NULL;
481 char buf[10240];
482 struct evp_test t;
0f113f3e 483
b033e5d5
DSH
484 if (argc != 2) {
485 fprintf(stderr, "usage: evp_test testfile.txt\n");
486 return 1;
487 }
488
d5ec8efc
DSH
489 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
490
307e3978
DSH
491 ERR_load_crypto_strings();
492 OpenSSL_add_all_algorithms();
1526fea5 493
366448ec 494 memset(&t, 0, sizeof(t));
307e3978 495 t.meth = NULL;
5824cc29
DSH
496 t.public = NULL;
497 t.private = NULL;
307e3978
DSH
498 t.err = NULL;
499 t.line = 0;
500 t.start_line = -1;
501 t.errors = 0;
502 t.ntests = 0;
b033e5d5
DSH
503 t.out_expected = NULL;
504 t.out_got = NULL;
505 t.out_len = 0;
307e3978 506 in = fopen(argv[1], "r");
5824cc29 507 t.in = in;
307e3978
DSH
508 while (fgets(buf, sizeof(buf), in)) {
509 t.line++;
510 if (!process_test(&t, buf, 0))
511 exit(1);
512 }
513 /* Run any final test we have */
514 if (!setup_test(&t, NULL))
515 exit(1);
7a6c9792
DSH
516 fprintf(stderr, "%d tests completed with %d errors, %d skipped\n",
517 t.ntests, t.errors, t.nskip);
5824cc29
DSH
518 free_key_list(t.public);
519 free_key_list(t.private);
307e3978 520 fclose(in);
d5ec8efc
DSH
521 EVP_cleanup();
522 CRYPTO_cleanup_all_ex_data();
523 ERR_remove_thread_state(NULL);
524 ERR_free_strings();
525 CRYPTO_mem_leaks_fp(stderr);
6906a7c1
DSH
526 if (t.errors)
527 return 1;
307e3978 528 return 0;
0f113f3e
MC
529}
530
307e3978 531static void test_free(void *d)
0f113f3e 532{
b548a1f1 533 OPENSSL_free(d);
307e3978 534}
4897dc40 535
307e3978 536/* Message digest tests */
4897dc40 537
307e3978
DSH
538struct digest_data {
539 /* Digest this test is for */
540 const EVP_MD *digest;
541 /* Input to digest */
542 unsigned char *input;
543 size_t input_len;
618be04e
DSH
544 /* Repeat count for input */
545 size_t nrpt;
307e3978
DSH
546 /* Expected output */
547 unsigned char *output;
548 size_t output_len;
549};
4897dc40 550
307e3978
DSH
551static int digest_test_init(struct evp_test *t, const char *alg)
552{
553 const EVP_MD *digest;
554 struct digest_data *mdat = t->data;
555 digest = EVP_get_digestbyname(alg);
578ce42d
DSH
556 if (!digest) {
557 /* If alg has an OID assume disabled algorithm */
558 if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
559 t->skip = 1;
560 return 1;
561 }
307e3978 562 return 0;
578ce42d 563 }
307e3978
DSH
564 mdat = OPENSSL_malloc(sizeof(struct digest_data));
565 mdat->digest = digest;
566 mdat->input = NULL;
567 mdat->output = NULL;
618be04e 568 mdat->nrpt = 1;
307e3978 569 t->data = mdat;
4897dc40 570 return 1;
0f113f3e 571}
4897dc40 572
307e3978
DSH
573static void digest_test_cleanup(struct evp_test *t)
574{
575 struct digest_data *mdat = t->data;
576 test_free(mdat->input);
577 test_free(mdat->output);
578}
579
580static int digest_test_parse(struct evp_test *t,
581 const char *keyword, const char *value)
582{
583 struct digest_data *mdata = t->data;
584 if (!strcmp(keyword, "Input"))
585 return test_bin(value, &mdata->input, &mdata->input_len);
586 if (!strcmp(keyword, "Output"))
587 return test_bin(value, &mdata->output, &mdata->output_len);
618be04e
DSH
588 if (!strcmp(keyword, "Count")) {
589 long nrpt = atoi(value);
590 if (nrpt <= 0)
591 return 0;
592 mdata->nrpt = (size_t)nrpt;
593 return 1;
594 }
307e3978
DSH
595 return 0;
596}
597
598static int digest_test_run(struct evp_test *t)
0f113f3e 599{
307e3978 600 struct digest_data *mdata = t->data;
618be04e 601 size_t i;
307e3978
DSH
602 const char *err = "INTERNAL_ERROR";
603 EVP_MD_CTX *mctx;
4897dc40 604 unsigned char md[EVP_MAX_MD_SIZE];
307e3978
DSH
605 unsigned int md_len;
606 mctx = EVP_MD_CTX_create();
607 if (!mctx)
608 goto err;
609 err = "DIGESTINIT_ERROR";
610 if (!EVP_DigestInit_ex(mctx, mdata->digest, NULL))
611 goto err;
612 err = "DIGESTUPDATE_ERROR";
618be04e
DSH
613 for (i = 0; i < mdata->nrpt; i++) {
614 if (!EVP_DigestUpdate(mctx, mdata->input, mdata->input_len))
615 goto err;
616 }
307e3978
DSH
617 err = "DIGESTFINAL_ERROR";
618 if (!EVP_DigestFinal(mctx, md, &md_len))
619 goto err;
620 err = "DIGEST_LENGTH_MISMATCH";
621 if (md_len != mdata->output_len)
622 goto err;
623 err = "DIGEST_MISMATCH";
b033e5d5 624 if (check_output(t, mdata->output, md, md_len))
307e3978
DSH
625 goto err;
626 err = NULL;
627 err:
628 if (mctx)
629 EVP_MD_CTX_destroy(mctx);
630 t->err = err;
b033e5d5 631 return 1;
307e3978 632}
4897dc40 633
307e3978
DSH
634static const struct evp_test_method digest_test_method = {
635 "Digest",
636 digest_test_init,
637 digest_test_cleanup,
638 digest_test_parse,
639 digest_test_run
640};
641
642/* Cipher tests */
643struct cipher_data {
644 const EVP_CIPHER *cipher;
645 int enc;
2207ba7b 646 /* EVP_CIPH_GCM_MODE, EVP_CIPH_CCM_MODE or EVP_CIPH_OCB_MODE if AEAD */
307e3978
DSH
647 int aead;
648 unsigned char *key;
649 size_t key_len;
650 unsigned char *iv;
651 size_t iv_len;
652 unsigned char *plaintext;
653 size_t plaintext_len;
654 unsigned char *ciphertext;
655 size_t ciphertext_len;
656 /* GCM, CCM only */
657 unsigned char *aad;
658 size_t aad_len;
659 unsigned char *tag;
660 size_t tag_len;
661};
662
663static int cipher_test_init(struct evp_test *t, const char *alg)
664{
665 const EVP_CIPHER *cipher;
666 struct cipher_data *cdat = t->data;
667 cipher = EVP_get_cipherbyname(alg);
33a89fa6
DSH
668 if (!cipher) {
669 /* If alg has an OID assume disabled algorithm */
670 if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
671 t->skip = 1;
672 return 1;
673 }
0f113f3e 674 return 0;
33a89fa6 675 }
307e3978
DSH
676 cdat = OPENSSL_malloc(sizeof(struct cipher_data));
677 cdat->cipher = cipher;
678 cdat->enc = -1;
679 cdat->key = NULL;
680 cdat->iv = NULL;
681 cdat->ciphertext = NULL;
682 cdat->plaintext = NULL;
683 cdat->aad = NULL;
684 cdat->tag = NULL;
685 t->data = cdat;
686 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE
2207ba7b 687 || EVP_CIPHER_mode(cipher) == EVP_CIPH_OCB_MODE
307e3978
DSH
688 || EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE)
689 cdat->aead = EVP_CIPHER_mode(cipher);
690 else
691 cdat->aead = 0;
4897dc40 692
307e3978
DSH
693 return 1;
694}
4897dc40 695
307e3978
DSH
696static void cipher_test_cleanup(struct evp_test *t)
697{
698 struct cipher_data *cdat = t->data;
699 test_free(cdat->key);
700 test_free(cdat->iv);
701 test_free(cdat->ciphertext);
702 test_free(cdat->plaintext);
703 test_free(cdat->aad);
704 test_free(cdat->tag);
705}
4897dc40 706
307e3978
DSH
707static int cipher_test_parse(struct evp_test *t, const char *keyword,
708 const char *value)
709{
710 struct cipher_data *cdat = t->data;
711 if (!strcmp(keyword, "Key"))
712 return test_bin(value, &cdat->key, &cdat->key_len);
713 if (!strcmp(keyword, "IV"))
714 return test_bin(value, &cdat->iv, &cdat->iv_len);
715 if (!strcmp(keyword, "Plaintext"))
716 return test_bin(value, &cdat->plaintext, &cdat->plaintext_len);
717 if (!strcmp(keyword, "Ciphertext"))
718 return test_bin(value, &cdat->ciphertext, &cdat->ciphertext_len);
719 if (cdat->aead) {
720 if (!strcmp(keyword, "AAD"))
721 return test_bin(value, &cdat->aad, &cdat->aad_len);
722 if (!strcmp(keyword, "Tag"))
723 return test_bin(value, &cdat->tag, &cdat->tag_len);
0f113f3e 724 }
4897dc40 725
307e3978
DSH
726 if (!strcmp(keyword, "Operation")) {
727 if (!strcmp(value, "ENCRYPT"))
728 cdat->enc = 1;
729 else if (!strcmp(value, "DECRYPT"))
730 cdat->enc = 0;
731 else
732 return 0;
733 return 1;
0f113f3e 734 }
307e3978 735 return 0;
0f113f3e 736}
4897dc40 737
307e3978 738static int cipher_test_enc(struct evp_test *t, int enc)
0f113f3e 739{
307e3978
DSH
740 struct cipher_data *cdat = t->data;
741 unsigned char *in, *out, *tmp = NULL;
742 size_t in_len, out_len;
743 int tmplen, tmpflen;
744 EVP_CIPHER_CTX *ctx = NULL;
745 const char *err;
746 err = "INTERNAL_ERROR";
747 ctx = EVP_CIPHER_CTX_new();
748 if (!ctx)
749 goto err;
750 EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
751 if (enc) {
752 in = cdat->plaintext;
753 in_len = cdat->plaintext_len;
754 out = cdat->ciphertext;
755 out_len = cdat->ciphertext_len;
756 } else {
757 in = cdat->ciphertext;
758 in_len = cdat->ciphertext_len;
759 out = cdat->plaintext;
760 out_len = cdat->plaintext_len;
0f113f3e 761 }
307e3978
DSH
762 tmp = OPENSSL_malloc(in_len + 2 * EVP_MAX_BLOCK_LENGTH);
763 if (!tmp)
764 goto err;
765 err = "CIPHERINIT_ERROR";
766 if (!EVP_CipherInit_ex(ctx, cdat->cipher, NULL, NULL, NULL, enc))
767 goto err;
768 err = "INVALID_IV_LENGTH";
769 if (cdat->iv) {
2207ba7b
DSH
770 if (cdat->aead) {
771 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
307e3978
DSH
772 cdat->iv_len, 0))
773 goto err;
774 } else if (cdat->iv_len != (size_t)EVP_CIPHER_CTX_iv_length(ctx))
775 goto err;
0f113f3e 776 }
307e3978
DSH
777 if (cdat->aead) {
778 unsigned char *tag;
779 /*
2207ba7b
DSH
780 * If encrypting or OCB just set tag length initially, otherwise
781 * set tag length and value.
307e3978 782 */
2207ba7b 783 if (enc || cdat->aead == EVP_CIPH_OCB_MODE) {
307e3978
DSH
784 err = "TAG_LENGTH_SET_ERROR";
785 tag = NULL;
0f113f3e 786 } else {
307e3978
DSH
787 err = "TAG_SET_ERROR";
788 tag = cdat->tag;
0f113f3e 789 }
2207ba7b
DSH
790 if (tag || cdat->aead != EVP_CIPH_GCM_MODE) {
791 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
366448ec 792 cdat->tag_len, tag))
307e3978 793 goto err;
0f113f3e 794 }
307e3978 795 }
0f113f3e 796
307e3978
DSH
797 err = "INVALID_KEY_LENGTH";
798 if (!EVP_CIPHER_CTX_set_key_length(ctx, cdat->key_len))
799 goto err;
800 err = "KEY_SET_ERROR";
801 if (!EVP_CipherInit_ex(ctx, NULL, NULL, cdat->key, cdat->iv, -1))
802 goto err;
803
2207ba7b
DSH
804 if (!enc && cdat->aead == EVP_CIPH_OCB_MODE) {
805 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
806 cdat->tag_len, cdat->tag)) {
366448ec
DSH
807 err = "TAG_SET_ERROR";
808 goto err;
2207ba7b
DSH
809 }
810 }
811
307e3978
DSH
812 if (cdat->aead == EVP_CIPH_CCM_MODE) {
813 if (!EVP_CipherUpdate(ctx, NULL, &tmplen, NULL, out_len)) {
814 err = "CCM_PLAINTEXT_LENGTH_SET_ERROR";
815 goto err;
0f113f3e
MC
816 }
817 }
307e3978
DSH
818 if (cdat->aad) {
819 if (!EVP_CipherUpdate(ctx, NULL, &tmplen, cdat->aad, cdat->aad_len)) {
820 err = "AAD_SET_ERROR";
821 goto err;
822 }
823 }
824 EVP_CIPHER_CTX_set_padding(ctx, 0);
825 err = "CIPHERUPDATE_ERROR";
826 if (!EVP_CipherUpdate(ctx, tmp, &tmplen, in, in_len))
827 goto err;
828 if (cdat->aead == EVP_CIPH_CCM_MODE)
829 tmpflen = 0;
830 else {
831 err = "CIPHERFINAL_ERROR";
832 if (!EVP_CipherFinal_ex(ctx, tmp + tmplen, &tmpflen))
833 goto err;
834 }
835 err = "LENGTH_MISMATCH";
836 if (out_len != (size_t)(tmplen + tmpflen))
837 goto err;
838 err = "VALUE_MISMATCH";
b033e5d5 839 if (check_output(t, out, tmp, out_len))
307e3978
DSH
840 goto err;
841 if (enc && cdat->aead) {
842 unsigned char rtag[16];
843 if (cdat->tag_len > sizeof(rtag)) {
844 err = "TAG_LENGTH_INTERNAL_ERROR";
845 goto err;
846 }
2207ba7b 847 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
307e3978
DSH
848 cdat->tag_len, rtag)) {
849 err = "TAG_RETRIEVE_ERROR";
850 goto err;
851 }
b033e5d5 852 if (check_output(t, cdat->tag, rtag, cdat->tag_len)) {
307e3978
DSH
853 err = "TAG_VALUE_MISMATCH";
854 goto err;
855 }
856 }
857 err = NULL;
858 err:
b548a1f1 859 OPENSSL_free(tmp);
307e3978
DSH
860 EVP_CIPHER_CTX_free(ctx);
861 t->err = err;
862 return err ? 0 : 1;
863}
0e360199 864
307e3978
DSH
865static int cipher_test_run(struct evp_test *t)
866{
867 struct cipher_data *cdat = t->data;
868 int rv;
869 if (!cdat->key) {
870 t->err = "NO_KEY";
871 return 0;
872 }
873 if (!cdat->iv && EVP_CIPHER_iv_length(cdat->cipher)) {
874 /* IV is optional and usually omitted in wrap mode */
875 if (EVP_CIPHER_mode(cdat->cipher) != EVP_CIPH_WRAP_MODE) {
876 t->err = "NO_IV";
877 return 0;
878 }
879 }
880 if (cdat->aead && !cdat->tag) {
881 t->err = "NO_TAG";
882 return 0;
883 }
884 if (cdat->enc) {
885 rv = cipher_test_enc(t, 1);
886 /* Not fatal errors: return */
887 if (rv != 1) {
888 if (rv < 0)
889 return 0;
890 return 1;
891 }
892 }
893 if (cdat->enc != 1) {
894 rv = cipher_test_enc(t, 0);
895 /* Not fatal errors: return */
896 if (rv != 1) {
897 if (rv < 0)
898 return 0;
899 return 1;
900 }
901 }
902 return 1;
0f113f3e 903}
307e3978
DSH
904
905static const struct evp_test_method cipher_test_method = {
906 "Cipher",
907 cipher_test_init,
908 cipher_test_cleanup,
909 cipher_test_parse,
910 cipher_test_run
911};
83251f39
DSH
912
913struct mac_data {
914 /* MAC type */
915 int type;
916 /* Algorithm string for this MAC */
917 char *alg;
918 /* MAC key */
919 unsigned char *key;
920 size_t key_len;
921 /* Input to MAC */
922 unsigned char *input;
923 size_t input_len;
924 /* Expected output */
925 unsigned char *output;
926 size_t output_len;
927};
928
929static int mac_test_init(struct evp_test *t, const char *alg)
930{
931 int type;
932 struct mac_data *mdat;
933 if (!strcmp(alg, "HMAC"))
934 type = EVP_PKEY_HMAC;
935 else if (!strcmp(alg, "CMAC"))
936 type = EVP_PKEY_CMAC;
937 else
938 return 0;
939
940 mdat = OPENSSL_malloc(sizeof(struct mac_data));
941 mdat->type = type;
942 mdat->alg = NULL;
943 mdat->key = NULL;
944 mdat->input = NULL;
945 mdat->output = NULL;
946 t->data = mdat;
947 return 1;
948}
949
950static void mac_test_cleanup(struct evp_test *t)
951{
952 struct mac_data *mdat = t->data;
953 test_free(mdat->alg);
954 test_free(mdat->key);
955 test_free(mdat->input);
956 test_free(mdat->output);
957}
958
959static int mac_test_parse(struct evp_test *t,
960 const char *keyword, const char *value)
961{
962 struct mac_data *mdata = t->data;
963 if (!strcmp(keyword, "Key"))
964 return test_bin(value, &mdata->key, &mdata->key_len);
965 if (!strcmp(keyword, "Algorithm")) {
966 mdata->alg = BUF_strdup(value);
967 if (!mdata->alg)
968 return 0;
969 return 1;
970 }
971 if (!strcmp(keyword, "Input"))
972 return test_bin(value, &mdata->input, &mdata->input_len);
973 if (!strcmp(keyword, "Output"))
974 return test_bin(value, &mdata->output, &mdata->output_len);
975 return 0;
976}
977
978static int mac_test_run(struct evp_test *t)
979{
980 struct mac_data *mdata = t->data;
981 const char *err = "INTERNAL_ERROR";
982 EVP_MD_CTX *mctx = NULL;
983 EVP_PKEY_CTX *pctx = NULL, *genctx = NULL;
984 EVP_PKEY *key = NULL;
985 const EVP_MD *md = NULL;
986 unsigned char *mac = NULL;
987 size_t mac_len;
988
989 err = "MAC_PKEY_CTX_ERROR";
990 genctx = EVP_PKEY_CTX_new_id(mdata->type, NULL);
991 if (!genctx)
992 goto err;
993
994 err = "MAC_KEYGEN_INIT_ERROR";
995 if (EVP_PKEY_keygen_init(genctx) <= 0)
996 goto err;
997 if (mdata->type == EVP_PKEY_CMAC) {
998 err = "MAC_ALGORITHM_SET_ERROR";
999 if (EVP_PKEY_CTX_ctrl_str(genctx, "cipher", mdata->alg) <= 0)
1000 goto err;
1001 }
1002
1003 err = "MAC_KEY_SET_ERROR";
1004 if (EVP_PKEY_CTX_set_mac_key(genctx, mdata->key, mdata->key_len) <= 0)
1005 goto err;
1006
1007 err = "MAC_KEY_GENERATE_ERROR";
1008 if (EVP_PKEY_keygen(genctx, &key) <= 0)
1009 goto err;
1010 if (mdata->type == EVP_PKEY_HMAC) {
1011 err = "MAC_ALGORITHM_SET_ERROR";
1012 md = EVP_get_digestbyname(mdata->alg);
1013 if (!md)
1014 goto err;
1015 }
1016 mctx = EVP_MD_CTX_create();
1017 if (!mctx)
1018 goto err;
1019 err = "DIGESTSIGNINIT_ERROR";
1020 if (!EVP_DigestSignInit(mctx, &pctx, md, NULL, key))
1021 goto err;
1022
1023 err = "DIGESTSIGNUPDATE_ERROR";
1024 if (!EVP_DigestSignUpdate(mctx, mdata->input, mdata->input_len))
1025 goto err;
1026 err = "DIGESTSIGNFINAL_LENGTH_ERROR";
1027 if (!EVP_DigestSignFinal(mctx, NULL, &mac_len))
1028 goto err;
1029 mac = OPENSSL_malloc(mac_len);
1030 if (!mac) {
1031 fprintf(stderr, "Error allocating mac buffer!\n");
1032 exit(1);
1033 }
1034 if (!EVP_DigestSignFinal(mctx, mac, &mac_len))
1035 goto err;
1036 err = "MAC_LENGTH_MISMATCH";
1037 if (mac_len != mdata->output_len)
1038 goto err;
1039 err = "MAC_MISMATCH";
1040 if (check_output(t, mdata->output, mac, mac_len))
1041 goto err;
1042 err = NULL;
1043 err:
1044 if (mctx)
1045 EVP_MD_CTX_destroy(mctx);
b548a1f1 1046 OPENSSL_free(mac);
c5ba2d99
RS
1047 EVP_PKEY_CTX_free(genctx);
1048 EVP_PKEY_free(key);
83251f39
DSH
1049 t->err = err;
1050 return 1;
1051}
1052
1053static const struct evp_test_method mac_test_method = {
1054 "MAC",
1055 mac_test_init,
1056 mac_test_cleanup,
1057 mac_test_parse,
1058 mac_test_run
1059};
5824cc29
DSH
1060
1061/*
1062 * Public key operations. These are all very similar and can share
1063 * a lot of common code.
1064 */
1065
1066struct pkey_data {
1067 /* Context for this operation */
1068 EVP_PKEY_CTX *ctx;
1069 /* Key operation to perform */
1070 int (*keyop) (EVP_PKEY_CTX *ctx,
1071 unsigned char *sig, size_t *siglen,
1072 const unsigned char *tbs, size_t tbslen);
1073 /* Input to MAC */
1074 unsigned char *input;
1075 size_t input_len;
1076 /* Expected output */
1077 unsigned char *output;
1078 size_t output_len;
1079};
1080
1081/*
1082 * Perform public key operation setup: lookup key, allocated ctx and call
1083 * the appropriate initialisation function
1084 */
1085static int pkey_test_init(struct evp_test *t, const char *name,
1086 int use_public,
1087 int (*keyopinit) (EVP_PKEY_CTX *ctx),
1088 int (*keyop) (EVP_PKEY_CTX *ctx,
1089 unsigned char *sig, size_t *siglen,
1090 const unsigned char *tbs,
1091 size_t tbslen)
1092 )
1093{
1094 struct pkey_data *kdata;
1095 EVP_PKEY *pkey = NULL;
7a6c9792
DSH
1096 int rv = 0;
1097 if (use_public)
1098 rv = find_key(&pkey, name, t->public);
1099 if (!rv)
1100 rv = find_key(&pkey, name, t->private);
1101 if (!rv)
1102 return 0;
1103 if (!pkey) {
1104 t->skip = 1;
1105 return 1;
1106 }
1107
5824cc29 1108 kdata = OPENSSL_malloc(sizeof(struct pkey_data));
7a6c9792
DSH
1109 if (!kdata) {
1110 EVP_PKEY_free(pkey);
5824cc29 1111 return 0;
7a6c9792 1112 }
5824cc29
DSH
1113 kdata->ctx = NULL;
1114 kdata->input = NULL;
1115 kdata->output = NULL;
1116 kdata->keyop = keyop;
1117 t->data = kdata;
5824cc29
DSH
1118 kdata->ctx = EVP_PKEY_CTX_new(pkey, NULL);
1119 if (!kdata->ctx)
1120 return 0;
1121 if (keyopinit(kdata->ctx) <= 0)
1122 return 0;
1123 return 1;
1124}
1125
1126static void pkey_test_cleanup(struct evp_test *t)
1127{
1128 struct pkey_data *kdata = t->data;
b548a1f1
RS
1129
1130 OPENSSL_free(kdata->input);
1131 OPENSSL_free(kdata->output);
c5ba2d99 1132 EVP_PKEY_CTX_free(kdata->ctx);
5824cc29
DSH
1133}
1134
1135static int pkey_test_parse(struct evp_test *t,
1136 const char *keyword, const char *value)
1137{
1138 struct pkey_data *kdata = t->data;
1139 if (!strcmp(keyword, "Input"))
1140 return test_bin(value, &kdata->input, &kdata->input_len);
1141 if (!strcmp(keyword, "Output"))
1142 return test_bin(value, &kdata->output, &kdata->output_len);
1143 if (!strcmp(keyword, "Ctrl")) {
1144 char *p = strchr(value, ':');
1145 if (p)
1146 *p++ = 0;
1147 if (EVP_PKEY_CTX_ctrl_str(kdata->ctx, value, p) <= 0)
1148 return 0;
1149 return 1;
1150 }
1151 return 0;
1152}
1153
1154static int pkey_test_run(struct evp_test *t)
1155{
1156 struct pkey_data *kdata = t->data;
1157 unsigned char *out = NULL;
1158 size_t out_len;
1159 const char *err = "KEYOP_LENGTH_ERROR";
1160 if (kdata->keyop(kdata->ctx, NULL, &out_len, kdata->input,
1161 kdata->input_len) <= 0)
1162 goto err;
1163 out = OPENSSL_malloc(out_len);
1164 if (!out) {
1165 fprintf(stderr, "Error allocating output buffer!\n");
1166 exit(1);
1167 }
1168 err = "KEYOP_ERROR";
1169 if (kdata->keyop
1170 (kdata->ctx, out, &out_len, kdata->input, kdata->input_len) <= 0)
1171 goto err;
1172 err = "KEYOP_LENGTH_MISMATCH";
1173 if (out_len != kdata->output_len)
1174 goto err;
1175 err = "KEYOP_MISMATCH";
1176 if (check_output(t, kdata->output, out, out_len))
1177 goto err;
1178 err = NULL;
1179 err:
b548a1f1 1180 OPENSSL_free(out);
5824cc29
DSH
1181 t->err = err;
1182 return 1;
1183}
1184
1185static int sign_test_init(struct evp_test *t, const char *name)
1186{
1187 return pkey_test_init(t, name, 0, EVP_PKEY_sign_init, EVP_PKEY_sign);
1188}
1189
1190static const struct evp_test_method psign_test_method = {
1191 "Sign",
1192 sign_test_init,
1193 pkey_test_cleanup,
1194 pkey_test_parse,
1195 pkey_test_run
1196};
1197
1198static int verify_recover_test_init(struct evp_test *t, const char *name)
1199{
1200 return pkey_test_init(t, name, 1, EVP_PKEY_verify_recover_init,
1201 EVP_PKEY_verify_recover);
1202}
1203
1204static const struct evp_test_method pverify_recover_test_method = {
1205 "VerifyRecover",
1206 verify_recover_test_init,
1207 pkey_test_cleanup,
1208 pkey_test_parse,
1209 pkey_test_run
1210};
1211
1212static int decrypt_test_init(struct evp_test *t, const char *name)
1213{
1214 return pkey_test_init(t, name, 0, EVP_PKEY_decrypt_init,
1215 EVP_PKEY_decrypt);
1216}
1217
1218static const struct evp_test_method pdecrypt_test_method = {
1219 "Decrypt",
1220 decrypt_test_init,
1221 pkey_test_cleanup,
1222 pkey_test_parse,
1223 pkey_test_run
1224};
1225
1226static int verify_test_init(struct evp_test *t, const char *name)
1227{
1228 return pkey_test_init(t, name, 1, EVP_PKEY_verify_init, 0);
1229}
1230
1231static int verify_test_run(struct evp_test *t)
1232{
1233 struct pkey_data *kdata = t->data;
1234 if (EVP_PKEY_verify(kdata->ctx, kdata->output, kdata->output_len,
1235 kdata->input, kdata->input_len) <= 0)
1236 t->err = "VERIFY_ERROR";
1237 return 1;
1238}
1239
1240static const struct evp_test_method pverify_test_method = {
1241 "Verify",
1242 verify_test_init,
1243 pkey_test_cleanup,
1244 pkey_test_parse,
1245 verify_test_run
1246};