Line data Source code
1 : /* fipsdrv.c - A driver to help with FIPS CAVS tests.
2 : Copyright (C) 2008 Free Software Foundation, Inc.
3 :
4 : This file is part of Libgcrypt.
5 :
6 : Libgcrypt is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU Lesser General Public License as
8 : published by the Free Software Foundation; either version 2.1 of
9 : the License, or (at your option) any later version.
10 :
11 : Libgcrypt is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU Lesser General Public License for more details.
15 :
16 : You should have received a copy of the GNU Lesser General Public
17 : License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #ifdef HAVE_CONFIG_H
21 : #include <config.h>
22 : #endif
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <stdarg.h>
27 : #include <errno.h>
28 : #include <ctype.h>
29 : #ifdef HAVE_W32_SYSTEM
30 : # include <fcntl.h> /* We need setmode(). */
31 : #else
32 : # include <signal.h>
33 : #endif
34 : #include <assert.h>
35 : #include <unistd.h>
36 :
37 : #ifndef _GCRYPT_IN_LIBGCRYPT
38 : # include <gcrypt.h>
39 : # define PACKAGE_BUGREPORT "devnull@example.org"
40 : # define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
41 : #endif
42 : #include "../src/gcrypt-testapi.h"
43 :
44 : #define PGM "fipsdrv"
45 : #include "t-common.h"
46 :
47 :
48 : /* Binary input flag. */
49 : static int binary_input;
50 :
51 : /* Binary output flag. */
52 : static int binary_output;
53 :
54 : /* Base64 output flag. */
55 : static int base64_output;
56 :
57 : /* We need to know whether we are in loop_mode. */
58 : static int loop_mode;
59 :
60 : /* If true some functions are modified to print the output in the CAVS
61 : response file format. */
62 : static int standalone_mode;
63 :
64 :
65 : /* ASN.1 classes. */
66 : enum
67 : {
68 : UNIVERSAL = 0,
69 : APPLICATION = 1,
70 : ASNCONTEXT = 2,
71 : PRIVATE = 3
72 : };
73 :
74 :
75 : /* ASN.1 tags. */
76 : enum
77 : {
78 : TAG_NONE = 0,
79 : TAG_BOOLEAN = 1,
80 : TAG_INTEGER = 2,
81 : TAG_BIT_STRING = 3,
82 : TAG_OCTET_STRING = 4,
83 : TAG_NULL = 5,
84 : TAG_OBJECT_ID = 6,
85 : TAG_OBJECT_DESCRIPTOR = 7,
86 : TAG_EXTERNAL = 8,
87 : TAG_REAL = 9,
88 : TAG_ENUMERATED = 10,
89 : TAG_EMBEDDED_PDV = 11,
90 : TAG_UTF8_STRING = 12,
91 : TAG_REALTIVE_OID = 13,
92 : TAG_SEQUENCE = 16,
93 : TAG_SET = 17,
94 : TAG_NUMERIC_STRING = 18,
95 : TAG_PRINTABLE_STRING = 19,
96 : TAG_TELETEX_STRING = 20,
97 : TAG_VIDEOTEX_STRING = 21,
98 : TAG_IA5_STRING = 22,
99 : TAG_UTC_TIME = 23,
100 : TAG_GENERALIZED_TIME = 24,
101 : TAG_GRAPHIC_STRING = 25,
102 : TAG_VISIBLE_STRING = 26,
103 : TAG_GENERAL_STRING = 27,
104 : TAG_UNIVERSAL_STRING = 28,
105 : TAG_CHARACTER_STRING = 29,
106 : TAG_BMP_STRING = 30
107 : };
108 :
109 : /* ASN.1 Parser object. */
110 : struct tag_info
111 : {
112 : int class; /* Object class. */
113 : unsigned long tag; /* The tag of the object. */
114 : unsigned long length; /* Length of the values. */
115 : int nhdr; /* Length of the header (TL). */
116 : unsigned int ndef:1; /* The object has an indefinite length. */
117 : unsigned int cons:1; /* This is a constructed object. */
118 : };
119 :
120 :
121 : static void
122 0 : showhex (const char *prefix, const void *buffer, size_t length)
123 : {
124 0 : const unsigned char *p = buffer;
125 :
126 0 : if (prefix)
127 0 : fprintf (stderr, PGM ": %s: ", prefix);
128 0 : while (length-- )
129 0 : fprintf (stderr, "%02X", *p++);
130 0 : if (prefix)
131 0 : putc ('\n', stderr);
132 0 : }
133 :
134 : /* static void */
135 : /* show_sexp (const char *prefix, gcry_sexp_t a) */
136 : /* { */
137 : /* char *buf; */
138 : /* size_t size; */
139 :
140 : /* if (prefix) */
141 : /* fputs (prefix, stderr); */
142 : /* size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */
143 : /* buf = gcry_xmalloc (size); */
144 :
145 : /* gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */
146 : /* fprintf (stderr, "%.*s", (int)size, buf); */
147 : /* gcry_free (buf); */
148 : /* } */
149 :
150 :
151 : /* Convert STRING consisting of hex characters into its binary
152 : representation and store that at BUFFER. BUFFER needs to be of
153 : LENGTH bytes. The function checks that the STRING will convert
154 : exactly to LENGTH bytes. The string is delimited by either end of
155 : string or a white space character. The function returns -1 on
156 : error or the length of the parsed string. */
157 : static int
158 0 : hex2bin (const char *string, void *buffer, size_t length)
159 : {
160 : int i;
161 0 : const char *s = string;
162 :
163 0 : for (i=0; i < length; )
164 : {
165 0 : if (!hexdigitp (s) || !hexdigitp (s+1))
166 0 : return -1; /* Invalid hex digits. */
167 0 : ((unsigned char*)buffer)[i++] = xtoi_2 (s);
168 0 : s += 2;
169 : }
170 0 : if (*s && (!my_isascii (*s) || !isspace (*s)) )
171 0 : return -1; /* Not followed by Nul or white space. */
172 0 : if (i != length)
173 0 : return -1; /* Not of expected length. */
174 0 : if (*s)
175 0 : s++; /* Skip the delimiter. */
176 0 : return s - string;
177 : }
178 :
179 :
180 : /* Convert STRING consisting of hex characters into its binary
181 : representation and return it as an allocated buffer. The valid
182 : length of the buffer is returned at R_LENGTH. The string is
183 : delimited by end of string. The function returns NULL on
184 : error. */
185 : static void *
186 0 : hex2buffer (const char *string, size_t *r_length)
187 : {
188 : const char *s;
189 : unsigned char *buffer;
190 : size_t length;
191 :
192 0 : buffer = gcry_xmalloc (strlen(string)/2+1);
193 0 : length = 0;
194 0 : for (s=string; *s; s +=2 )
195 : {
196 0 : if (!hexdigitp (s) || !hexdigitp (s+1))
197 0 : return NULL; /* Invalid hex digits. */
198 0 : ((unsigned char*)buffer)[length++] = xtoi_2 (s);
199 : }
200 0 : *r_length = length;
201 0 : return buffer;
202 : }
203 :
204 :
205 : static char *
206 0 : read_textline (FILE *fp)
207 : {
208 : char line[256];
209 : char *p;
210 0 : int any = 0;
211 :
212 : /* Read line but skip over initial empty lines. */
213 : do
214 : {
215 : do
216 : {
217 0 : if (!fgets (line, sizeof line, fp))
218 : {
219 0 : if (feof (fp))
220 0 : return NULL;
221 0 : die ("error reading input line: %s\n", strerror (errno));
222 : }
223 0 : p = strchr (line, '\n');
224 0 : if (p)
225 0 : *p = 0;
226 0 : p = line + (*line? (strlen (line)-1):0);
227 0 : for ( ;p > line; p--)
228 0 : if (my_isascii (*p) && isspace (*p))
229 0 : *p = 0;
230 : }
231 0 : while (!any && !*line);
232 0 : any = 1;
233 : }
234 0 : while (*line == '#'); /* Always skip comment lines. */
235 0 : if (verbose > 1)
236 0 : fprintf (stderr, PGM ": received line: %s\n", line);
237 0 : return gcry_xstrdup (line);
238 : }
239 :
240 : static char *
241 0 : read_hexline (FILE *fp, size_t *retlen)
242 : {
243 : char *line, *p;
244 :
245 0 : line = read_textline (fp);
246 0 : if (!line)
247 0 : return NULL;
248 0 : p = hex2buffer (line, retlen);
249 0 : if (!p)
250 0 : die ("error decoding hex string on input\n");
251 0 : gcry_free (line);
252 0 : return p;
253 : }
254 :
255 : static void
256 0 : skip_to_empty_line (FILE *fp)
257 : {
258 : char line[256];
259 : char *p;
260 :
261 : do
262 : {
263 0 : if (!fgets (line, sizeof line, fp))
264 : {
265 0 : if (feof (fp))
266 0 : return;
267 0 : die ("error reading input line: %s\n", strerror (errno));
268 : }
269 0 : p = strchr (line, '\n');
270 0 : if (p)
271 0 : *p =0;
272 : }
273 0 : while (*line);
274 : }
275 :
276 :
277 :
278 : /* Read a file from stream FP into a newly allocated buffer and return
279 : that buffer. The valid length of the buffer is stored at R_LENGTH.
280 : Returns NULL on failure. If decode is set, the file is assumed to
281 : be hex encoded and the decoded content is returned. */
282 : static void *
283 0 : read_file (FILE *fp, int decode, size_t *r_length)
284 : {
285 : char *buffer;
286 : size_t buflen;
287 0 : size_t nread, bufsize = 0;
288 :
289 0 : *r_length = 0;
290 : #define NCHUNK 8192
291 : #ifdef HAVE_DOSISH_SYSTEM
292 : setmode (fileno(fp), O_BINARY);
293 : #endif
294 0 : buffer = NULL;
295 0 : buflen = 0;
296 : do
297 : {
298 0 : bufsize += NCHUNK;
299 0 : if (!buffer)
300 0 : buffer = gcry_xmalloc (bufsize);
301 : else
302 0 : buffer = gcry_xrealloc (buffer, bufsize);
303 :
304 0 : nread = fread (buffer + buflen, 1, NCHUNK, fp);
305 0 : if (nread < NCHUNK && ferror (fp))
306 : {
307 0 : gcry_free (buffer);
308 0 : return NULL;
309 : }
310 0 : buflen += nread;
311 : }
312 0 : while (nread == NCHUNK);
313 : #undef NCHUNK
314 0 : if (decode)
315 : {
316 : const char *s;
317 : char *p;
318 :
319 0 : for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 )
320 : {
321 0 : if (!hexdigitp (s) || !hexdigitp (s+1))
322 : {
323 0 : gcry_free (buffer);
324 0 : return NULL; /* Invalid hex digits. */
325 : }
326 0 : *(unsigned char*)p++ = xtoi_2 (s);
327 : }
328 0 : if (nread != buflen)
329 : {
330 0 : gcry_free (buffer);
331 0 : return NULL; /* Odd number of hex digits. */
332 : }
333 0 : buflen = p - buffer;
334 : }
335 :
336 0 : *r_length = buflen;
337 0 : return buffer;
338 : }
339 :
340 : /* Do in-place decoding of base-64 data of LENGTH in BUFFER. Returns
341 : the new length of the buffer. Dies on error. */
342 : static size_t
343 0 : base64_decode (char *buffer, size_t length)
344 : {
345 : static unsigned char const asctobin[128] =
346 : {
347 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
348 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
349 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
350 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
351 : 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
352 : 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
353 : 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
354 : 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
355 : 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
356 : 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
357 : 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
358 : };
359 :
360 0 : int idx = 0;
361 0 : unsigned char val = 0;
362 0 : int c = 0;
363 : char *d, *s;
364 0 : int lfseen = 1;
365 :
366 : /* Find BEGIN line. */
367 0 : for (s=buffer; length; length--, s++)
368 : {
369 0 : if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11))
370 : {
371 0 : for (; length && *s != '\n'; length--, s++)
372 : ;
373 0 : break;
374 : }
375 0 : lfseen = (*s == '\n');
376 : }
377 :
378 : /* Decode until pad character or END line. */
379 0 : for (d=buffer; length; length--, s++)
380 : {
381 0 : if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9))
382 0 : break;
383 0 : if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t')
384 0 : continue;
385 0 : if (*s == '=')
386 : {
387 : /* Pad character: stop */
388 0 : if (idx == 1)
389 0 : *d++ = val;
390 0 : break;
391 : }
392 :
393 0 : if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff)
394 0 : die ("invalid base64 character %02X at pos %d detected\n",
395 0 : *(unsigned char*)s, (int)(s-buffer));
396 :
397 0 : switch (idx)
398 : {
399 : case 0:
400 0 : val = c << 2;
401 0 : break;
402 : case 1:
403 0 : val |= (c>>4)&3;
404 0 : *d++ = val;
405 0 : val = (c<<4)&0xf0;
406 0 : break;
407 : case 2:
408 0 : val |= (c>>2)&15;
409 0 : *d++ = val;
410 0 : val = (c<<6)&0xc0;
411 0 : break;
412 : case 3:
413 0 : val |= c&0x3f;
414 0 : *d++ = val;
415 0 : break;
416 : }
417 0 : idx = (idx+1) % 4;
418 : }
419 :
420 0 : return d - buffer;
421 : }
422 :
423 :
424 : /* Parse the buffer at the address BUFFER which consists of the number
425 : of octets as stored at BUFLEN. Return the tag and the length part
426 : from the TLV triplet. Update BUFFER and BUFLEN on success. Checks
427 : that the encoded length does not exhaust the length of the provided
428 : buffer. */
429 : static int
430 0 : parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti)
431 : {
432 : int c;
433 : unsigned long tag;
434 0 : const unsigned char *buf = *buffer;
435 0 : size_t length = *buflen;
436 :
437 0 : ti->length = 0;
438 0 : ti->ndef = 0;
439 0 : ti->nhdr = 0;
440 :
441 : /* Get the tag */
442 0 : if (!length)
443 0 : return -1; /* Premature EOF. */
444 0 : c = *buf++; length--;
445 0 : ti->nhdr++;
446 :
447 0 : ti->class = (c & 0xc0) >> 6;
448 0 : ti->cons = !!(c & 0x20);
449 0 : tag = (c & 0x1f);
450 :
451 0 : if (tag == 0x1f)
452 : {
453 0 : tag = 0;
454 : do
455 : {
456 0 : tag <<= 7;
457 0 : if (!length)
458 0 : return -1; /* Premature EOF. */
459 0 : c = *buf++; length--;
460 0 : ti->nhdr++;
461 0 : tag |= (c & 0x7f);
462 : }
463 0 : while ( (c & 0x80) );
464 : }
465 0 : ti->tag = tag;
466 :
467 : /* Get the length */
468 0 : if (!length)
469 0 : return -1; /* Premature EOF. */
470 0 : c = *buf++; length--;
471 0 : ti->nhdr++;
472 :
473 0 : if ( !(c & 0x80) )
474 0 : ti->length = c;
475 0 : else if (c == 0x80)
476 0 : ti->ndef = 1;
477 0 : else if (c == 0xff)
478 0 : return -1; /* Forbidden length value. */
479 : else
480 : {
481 0 : unsigned long len = 0;
482 0 : int count = c & 0x7f;
483 :
484 0 : for (; count; count--)
485 : {
486 0 : len <<= 8;
487 0 : if (!length)
488 0 : return -1; /* Premature EOF. */
489 0 : c = *buf++; length--;
490 0 : ti->nhdr++;
491 0 : len |= (c & 0xff);
492 : }
493 0 : ti->length = len;
494 : }
495 :
496 0 : if (ti->class == UNIVERSAL && !ti->tag)
497 0 : ti->length = 0;
498 :
499 0 : if (ti->length > length)
500 0 : return -1; /* Data larger than buffer. */
501 :
502 0 : *buffer = buf;
503 0 : *buflen = length;
504 0 : return 0;
505 : }
506 :
507 :
508 : /* Read the file FNAME assuming it is a PEM encoded private key file
509 : and return an S-expression. With SHOW set, the key parameters are
510 : printed. */
511 : static gcry_sexp_t
512 0 : read_private_key_file (const char *fname, int show)
513 : {
514 : gcry_error_t err;
515 : FILE *fp;
516 : char *buffer;
517 : size_t buflen;
518 : const unsigned char *der;
519 : size_t derlen;
520 : struct tag_info ti;
521 : gcry_mpi_t keyparms[8];
522 0 : int n_keyparms = 8;
523 : int idx;
524 : gcry_sexp_t s_key;
525 :
526 0 : fp = fopen (fname, binary_input?"rb":"r");
527 0 : if (!fp)
528 0 : die ("can't open `%s': %s\n", fname, strerror (errno));
529 0 : buffer = read_file (fp, 0, &buflen);
530 0 : if (!buffer)
531 0 : die ("error reading `%s'\n", fname);
532 0 : fclose (fp);
533 :
534 0 : buflen = base64_decode (buffer, buflen);
535 :
536 : /* Parse the ASN.1 structure. */
537 0 : der = (const unsigned char*)buffer;
538 0 : derlen = buflen;
539 0 : if ( parse_tag (&der, &derlen, &ti)
540 0 : || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
541 : goto bad_asn1;
542 0 : if ( parse_tag (&der, &derlen, &ti)
543 0 : || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
544 : goto bad_asn1;
545 0 : if (ti.length != 1 || *der)
546 : goto bad_asn1; /* The value of the first integer is no 0. */
547 0 : der += ti.length; derlen -= ti.length;
548 :
549 0 : for (idx=0; idx < n_keyparms; idx++)
550 : {
551 0 : if ( parse_tag (&der, &derlen, &ti)
552 0 : || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
553 : goto bad_asn1;
554 0 : if (show)
555 : {
556 : char prefix[2];
557 :
558 0 : prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
559 0 : prefix[1] = 0;
560 0 : showhex (prefix, der, ti.length);
561 : }
562 0 : err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
563 0 : if (err)
564 0 : die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
565 0 : der += ti.length; derlen -= ti.length;
566 : }
567 0 : if (idx != n_keyparms)
568 0 : die ("not enough RSA key parameters\n");
569 :
570 0 : gcry_free (buffer);
571 :
572 : /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
573 : /* First check that p < q; if not swap p and q and recompute u. */
574 0 : if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
575 : {
576 0 : gcry_mpi_swap (keyparms[3], keyparms[4]);
577 0 : gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
578 : }
579 :
580 : /* Build the S-expression. */
581 0 : err = gcry_sexp_build (&s_key, NULL,
582 : "(private-key(rsa(n%m)(e%m)"
583 : /**/ "(d%m)(p%m)(q%m)(u%m)))",
584 : keyparms[0], keyparms[1], keyparms[2],
585 : keyparms[3], keyparms[4], keyparms[7] );
586 0 : if (err)
587 0 : die ("error building S-expression: %s\n", gpg_strerror (err));
588 :
589 0 : for (idx=0; idx < n_keyparms; idx++)
590 0 : gcry_mpi_release (keyparms[idx]);
591 :
592 0 : return s_key;
593 :
594 : bad_asn1:
595 0 : die ("invalid ASN.1 structure in `%s'\n", fname);
596 : return NULL; /*NOTREACHED*/
597 : }
598 :
599 :
600 : /* Read the file FNAME assuming it is a PEM encoded public key file
601 : and return an S-expression. With SHOW set, the key parameters are
602 : printed. */
603 : static gcry_sexp_t
604 0 : read_public_key_file (const char *fname, int show)
605 : {
606 : gcry_error_t err;
607 : FILE *fp;
608 : char *buffer;
609 : size_t buflen;
610 : const unsigned char *der;
611 : size_t derlen;
612 : struct tag_info ti;
613 : gcry_mpi_t keyparms[2];
614 0 : int n_keyparms = 2;
615 : int idx;
616 : gcry_sexp_t s_key;
617 :
618 0 : fp = fopen (fname, binary_input?"rb":"r");
619 0 : if (!fp)
620 0 : die ("can't open `%s': %s\n", fname, strerror (errno));
621 0 : buffer = read_file (fp, 0, &buflen);
622 0 : if (!buffer)
623 0 : die ("error reading `%s'\n", fname);
624 0 : fclose (fp);
625 :
626 0 : buflen = base64_decode (buffer, buflen);
627 :
628 : /* Parse the ASN.1 structure. */
629 0 : der = (const unsigned char*)buffer;
630 0 : derlen = buflen;
631 0 : if ( parse_tag (&der, &derlen, &ti)
632 0 : || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
633 : goto bad_asn1;
634 0 : if ( parse_tag (&der, &derlen, &ti)
635 0 : || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
636 : goto bad_asn1;
637 : /* We skip the description of the key parameters and assume it is RSA. */
638 0 : der += ti.length; derlen -= ti.length;
639 :
640 0 : if ( parse_tag (&der, &derlen, &ti)
641 0 : || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
642 : goto bad_asn1;
643 0 : if (ti.length < 1 || *der)
644 : goto bad_asn1; /* The number of unused bits needs to be 0. */
645 0 : der += 1; derlen -= 1;
646 :
647 : /* Parse the BIT string. */
648 0 : if ( parse_tag (&der, &derlen, &ti)
649 0 : || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
650 : goto bad_asn1;
651 :
652 0 : for (idx=0; idx < n_keyparms; idx++)
653 : {
654 0 : if ( parse_tag (&der, &derlen, &ti)
655 0 : || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
656 : goto bad_asn1;
657 0 : if (show)
658 : {
659 : char prefix[2];
660 :
661 0 : prefix[0] = idx < 2? "ne"[idx] : '?';
662 0 : prefix[1] = 0;
663 0 : showhex (prefix, der, ti.length);
664 : }
665 0 : err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
666 0 : if (err)
667 0 : die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
668 0 : der += ti.length; derlen -= ti.length;
669 : }
670 0 : if (idx != n_keyparms)
671 0 : die ("not enough RSA key parameters\n");
672 :
673 0 : gcry_free (buffer);
674 :
675 : /* Build the S-expression. */
676 0 : err = gcry_sexp_build (&s_key, NULL,
677 : "(public-key(rsa(n%m)(e%m)))",
678 : keyparms[0], keyparms[1] );
679 0 : if (err)
680 0 : die ("error building S-expression: %s\n", gpg_strerror (err));
681 :
682 0 : for (idx=0; idx < n_keyparms; idx++)
683 0 : gcry_mpi_release (keyparms[idx]);
684 :
685 0 : return s_key;
686 :
687 : bad_asn1:
688 0 : die ("invalid ASN.1 structure in `%s'\n", fname);
689 : return NULL; /*NOTREACHED*/
690 : }
691 :
692 :
693 :
694 : /* Read the file FNAME assuming it is a binary signature result and
695 : return an an S-expression suitable for gcry_pk_verify. */
696 : static gcry_sexp_t
697 0 : read_sig_file (const char *fname)
698 : {
699 : gcry_error_t err;
700 : FILE *fp;
701 : char *buffer;
702 : size_t buflen;
703 : gcry_mpi_t tmpmpi;
704 : gcry_sexp_t s_sig;
705 :
706 0 : fp = fopen (fname, "rb");
707 0 : if (!fp)
708 0 : die ("can't open `%s': %s\n", fname, strerror (errno));
709 0 : buffer = read_file (fp, 0, &buflen);
710 0 : if (!buffer)
711 0 : die ("error reading `%s'\n", fname);
712 0 : fclose (fp);
713 :
714 0 : err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL);
715 0 : if (!err)
716 0 : err = gcry_sexp_build (&s_sig, NULL,
717 : "(sig-val(rsa(s %m)))", tmpmpi);
718 0 : if (err)
719 0 : die ("error building S-expression: %s\n", gpg_strerror (err));
720 0 : gcry_mpi_release (tmpmpi);
721 0 : gcry_free (buffer);
722 :
723 0 : return s_sig;
724 : }
725 :
726 :
727 : /* Read an S-expression from FNAME. */
728 : static gcry_sexp_t
729 0 : read_sexp_from_file (const char *fname)
730 : {
731 : gcry_error_t err;
732 : FILE *fp;
733 : char *buffer;
734 : size_t buflen;
735 : gcry_sexp_t sexp;
736 :
737 0 : fp = fopen (fname, "rb");
738 0 : if (!fp)
739 0 : die ("can't open `%s': %s\n", fname, strerror (errno));
740 0 : buffer = read_file (fp, 0, &buflen);
741 0 : if (!buffer)
742 0 : die ("error reading `%s'\n", fname);
743 0 : fclose (fp);
744 0 : if (!buflen)
745 0 : die ("error: file `%s' is empty\n", fname);
746 :
747 0 : err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free);
748 0 : if (err)
749 0 : die ("error parsing `%s': %s\n", fname, gpg_strerror (err));
750 :
751 0 : return sexp;
752 : }
753 :
754 :
755 : static void
756 0 : print_buffer (const void *buffer, size_t length)
757 : {
758 0 : int writerr = 0;
759 :
760 0 : if (base64_output)
761 : {
762 : static const unsigned char bintoasc[64+1] =
763 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
764 : "abcdefghijklmnopqrstuvwxyz"
765 : "0123456789+/";
766 : const unsigned char *p;
767 : unsigned char inbuf[4];
768 : char outbuf[4];
769 : int idx, quads;
770 :
771 0 : idx = quads = 0;
772 0 : for (p = buffer; length; p++, length--)
773 : {
774 0 : inbuf[idx++] = *p;
775 0 : if (idx > 2)
776 : {
777 0 : outbuf[0] = bintoasc[(*inbuf>>2)&077];
778 0 : outbuf[1] = bintoasc[(((*inbuf<<4)&060)
779 0 : |((inbuf[1] >> 4)&017))&077];
780 0 : outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
781 0 : |((inbuf[2]>>6)&03))&077];
782 0 : outbuf[3] = bintoasc[inbuf[2]&077];
783 0 : if (fwrite (outbuf, 4, 1, stdout) != 1)
784 0 : writerr = 1;
785 0 : idx = 0;
786 0 : if (++quads >= (64/4))
787 : {
788 0 : if (fwrite ("\n", 1, 1, stdout) != 1)
789 0 : writerr = 1;
790 0 : quads = 0;
791 : }
792 : }
793 : }
794 0 : if (idx)
795 : {
796 0 : outbuf[0] = bintoasc[(*inbuf>>2)&077];
797 0 : if (idx == 1)
798 : {
799 0 : outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
800 0 : outbuf[2] = outbuf[3] = '=';
801 : }
802 : else
803 : {
804 0 : outbuf[1] = bintoasc[(((*inbuf<<4)&060)
805 0 : |((inbuf[1]>>4)&017))&077];
806 0 : outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
807 0 : outbuf[3] = '=';
808 : }
809 0 : if (fwrite (outbuf, 4, 1, stdout) != 1)
810 0 : writerr = 1;
811 0 : quads++;
812 : }
813 0 : if (quads && fwrite ("\n", 1, 1, stdout) != 1)
814 0 : writerr = 1;
815 : }
816 0 : else if (binary_output)
817 : {
818 0 : if (fwrite (buffer, length, 1, stdout) != 1)
819 0 : writerr++;
820 : }
821 : else
822 : {
823 0 : const unsigned char *p = buffer;
824 :
825 0 : if (verbose > 1)
826 0 : showhex ("sent line", buffer, length);
827 0 : while (length-- && !ferror (stdout) )
828 0 : printf ("%02X", *p++);
829 0 : if (ferror (stdout))
830 0 : writerr++;
831 : }
832 0 : if (!writerr && fflush (stdout) == EOF)
833 0 : writerr++;
834 0 : if (writerr)
835 : {
836 : #ifndef HAVE_W32_SYSTEM
837 0 : if (loop_mode && errno == EPIPE)
838 0 : loop_mode = 0;
839 : else
840 : #endif
841 0 : die ("writing output failed: %s\n", strerror (errno));
842 : }
843 0 : }
844 :
845 :
846 : /* Print an MPI on a line. */
847 : static void
848 0 : print_mpi_line (gcry_mpi_t a, int no_lz)
849 : {
850 : unsigned char *buf, *p;
851 : gcry_error_t err;
852 0 : int writerr = 0;
853 :
854 0 : err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
855 0 : if (err)
856 0 : die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
857 :
858 0 : p = buf;
859 0 : if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
860 0 : p += 2;
861 :
862 0 : printf ("%s\n", p);
863 0 : if (ferror (stdout))
864 0 : writerr++;
865 0 : if (!writerr && fflush (stdout) == EOF)
866 0 : writerr++;
867 0 : if (writerr)
868 0 : die ("writing output failed: %s\n", strerror (errno));
869 0 : gcry_free (buf);
870 0 : }
871 :
872 :
873 : /* Print some data on hex format on a line. */
874 : static void
875 0 : print_data_line (const void *data, size_t datalen)
876 : {
877 0 : const unsigned char *p = data;
878 0 : int writerr = 0;
879 :
880 0 : while (data && datalen-- && !ferror (stdout) )
881 0 : printf ("%02X", *p++);
882 0 : putchar ('\n');
883 0 : if (ferror (stdout))
884 0 : writerr++;
885 0 : if (!writerr && fflush (stdout) == EOF)
886 0 : writerr++;
887 0 : if (writerr)
888 0 : die ("writing output failed: %s\n", strerror (errno));
889 0 : }
890 :
891 : /* Print the S-expression A to the stream FP. */
892 : static void
893 0 : print_sexp (gcry_sexp_t a, FILE *fp)
894 : {
895 : char *buf;
896 : size_t size;
897 :
898 0 : size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
899 0 : buf = gcry_xmalloc (size);
900 0 : gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
901 0 : if (fwrite (buf, size, 1, fp) != 1)
902 0 : die ("error writing to stream: %s\n", strerror (errno));
903 0 : gcry_free (buf);
904 0 : }
905 :
906 :
907 :
908 :
909 : static gcry_error_t
910 0 : init_external_rng_test (void **r_context,
911 : unsigned int flags,
912 : const void *key, size_t keylen,
913 : const void *seed, size_t seedlen,
914 : const void *dt, size_t dtlen)
915 : {
916 0 : return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST,
917 : r_context, flags,
918 : key, keylen,
919 : seed, seedlen,
920 : dt, dtlen);
921 : }
922 :
923 : static gcry_error_t
924 0 : run_external_rng_test (void *context, void *buffer, size_t buflen)
925 : {
926 0 : return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen);
927 : }
928 :
929 : static void
930 0 : deinit_external_rng_test (void *context)
931 : {
932 0 : xgcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context);
933 0 : }
934 :
935 :
936 : /* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm
937 : identified and store the libgcrypt mode at R_MODE. Returns 0 on
938 : error. */
939 : static int
940 0 : map_openssl_cipher_name (const char *name, int *r_mode)
941 : {
942 : static struct {
943 : const char *name;
944 : int algo;
945 : int mode;
946 : } table[] =
947 : {
948 : { "bf-cbc", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
949 : { "bf", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
950 : { "bf-cfb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
951 : { "bf-ecb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
952 : { "bf-ofb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
953 :
954 : { "cast-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
955 : { "cast", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
956 : { "cast5-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
957 : { "cast5-cfb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
958 : { "cast5-ecb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
959 : { "cast5-ofb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
960 :
961 : { "des-cbc", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
962 : { "des", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
963 : { "des-cfb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
964 : { "des-ofb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
965 : { "des-ecb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
966 :
967 : { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
968 : { "des-ede3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
969 : { "des3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
970 : { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
971 : { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
972 :
973 : { "rc4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
974 :
975 : { "aes-128-cbc", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
976 : { "aes-128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
977 : { "aes-128-cfb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
978 : { "aes-128-ecb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
979 : { "aes-128-ofb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
980 :
981 : { "aes-192-cbc", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
982 : { "aes-192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
983 : { "aes-192-cfb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
984 : { "aes-192-ecb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
985 : { "aes-192-ofb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
986 :
987 : { "aes-256-cbc", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
988 : { "aes-256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
989 : { "aes-256-cfb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
990 : { "aes-256-ecb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
991 : { "aes-256-ofb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
992 :
993 : { NULL, 0 , 0 }
994 : };
995 : int idx;
996 :
997 0 : for (idx=0; table[idx].name; idx++)
998 0 : if (!strcmp (name, table[idx].name))
999 : {
1000 0 : *r_mode = table[idx].mode;
1001 0 : return table[idx].algo;
1002 : }
1003 0 : *r_mode = 0;
1004 0 : return 0;
1005 : }
1006 :
1007 :
1008 :
1009 : /* Run an encrypt or decryption operations. If DATA is NULL the
1010 : function reads its input in chunks of size DATALEN from fp and
1011 : processes it and writes it out until EOF. */
1012 : static void
1013 0 : run_encrypt_decrypt (int encrypt_mode,
1014 : int cipher_algo, int cipher_mode,
1015 : const void *iv_buffer, size_t iv_buflen,
1016 : const void *key_buffer, size_t key_buflen,
1017 : const void *data, size_t datalen, FILE *fp)
1018 : {
1019 : gpg_error_t err;
1020 : gcry_cipher_hd_t hd;
1021 : void *outbuf;
1022 : size_t outbuflen;
1023 : void *inbuf;
1024 : size_t inbuflen;
1025 : size_t blocklen;
1026 :
1027 0 : err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
1028 0 : if (err)
1029 0 : die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
1030 : cipher_algo, cipher_mode, gpg_strerror (err));
1031 :
1032 0 : blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
1033 0 : assert (blocklen);
1034 :
1035 0 : gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
1036 :
1037 0 : err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
1038 0 : if (err)
1039 0 : die ("gcry_cipher_setkey failed with keylen %u: %s\n",
1040 : (unsigned int)key_buflen, gpg_strerror (err));
1041 :
1042 0 : if (iv_buffer)
1043 : {
1044 0 : err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
1045 0 : if (err)
1046 0 : die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
1047 : (unsigned int)iv_buflen, gpg_strerror (err));
1048 : }
1049 :
1050 0 : inbuf = data? NULL : gcry_xmalloc (datalen);
1051 0 : outbuflen = datalen;
1052 0 : outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen);
1053 :
1054 : do
1055 : {
1056 0 : if (inbuf)
1057 : {
1058 0 : int nread = fread (inbuf, 1, datalen, fp);
1059 0 : if (nread < (int)datalen && ferror (fp))
1060 0 : die ("error reading input\n");
1061 0 : data = inbuf;
1062 0 : inbuflen = nread;
1063 : }
1064 : else
1065 0 : inbuflen = datalen;
1066 :
1067 0 : if (encrypt_mode)
1068 0 : err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
1069 : else
1070 0 : err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
1071 0 : if (err)
1072 0 : die ("gcry_cipher_%scrypt failed: %s\n",
1073 : encrypt_mode? "en":"de", gpg_strerror (err));
1074 :
1075 0 : print_buffer (outbuf, outbuflen);
1076 : }
1077 0 : while (inbuf);
1078 :
1079 0 : gcry_cipher_close (hd);
1080 0 : gcry_free (outbuf);
1081 0 : gcry_free (inbuf);
1082 0 : }
1083 :
1084 :
1085 : static void
1086 0 : get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen)
1087 : {
1088 : unsigned char tmp[17];
1089 :
1090 0 : if (gcry_cipher_ctl (hd, PRIV_CIPHERCTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
1091 0 : die ("error getting current input vector\n");
1092 0 : if (buflen > *tmp)
1093 0 : die ("buffer too short to store the current input vector\n");
1094 0 : memcpy (buffer, tmp+1, *tmp);
1095 0 : }
1096 :
1097 : /* Run the inner loop of the CAVS monte carlo test. */
1098 : static void
1099 0 : run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode,
1100 : const void *iv_buffer, size_t iv_buflen,
1101 : const void *key_buffer, size_t key_buflen,
1102 : const void *data, size_t datalen, int iterations)
1103 : {
1104 : gpg_error_t err;
1105 : gcry_cipher_hd_t hd;
1106 : size_t blocklen;
1107 : int count;
1108 : char input[16];
1109 : char output[16];
1110 : char last_output[16];
1111 : char last_last_output[16];
1112 : char last_iv[16];
1113 :
1114 :
1115 0 : err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
1116 0 : if (err)
1117 0 : die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
1118 : cipher_algo, cipher_mode, gpg_strerror (err));
1119 :
1120 0 : blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
1121 0 : if (!blocklen || blocklen > sizeof output)
1122 0 : die ("invalid block length %d\n", (int)blocklen);
1123 :
1124 :
1125 0 : gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
1126 :
1127 0 : err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
1128 0 : if (err)
1129 0 : die ("gcry_cipher_setkey failed with keylen %u: %s\n",
1130 : (unsigned int)key_buflen, gpg_strerror (err));
1131 :
1132 0 : if (iv_buffer)
1133 : {
1134 0 : err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
1135 0 : if (err)
1136 0 : die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
1137 : (unsigned int)iv_buflen, gpg_strerror (err));
1138 : }
1139 :
1140 0 : if (datalen != blocklen)
1141 0 : die ("length of input (%u) does not match block length (%u)\n",
1142 : (unsigned int)datalen, (unsigned int)blocklen);
1143 0 : memcpy (input, data, datalen);
1144 0 : memset (output, 0, sizeof output);
1145 0 : for (count=0; count < iterations; count++)
1146 : {
1147 0 : memcpy (last_last_output, last_output, sizeof last_output);
1148 0 : memcpy (last_output, output, sizeof output);
1149 :
1150 0 : get_current_iv (hd, last_iv, blocklen);
1151 :
1152 0 : if (encrypt_mode)
1153 0 : err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen);
1154 : else
1155 0 : err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen);
1156 0 : if (err)
1157 0 : die ("gcry_cipher_%scrypt failed: %s\n",
1158 : encrypt_mode? "en":"de", gpg_strerror (err));
1159 :
1160 :
1161 0 : if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB
1162 0 : || cipher_mode == GCRY_CIPHER_MODE_CBC))
1163 0 : memcpy (input, last_iv, blocklen);
1164 0 : else if (cipher_mode == GCRY_CIPHER_MODE_OFB)
1165 0 : memcpy (input, last_iv, blocklen);
1166 0 : else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB)
1167 0 : {
1168 : /* Reconstruct the output vector. */
1169 : int i;
1170 0 : for (i=0; i < blocklen; i++)
1171 0 : input[i] ^= output[i];
1172 : }
1173 : else
1174 0 : memcpy (input, output, blocklen);
1175 : }
1176 :
1177 0 : print_buffer (output, blocklen);
1178 0 : putchar ('\n');
1179 0 : print_buffer (last_output, blocklen);
1180 0 : putchar ('\n');
1181 0 : print_buffer (last_last_output, blocklen);
1182 0 : putchar ('\n');
1183 0 : get_current_iv (hd, last_iv, blocklen);
1184 0 : print_buffer (last_iv, blocklen); /* Last output vector. */
1185 0 : putchar ('\n');
1186 0 : print_buffer (input, blocklen); /* Next input text. */
1187 0 : putchar ('\n');
1188 0 : if (verbose > 1)
1189 0 : showhex ("sent line", "", 0);
1190 0 : putchar ('\n');
1191 0 : fflush (stdout);
1192 :
1193 0 : gcry_cipher_close (hd);
1194 0 : }
1195 :
1196 :
1197 :
1198 : /* Run a digest operation. */
1199 : static void
1200 0 : run_digest (int digest_algo, const void *data, size_t datalen)
1201 : {
1202 : gpg_error_t err;
1203 : gcry_md_hd_t hd;
1204 : const unsigned char *digest;
1205 : unsigned int digestlen;
1206 :
1207 0 : err = gcry_md_open (&hd, digest_algo, 0);
1208 0 : if (err)
1209 0 : die ("gcry_md_open failed for algo %d: %s\n",
1210 : digest_algo, gpg_strerror (err));
1211 :
1212 0 : gcry_md_write (hd, data, datalen);
1213 0 : digest = gcry_md_read (hd, digest_algo);
1214 0 : digestlen = gcry_md_get_algo_dlen (digest_algo);
1215 0 : print_buffer (digest, digestlen);
1216 0 : gcry_md_close (hd);
1217 0 : }
1218 :
1219 :
1220 : /* Run a HMAC operation. */
1221 : static void
1222 0 : run_hmac (int digest_algo, const void *key, size_t keylen,
1223 : const void *data, size_t datalen)
1224 : {
1225 : gpg_error_t err;
1226 : gcry_md_hd_t hd;
1227 : const unsigned char *digest;
1228 : unsigned int digestlen;
1229 :
1230 0 : err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
1231 0 : if (err)
1232 0 : die ("gcry_md_open failed for HMAC algo %d: %s\n",
1233 : digest_algo, gpg_strerror (err));
1234 :
1235 0 : gcry_md_setkey (hd, key, keylen);
1236 0 : if (err)
1237 0 : die ("gcry_md_setkey failed for HMAC algo %d: %s\n",
1238 : digest_algo, gpg_strerror (err));
1239 :
1240 0 : gcry_md_write (hd, data, datalen);
1241 0 : digest = gcry_md_read (hd, digest_algo);
1242 0 : digestlen = gcry_md_get_algo_dlen (digest_algo);
1243 0 : print_buffer (digest, digestlen);
1244 0 : gcry_md_close (hd);
1245 0 : }
1246 :
1247 :
1248 :
1249 : /* Derive an RSA key using the S-expression in (DATA,DATALEN). This
1250 : S-expression is used directly as input to gcry_pk_genkey. The
1251 : result is printed to stdout with one parameter per line in hex
1252 : format and in this order: p, q, n, d. */
1253 : static void
1254 0 : run_rsa_derive (const void *data, size_t datalen)
1255 : {
1256 : gpg_error_t err;
1257 : gcry_sexp_t s_keyspec, s_key, s_top, l1;
1258 : gcry_mpi_t mpi;
1259 : const char *parmlist;
1260 : int idx;
1261 :
1262 0 : if (!datalen)
1263 0 : err = gpg_error (GPG_ERR_NO_DATA);
1264 : else
1265 0 : err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
1266 0 : if (err)
1267 0 : die ("gcry_sexp_new failed for RSA key derive: %s\n",
1268 : gpg_strerror (err));
1269 :
1270 0 : err = gcry_pk_genkey (&s_key, s_keyspec);
1271 0 : if (err)
1272 0 : die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1273 :
1274 0 : gcry_sexp_release (s_keyspec);
1275 :
1276 : /* P and Q might have been swapped but we need to to return them in
1277 : the proper order. Build the parameter list accordingly. */
1278 0 : parmlist = "pqnd";
1279 0 : s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0);
1280 0 : if (s_top)
1281 : {
1282 0 : l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0);
1283 0 : if (l1)
1284 0 : parmlist = "qpnd";
1285 0 : gcry_sexp_release (l1);
1286 0 : gcry_sexp_release (s_top);
1287 : }
1288 :
1289 : /* Parse and print the parameters. */
1290 0 : l1 = gcry_sexp_find_token (s_key, "private-key", 0);
1291 0 : s_top = gcry_sexp_find_token (l1, "rsa", 0);
1292 0 : gcry_sexp_release (l1);
1293 0 : if (!s_top)
1294 0 : die ("private-key part not found in result\n");
1295 :
1296 0 : for (idx=0; parmlist[idx]; idx++)
1297 : {
1298 0 : l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
1299 0 : mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1300 0 : gcry_sexp_release (l1);
1301 0 : if (!mpi)
1302 0 : die ("parameter %c missing in private-key\n", parmlist[idx]);
1303 0 : print_mpi_line (mpi, 1);
1304 0 : gcry_mpi_release (mpi);
1305 : }
1306 :
1307 0 : gcry_sexp_release (s_top);
1308 0 : gcry_sexp_release (s_key);
1309 0 : }
1310 :
1311 :
1312 : /* Generate RSA key using the S-expression in (DATA,DATALEN). This
1313 : S-expression is used directly as input to gcry_pk_genkey. The
1314 : result is printed to stdout with one parameter per line in hex
1315 : format and in this order: e, p, q, n, d. */
1316 : static void
1317 0 : run_rsa_keygen (const void *data, size_t datalen, int test)
1318 : {
1319 : gpg_error_t err;
1320 : gcry_sexp_t s_keyspec, s_key, s_top, l1;
1321 : gcry_mpi_t mpi;
1322 : const char *parmlist;
1323 : int idx;
1324 :
1325 0 : if (!datalen)
1326 0 : err = gpg_error (GPG_ERR_NO_DATA);
1327 : else
1328 0 : err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
1329 0 : if (err)
1330 0 : die ("gcry_sexp_new failed for RSA key generation: %s\n",
1331 : gpg_strerror (err));
1332 :
1333 0 : err = gcry_pk_genkey (&s_key, s_keyspec);
1334 :
1335 0 : gcry_sexp_release (s_keyspec);
1336 :
1337 0 : if (test) {
1338 0 : if (err)
1339 0 : printf("F\n");
1340 : else {
1341 0 : gcry_sexp_release (s_key);
1342 0 : printf("P\n");
1343 : }
1344 0 : return;
1345 : }
1346 :
1347 0 : if (err)
1348 0 : die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1349 :
1350 0 : parmlist = "epqnd";
1351 :
1352 : /* Parse and print the parameters. */
1353 0 : l1 = gcry_sexp_find_token (s_key, "private-key", 0);
1354 0 : s_top = gcry_sexp_find_token (l1, "rsa", 0);
1355 0 : gcry_sexp_release (l1);
1356 0 : if (!s_top)
1357 0 : die ("private-key part not found in result\n");
1358 :
1359 0 : for (idx=0; parmlist[idx]; idx++)
1360 : {
1361 0 : l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
1362 0 : mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1363 0 : gcry_sexp_release (l1);
1364 0 : if (!mpi)
1365 0 : die ("parameter %c missing in private-key\n", parmlist[idx]);
1366 0 : print_mpi_line (mpi, 1);
1367 0 : gcry_mpi_release (mpi);
1368 : }
1369 :
1370 0 : gcry_sexp_release (s_top);
1371 0 : gcry_sexp_release (s_key);
1372 : }
1373 :
1374 :
1375 :
1376 : static size_t
1377 0 : compute_tag_length (size_t n)
1378 : {
1379 0 : int needed = 0;
1380 :
1381 0 : if (n < 128)
1382 0 : needed += 2; /* Tag and one length byte. */
1383 0 : else if (n < 256)
1384 0 : needed += 3; /* Tag, number of length bytes, 1 length byte. */
1385 0 : else if (n < 65536)
1386 0 : needed += 4; /* Tag, number of length bytes, 2 length bytes. */
1387 : else
1388 0 : die ("DER object too long to encode\n");
1389 :
1390 0 : return needed;
1391 : }
1392 :
1393 : static unsigned char *
1394 0 : store_tag_length (unsigned char *p, int tag, size_t n)
1395 : {
1396 0 : if (tag == TAG_SEQUENCE)
1397 0 : tag |= 0x20; /* constructed */
1398 :
1399 0 : *p++ = tag;
1400 0 : if (n < 128)
1401 0 : *p++ = n;
1402 0 : else if (n < 256)
1403 : {
1404 0 : *p++ = 0x81;
1405 0 : *p++ = n;
1406 : }
1407 0 : else if (n < 65536)
1408 : {
1409 0 : *p++ = 0x82;
1410 0 : *p++ = n >> 8;
1411 0 : *p++ = n;
1412 : }
1413 :
1414 0 : return p;
1415 : }
1416 :
1417 :
1418 : /* Generate an RSA key of size KEYSIZE using the public exponent
1419 : PUBEXP and print it to stdout in the OpenSSL format. The format
1420 : is:
1421 :
1422 : SEQUENCE {
1423 : INTEGER (0) -- Unknown constant.
1424 : INTEGER -- n
1425 : INTEGER -- e
1426 : INTEGER -- d
1427 : INTEGER -- p
1428 : INTEGER -- q (with p < q)
1429 : INTEGER -- dmp1 = d mod (p-1)
1430 : INTEGER -- dmq1 = d mod (q-1)
1431 : INTEGER -- u = p^{-1} mod q
1432 : }
1433 :
1434 : */
1435 : static void
1436 0 : run_rsa_gen (int keysize, int pubexp)
1437 : {
1438 : gpg_error_t err;
1439 : gcry_sexp_t keyspec, key, l1;
1440 0 : const char keyelems[] = "nedpq..u";
1441 : gcry_mpi_t keyparms[8];
1442 : size_t keyparmslen[8];
1443 : int idx;
1444 : size_t derlen, needed, n;
1445 : unsigned char *derbuf, *der;
1446 :
1447 0 : err = gcry_sexp_build (&keyspec, NULL,
1448 : "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
1449 : keysize, pubexp);
1450 0 : if (err)
1451 0 : die ("gcry_sexp_build failed for RSA key generation: %s\n",
1452 : gpg_strerror (err));
1453 :
1454 0 : err = gcry_pk_genkey (&key, keyspec);
1455 0 : if (err)
1456 0 : die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1457 :
1458 0 : gcry_sexp_release (keyspec);
1459 :
1460 0 : l1 = gcry_sexp_find_token (key, "private-key", 0);
1461 0 : if (!l1)
1462 0 : die ("private key not found in genkey result\n");
1463 0 : gcry_sexp_release (key);
1464 0 : key = l1;
1465 :
1466 0 : l1 = gcry_sexp_find_token (key, "rsa", 0);
1467 0 : if (!l1)
1468 0 : die ("returned private key not formed as expected\n");
1469 0 : gcry_sexp_release (key);
1470 0 : key = l1;
1471 :
1472 : /* Extract the parameters from the S-expression and store them in a
1473 : well defined order in KEYPARMS. */
1474 0 : for (idx=0; idx < DIM(keyparms); idx++)
1475 : {
1476 0 : if (keyelems[idx] == '.')
1477 : {
1478 0 : keyparms[idx] = gcry_mpi_new (0);
1479 0 : continue;
1480 : }
1481 0 : l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
1482 0 : if (!l1)
1483 0 : die ("no %c parameter in returned private key\n", keyelems[idx]);
1484 0 : keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1485 0 : if (!keyparms[idx])
1486 0 : die ("no value for %c parameter in returned private key\n",
1487 0 : keyelems[idx]);
1488 0 : gcry_sexp_release (l1);
1489 : }
1490 :
1491 0 : gcry_sexp_release (key);
1492 :
1493 : /* Check that p < q; if not swap p and q and recompute u. */
1494 0 : if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
1495 : {
1496 0 : gcry_mpi_swap (keyparms[3], keyparms[4]);
1497 0 : gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
1498 : }
1499 :
1500 : /* Compute the additional parameters. */
1501 0 : gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
1502 0 : gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
1503 0 : gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
1504 0 : gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
1505 :
1506 : /* Compute the length of the DER encoding. */
1507 0 : needed = compute_tag_length (1) + 1;
1508 0 : for (idx=0; idx < DIM(keyparms); idx++)
1509 : {
1510 0 : err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
1511 0 : if (err)
1512 0 : die ("error formatting parameter: %s\n", gpg_strerror (err));
1513 0 : keyparmslen[idx] = n;
1514 0 : needed += compute_tag_length (n) + n;
1515 : }
1516 :
1517 : /* Store the key parameters. */
1518 0 : derlen = compute_tag_length (needed) + needed;
1519 0 : der = derbuf = gcry_xmalloc (derlen);
1520 :
1521 0 : der = store_tag_length (der, TAG_SEQUENCE, needed);
1522 0 : der = store_tag_length (der, TAG_INTEGER, 1);
1523 0 : *der++ = 0;
1524 0 : for (idx=0; idx < DIM(keyparms); idx++)
1525 : {
1526 0 : der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
1527 0 : err = gcry_mpi_print (GCRYMPI_FMT_STD, der,
1528 : keyparmslen[idx], NULL, keyparms[idx]);
1529 0 : if (err)
1530 0 : die ("error formatting parameter: %s\n", gpg_strerror (err));
1531 0 : der += keyparmslen[idx];
1532 : }
1533 :
1534 : /* Print the stuff. */
1535 0 : for (idx=0; idx < DIM(keyparms); idx++)
1536 0 : gcry_mpi_release (keyparms[idx]);
1537 :
1538 0 : assert (der - derbuf == derlen);
1539 :
1540 0 : if (base64_output)
1541 0 : puts ("-----BEGIN RSA PRIVATE KEY-----");
1542 0 : print_buffer (derbuf, derlen);
1543 0 : if (base64_output)
1544 0 : puts ("-----END RSA PRIVATE KEY-----");
1545 :
1546 0 : gcry_free (derbuf);
1547 0 : }
1548 :
1549 :
1550 :
1551 : /* Sign DATA of length DATALEN using the key taken from the PEM
1552 : encoded KEYFILE and the hash algorithm HASHALGO. */
1553 : static void
1554 0 : run_rsa_sign (const void *data, size_t datalen,
1555 : int hashalgo, int pkcs1, int pss, const char *keyfile)
1556 :
1557 : {
1558 : gpg_error_t err;
1559 : gcry_sexp_t s_data, s_key, s_sig, s_tmp;
1560 0 : gcry_mpi_t sig_mpi = NULL;
1561 : unsigned char *outbuf;
1562 : size_t outlen;
1563 :
1564 : /* showhex ("D", data, datalen); */
1565 0 : if (pkcs1)
1566 : {
1567 : unsigned char hash[64];
1568 : unsigned int hashsize;
1569 :
1570 0 : hashsize = gcry_md_get_algo_dlen (hashalgo);
1571 0 : if (!hashsize || hashsize > sizeof hash)
1572 0 : die ("digest too long for buffer or unknown hash algorithm\n");
1573 0 : gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1574 0 : err = gcry_sexp_build (&s_data, NULL,
1575 : "(data (flags pkcs1)(hash %s %b))",
1576 : gcry_md_algo_name (hashalgo),
1577 : (int)hashsize, hash);
1578 : }
1579 0 : else if (pss)
1580 : {
1581 : unsigned char hash[64];
1582 : unsigned int hashsize;
1583 :
1584 0 : hashsize = gcry_md_get_algo_dlen (hashalgo);
1585 0 : if (!hashsize || hashsize > sizeof hash)
1586 0 : die ("digest too long for buffer or unknown hash algorithm\n");
1587 0 : gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1588 0 : err = gcry_sexp_build (&s_data, NULL,
1589 : "(data (flags pss)(salt-length #00#)(hash %s %b))",
1590 : gcry_md_algo_name (hashalgo),
1591 : (int)hashsize, hash);
1592 : }
1593 : else
1594 : {
1595 : gcry_mpi_t tmp;
1596 :
1597 0 : err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1598 0 : if (!err)
1599 : {
1600 0 : err = gcry_sexp_build (&s_data, NULL,
1601 : "(data (flags raw)(value %m))", tmp);
1602 0 : gcry_mpi_release (tmp);
1603 : }
1604 : }
1605 0 : if (err)
1606 0 : die ("gcry_sexp_build failed for RSA data input: %s\n",
1607 : gpg_strerror (err));
1608 :
1609 0 : s_key = read_private_key_file (keyfile, 0);
1610 :
1611 0 : err = gcry_pk_sign (&s_sig, s_data, s_key);
1612 0 : if (err)
1613 : {
1614 0 : gcry_sexp_release (read_private_key_file (keyfile, 1));
1615 0 : die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
1616 : (int)datalen, keyfile, gpg_strerror (err));
1617 : }
1618 0 : gcry_sexp_release (s_key);
1619 0 : gcry_sexp_release (s_data);
1620 :
1621 0 : s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
1622 0 : if (s_tmp)
1623 : {
1624 0 : gcry_sexp_release (s_sig);
1625 0 : s_sig = s_tmp;
1626 0 : s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
1627 0 : if (s_tmp)
1628 : {
1629 0 : gcry_sexp_release (s_sig);
1630 0 : s_sig = s_tmp;
1631 0 : s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
1632 0 : if (s_tmp)
1633 : {
1634 0 : gcry_sexp_release (s_sig);
1635 0 : s_sig = s_tmp;
1636 0 : sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
1637 : }
1638 : }
1639 : }
1640 0 : gcry_sexp_release (s_sig);
1641 :
1642 0 : if (!sig_mpi)
1643 0 : die ("no value in returned S-expression\n");
1644 0 : err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
1645 0 : if (err)
1646 0 : die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
1647 0 : gcry_mpi_release (sig_mpi);
1648 :
1649 0 : print_buffer (outbuf, outlen);
1650 0 : gcry_free (outbuf);
1651 0 : }
1652 :
1653 :
1654 :
1655 : /* Verify DATA of length DATALEN using the public key taken from the
1656 : PEM encoded KEYFILE and the hash algorithm HASHALGO against the
1657 : binary signature in SIGFILE. */
1658 : static void
1659 0 : run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
1660 : int pss, const char *keyfile, const char *sigfile)
1661 :
1662 : {
1663 : gpg_error_t err;
1664 : gcry_sexp_t s_data, s_key, s_sig;
1665 :
1666 0 : if (pkcs1)
1667 : {
1668 : unsigned char hash[64];
1669 : unsigned int hashsize;
1670 :
1671 0 : hashsize = gcry_md_get_algo_dlen (hashalgo);
1672 0 : if (!hashsize || hashsize > sizeof hash)
1673 0 : die ("digest too long for buffer or unknown hash algorithm\n");
1674 0 : gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1675 0 : err = gcry_sexp_build (&s_data, NULL,
1676 : "(data (flags pkcs1)(hash %s %b))",
1677 : gcry_md_algo_name (hashalgo),
1678 : (int)hashsize, hash);
1679 : }
1680 0 : else if (pss)
1681 : {
1682 : unsigned char hash[64];
1683 : unsigned int hashsize;
1684 :
1685 0 : hashsize = gcry_md_get_algo_dlen (hashalgo);
1686 0 : if (!hashsize || hashsize > sizeof hash)
1687 0 : die ("digest too long for buffer or unknown hash algorithm\n");
1688 0 : gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1689 0 : err = gcry_sexp_build (&s_data, NULL,
1690 : "(data (flags pss)(salt-length #00#)(hash %s %b))",
1691 : gcry_md_algo_name (hashalgo),
1692 : (int)hashsize, hash);
1693 : }
1694 : else
1695 : {
1696 : gcry_mpi_t tmp;
1697 :
1698 0 : err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1699 0 : if (!err)
1700 : {
1701 0 : err = gcry_sexp_build (&s_data, NULL,
1702 : "(data (flags raw)(value %m))", tmp);
1703 0 : gcry_mpi_release (tmp);
1704 : }
1705 : }
1706 0 : if (err)
1707 0 : die ("gcry_sexp_build failed for RSA data input: %s\n",
1708 : gpg_strerror (err));
1709 :
1710 0 : s_key = read_public_key_file (keyfile, 0);
1711 :
1712 0 : s_sig = read_sig_file (sigfile);
1713 :
1714 0 : err = gcry_pk_verify (s_sig, s_data, s_key);
1715 0 : if (!err)
1716 0 : puts ("GOOD signature");
1717 0 : else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
1718 0 : puts ("BAD signature");
1719 : else
1720 0 : printf ("ERROR (%s)\n", gpg_strerror (err));
1721 :
1722 0 : gcry_sexp_release (s_sig);
1723 0 : gcry_sexp_release (s_key);
1724 0 : gcry_sexp_release (s_data);
1725 0 : }
1726 :
1727 :
1728 :
1729 : /* Generate a DSA key of size KEYSIZE and return the complete
1730 : S-expression. */
1731 : static gcry_sexp_t
1732 0 : dsa_gen (int keysize)
1733 : {
1734 : gpg_error_t err;
1735 : gcry_sexp_t keyspec, key;
1736 :
1737 0 : err = gcry_sexp_build (&keyspec, NULL,
1738 : "(genkey (dsa (nbits %d)(use-fips186-2)))",
1739 : keysize);
1740 0 : if (err)
1741 0 : die ("gcry_sexp_build failed for DSA key generation: %s\n",
1742 : gpg_strerror (err));
1743 :
1744 0 : err = gcry_pk_genkey (&key, keyspec);
1745 0 : if (err)
1746 0 : die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
1747 :
1748 0 : gcry_sexp_release (keyspec);
1749 :
1750 0 : return key;
1751 : }
1752 :
1753 :
1754 : /* Generate a DSA key of size KEYSIZE and return the complete
1755 : S-expression. */
1756 : static gcry_sexp_t
1757 0 : dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen)
1758 : {
1759 : gpg_error_t err;
1760 : gcry_sexp_t keyspec, key;
1761 :
1762 0 : err = gcry_sexp_build (&keyspec, NULL,
1763 : "(genkey"
1764 : " (dsa"
1765 : " (nbits %d)"
1766 : " (use-fips186-2)"
1767 : " (derive-parms"
1768 : " (seed %b))))",
1769 : keysize, (int)seedlen, seed);
1770 0 : if (err)
1771 0 : die ("gcry_sexp_build failed for DSA key generation: %s\n",
1772 : gpg_strerror (err));
1773 :
1774 0 : err = gcry_pk_genkey (&key, keyspec);
1775 0 : if (err)
1776 0 : die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
1777 :
1778 0 : gcry_sexp_release (keyspec);
1779 :
1780 0 : return key;
1781 : }
1782 :
1783 :
1784 : /* Generate an ECDSA key on the specified curve and return the complete
1785 : S-expression. */
1786 : static gcry_sexp_t
1787 0 : ecdsa_gen_key (const char *curve)
1788 : {
1789 : gpg_error_t err;
1790 : gcry_sexp_t keyspec, key;
1791 :
1792 0 : err = gcry_sexp_build (&keyspec, NULL,
1793 : "(genkey"
1794 : " (ecc"
1795 : " (use-fips186)"
1796 : " (curve %s)))",
1797 : curve);
1798 0 : if (err)
1799 0 : die ("gcry_sexp_build failed for ECDSA key generation: %s\n",
1800 : gpg_strerror (err));
1801 0 : err = gcry_pk_genkey (&key, keyspec);
1802 0 : if (err)
1803 0 : die ("gcry_pk_genkey failed for ECDSA: %s\n", gpg_strerror (err));
1804 :
1805 0 : gcry_sexp_release (keyspec);
1806 :
1807 0 : return key;
1808 : }
1809 :
1810 :
1811 : /* Print the domain parameter as well as the derive information. KEY
1812 : is the complete key as returned by dsa_gen. We print to stdout
1813 : with one parameter per line in hex format using this order: p, q,
1814 : g, seed, counter, h. */
1815 : static void
1816 0 : print_dsa_domain_parameters (gcry_sexp_t key)
1817 : {
1818 : gcry_sexp_t l1, l2;
1819 : gcry_mpi_t mpi;
1820 : int idx;
1821 : const void *data;
1822 : size_t datalen;
1823 : char *string;
1824 :
1825 0 : l1 = gcry_sexp_find_token (key, "public-key", 0);
1826 0 : if (!l1)
1827 0 : die ("public key not found in genkey result\n");
1828 :
1829 0 : l2 = gcry_sexp_find_token (l1, "dsa", 0);
1830 0 : if (!l2)
1831 0 : die ("returned public key not formed as expected\n");
1832 0 : gcry_sexp_release (l1);
1833 0 : l1 = l2;
1834 :
1835 : /* Extract the parameters from the S-expression and print them to stdout. */
1836 0 : for (idx=0; "pqg"[idx]; idx++)
1837 : {
1838 0 : l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1);
1839 0 : if (!l2)
1840 0 : die ("no %c parameter in returned public key\n", "pqg"[idx]);
1841 0 : mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1842 0 : if (!mpi)
1843 0 : die ("no value for %c parameter in returned public key\n","pqg"[idx]);
1844 0 : gcry_sexp_release (l2);
1845 0 : if (standalone_mode)
1846 0 : printf ("%c = ", "PQG"[idx]);
1847 0 : print_mpi_line (mpi, 1);
1848 0 : gcry_mpi_release (mpi);
1849 : }
1850 0 : gcry_sexp_release (l1);
1851 :
1852 : /* Extract the seed values. */
1853 0 : l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
1854 0 : if (!l1)
1855 0 : die ("misc-key-info not found in genkey result\n");
1856 :
1857 0 : l2 = gcry_sexp_find_token (l1, "seed-values", 0);
1858 0 : if (!l2)
1859 0 : die ("no seed-values in returned key\n");
1860 0 : gcry_sexp_release (l1);
1861 0 : l1 = l2;
1862 :
1863 0 : l2 = gcry_sexp_find_token (l1, "seed", 0);
1864 0 : if (!l2)
1865 0 : die ("no seed value in returned key\n");
1866 0 : data = gcry_sexp_nth_data (l2, 1, &datalen);
1867 0 : if (!data)
1868 0 : die ("no seed value in returned key\n");
1869 0 : if (standalone_mode)
1870 0 : printf ("Seed = ");
1871 0 : print_data_line (data, datalen);
1872 0 : gcry_sexp_release (l2);
1873 :
1874 0 : l2 = gcry_sexp_find_token (l1, "counter", 0);
1875 0 : if (!l2)
1876 0 : die ("no counter value in returned key\n");
1877 0 : string = gcry_sexp_nth_string (l2, 1);
1878 0 : if (!string)
1879 0 : die ("no counter value in returned key\n");
1880 0 : if (standalone_mode)
1881 0 : printf ("c = %ld\n", strtoul (string, NULL, 10));
1882 : else
1883 0 : printf ("%lX\n", strtoul (string, NULL, 10));
1884 0 : gcry_free (string);
1885 0 : gcry_sexp_release (l2);
1886 :
1887 0 : l2 = gcry_sexp_find_token (l1, "h", 0);
1888 0 : if (!l2)
1889 0 : die ("no n value in returned key\n");
1890 0 : mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1891 0 : if (!mpi)
1892 0 : die ("no h value in returned key\n");
1893 0 : if (standalone_mode)
1894 0 : printf ("H = ");
1895 0 : print_mpi_line (mpi, 1);
1896 0 : gcry_mpi_release (mpi);
1897 0 : gcry_sexp_release (l2);
1898 :
1899 0 : gcry_sexp_release (l1);
1900 0 : }
1901 :
1902 :
1903 : /* Print public key Q (in octet-string format) and private key d.
1904 : KEY is the complete key as returned by ecdsa_gen_key.
1905 : with one parameter per line in hex format using this order: d, Q. */
1906 : static void
1907 0 : print_ecdsa_dq (gcry_sexp_t key)
1908 : {
1909 : gcry_sexp_t l1, l2;
1910 : gcry_mpi_t mpi;
1911 : int idx;
1912 :
1913 0 : l1 = gcry_sexp_find_token (key, "private-key", 0);
1914 0 : if (!l1)
1915 0 : die ("private key not found in genkey result\n");
1916 :
1917 0 : l2 = gcry_sexp_find_token (l1, "ecc", 0);
1918 0 : if (!l2)
1919 0 : die ("returned private key not formed as expected\n");
1920 0 : gcry_sexp_release (l1);
1921 0 : l1 = l2;
1922 :
1923 : /* Extract the parameters from the S-expression and print them to stdout. */
1924 0 : for (idx=0; "dq"[idx]; idx++)
1925 : {
1926 0 : l2 = gcry_sexp_find_token (l1, "dq"+idx, 1);
1927 0 : if (!l2)
1928 0 : die ("no %c parameter in returned public key\n", "dq"[idx]);
1929 0 : mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1930 0 : if (!mpi)
1931 0 : die ("no value for %c parameter in returned private key\n","dq"[idx]);
1932 0 : gcry_sexp_release (l2);
1933 0 : if (standalone_mode)
1934 0 : printf ("%c = ", "dQ"[idx]);
1935 0 : print_mpi_line (mpi, 1);
1936 0 : gcry_mpi_release (mpi);
1937 : }
1938 :
1939 0 : gcry_sexp_release (l1);
1940 0 : }
1941 :
1942 :
1943 : /* Generate DSA domain parameters for a modulus size of KEYSIZE. The
1944 : result is printed to stdout with one parameter per line in hex
1945 : format and in this order: p, q, g, seed, counter, h. If SEED is
1946 : not NULL this seed value will be used for the generation. */
1947 : static void
1948 0 : run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen)
1949 : {
1950 : gcry_sexp_t key;
1951 :
1952 0 : if (seed)
1953 0 : key = dsa_gen_with_seed (keysize, seed, seedlen);
1954 : else
1955 0 : key = dsa_gen (keysize);
1956 0 : print_dsa_domain_parameters (key);
1957 0 : gcry_sexp_release (key);
1958 0 : }
1959 :
1960 :
1961 : /* Generate a DSA key of size of KEYSIZE and write the private key to
1962 : FILENAME. Also write the parameters to stdout in the same way as
1963 : run_dsa_pqg_gen. */
1964 : static void
1965 0 : run_dsa_gen (int keysize, const char *filename)
1966 : {
1967 : gcry_sexp_t key, private_key;
1968 : FILE *fp;
1969 :
1970 0 : key = dsa_gen (keysize);
1971 0 : private_key = gcry_sexp_find_token (key, "private-key", 0);
1972 0 : if (!private_key)
1973 0 : die ("private key not found in genkey result\n");
1974 0 : print_dsa_domain_parameters (key);
1975 :
1976 0 : fp = fopen (filename, "wb");
1977 0 : if (!fp)
1978 0 : die ("can't create `%s': %s\n", filename, strerror (errno));
1979 0 : print_sexp (private_key, fp);
1980 0 : fclose (fp);
1981 :
1982 0 : gcry_sexp_release (private_key);
1983 0 : gcry_sexp_release (key);
1984 0 : }
1985 :
1986 :
1987 :
1988 : /* Sign DATA of length DATALEN using the key taken from the S-expression
1989 : encoded KEYFILE. */
1990 : static void
1991 0 : run_dsa_sign (const void *data, size_t datalen, const char *keyfile)
1992 :
1993 : {
1994 : gpg_error_t err;
1995 : gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2;
1996 : char hash[20];
1997 : gcry_mpi_t tmpmpi;
1998 :
1999 0 : gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
2000 0 : err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
2001 0 : if (!err)
2002 : {
2003 0 : err = gcry_sexp_build (&s_data, NULL,
2004 : "(data (flags raw)(value %m))", tmpmpi);
2005 0 : gcry_mpi_release (tmpmpi);
2006 : }
2007 0 : if (err)
2008 0 : die ("gcry_sexp_build failed for DSA data input: %s\n",
2009 : gpg_strerror (err));
2010 :
2011 0 : s_key = read_sexp_from_file (keyfile);
2012 :
2013 0 : err = gcry_pk_sign (&s_sig, s_data, s_key);
2014 0 : if (err)
2015 : {
2016 0 : gcry_sexp_release (read_private_key_file (keyfile, 1));
2017 0 : die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
2018 : (int)datalen, keyfile, gpg_strerror (err));
2019 : }
2020 0 : gcry_sexp_release (s_data);
2021 :
2022 : /* We need to return the Y parameter first. */
2023 0 : s_tmp = gcry_sexp_find_token (s_key, "private-key", 0);
2024 0 : if (!s_tmp)
2025 0 : die ("private key part not found in provided key\n");
2026 :
2027 0 : s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0);
2028 0 : if (!s_tmp2)
2029 0 : die ("private key part is not a DSA key\n");
2030 0 : gcry_sexp_release (s_tmp);
2031 :
2032 0 : s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0);
2033 0 : tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2034 0 : if (!tmpmpi)
2035 0 : die ("no y parameter in DSA key\n");
2036 0 : print_mpi_line (tmpmpi, 1);
2037 0 : gcry_mpi_release (tmpmpi);
2038 0 : gcry_sexp_release (s_tmp);
2039 :
2040 0 : gcry_sexp_release (s_key);
2041 :
2042 :
2043 : /* Now return the actual signature. */
2044 0 : s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
2045 0 : if (!s_tmp)
2046 0 : die ("no sig-val element in returned S-expression\n");
2047 :
2048 0 : gcry_sexp_release (s_sig);
2049 0 : s_sig = s_tmp;
2050 0 : s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0);
2051 0 : if (!s_tmp)
2052 0 : die ("no dsa element in returned S-expression\n");
2053 :
2054 0 : gcry_sexp_release (s_sig);
2055 0 : s_sig = s_tmp;
2056 :
2057 0 : s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
2058 0 : tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2059 0 : if (!tmpmpi)
2060 0 : die ("no r parameter in returned S-expression\n");
2061 0 : print_mpi_line (tmpmpi, 1);
2062 0 : gcry_mpi_release (tmpmpi);
2063 0 : gcry_sexp_release (s_tmp);
2064 :
2065 0 : s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
2066 0 : tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2067 0 : if (!tmpmpi)
2068 0 : die ("no s parameter in returned S-expression\n");
2069 0 : print_mpi_line (tmpmpi, 1);
2070 0 : gcry_mpi_release (tmpmpi);
2071 0 : gcry_sexp_release (s_tmp);
2072 :
2073 0 : gcry_sexp_release (s_sig);
2074 0 : }
2075 :
2076 :
2077 :
2078 : /* Verify DATA of length DATALEN using the public key taken from the
2079 : S-expression in KEYFILE against the S-expression formatted
2080 : signature in SIGFILE. */
2081 : static void
2082 0 : run_dsa_verify (const void *data, size_t datalen,
2083 : const char *keyfile, const char *sigfile)
2084 :
2085 : {
2086 : gpg_error_t err;
2087 : gcry_sexp_t s_data, s_key, s_sig;
2088 : char hash[20];
2089 : gcry_mpi_t tmpmpi;
2090 :
2091 0 : gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
2092 : /* Note that we can't simply use %b with HASH to build the
2093 : S-expression, because that might yield a negative value. */
2094 0 : err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
2095 0 : if (!err)
2096 : {
2097 0 : err = gcry_sexp_build (&s_data, NULL,
2098 : "(data (flags raw)(value %m))", tmpmpi);
2099 0 : gcry_mpi_release (tmpmpi);
2100 : }
2101 0 : if (err)
2102 0 : die ("gcry_sexp_build failed for DSA data input: %s\n",
2103 : gpg_strerror (err));
2104 :
2105 0 : s_key = read_sexp_from_file (keyfile);
2106 0 : s_sig = read_sexp_from_file (sigfile);
2107 :
2108 0 : err = gcry_pk_verify (s_sig, s_data, s_key);
2109 0 : if (!err)
2110 0 : puts ("GOOD signature");
2111 0 : else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
2112 0 : puts ("BAD signature");
2113 : else
2114 0 : printf ("ERROR (%s)\n", gpg_strerror (err));
2115 :
2116 0 : gcry_sexp_release (s_sig);
2117 0 : gcry_sexp_release (s_key);
2118 0 : gcry_sexp_release (s_data);
2119 0 : }
2120 :
2121 :
2122 :
2123 : /* Sign DATA of length DATALEN using the key taken from the S-expression
2124 : encoded KEYFILE. */
2125 : static void
2126 0 : run_ecdsa_sign (const void *data, size_t datalen,
2127 : const char *keyfile, const int algo)
2128 :
2129 : {
2130 : gpg_error_t err;
2131 : gcry_sexp_t s_data, s_key, s_sig, s_tmp;
2132 : char hash[128];
2133 : gcry_mpi_t tmpmpi;
2134 :
2135 0 : s_key = read_sexp_from_file (keyfile);
2136 :
2137 0 : gcry_md_hash_buffer (algo, hash, data, datalen);
2138 0 : err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
2139 0 : gcry_md_get_algo_dlen(algo), NULL);
2140 0 : if (!err)
2141 : {
2142 0 : err = gcry_sexp_build (&s_data, NULL,
2143 : "(data (flags raw)(hash %s %M))",
2144 : gcry_md_algo_name(algo), tmpmpi);
2145 0 : gcry_mpi_release (tmpmpi);
2146 : }
2147 0 : if (err)
2148 0 : die ("gcry_sexp_build failed for ECDSA data input: %s\n",
2149 : gpg_strerror (err));
2150 :
2151 0 : err = gcry_pk_sign (&s_sig, s_data, s_key);
2152 0 : if (err)
2153 : {
2154 0 : die ("gcry_pk_signed failed: %s\n", gpg_strerror (err));
2155 : }
2156 0 : gcry_sexp_release (s_data);
2157 0 : gcry_sexp_release (s_key);
2158 :
2159 : /* Now return the actual signature. */
2160 0 : s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
2161 0 : if (!s_tmp)
2162 0 : die ("no sig-val element in returned S-expression\n");
2163 :
2164 0 : gcry_sexp_release (s_sig);
2165 0 : s_sig = s_tmp;
2166 0 : s_tmp = gcry_sexp_find_token (s_sig, "ecdsa", 0);
2167 0 : if (!s_tmp)
2168 0 : die ("no ecdsa element in returned S-expression\n");
2169 :
2170 0 : gcry_sexp_release (s_sig);
2171 0 : s_sig = s_tmp;
2172 :
2173 0 : s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
2174 0 : tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2175 0 : if (!tmpmpi)
2176 0 : die ("no r parameter in returned S-expression\n");
2177 0 : print_mpi_line (tmpmpi, 1);
2178 0 : gcry_mpi_release (tmpmpi);
2179 0 : gcry_sexp_release (s_tmp);
2180 :
2181 0 : s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
2182 0 : tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2183 0 : if (!tmpmpi)
2184 0 : die ("no s parameter in returned S-expression\n");
2185 0 : print_mpi_line (tmpmpi, 1);
2186 0 : gcry_mpi_release (tmpmpi);
2187 0 : gcry_sexp_release (s_tmp);
2188 :
2189 0 : gcry_sexp_release (s_sig);
2190 0 : }
2191 :
2192 :
2193 :
2194 : /* Verify DATA of length DATALEN using the public key taken from the
2195 : S-expression in KEYFILE against the S-expression formatted
2196 : signature in SIGFILE. */
2197 : static void
2198 0 : run_ecdsa_verify (const void *data, size_t datalen,
2199 : const char *keyfile, const int algo, const char *sigfile)
2200 :
2201 : {
2202 : gpg_error_t err;
2203 : gcry_sexp_t s_data, s_key, s_sig;
2204 : char hash[128];
2205 : gcry_mpi_t tmpmpi;
2206 :
2207 0 : s_key = read_sexp_from_file (keyfile);
2208 :
2209 0 : gcry_md_hash_buffer (algo, hash, data, datalen);
2210 : /* Note that we can't simply use %b with HASH to build the
2211 : S-expression, because that might yield a negative value. */
2212 0 : err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
2213 0 : gcry_md_get_algo_dlen(algo), NULL);
2214 0 : if (!err)
2215 : {
2216 0 : err = gcry_sexp_build (&s_data, NULL,
2217 : "(data (flags raw)(hash %s %M))",
2218 : gcry_md_algo_name(algo), tmpmpi);
2219 0 : gcry_mpi_release (tmpmpi);
2220 : }
2221 0 : if (err)
2222 0 : die ("gcry_sexp_build failed for DSA data input: %s\n",
2223 : gpg_strerror (err));
2224 :
2225 0 : s_sig = read_sexp_from_file (sigfile);
2226 :
2227 0 : err = gcry_pk_verify (s_sig, s_data, s_key);
2228 0 : if (!err)
2229 0 : puts ("GOOD signature");
2230 0 : else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
2231 0 : puts ("BAD signature");
2232 : else
2233 0 : printf ("ERROR (%s)\n", gpg_strerror (err));
2234 :
2235 0 : gcry_sexp_release (s_sig);
2236 0 : gcry_sexp_release (s_key);
2237 0 : gcry_sexp_release (s_data);
2238 0 : }
2239 :
2240 :
2241 : /* Generate an ECDSA key with specified domain parameters
2242 : and print the d and Q values, in the standard octet-string format. */
2243 : static void
2244 0 : run_ecdsa_gen_key (const char *curve)
2245 : {
2246 : gcry_sexp_t key;
2247 :
2248 0 : key = ecdsa_gen_key (curve);
2249 0 : print_ecdsa_dq (key);
2250 :
2251 0 : gcry_sexp_release (key);
2252 0 : }
2253 :
2254 :
2255 :
2256 : static void
2257 0 : usage (int show_help)
2258 : {
2259 0 : if (!show_help)
2260 : {
2261 0 : fputs ("usage: " PGM
2262 : " [OPTION] [FILE] (try --help for more information)\n", stderr);
2263 0 : exit (2);
2264 : }
2265 0 : fputs
2266 : ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
2267 : "Run a crypto operation using hex encoded input and output.\n"
2268 : "MODE:\n"
2269 : " encrypt, decrypt, digest, random, hmac-sha,\n"
2270 : " rsa-{derive,gen,sign,verify},\n"
2271 : " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n"
2272 : "OPTIONS:\n"
2273 : " --verbose Print additional information\n"
2274 : " --binary Input and output is in binary form\n"
2275 : " --no-fips Do not force FIPS mode\n"
2276 : " --key KEY Use the hex encoded KEY\n"
2277 : " --iv IV Use the hex encoded IV\n"
2278 : " --dt DT Use the hex encoded DT for the RNG\n"
2279 : " --algo NAME Use algorithm NAME\n"
2280 : " --curve NAME Select ECC curve spec NAME\n"
2281 : " --keysize N Use a keysize of N bits\n"
2282 : " --signature NAME Take signature from file NAME\n"
2283 : " --chunk N Read in chunks of N bytes (implies --binary)\n"
2284 : " --pkcs1 Use PKCS#1 encoding\n"
2285 : " --pss Use PSS encoding with a zero length salt\n"
2286 : " --mct-server Run a monte carlo test server\n"
2287 : " --loop Enable random loop mode\n"
2288 : " --progress Print pogress indicators\n"
2289 : " --help Print this text\n"
2290 : "With no FILE, or when FILE is -, read standard input.\n"
2291 : "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
2292 0 : exit (0);
2293 : }
2294 :
2295 : int
2296 0 : main (int argc, char **argv)
2297 : {
2298 0 : int last_argc = -1;
2299 : gpg_error_t err;
2300 0 : int no_fips = 0;
2301 0 : int progress = 0;
2302 0 : int use_pkcs1 = 0;
2303 0 : int use_pss = 0;
2304 : const char *mode_string;
2305 0 : const char *curve_string = NULL;
2306 0 : const char *key_string = NULL;
2307 0 : const char *iv_string = NULL;
2308 0 : const char *dt_string = NULL;
2309 0 : const char *algo_string = NULL;
2310 0 : const char *keysize_string = NULL;
2311 0 : const char *signature_string = NULL;
2312 : FILE *input;
2313 : void *data;
2314 : size_t datalen;
2315 0 : size_t chunksize = 0;
2316 0 : int mct_server = 0;
2317 :
2318 :
2319 0 : if (argc)
2320 0 : { argc--; argv++; }
2321 :
2322 0 : while (argc && last_argc != argc )
2323 : {
2324 0 : last_argc = argc;
2325 0 : if (!strcmp (*argv, "--"))
2326 : {
2327 0 : argc--; argv++;
2328 0 : break;
2329 : }
2330 0 : else if (!strcmp (*argv, "--help"))
2331 : {
2332 0 : usage (1);
2333 : }
2334 0 : else if (!strcmp (*argv, "--version"))
2335 : {
2336 0 : fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
2337 0 : exit (0);
2338 : }
2339 0 : else if (!strcmp (*argv, "--verbose"))
2340 : {
2341 0 : verbose++;
2342 0 : argc--; argv++;
2343 : }
2344 0 : else if (!strcmp (*argv, "--binary"))
2345 : {
2346 0 : binary_input = binary_output = 1;
2347 0 : argc--; argv++;
2348 : }
2349 0 : else if (!strcmp (*argv, "--no-fips"))
2350 : {
2351 0 : no_fips++;
2352 0 : argc--; argv++;
2353 : }
2354 0 : else if (!strcmp (*argv, "--loop"))
2355 : {
2356 0 : loop_mode = 1;
2357 0 : argc--; argv++;
2358 : }
2359 0 : else if (!strcmp (*argv, "--progress"))
2360 : {
2361 0 : progress = 1;
2362 0 : argc--; argv++;
2363 : }
2364 0 : else if (!strcmp (*argv, "--key"))
2365 : {
2366 0 : argc--; argv++;
2367 0 : if (!argc)
2368 0 : usage (0);
2369 0 : key_string = *argv;
2370 0 : argc--; argv++;
2371 : }
2372 0 : else if (!strcmp (*argv, "--iv"))
2373 : {
2374 0 : argc--; argv++;
2375 0 : if (!argc)
2376 0 : usage (0);
2377 0 : iv_string = *argv;
2378 0 : argc--; argv++;
2379 : }
2380 0 : else if (!strcmp (*argv, "--dt"))
2381 : {
2382 0 : argc--; argv++;
2383 0 : if (!argc)
2384 0 : usage (0);
2385 0 : dt_string = *argv;
2386 0 : argc--; argv++;
2387 : }
2388 0 : else if (!strcmp (*argv, "--algo"))
2389 : {
2390 0 : argc--; argv++;
2391 0 : if (!argc)
2392 0 : usage (0);
2393 0 : algo_string = *argv;
2394 0 : argc--; argv++;
2395 : }
2396 0 : else if (!strcmp (*argv, "--keysize"))
2397 : {
2398 0 : argc--; argv++;
2399 0 : if (!argc)
2400 0 : usage (0);
2401 0 : keysize_string = *argv;
2402 0 : argc--; argv++;
2403 : }
2404 0 : else if (!strcmp (*argv, "--signature"))
2405 : {
2406 0 : argc--; argv++;
2407 0 : if (!argc)
2408 0 : usage (0);
2409 0 : signature_string = *argv;
2410 0 : argc--; argv++;
2411 : }
2412 0 : else if (!strcmp (*argv, "--chunk"))
2413 : {
2414 0 : argc--; argv++;
2415 0 : if (!argc)
2416 0 : usage (0);
2417 0 : chunksize = atoi (*argv);
2418 0 : binary_input = binary_output = 1;
2419 0 : argc--; argv++;
2420 : }
2421 0 : else if (!strcmp (*argv, "--curve"))
2422 : {
2423 0 : argc--; argv++;
2424 0 : if (!argc)
2425 0 : usage (0);
2426 0 : curve_string = *argv;
2427 0 : argc--; argv++;
2428 : }
2429 0 : else if (!strcmp (*argv, "--pkcs1"))
2430 : {
2431 0 : use_pkcs1 = 1;
2432 0 : argc--; argv++;
2433 : }
2434 0 : else if (!strcmp (*argv, "--pss"))
2435 : {
2436 0 : use_pss = 1;
2437 0 : argc--; argv++;
2438 : }
2439 0 : else if (!strcmp (*argv, "--mct-server"))
2440 : {
2441 0 : mct_server = 1;
2442 0 : argc--; argv++;
2443 : }
2444 0 : else if (!strcmp (*argv, "--standalone"))
2445 : {
2446 0 : standalone_mode = 1;
2447 0 : argc--; argv++;
2448 : }
2449 : }
2450 :
2451 0 : if (!argc || argc > 2)
2452 0 : usage (0);
2453 :
2454 0 : mode_string = *argv;
2455 :
2456 0 : if (use_pkcs1 && use_pss)
2457 0 : die ("Only one of --pkcs or --pss may be given\n");
2458 :
2459 0 : if (!strcmp (mode_string, "rsa-derive"))
2460 0 : binary_input = 1;
2461 :
2462 0 : if (argc == 2 && strcmp (argv[1], "-"))
2463 : {
2464 0 : input = fopen (argv[1], binary_input? "rb":"r");
2465 0 : if (!input)
2466 0 : die ("can't open `%s': %s\n", argv[1], strerror (errno));
2467 : }
2468 : else
2469 0 : input = stdin;
2470 :
2471 : #ifndef HAVE_W32_SYSTEM
2472 0 : if (loop_mode)
2473 0 : signal (SIGPIPE, SIG_IGN);
2474 : #endif
2475 :
2476 0 : if (verbose)
2477 0 : fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
2478 :
2479 0 : xgcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
2480 0 : if (!no_fips)
2481 0 : xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
2482 0 : if (!gcry_check_version ("1.4.3"))
2483 0 : die ("Libgcrypt is not sufficient enough\n");
2484 0 : if (verbose)
2485 0 : fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
2486 0 : if (no_fips)
2487 0 : xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
2488 0 : xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
2489 :
2490 : /* Most operations need some input data. */
2491 0 : if (!chunksize
2492 0 : && !mct_server
2493 0 : && strcmp (mode_string, "random")
2494 0 : && strcmp (mode_string, "rsa-gen")
2495 0 : && strcmp (mode_string, "rsa-keygen")
2496 0 : && strcmp (mode_string, "rsa-keygen-kat")
2497 0 : && strcmp (mode_string, "dsa-gen")
2498 0 : && strcmp (mode_string, "ecdsa-gen-key") )
2499 : {
2500 0 : data = read_file (input, !binary_input, &datalen);
2501 0 : if (!data)
2502 0 : die ("error reading%s input\n", binary_input?"":" and decoding");
2503 0 : if (verbose)
2504 0 : fprintf (stderr, PGM ": %u bytes of input data\n",
2505 : (unsigned int)datalen);
2506 : }
2507 : else
2508 : {
2509 0 : data = NULL;
2510 0 : datalen = 0;
2511 : }
2512 :
2513 :
2514 0 : if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
2515 0 : {
2516 : int cipher_algo, cipher_mode;
2517 0 : void *iv_buffer = NULL;
2518 0 : void *key_buffer = NULL;
2519 : size_t iv_buflen, key_buflen;
2520 :
2521 0 : if (!algo_string)
2522 0 : die ("option --algo is required in this mode\n");
2523 0 : cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
2524 0 : if (!cipher_algo)
2525 0 : die ("cipher algorithm `%s' is not supported\n", algo_string);
2526 0 : if (mct_server)
2527 : {
2528 : int iterations;
2529 :
2530 : for (;;)
2531 : {
2532 0 : gcry_free (key_buffer); key_buffer = NULL;
2533 0 : gcry_free (iv_buffer); iv_buffer = NULL;
2534 0 : gcry_free (data); data = NULL;
2535 0 : if (!(key_buffer = read_textline (input)))
2536 : {
2537 0 : if (feof (input))
2538 0 : break;
2539 0 : die ("no version info in input\n");
2540 : }
2541 0 : if (atoi (key_buffer) != 1)
2542 0 : die ("unsupported input version %s\n",
2543 : (const char*)key_buffer);
2544 0 : gcry_free (key_buffer);
2545 0 : if (!(key_buffer = read_textline (input)))
2546 0 : die ("no iteration count in input\n");
2547 0 : iterations = atoi (key_buffer);
2548 0 : gcry_free (key_buffer);
2549 0 : if (!(key_buffer = read_hexline (input, &key_buflen)))
2550 0 : die ("no key in input\n");
2551 0 : if (!(iv_buffer = read_hexline (input, &iv_buflen)))
2552 0 : die ("no IV in input\n");
2553 0 : if (!(data = read_hexline (input, &datalen)))
2554 0 : die ("no data in input\n");
2555 0 : skip_to_empty_line (input);
2556 :
2557 0 : run_cipher_mct_loop ((*mode_string == 'e'),
2558 : cipher_algo, cipher_mode,
2559 : iv_buffer, iv_buflen,
2560 : key_buffer, key_buflen,
2561 : data, datalen, iterations);
2562 : }
2563 : }
2564 : else
2565 : {
2566 0 : if (cipher_mode != GCRY_CIPHER_MODE_ECB)
2567 : {
2568 0 : if (!iv_string)
2569 0 : die ("option --iv is required in this mode\n");
2570 0 : iv_buffer = hex2buffer (iv_string, &iv_buflen);
2571 0 : if (!iv_buffer)
2572 0 : die ("invalid value for IV\n");
2573 : }
2574 : else
2575 : {
2576 0 : iv_buffer = NULL;
2577 0 : iv_buflen = 0;
2578 : }
2579 0 : if (!key_string)
2580 0 : die ("option --key is required in this mode\n");
2581 0 : key_buffer = hex2buffer (key_string, &key_buflen);
2582 0 : if (!key_buffer)
2583 0 : die ("invalid value for KEY\n");
2584 :
2585 0 : run_encrypt_decrypt ((*mode_string == 'e'),
2586 : cipher_algo, cipher_mode,
2587 : iv_buffer, iv_buflen,
2588 : key_buffer, key_buflen,
2589 : data, data? datalen:chunksize, input);
2590 : }
2591 0 : gcry_free (key_buffer);
2592 0 : gcry_free (iv_buffer);
2593 : }
2594 0 : else if (!strcmp (mode_string, "digest"))
2595 : {
2596 : int algo;
2597 :
2598 0 : if (!algo_string)
2599 0 : die ("option --algo is required in this mode\n");
2600 0 : algo = gcry_md_map_name (algo_string);
2601 0 : if (!algo)
2602 0 : die ("digest algorithm `%s' is not supported\n", algo_string);
2603 0 : if (!data)
2604 0 : die ("no data available (do not use --chunk)\n");
2605 :
2606 0 : run_digest (algo, data, datalen);
2607 : }
2608 0 : else if (!strcmp (mode_string, "random"))
2609 : {
2610 : void *context;
2611 : unsigned char key[16];
2612 : unsigned char seed[16];
2613 : unsigned char dt[16];
2614 : unsigned char buffer[16];
2615 0 : size_t count = 0;
2616 :
2617 0 : if (!key_string || hex2bin (key_string, key, 16) < 0 )
2618 0 : die ("value for --key are not 32 hex digits\n");
2619 0 : if (!iv_string || hex2bin (iv_string, seed, 16) < 0 )
2620 0 : die ("value for --iv are not 32 hex digits\n");
2621 0 : if (!dt_string || hex2bin (dt_string, dt, 16) < 0 )
2622 0 : die ("value for --dt are not 32 hex digits\n");
2623 :
2624 : /* The flag value 1 disables the dup check, so that the RNG
2625 : returns all generated data. */
2626 0 : err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
2627 0 : if (err)
2628 0 : die ("init external RNG test failed: %s\n", gpg_strerror (err));
2629 :
2630 : do
2631 : {
2632 0 : err = run_external_rng_test (context, buffer, sizeof buffer);
2633 0 : if (err)
2634 0 : die ("running external RNG test failed: %s\n", gpg_strerror (err));
2635 0 : print_buffer (buffer, sizeof buffer);
2636 0 : if (progress)
2637 : {
2638 0 : if (!(++count % 1000))
2639 0 : fprintf (stderr, PGM ": %lu random bytes so far\n",
2640 : (unsigned long int)(count * sizeof buffer));
2641 : }
2642 : }
2643 0 : while (loop_mode);
2644 :
2645 0 : if (progress)
2646 0 : fprintf (stderr, PGM ": %lu random bytes\n",
2647 : (unsigned long int)(count * sizeof buffer));
2648 :
2649 0 : deinit_external_rng_test (context);
2650 : }
2651 0 : else if (!strcmp (mode_string, "hmac-sha"))
2652 : {
2653 : int algo;
2654 : void *key_buffer;
2655 : size_t key_buflen;
2656 :
2657 0 : if (!data)
2658 0 : die ("no data available (do not use --chunk)\n");
2659 0 : if (!algo_string)
2660 0 : die ("option --algo is required in this mode\n");
2661 0 : switch (atoi (algo_string))
2662 : {
2663 0 : case 1: algo = GCRY_MD_SHA1; break;
2664 0 : case 224: algo = GCRY_MD_SHA224; break;
2665 0 : case 256: algo = GCRY_MD_SHA256; break;
2666 0 : case 384: algo = GCRY_MD_SHA384; break;
2667 0 : case 512: algo = GCRY_MD_SHA512; break;
2668 0 : default: algo = 0; break;
2669 : }
2670 0 : if (!algo)
2671 0 : die ("no digest algorithm found for hmac type `%s'\n", algo_string);
2672 0 : if (!key_string)
2673 0 : die ("option --key is required in this mode\n");
2674 0 : key_buffer = hex2buffer (key_string, &key_buflen);
2675 0 : if (!key_buffer)
2676 0 : die ("invalid value for KEY\n");
2677 :
2678 0 : run_hmac (algo, key_buffer, key_buflen, data, datalen);
2679 :
2680 0 : gcry_free (key_buffer);
2681 : }
2682 0 : else if (!strcmp (mode_string, "rsa-derive"))
2683 : {
2684 0 : if (!data)
2685 0 : die ("no data available (do not use --chunk)\n");
2686 0 : run_rsa_derive (data, datalen);
2687 : }
2688 0 : else if (!strcmp (mode_string, "rsa-keygen"))
2689 : {
2690 0 : data = read_file (input, 0, &datalen);
2691 0 : if (!data)
2692 0 : die ("no data available (do not use --chunk)\n");
2693 0 : run_rsa_keygen (data, datalen, 0);
2694 : }
2695 0 : else if (!strcmp (mode_string, "rsa-keygen-kat"))
2696 : {
2697 0 : data = read_file (input, 0, &datalen);
2698 0 : if (!data)
2699 0 : die ("no data available (do not use --chunk)\n");
2700 0 : run_rsa_keygen (data, datalen, 1);
2701 : }
2702 0 : else if (!strcmp (mode_string, "rsa-gen"))
2703 : {
2704 : int keysize;
2705 :
2706 0 : if (!binary_output)
2707 0 : base64_output = 1;
2708 :
2709 0 : keysize = keysize_string? atoi (keysize_string) : 0;
2710 0 : if (keysize < 128 || keysize > 16384)
2711 0 : die ("invalid keysize specified; needs to be 128 .. 16384\n");
2712 0 : run_rsa_gen (keysize, 65537);
2713 : }
2714 0 : else if (!strcmp (mode_string, "rsa-sign"))
2715 : {
2716 : int algo;
2717 :
2718 0 : if (!key_string)
2719 0 : die ("option --key is required in this mode\n");
2720 0 : if (access (key_string, R_OK))
2721 0 : die ("option --key needs to specify an existing keyfile\n");
2722 0 : if (!algo_string)
2723 0 : die ("option --algo is required in this mode\n");
2724 0 : algo = gcry_md_map_name (algo_string);
2725 0 : if (!algo)
2726 0 : die ("digest algorithm `%s' is not supported\n", algo_string);
2727 0 : if (!data)
2728 0 : die ("no data available (do not use --chunk)\n");
2729 :
2730 0 : run_rsa_sign (data, datalen, algo, use_pkcs1, use_pss, key_string);
2731 :
2732 : }
2733 0 : else if (!strcmp (mode_string, "rsa-verify"))
2734 : {
2735 : int algo;
2736 :
2737 0 : if (!key_string)
2738 0 : die ("option --key is required in this mode\n");
2739 0 : if (access (key_string, R_OK))
2740 0 : die ("option --key needs to specify an existing keyfile\n");
2741 0 : if (!algo_string)
2742 0 : die ("option --algo is required in this mode\n");
2743 0 : algo = gcry_md_map_name (algo_string);
2744 0 : if (!algo)
2745 0 : die ("digest algorithm `%s' is not supported\n", algo_string);
2746 0 : if (!data)
2747 0 : die ("no data available (do not use --chunk)\n");
2748 0 : if (!signature_string)
2749 0 : die ("option --signature is required in this mode\n");
2750 0 : if (access (signature_string, R_OK))
2751 0 : die ("option --signature needs to specify an existing file\n");
2752 :
2753 0 : run_rsa_verify (data, datalen, algo, use_pkcs1, use_pss, key_string,
2754 : signature_string);
2755 :
2756 : }
2757 0 : else if (!strcmp (mode_string, "dsa-pqg-gen"))
2758 : {
2759 : int keysize;
2760 :
2761 0 : keysize = keysize_string? atoi (keysize_string) : 0;
2762 0 : if (keysize < 1024 || keysize > 3072)
2763 0 : die ("invalid keysize specified; needs to be 1024 .. 3072\n");
2764 0 : run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen);
2765 : }
2766 0 : else if (!strcmp (mode_string, "dsa-gen"))
2767 : {
2768 : int keysize;
2769 :
2770 0 : keysize = keysize_string? atoi (keysize_string) : 0;
2771 0 : if (keysize < 1024 || keysize > 3072)
2772 0 : die ("invalid keysize specified; needs to be 1024 .. 3072\n");
2773 0 : if (!key_string)
2774 0 : die ("option --key is required in this mode\n");
2775 0 : run_dsa_gen (keysize, key_string);
2776 : }
2777 0 : else if (!strcmp (mode_string, "dsa-sign"))
2778 : {
2779 0 : if (!key_string)
2780 0 : die ("option --key is required in this mode\n");
2781 0 : if (access (key_string, R_OK))
2782 0 : die ("option --key needs to specify an existing keyfile\n");
2783 0 : if (!data)
2784 0 : die ("no data available (do not use --chunk)\n");
2785 :
2786 0 : run_dsa_sign (data, datalen, key_string);
2787 : }
2788 0 : else if (!strcmp (mode_string, "dsa-verify"))
2789 : {
2790 0 : if (!key_string)
2791 0 : die ("option --key is required in this mode\n");
2792 0 : if (access (key_string, R_OK))
2793 0 : die ("option --key needs to specify an existing keyfile\n");
2794 0 : if (!data)
2795 0 : die ("no data available (do not use --chunk)\n");
2796 0 : if (!signature_string)
2797 0 : die ("option --signature is required in this mode\n");
2798 0 : if (access (signature_string, R_OK))
2799 0 : die ("option --signature needs to specify an existing file\n");
2800 :
2801 0 : run_dsa_verify (data, datalen, key_string, signature_string);
2802 : }
2803 0 : else if (!strcmp (mode_string, "ecdsa-gen-key"))
2804 : {
2805 0 : if (!curve_string)
2806 0 : die ("option --curve containing name of the specified curve is required in this mode\n");
2807 0 : run_ecdsa_gen_key (curve_string);
2808 : }
2809 0 : else if (!strcmp (mode_string, "ecdsa-sign"))
2810 : {
2811 : int algo;
2812 :
2813 0 : if (!key_string)
2814 0 : die ("option --key is required in this mode\n");
2815 0 : if (access (key_string, R_OK))
2816 0 : die ("option --key needs to specify an existing keyfile\n");
2817 0 : if (!algo_string)
2818 0 : die ("use --algo to specify the digest algorithm\n");
2819 0 : algo = gcry_md_map_name (algo_string);
2820 0 : if (!algo)
2821 0 : die ("digest algorithm `%s' is not supported\n", algo_string);
2822 :
2823 0 : if (!data)
2824 0 : die ("no data available (do not use --chunk)\n");
2825 :
2826 0 : run_ecdsa_sign (data, datalen, key_string, algo);
2827 : }
2828 0 : else if (!strcmp (mode_string, "ecdsa-verify"))
2829 : {
2830 : int algo;
2831 :
2832 0 : if (!key_string)
2833 0 : die ("option --key is required in this mode\n");
2834 0 : if (access (key_string, R_OK))
2835 0 : die ("option --key needs to specify an existing keyfile\n");
2836 0 : if (!algo_string)
2837 0 : die ("use --algo to specify the digest algorithm\n");
2838 0 : algo = gcry_md_map_name (algo_string);
2839 0 : if (!algo)
2840 0 : die ("digest algorithm `%s' is not supported\n", algo_string);
2841 0 : if (!data)
2842 0 : die ("no data available (do not use --chunk)\n");
2843 0 : if (!signature_string)
2844 0 : die ("option --signature is required in this mode\n");
2845 0 : if (access (signature_string, R_OK))
2846 0 : die ("option --signature needs to specify an existing file\n");
2847 :
2848 0 : run_ecdsa_verify (data, datalen, key_string, algo, signature_string);
2849 : }
2850 : else
2851 0 : usage (0);
2852 :
2853 0 : gcry_free (data);
2854 :
2855 : /* Because Libgcrypt does not enforce FIPS mode in all cases we let
2856 : the process die if Libgcrypt is not anymore in FIPS mode after
2857 : the actual operation. */
2858 0 : if (!no_fips && !gcry_fips_mode_active ())
2859 0 : die ("FIPS mode is not anymore active\n");
2860 :
2861 0 : if (verbose)
2862 0 : fputs (PGM ": ready\n", stderr);
2863 :
2864 0 : return 0;
2865 : }
|