tests: Check the result of all gcry_control operations.
[libgcrypt.git] / tests / fipsdrv.c
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 showhex (const char *prefix, const void *buffer, size_t length)
123 {
124   const unsigned char *p = buffer;
125
126   if (prefix)
127     fprintf (stderr, PGM ": %s: ", prefix);
128   while (length-- )
129     fprintf (stderr, "%02X", *p++);
130   if (prefix)
131     putc ('\n', stderr);
132 }
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 hex2bin (const char *string, void *buffer, size_t length)
159 {
160   int i;
161   const char *s = string;
162
163   for (i=0; i < length; )
164     {
165       if (!hexdigitp (s) || !hexdigitp (s+1))
166         return -1;           /* Invalid hex digits. */
167       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
168       s += 2;
169     }
170   if (*s && (!my_isascii (*s) || !isspace (*s)) )
171     return -1;             /* Not followed by Nul or white space.  */
172   if (i != length)
173     return -1;             /* Not of expected length.  */
174   if (*s)
175     s++; /* Skip the delimiter. */
176   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 hex2buffer (const char *string, size_t *r_length)
187 {
188   const char *s;
189   unsigned char *buffer;
190   size_t length;
191
192   buffer = gcry_xmalloc (strlen(string)/2+1);
193   length = 0;
194   for (s=string; *s; s +=2 )
195     {
196       if (!hexdigitp (s) || !hexdigitp (s+1))
197         return NULL;           /* Invalid hex digits. */
198       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
199     }
200   *r_length = length;
201   return buffer;
202 }
203
204
205 static char *
206 read_textline (FILE *fp)
207 {
208   char line[256];
209   char *p;
210   int any = 0;
211
212   /* Read line but skip over initial empty lines.  */
213   do
214     {
215       do
216         {
217           if (!fgets (line, sizeof line, fp))
218             {
219               if (feof (fp))
220                 return NULL;
221               die ("error reading input line: %s\n", strerror (errno));
222             }
223           p = strchr (line, '\n');
224           if (p)
225             *p = 0;
226           p = line + (*line? (strlen (line)-1):0);
227           for ( ;p > line; p--)
228             if (my_isascii (*p) && isspace (*p))
229               *p = 0;
230         }
231       while (!any && !*line);
232       any = 1;
233     }
234   while (*line == '#');  /* Always skip comment lines.  */
235   if (verbose > 1)
236     fprintf (stderr, PGM ": received line: %s\n", line);
237   return gcry_xstrdup (line);
238 }
239
240 static char *
241 read_hexline (FILE *fp, size_t *retlen)
242 {
243   char *line, *p;
244
245   line = read_textline (fp);
246   if (!line)
247     return NULL;
248   p = hex2buffer (line, retlen);
249   if (!p)
250     die ("error decoding hex string on input\n");
251   gcry_free (line);
252   return p;
253 }
254
255 static void
256 skip_to_empty_line (FILE *fp)
257 {
258   char line[256];
259   char *p;
260
261   do
262     {
263       if (!fgets (line, sizeof line, fp))
264         {
265           if (feof (fp))
266             return;
267           die ("error reading input line: %s\n", strerror (errno));
268         }
269       p = strchr (line, '\n');
270       if (p)
271         *p =0;
272     }
273   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 read_file (FILE *fp, int decode, size_t *r_length)
284 {
285   char *buffer;
286   size_t buflen;
287   size_t nread, bufsize = 0;
288
289   *r_length = 0;
290 #define NCHUNK 8192
291 #ifdef HAVE_DOSISH_SYSTEM
292   setmode (fileno(fp), O_BINARY);
293 #endif
294   buffer = NULL;
295   buflen = 0;
296   do
297     {
298       bufsize += NCHUNK;
299       if (!buffer)
300         buffer = gcry_xmalloc (bufsize);
301       else
302         buffer = gcry_xrealloc (buffer, bufsize);
303
304       nread = fread (buffer + buflen, 1, NCHUNK, fp);
305       if (nread < NCHUNK && ferror (fp))
306         {
307           gcry_free (buffer);
308           return NULL;
309         }
310       buflen += nread;
311     }
312   while (nread == NCHUNK);
313 #undef NCHUNK
314   if (decode)
315     {
316       const char *s;
317       char *p;
318
319       for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 )
320         {
321           if (!hexdigitp (s) || !hexdigitp (s+1))
322             {
323               gcry_free (buffer);
324               return NULL;  /* Invalid hex digits. */
325             }
326           *(unsigned char*)p++ = xtoi_2 (s);
327         }
328       if (nread != buflen)
329         {
330           gcry_free (buffer);
331           return NULL;  /* Odd number of hex digits. */
332         }
333       buflen = p - buffer;
334     }
335
336   *r_length = buflen;
337   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 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   int idx = 0;
361   unsigned char val = 0;
362   int c = 0;
363   char *d, *s;
364   int lfseen = 1;
365
366   /* Find BEGIN line.  */
367   for (s=buffer; length; length--, s++)
368     {
369       if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11))
370         {
371           for (; length && *s != '\n'; length--, s++)
372             ;
373           break;
374         }
375       lfseen = (*s == '\n');
376     }
377
378   /* Decode until pad character or END line.  */
379   for (d=buffer; length; length--, s++)
380     {
381       if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9))
382         break;
383       if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t')
384         continue;
385       if (*s == '=')
386         {
387           /* Pad character: stop */
388           if (idx == 1)
389             *d++ = val;
390           break;
391         }
392
393       if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff)
394         die ("invalid base64 character %02X at pos %d detected\n",
395              *(unsigned char*)s, (int)(s-buffer));
396
397       switch (idx)
398         {
399         case 0:
400           val = c << 2;
401           break;
402         case 1:
403           val |= (c>>4)&3;
404           *d++ = val;
405           val = (c<<4)&0xf0;
406           break;
407         case 2:
408           val |= (c>>2)&15;
409           *d++ = val;
410           val = (c<<6)&0xc0;
411           break;
412         case 3:
413           val |= c&0x3f;
414           *d++ = val;
415           break;
416         }
417       idx = (idx+1) % 4;
418     }
419
420   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 parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti)
431 {
432   int c;
433   unsigned long tag;
434   const unsigned char *buf = *buffer;
435   size_t length = *buflen;
436
437   ti->length = 0;
438   ti->ndef = 0;
439   ti->nhdr = 0;
440
441   /* Get the tag */
442   if (!length)
443     return -1; /* Premature EOF.  */
444   c = *buf++; length--;
445   ti->nhdr++;
446
447   ti->class = (c & 0xc0) >> 6;
448   ti->cons  = !!(c & 0x20);
449   tag       = (c & 0x1f);
450
451   if (tag == 0x1f)
452     {
453       tag = 0;
454       do
455         {
456           tag <<= 7;
457           if (!length)
458             return -1; /* Premature EOF.  */
459           c = *buf++; length--;
460           ti->nhdr++;
461           tag |= (c & 0x7f);
462         }
463       while ( (c & 0x80) );
464     }
465   ti->tag = tag;
466
467   /* Get the length */
468   if (!length)
469     return -1; /* Premature EOF. */
470   c = *buf++; length--;
471   ti->nhdr++;
472
473   if ( !(c & 0x80) )
474     ti->length = c;
475   else if (c == 0x80)
476     ti->ndef = 1;
477   else if (c == 0xff)
478     return -1; /* Forbidden length value.  */
479   else
480     {
481       unsigned long len = 0;
482       int count = c & 0x7f;
483
484       for (; count; count--)
485         {
486           len <<= 8;
487           if (!length)
488             return -1; /* Premature EOF.  */
489           c = *buf++; length--;
490           ti->nhdr++;
491           len |= (c & 0xff);
492         }
493       ti->length = len;
494     }
495
496   if (ti->class == UNIVERSAL && !ti->tag)
497     ti->length = 0;
498
499   if (ti->length > length)
500     return -1; /* Data larger than buffer.  */
501
502   *buffer = buf;
503   *buflen = length;
504   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 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   int n_keyparms = 8;
523   int idx;
524   gcry_sexp_t s_key;
525
526   fp = fopen (fname, binary_input?"rb":"r");
527   if (!fp)
528     die ("can't open `%s': %s\n", fname, strerror (errno));
529   buffer = read_file (fp, 0, &buflen);
530   if (!buffer)
531     die ("error reading `%s'\n", fname);
532   fclose (fp);
533
534   buflen = base64_decode (buffer, buflen);
535
536   /* Parse the ASN.1 structure.  */
537   der = (const unsigned char*)buffer;
538   derlen = buflen;
539   if ( parse_tag (&der, &derlen, &ti)
540        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
541     goto bad_asn1;
542   if ( parse_tag (&der, &derlen, &ti)
543        || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
544     goto bad_asn1;
545   if (ti.length != 1 || *der)
546     goto bad_asn1;  /* The value of the first integer is no 0. */
547   der += ti.length; derlen -= ti.length;
548
549   for (idx=0; idx < n_keyparms; idx++)
550     {
551       if ( parse_tag (&der, &derlen, &ti)
552            || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
553         goto bad_asn1;
554       if (show)
555         {
556           char prefix[2];
557
558           prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
559           prefix[1] = 0;
560           showhex (prefix, der, ti.length);
561         }
562       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
563       if (err)
564         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
565       der += ti.length; derlen -= ti.length;
566     }
567   if (idx != n_keyparms)
568     die ("not enough RSA key parameters\n");
569
570   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   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
575     {
576       gcry_mpi_swap (keyparms[3], keyparms[4]);
577       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
578     }
579
580   /* Build the S-expression.  */
581   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   if (err)
587     die ("error building S-expression: %s\n", gpg_strerror (err));
588
589   for (idx=0; idx < n_keyparms; idx++)
590     gcry_mpi_release (keyparms[idx]);
591
592   return s_key;
593
594  bad_asn1:
595   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 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   int n_keyparms = 2;
615   int idx;
616   gcry_sexp_t s_key;
617
618   fp = fopen (fname, binary_input?"rb":"r");
619   if (!fp)
620     die ("can't open `%s': %s\n", fname, strerror (errno));
621   buffer = read_file (fp, 0, &buflen);
622   if (!buffer)
623     die ("error reading `%s'\n", fname);
624   fclose (fp);
625
626   buflen = base64_decode (buffer, buflen);
627
628   /* Parse the ASN.1 structure.  */
629   der = (const unsigned char*)buffer;
630   derlen = buflen;
631   if ( parse_tag (&der, &derlen, &ti)
632        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
633     goto bad_asn1;
634   if ( parse_tag (&der, &derlen, &ti)
635        || 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   der += ti.length; derlen -= ti.length;
639
640   if ( parse_tag (&der, &derlen, &ti)
641        || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
642     goto bad_asn1;
643   if (ti.length < 1 || *der)
644     goto bad_asn1;  /* The number of unused bits needs to be 0. */
645   der += 1; derlen -= 1;
646
647   /* Parse the BIT string.  */
648   if ( parse_tag (&der, &derlen, &ti)
649        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
650     goto bad_asn1;
651
652   for (idx=0; idx < n_keyparms; idx++)
653     {
654       if ( parse_tag (&der, &derlen, &ti)
655            || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
656         goto bad_asn1;
657       if (show)
658         {
659           char prefix[2];
660
661           prefix[0] = idx < 2? "ne"[idx] : '?';
662           prefix[1] = 0;
663           showhex (prefix, der, ti.length);
664         }
665       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
666       if (err)
667         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
668       der += ti.length; derlen -= ti.length;
669     }
670   if (idx != n_keyparms)
671     die ("not enough RSA key parameters\n");
672
673   gcry_free (buffer);
674
675   /* Build the S-expression.  */
676   err = gcry_sexp_build (&s_key, NULL,
677                          "(public-key(rsa(n%m)(e%m)))",
678                          keyparms[0], keyparms[1] );
679   if (err)
680     die ("error building S-expression: %s\n", gpg_strerror (err));
681
682   for (idx=0; idx < n_keyparms; idx++)
683     gcry_mpi_release (keyparms[idx]);
684
685   return s_key;
686
687  bad_asn1:
688   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 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   fp = fopen (fname, "rb");
707   if (!fp)
708     die ("can't open `%s': %s\n", fname, strerror (errno));
709   buffer = read_file (fp, 0, &buflen);
710   if (!buffer)
711     die ("error reading `%s'\n", fname);
712   fclose (fp);
713
714   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL);
715   if (!err)
716     err = gcry_sexp_build (&s_sig, NULL,
717                            "(sig-val(rsa(s %m)))", tmpmpi);
718   if (err)
719     die ("error building S-expression: %s\n", gpg_strerror (err));
720   gcry_mpi_release (tmpmpi);
721   gcry_free (buffer);
722
723   return s_sig;
724 }
725
726
727 /* Read an S-expression from FNAME.  */
728 static gcry_sexp_t
729 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   fp = fopen (fname, "rb");
738   if (!fp)
739     die ("can't open `%s': %s\n", fname, strerror (errno));
740   buffer = read_file (fp, 0, &buflen);
741   if (!buffer)
742     die ("error reading `%s'\n", fname);
743   fclose (fp);
744   if (!buflen)
745     die ("error: file `%s' is empty\n", fname);
746
747   err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free);
748   if (err)
749     die ("error parsing `%s': %s\n", fname, gpg_strerror (err));
750
751   return sexp;
752 }
753
754
755 static void
756 print_buffer (const void *buffer, size_t length)
757 {
758   int writerr = 0;
759
760   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       idx = quads = 0;
772       for (p = buffer; length; p++, length--)
773         {
774           inbuf[idx++] = *p;
775           if (idx > 2)
776             {
777               outbuf[0] = bintoasc[(*inbuf>>2)&077];
778               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
779                                     |((inbuf[1] >> 4)&017))&077];
780               outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
781                                     |((inbuf[2]>>6)&03))&077];
782               outbuf[3] = bintoasc[inbuf[2]&077];
783               if (fwrite (outbuf, 4, 1, stdout) != 1)
784                 writerr = 1;
785               idx = 0;
786               if (++quads >= (64/4))
787                 {
788                   if (fwrite ("\n", 1, 1, stdout) != 1)
789                     writerr = 1;
790                   quads = 0;
791                 }
792             }
793         }
794       if (idx)
795         {
796           outbuf[0] = bintoasc[(*inbuf>>2)&077];
797           if (idx == 1)
798             {
799               outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
800               outbuf[2] = outbuf[3] = '=';
801             }
802           else
803             {
804               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
805                                     |((inbuf[1]>>4)&017))&077];
806               outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
807               outbuf[3] = '=';
808             }
809           if (fwrite (outbuf, 4, 1, stdout) != 1)
810             writerr = 1;
811           quads++;
812         }
813       if (quads && fwrite ("\n", 1, 1, stdout) != 1)
814         writerr = 1;
815     }
816   else if (binary_output)
817     {
818       if (fwrite (buffer, length, 1, stdout) != 1)
819         writerr++;
820     }
821   else
822     {
823       const unsigned char *p = buffer;
824
825       if (verbose > 1)
826         showhex ("sent line", buffer, length);
827       while (length-- && !ferror (stdout) )
828         printf ("%02X", *p++);
829       if (ferror (stdout))
830         writerr++;
831     }
832   if (!writerr && fflush (stdout) == EOF)
833     writerr++;
834   if (writerr)
835     {
836 #ifndef HAVE_W32_SYSTEM
837       if (loop_mode && errno == EPIPE)
838         loop_mode = 0;
839       else
840 #endif
841         die ("writing output failed: %s\n", strerror (errno));
842     }
843 }
844
845
846 /* Print an MPI on a line.  */
847 static void
848 print_mpi_line (gcry_mpi_t a, int no_lz)
849 {
850   unsigned char *buf, *p;
851   gcry_error_t err;
852   int writerr = 0;
853
854   err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
855   if (err)
856     die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
857
858   p = buf;
859   if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
860     p += 2;
861
862   printf ("%s\n", p);
863   if (ferror (stdout))
864     writerr++;
865   if (!writerr && fflush (stdout) == EOF)
866     writerr++;
867   if (writerr)
868     die ("writing output failed: %s\n", strerror (errno));
869   gcry_free (buf);
870 }
871
872
873 /* Print some data on hex format on a line.  */
874 static void
875 print_data_line (const void *data, size_t datalen)
876 {
877   const unsigned char *p = data;
878   int writerr = 0;
879
880   while (data && datalen-- && !ferror (stdout) )
881     printf ("%02X", *p++);
882   putchar ('\n');
883   if (ferror (stdout))
884     writerr++;
885   if (!writerr && fflush (stdout) == EOF)
886     writerr++;
887   if (writerr)
888     die ("writing output failed: %s\n", strerror (errno));
889 }
890
891 /* Print the S-expression A to the stream FP.  */
892 static void
893 print_sexp (gcry_sexp_t a, FILE *fp)
894 {
895   char *buf;
896   size_t size;
897
898   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
899   buf = gcry_xmalloc (size);
900   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
901   if (fwrite (buf, size, 1, fp) != 1)
902     die ("error writing to stream: %s\n", strerror (errno));
903   gcry_free (buf);
904 }
905
906
907
908
909 static gcry_error_t
910 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   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 run_external_rng_test (void *context, void *buffer, size_t buflen)
925 {
926   return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen);
927 }
928
929 static void
930 deinit_external_rng_test (void *context)
931 {
932   xgcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context);
933 }
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 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   for (idx=0; table[idx].name; idx++)
998     if (!strcmp (name, table[idx].name))
999       {
1000         *r_mode = table[idx].mode;
1001         return table[idx].algo;
1002       }
1003   *r_mode = 0;
1004   return 0;
1005 }
1006
1007
1008 \f
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 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   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
1028   if (err)
1029     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
1030          cipher_algo, cipher_mode, gpg_strerror (err));
1031
1032   blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
1033   assert (blocklen);
1034
1035   gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
1036
1037   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
1038   if (err)
1039     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
1040          (unsigned int)key_buflen, gpg_strerror (err));
1041
1042   if (iv_buffer)
1043     {
1044       err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
1045       if (err)
1046         die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
1047              (unsigned int)iv_buflen, gpg_strerror (err));
1048     }
1049
1050   inbuf = data? NULL : gcry_xmalloc (datalen);
1051   outbuflen = datalen;
1052   outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen);
1053
1054   do
1055     {
1056       if (inbuf)
1057         {
1058           int nread = fread (inbuf, 1, datalen, fp);
1059           if (nread < (int)datalen && ferror (fp))
1060             die ("error reading input\n");
1061           data = inbuf;
1062           inbuflen = nread;
1063         }
1064       else
1065         inbuflen = datalen;
1066
1067       if (encrypt_mode)
1068         err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
1069       else
1070         err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
1071       if (err)
1072         die ("gcry_cipher_%scrypt failed: %s\n",
1073              encrypt_mode? "en":"de", gpg_strerror (err));
1074
1075       print_buffer (outbuf, outbuflen);
1076     }
1077   while (inbuf);
1078
1079   gcry_cipher_close (hd);
1080   gcry_free (outbuf);
1081   gcry_free (inbuf);
1082 }
1083
1084
1085 static void
1086 get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen)
1087 {
1088   unsigned char tmp[17];
1089
1090   if (gcry_cipher_ctl (hd, PRIV_CIPHERCTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
1091     die ("error getting current input vector\n");
1092   if (buflen > *tmp)
1093     die ("buffer too short to store the current input vector\n");
1094   memcpy (buffer, tmp+1, *tmp);
1095 }
1096
1097 /* Run the inner loop of the CAVS monte carlo test.  */
1098 static void
1099 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   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
1116   if (err)
1117     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
1118          cipher_algo, cipher_mode, gpg_strerror (err));
1119
1120   blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
1121   if (!blocklen || blocklen > sizeof output)
1122     die ("invalid block length %d\n", (int)blocklen);
1123
1124
1125   gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
1126
1127   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
1128   if (err)
1129     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
1130          (unsigned int)key_buflen, gpg_strerror (err));
1131
1132   if (iv_buffer)
1133     {
1134       err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
1135       if (err)
1136         die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
1137              (unsigned int)iv_buflen, gpg_strerror (err));
1138     }
1139
1140   if (datalen != blocklen)
1141     die ("length of input (%u) does not match block length (%u)\n",
1142          (unsigned int)datalen, (unsigned int)blocklen);
1143   memcpy (input, data, datalen);
1144   memset (output, 0, sizeof output);
1145   for (count=0; count < iterations; count++)
1146     {
1147       memcpy (last_last_output, last_output, sizeof last_output);
1148       memcpy (last_output, output, sizeof output);
1149
1150       get_current_iv (hd, last_iv, blocklen);
1151
1152       if (encrypt_mode)
1153         err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen);
1154       else
1155         err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen);
1156       if (err)
1157         die ("gcry_cipher_%scrypt failed: %s\n",
1158              encrypt_mode? "en":"de", gpg_strerror (err));
1159
1160
1161       if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB
1162                            || cipher_mode == GCRY_CIPHER_MODE_CBC))
1163         memcpy (input, last_iv, blocklen);
1164       else if (cipher_mode == GCRY_CIPHER_MODE_OFB)
1165         memcpy (input, last_iv, blocklen);
1166       else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB)
1167         {
1168           /* Reconstruct the output vector.  */
1169           int i;
1170           for (i=0; i < blocklen; i++)
1171             input[i] ^= output[i];
1172         }
1173       else
1174         memcpy (input, output, blocklen);
1175     }
1176
1177   print_buffer (output, blocklen);
1178   putchar ('\n');
1179   print_buffer (last_output, blocklen);
1180   putchar ('\n');
1181   print_buffer (last_last_output, blocklen);
1182   putchar ('\n');
1183   get_current_iv (hd, last_iv, blocklen);
1184   print_buffer (last_iv, blocklen); /* Last output vector.  */
1185   putchar ('\n');
1186   print_buffer (input, blocklen);   /* Next input text. */
1187   putchar ('\n');
1188   if (verbose > 1)
1189     showhex ("sent line", "", 0);
1190   putchar ('\n');
1191   fflush (stdout);
1192
1193   gcry_cipher_close (hd);
1194 }
1195
1196
1197 \f
1198 /* Run a digest operation.  */
1199 static void
1200 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   err = gcry_md_open (&hd, digest_algo, 0);
1208   if (err)
1209     die ("gcry_md_open failed for algo %d: %s\n",
1210          digest_algo,  gpg_strerror (err));
1211
1212   gcry_md_write (hd, data, datalen);
1213   digest = gcry_md_read (hd, digest_algo);
1214   digestlen = gcry_md_get_algo_dlen (digest_algo);
1215   print_buffer (digest, digestlen);
1216   gcry_md_close (hd);
1217 }
1218
1219 \f
1220 /* Run a HMAC operation.  */
1221 static void
1222 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   err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
1231   if (err)
1232     die ("gcry_md_open failed for HMAC algo %d: %s\n",
1233          digest_algo,  gpg_strerror (err));
1234
1235   gcry_md_setkey (hd, key, keylen);
1236   if (err)
1237     die ("gcry_md_setkey failed for HMAC algo %d: %s\n",
1238          digest_algo,  gpg_strerror (err));
1239
1240   gcry_md_write (hd, data, datalen);
1241   digest = gcry_md_read (hd, digest_algo);
1242   digestlen = gcry_md_get_algo_dlen (digest_algo);
1243   print_buffer (digest, digestlen);
1244   gcry_md_close (hd);
1245 }
1246
1247
1248 \f
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 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   if (!datalen)
1263     err = gpg_error (GPG_ERR_NO_DATA);
1264   else
1265     err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
1266   if (err)
1267     die ("gcry_sexp_new failed for RSA key derive: %s\n",
1268          gpg_strerror (err));
1269
1270   err = gcry_pk_genkey (&s_key, s_keyspec);
1271   if (err)
1272     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1273
1274   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   parmlist = "pqnd";
1279   s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0);
1280   if (s_top)
1281     {
1282       l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0);
1283       if (l1)
1284         parmlist = "qpnd";
1285       gcry_sexp_release (l1);
1286       gcry_sexp_release (s_top);
1287     }
1288
1289   /* Parse and print the parameters.  */
1290   l1 = gcry_sexp_find_token (s_key, "private-key", 0);
1291   s_top = gcry_sexp_find_token (l1, "rsa", 0);
1292   gcry_sexp_release (l1);
1293   if (!s_top)
1294     die ("private-key part not found in result\n");
1295
1296   for (idx=0; parmlist[idx]; idx++)
1297     {
1298       l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
1299       mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1300       gcry_sexp_release (l1);
1301       if (!mpi)
1302         die ("parameter %c missing in private-key\n", parmlist[idx]);
1303       print_mpi_line (mpi, 1);
1304       gcry_mpi_release (mpi);
1305     }
1306
1307   gcry_sexp_release (s_top);
1308   gcry_sexp_release (s_key);
1309 }
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 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   if (!datalen)
1326     err = gpg_error (GPG_ERR_NO_DATA);
1327   else
1328     err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
1329   if (err)
1330     die ("gcry_sexp_new failed for RSA key generation: %s\n",
1331          gpg_strerror (err));
1332
1333   err = gcry_pk_genkey (&s_key, s_keyspec);
1334
1335   gcry_sexp_release (s_keyspec);
1336
1337   if (test) {
1338         if (err)
1339                 printf("F\n");
1340         else {
1341                 gcry_sexp_release (s_key);
1342                 printf("P\n");
1343         }
1344         return;
1345   }
1346
1347   if (err)
1348     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1349
1350   parmlist = "epqnd";
1351
1352   /* Parse and print the parameters.  */
1353   l1 = gcry_sexp_find_token (s_key, "private-key", 0);
1354   s_top = gcry_sexp_find_token (l1, "rsa", 0);
1355   gcry_sexp_release (l1);
1356   if (!s_top)
1357     die ("private-key part not found in result\n");
1358
1359   for (idx=0; parmlist[idx]; idx++)
1360     {
1361       l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
1362       mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1363       gcry_sexp_release (l1);
1364       if (!mpi)
1365         die ("parameter %c missing in private-key\n", parmlist[idx]);
1366       print_mpi_line (mpi, 1);
1367       gcry_mpi_release (mpi);
1368     }
1369
1370   gcry_sexp_release (s_top);
1371   gcry_sexp_release (s_key);
1372 }
1373
1374
1375 \f
1376 static size_t
1377 compute_tag_length (size_t n)
1378 {
1379   int needed = 0;
1380
1381   if (n < 128)
1382     needed += 2; /* Tag and one length byte.  */
1383   else if (n < 256)
1384     needed += 3; /* Tag, number of length bytes, 1 length byte.  */
1385   else if (n < 65536)
1386     needed += 4; /* Tag, number of length bytes, 2 length bytes.  */
1387   else
1388     die ("DER object too long to encode\n");
1389
1390   return needed;
1391 }
1392
1393 static unsigned char *
1394 store_tag_length (unsigned char *p, int tag, size_t n)
1395 {
1396   if (tag == TAG_SEQUENCE)
1397     tag |= 0x20; /* constructed */
1398
1399   *p++ = tag;
1400   if (n < 128)
1401     *p++ = n;
1402   else if (n < 256)
1403     {
1404       *p++ = 0x81;
1405       *p++ = n;
1406     }
1407   else if (n < 65536)
1408     {
1409       *p++ = 0x82;
1410       *p++ = n >> 8;
1411       *p++ = n;
1412     }
1413
1414   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 run_rsa_gen (int keysize, int pubexp)
1437 {
1438   gpg_error_t err;
1439   gcry_sexp_t keyspec, key, l1;
1440   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   err = gcry_sexp_build (&keyspec, NULL,
1448                          "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
1449                          keysize, pubexp);
1450   if (err)
1451     die ("gcry_sexp_build failed for RSA key generation: %s\n",
1452          gpg_strerror (err));
1453
1454   err = gcry_pk_genkey (&key, keyspec);
1455   if (err)
1456     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1457
1458   gcry_sexp_release (keyspec);
1459
1460   l1 = gcry_sexp_find_token (key, "private-key", 0);
1461   if (!l1)
1462     die ("private key not found in genkey result\n");
1463   gcry_sexp_release (key);
1464   key = l1;
1465
1466   l1 = gcry_sexp_find_token (key, "rsa", 0);
1467   if (!l1)
1468     die ("returned private key not formed as expected\n");
1469   gcry_sexp_release (key);
1470   key = l1;
1471
1472   /* Extract the parameters from the S-expression and store them in a
1473      well defined order in KEYPARMS.  */
1474   for (idx=0; idx < DIM(keyparms); idx++)
1475     {
1476       if (keyelems[idx] == '.')
1477         {
1478           keyparms[idx] = gcry_mpi_new (0);
1479           continue;
1480         }
1481       l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
1482       if (!l1)
1483         die ("no %c parameter in returned private key\n", keyelems[idx]);
1484       keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1485       if (!keyparms[idx])
1486         die ("no value for %c parameter in returned private key\n",
1487              keyelems[idx]);
1488       gcry_sexp_release (l1);
1489     }
1490
1491   gcry_sexp_release (key);
1492
1493   /* Check that p < q; if not swap p and q and recompute u.  */
1494   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
1495     {
1496       gcry_mpi_swap (keyparms[3], keyparms[4]);
1497       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
1498     }
1499
1500   /* Compute the additional parameters.  */
1501   gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
1502   gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
1503   gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
1504   gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
1505
1506   /* Compute the length of the DER encoding.  */
1507   needed = compute_tag_length (1) + 1;
1508   for (idx=0; idx < DIM(keyparms); idx++)
1509     {
1510       err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
1511       if (err)
1512         die ("error formatting parameter: %s\n", gpg_strerror (err));
1513       keyparmslen[idx] = n;
1514       needed += compute_tag_length (n) + n;
1515     }
1516
1517   /* Store the key parameters. */
1518   derlen = compute_tag_length (needed) + needed;
1519   der = derbuf = gcry_xmalloc (derlen);
1520
1521   der = store_tag_length (der, TAG_SEQUENCE, needed);
1522   der = store_tag_length (der, TAG_INTEGER, 1);
1523   *der++ = 0;
1524   for (idx=0; idx < DIM(keyparms); idx++)
1525     {
1526       der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
1527       err = gcry_mpi_print (GCRYMPI_FMT_STD, der,
1528                            keyparmslen[idx], NULL, keyparms[idx]);
1529       if (err)
1530         die ("error formatting parameter: %s\n", gpg_strerror (err));
1531       der += keyparmslen[idx];
1532     }
1533
1534   /* Print the stuff.  */
1535   for (idx=0; idx < DIM(keyparms); idx++)
1536     gcry_mpi_release (keyparms[idx]);
1537
1538   assert (der - derbuf == derlen);
1539
1540   if (base64_output)
1541     puts ("-----BEGIN RSA PRIVATE KEY-----");
1542   print_buffer (derbuf, derlen);
1543   if (base64_output)
1544     puts ("-----END RSA PRIVATE KEY-----");
1545
1546   gcry_free (derbuf);
1547 }
1548
1549
1550 \f
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 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   gcry_mpi_t sig_mpi = NULL;
1561   unsigned char *outbuf;
1562   size_t outlen;
1563
1564 /*   showhex ("D", data, datalen); */
1565   if (pkcs1)
1566     {
1567       unsigned char hash[64];
1568       unsigned int hashsize;
1569
1570       hashsize = gcry_md_get_algo_dlen (hashalgo);
1571       if (!hashsize || hashsize > sizeof hash)
1572         die ("digest too long for buffer or unknown hash algorithm\n");
1573       gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1574       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   else if (pss)
1580     {
1581       unsigned char hash[64];
1582       unsigned int hashsize;
1583
1584       hashsize = gcry_md_get_algo_dlen (hashalgo);
1585       if (!hashsize || hashsize > sizeof hash)
1586         die ("digest too long for buffer or unknown hash algorithm\n");
1587       gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1588       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       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1598       if (!err)
1599         {
1600           err = gcry_sexp_build (&s_data, NULL,
1601                                  "(data (flags raw)(value %m))", tmp);
1602           gcry_mpi_release (tmp);
1603         }
1604     }
1605   if (err)
1606     die ("gcry_sexp_build failed for RSA data input: %s\n",
1607          gpg_strerror (err));
1608
1609   s_key = read_private_key_file (keyfile, 0);
1610
1611   err = gcry_pk_sign (&s_sig, s_data, s_key);
1612   if (err)
1613     {
1614       gcry_sexp_release (read_private_key_file (keyfile, 1));
1615       die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
1616            (int)datalen, keyfile, gpg_strerror (err));
1617     }
1618   gcry_sexp_release (s_key);
1619   gcry_sexp_release (s_data);
1620
1621   s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
1622   if (s_tmp)
1623     {
1624       gcry_sexp_release (s_sig);
1625       s_sig = s_tmp;
1626       s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
1627       if (s_tmp)
1628         {
1629           gcry_sexp_release (s_sig);
1630           s_sig = s_tmp;
1631           s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
1632           if (s_tmp)
1633             {
1634               gcry_sexp_release (s_sig);
1635               s_sig = s_tmp;
1636               sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
1637             }
1638         }
1639     }
1640   gcry_sexp_release (s_sig);
1641
1642   if (!sig_mpi)
1643     die ("no value in returned S-expression\n");
1644   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
1645   if (err)
1646     die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
1647   gcry_mpi_release (sig_mpi);
1648
1649   print_buffer (outbuf, outlen);
1650   gcry_free (outbuf);
1651 }
1652
1653
1654 \f
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 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   if (pkcs1)
1667     {
1668       unsigned char hash[64];
1669       unsigned int hashsize;
1670
1671       hashsize = gcry_md_get_algo_dlen (hashalgo);
1672       if (!hashsize || hashsize > sizeof hash)
1673         die ("digest too long for buffer or unknown hash algorithm\n");
1674       gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1675       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   else if (pss)
1681     {
1682       unsigned char hash[64];
1683       unsigned int hashsize;
1684
1685       hashsize = gcry_md_get_algo_dlen (hashalgo);
1686       if (!hashsize || hashsize > sizeof hash)
1687         die ("digest too long for buffer or unknown hash algorithm\n");
1688       gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1689       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       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1699       if (!err)
1700         {
1701           err = gcry_sexp_build (&s_data, NULL,
1702                                  "(data (flags raw)(value %m))", tmp);
1703           gcry_mpi_release (tmp);
1704         }
1705     }
1706   if (err)
1707     die ("gcry_sexp_build failed for RSA data input: %s\n",
1708          gpg_strerror (err));
1709
1710   s_key = read_public_key_file (keyfile, 0);
1711
1712   s_sig = read_sig_file (sigfile);
1713
1714   err = gcry_pk_verify (s_sig, s_data, s_key);
1715   if (!err)
1716     puts ("GOOD signature");
1717   else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
1718     puts ("BAD signature");
1719   else
1720     printf ("ERROR (%s)\n", gpg_strerror (err));
1721
1722   gcry_sexp_release (s_sig);
1723   gcry_sexp_release (s_key);
1724   gcry_sexp_release (s_data);
1725 }
1726
1727
1728 \f
1729 /* Generate a DSA key of size KEYSIZE and return the complete
1730    S-expression.  */
1731 static gcry_sexp_t
1732 dsa_gen (int keysize)
1733 {
1734   gpg_error_t err;
1735   gcry_sexp_t keyspec, key;
1736
1737   err = gcry_sexp_build (&keyspec, NULL,
1738                          "(genkey (dsa (nbits %d)(use-fips186-2)))",
1739                          keysize);
1740   if (err)
1741     die ("gcry_sexp_build failed for DSA key generation: %s\n",
1742          gpg_strerror (err));
1743
1744   err = gcry_pk_genkey (&key, keyspec);
1745   if (err)
1746     die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
1747
1748   gcry_sexp_release (keyspec);
1749
1750   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 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   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   if (err)
1771     die ("gcry_sexp_build failed for DSA key generation: %s\n",
1772          gpg_strerror (err));
1773
1774   err = gcry_pk_genkey (&key, keyspec);
1775   if (err)
1776     die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
1777
1778   gcry_sexp_release (keyspec);
1779
1780   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 ecdsa_gen_key (const char *curve)
1788 {
1789   gpg_error_t err;
1790   gcry_sexp_t keyspec, key;
1791
1792   err = gcry_sexp_build (&keyspec, NULL,
1793                          "(genkey"
1794                          "  (ecc"
1795                          "    (use-fips186)"
1796                          "    (curve %s)))",
1797                          curve);
1798   if (err)
1799     die ("gcry_sexp_build failed for ECDSA key generation: %s\n",
1800          gpg_strerror (err));
1801   err = gcry_pk_genkey (&key, keyspec);
1802   if (err)
1803     die ("gcry_pk_genkey failed for ECDSA: %s\n", gpg_strerror (err));
1804
1805   gcry_sexp_release (keyspec);
1806
1807   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 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   l1 = gcry_sexp_find_token (key, "public-key", 0);
1826   if (!l1)
1827     die ("public key not found in genkey result\n");
1828
1829   l2 = gcry_sexp_find_token (l1, "dsa", 0);
1830   if (!l2)
1831     die ("returned public key not formed as expected\n");
1832   gcry_sexp_release (l1);
1833   l1 = l2;
1834
1835   /* Extract the parameters from the S-expression and print them to stdout.  */
1836   for (idx=0; "pqg"[idx]; idx++)
1837     {
1838       l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1);
1839       if (!l2)
1840         die ("no %c parameter in returned public key\n", "pqg"[idx]);
1841       mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1842       if (!mpi)
1843         die ("no value for %c parameter in returned public key\n","pqg"[idx]);
1844       gcry_sexp_release (l2);
1845       if (standalone_mode)
1846         printf ("%c = ", "PQG"[idx]);
1847       print_mpi_line (mpi, 1);
1848       gcry_mpi_release (mpi);
1849     }
1850   gcry_sexp_release (l1);
1851
1852   /* Extract the seed values.  */
1853   l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
1854   if (!l1)
1855     die ("misc-key-info not found in genkey result\n");
1856
1857   l2 = gcry_sexp_find_token (l1, "seed-values", 0);
1858   if (!l2)
1859     die ("no seed-values in returned key\n");
1860   gcry_sexp_release (l1);
1861   l1 = l2;
1862
1863   l2 = gcry_sexp_find_token (l1, "seed", 0);
1864   if (!l2)
1865     die ("no seed value in returned key\n");
1866   data = gcry_sexp_nth_data (l2, 1, &datalen);
1867   if (!data)
1868     die ("no seed value in returned key\n");
1869   if (standalone_mode)
1870     printf ("Seed = ");
1871   print_data_line (data, datalen);
1872   gcry_sexp_release (l2);
1873
1874   l2 = gcry_sexp_find_token (l1, "counter", 0);
1875   if (!l2)
1876     die ("no counter value in returned key\n");
1877   string = gcry_sexp_nth_string (l2, 1);
1878   if (!string)
1879     die ("no counter value in returned key\n");
1880   if (standalone_mode)
1881     printf ("c = %ld\n", strtoul (string, NULL, 10));
1882   else
1883     printf ("%lX\n", strtoul (string, NULL, 10));
1884   gcry_free (string);
1885   gcry_sexp_release (l2);
1886
1887   l2 = gcry_sexp_find_token (l1, "h", 0);
1888   if (!l2)
1889     die ("no n value in returned key\n");
1890   mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1891   if (!mpi)
1892     die ("no h value in returned key\n");
1893   if (standalone_mode)
1894     printf ("H = ");
1895   print_mpi_line (mpi, 1);
1896   gcry_mpi_release (mpi);
1897   gcry_sexp_release (l2);
1898
1899   gcry_sexp_release (l1);
1900 }
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 print_ecdsa_dq (gcry_sexp_t key)
1908 {
1909   gcry_sexp_t l1, l2;
1910   gcry_mpi_t mpi;
1911   int idx;
1912
1913   l1 = gcry_sexp_find_token (key, "private-key", 0);
1914   if (!l1)
1915     die ("private key not found in genkey result\n");
1916
1917   l2 = gcry_sexp_find_token (l1, "ecc", 0);
1918   if (!l2)
1919     die ("returned private key not formed as expected\n");
1920   gcry_sexp_release (l1);
1921   l1 = l2;
1922
1923   /* Extract the parameters from the S-expression and print them to stdout.  */
1924   for (idx=0; "dq"[idx]; idx++)
1925     {
1926       l2 = gcry_sexp_find_token (l1, "dq"+idx, 1);
1927       if (!l2)
1928         die ("no %c parameter in returned public key\n", "dq"[idx]);
1929       mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1930       if (!mpi)
1931         die ("no value for %c parameter in returned private key\n","dq"[idx]);
1932       gcry_sexp_release (l2);
1933       if (standalone_mode)
1934         printf ("%c = ", "dQ"[idx]);
1935       print_mpi_line (mpi, 1);
1936       gcry_mpi_release (mpi);
1937     }
1938
1939   gcry_sexp_release (l1);
1940 }
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 run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen)
1949 {
1950   gcry_sexp_t key;
1951
1952   if (seed)
1953     key = dsa_gen_with_seed (keysize, seed, seedlen);
1954   else
1955     key = dsa_gen (keysize);
1956   print_dsa_domain_parameters (key);
1957   gcry_sexp_release (key);
1958 }
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 run_dsa_gen (int keysize, const char *filename)
1966 {
1967   gcry_sexp_t key, private_key;
1968   FILE *fp;
1969
1970   key = dsa_gen (keysize);
1971   private_key = gcry_sexp_find_token (key, "private-key", 0);
1972   if (!private_key)
1973     die ("private key not found in genkey result\n");
1974   print_dsa_domain_parameters (key);
1975
1976   fp = fopen (filename, "wb");
1977   if (!fp)
1978     die ("can't create `%s': %s\n", filename, strerror (errno));
1979   print_sexp (private_key, fp);
1980   fclose (fp);
1981
1982   gcry_sexp_release (private_key);
1983   gcry_sexp_release (key);
1984 }
1985
1986
1987 \f
1988 /* Sign DATA of length DATALEN using the key taken from the S-expression
1989    encoded KEYFILE. */
1990 static void
1991 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   gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
2000   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
2001   if (!err)
2002     {
2003       err = gcry_sexp_build (&s_data, NULL,
2004                              "(data (flags raw)(value %m))", tmpmpi);
2005       gcry_mpi_release (tmpmpi);
2006     }
2007   if (err)
2008     die ("gcry_sexp_build failed for DSA data input: %s\n",
2009          gpg_strerror (err));
2010
2011   s_key = read_sexp_from_file (keyfile);
2012
2013   err = gcry_pk_sign (&s_sig, s_data, s_key);
2014   if (err)
2015     {
2016       gcry_sexp_release (read_private_key_file (keyfile, 1));
2017       die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
2018            (int)datalen, keyfile, gpg_strerror (err));
2019     }
2020   gcry_sexp_release (s_data);
2021
2022   /* We need to return the Y parameter first.  */
2023   s_tmp = gcry_sexp_find_token (s_key, "private-key", 0);
2024   if (!s_tmp)
2025     die ("private key part not found in provided key\n");
2026
2027   s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0);
2028   if (!s_tmp2)
2029     die ("private key part is not a DSA key\n");
2030   gcry_sexp_release (s_tmp);
2031
2032   s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0);
2033   tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2034   if (!tmpmpi)
2035     die ("no y parameter in DSA key\n");
2036   print_mpi_line (tmpmpi, 1);
2037   gcry_mpi_release (tmpmpi);
2038   gcry_sexp_release (s_tmp);
2039
2040   gcry_sexp_release (s_key);
2041
2042
2043   /* Now return the actual signature.  */
2044   s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
2045   if (!s_tmp)
2046     die ("no sig-val element in returned S-expression\n");
2047
2048   gcry_sexp_release (s_sig);
2049   s_sig = s_tmp;
2050   s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0);
2051   if (!s_tmp)
2052     die ("no dsa element in returned S-expression\n");
2053
2054   gcry_sexp_release (s_sig);
2055   s_sig = s_tmp;
2056
2057   s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
2058   tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2059   if (!tmpmpi)
2060     die ("no r parameter in returned S-expression\n");
2061   print_mpi_line (tmpmpi, 1);
2062   gcry_mpi_release (tmpmpi);
2063   gcry_sexp_release (s_tmp);
2064
2065   s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
2066   tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2067   if (!tmpmpi)
2068     die ("no s parameter in returned S-expression\n");
2069   print_mpi_line (tmpmpi, 1);
2070   gcry_mpi_release (tmpmpi);
2071   gcry_sexp_release (s_tmp);
2072
2073   gcry_sexp_release (s_sig);
2074 }
2075
2076
2077 \f
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 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   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   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
2095   if (!err)
2096     {
2097       err = gcry_sexp_build (&s_data, NULL,
2098                              "(data (flags raw)(value %m))", tmpmpi);
2099       gcry_mpi_release (tmpmpi);
2100     }
2101   if (err)
2102     die ("gcry_sexp_build failed for DSA data input: %s\n",
2103          gpg_strerror (err));
2104
2105   s_key = read_sexp_from_file (keyfile);
2106   s_sig = read_sexp_from_file (sigfile);
2107
2108   err = gcry_pk_verify (s_sig, s_data, s_key);
2109   if (!err)
2110     puts ("GOOD signature");
2111   else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
2112     puts ("BAD signature");
2113   else
2114     printf ("ERROR (%s)\n", gpg_strerror (err));
2115
2116   gcry_sexp_release (s_sig);
2117   gcry_sexp_release (s_key);
2118   gcry_sexp_release (s_data);
2119 }
2120
2121
2122 \f
2123 /* Sign DATA of length DATALEN using the key taken from the S-expression
2124    encoded KEYFILE. */
2125 static void
2126 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   s_key = read_sexp_from_file (keyfile);
2136
2137   gcry_md_hash_buffer (algo, hash, data, datalen);
2138   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
2139                        gcry_md_get_algo_dlen(algo), NULL);
2140   if (!err)
2141     {
2142       err = gcry_sexp_build (&s_data, NULL,
2143                              "(data (flags raw)(hash %s %M))",
2144                              gcry_md_algo_name(algo), tmpmpi);
2145       gcry_mpi_release (tmpmpi);
2146     }
2147   if (err)
2148     die ("gcry_sexp_build failed for ECDSA data input: %s\n",
2149          gpg_strerror (err));
2150
2151   err = gcry_pk_sign (&s_sig, s_data, s_key);
2152   if (err)
2153     {
2154       die ("gcry_pk_signed failed: %s\n", gpg_strerror (err));
2155     }
2156   gcry_sexp_release (s_data);
2157   gcry_sexp_release (s_key);
2158
2159   /* Now return the actual signature.  */
2160   s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
2161   if (!s_tmp)
2162     die ("no sig-val element in returned S-expression\n");
2163
2164   gcry_sexp_release (s_sig);
2165   s_sig = s_tmp;
2166   s_tmp = gcry_sexp_find_token (s_sig, "ecdsa", 0);
2167   if (!s_tmp)
2168     die ("no ecdsa element in returned S-expression\n");
2169
2170   gcry_sexp_release (s_sig);
2171   s_sig = s_tmp;
2172
2173   s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
2174   tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2175   if (!tmpmpi)
2176     die ("no r parameter in returned S-expression\n");
2177   print_mpi_line (tmpmpi, 1);
2178   gcry_mpi_release (tmpmpi);
2179   gcry_sexp_release (s_tmp);
2180
2181   s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
2182   tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
2183   if (!tmpmpi)
2184     die ("no s parameter in returned S-expression\n");
2185   print_mpi_line (tmpmpi, 1);
2186   gcry_mpi_release (tmpmpi);
2187   gcry_sexp_release (s_tmp);
2188
2189   gcry_sexp_release (s_sig);
2190 }
2191
2192
2193 \f
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 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   s_key = read_sexp_from_file (keyfile);
2208
2209   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   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
2213                        gcry_md_get_algo_dlen(algo), NULL);
2214   if (!err)
2215     {
2216       err = gcry_sexp_build (&s_data, NULL,
2217                              "(data (flags raw)(hash %s %M))",
2218                              gcry_md_algo_name(algo), tmpmpi);
2219       gcry_mpi_release (tmpmpi);
2220     }
2221   if (err)
2222     die ("gcry_sexp_build failed for DSA data input: %s\n",
2223          gpg_strerror (err));
2224
2225   s_sig = read_sexp_from_file (sigfile);
2226
2227   err = gcry_pk_verify (s_sig, s_data, s_key);
2228   if (!err)
2229     puts ("GOOD signature");
2230   else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
2231     puts ("BAD signature");
2232   else
2233     printf ("ERROR (%s)\n", gpg_strerror (err));
2234
2235   gcry_sexp_release (s_sig);
2236   gcry_sexp_release (s_key);
2237   gcry_sexp_release (s_data);
2238 }
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 run_ecdsa_gen_key (const char *curve)
2245 {
2246   gcry_sexp_t key;
2247
2248   key = ecdsa_gen_key (curve);
2249   print_ecdsa_dq (key);
2250
2251   gcry_sexp_release (key);
2252 }
2253
2254
2255 \f
2256 static void
2257 usage (int show_help)
2258 {
2259   if (!show_help)
2260     {
2261       fputs ("usage: " PGM
2262              " [OPTION] [FILE] (try --help for more information)\n", stderr);
2263       exit (2);
2264     }
2265   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   exit (0);
2293 }
2294
2295 int
2296 main (int argc, char **argv)
2297 {
2298   int last_argc = -1;
2299   gpg_error_t err;
2300   int no_fips = 0;
2301   int progress = 0;
2302   int use_pkcs1 = 0;
2303   int use_pss = 0;
2304   const char *mode_string;
2305   const char *curve_string = NULL;
2306   const char *key_string = NULL;
2307   const char *iv_string = NULL;
2308   const char *dt_string = NULL;
2309   const char *algo_string = NULL;
2310   const char *keysize_string = NULL;
2311   const char *signature_string = NULL;
2312   FILE *input;
2313   void *data;
2314   size_t datalen;
2315   size_t chunksize = 0;
2316   int mct_server = 0;
2317
2318
2319   if (argc)
2320     { argc--; argv++; }
2321
2322   while (argc && last_argc != argc )
2323     {
2324       last_argc = argc;
2325       if (!strcmp (*argv, "--"))
2326         {
2327           argc--; argv++;
2328           break;
2329         }
2330       else if (!strcmp (*argv, "--help"))
2331         {
2332           usage (1);
2333         }
2334       else if (!strcmp (*argv, "--version"))
2335         {
2336           fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
2337           exit (0);
2338         }
2339       else if (!strcmp (*argv, "--verbose"))
2340         {
2341           verbose++;
2342           argc--; argv++;
2343         }
2344       else if (!strcmp (*argv, "--binary"))
2345         {
2346           binary_input = binary_output = 1;
2347           argc--; argv++;
2348         }
2349       else if (!strcmp (*argv, "--no-fips"))
2350         {
2351           no_fips++;
2352           argc--; argv++;
2353         }
2354       else if (!strcmp (*argv, "--loop"))
2355         {
2356           loop_mode = 1;
2357           argc--; argv++;
2358         }
2359       else if (!strcmp (*argv, "--progress"))
2360         {
2361           progress = 1;
2362           argc--; argv++;
2363         }
2364       else if (!strcmp (*argv, "--key"))
2365         {
2366           argc--; argv++;
2367           if (!argc)
2368             usage (0);
2369           key_string = *argv;
2370           argc--; argv++;
2371         }
2372       else if (!strcmp (*argv, "--iv"))
2373         {
2374           argc--; argv++;
2375           if (!argc)
2376             usage (0);
2377           iv_string = *argv;
2378           argc--; argv++;
2379         }
2380       else if (!strcmp (*argv, "--dt"))
2381         {
2382           argc--; argv++;
2383           if (!argc)
2384             usage (0);
2385           dt_string = *argv;
2386           argc--; argv++;
2387         }
2388       else if (!strcmp (*argv, "--algo"))
2389         {
2390           argc--; argv++;
2391           if (!argc)
2392             usage (0);
2393           algo_string = *argv;
2394           argc--; argv++;
2395         }
2396       else if (!strcmp (*argv, "--keysize"))
2397         {
2398           argc--; argv++;
2399           if (!argc)
2400             usage (0);
2401           keysize_string = *argv;
2402           argc--; argv++;
2403         }
2404       else if (!strcmp (*argv, "--signature"))
2405         {
2406           argc--; argv++;
2407           if (!argc)
2408             usage (0);
2409           signature_string = *argv;
2410           argc--; argv++;
2411         }
2412       else if (!strcmp (*argv, "--chunk"))
2413         {
2414           argc--; argv++;
2415           if (!argc)
2416             usage (0);
2417           chunksize = atoi (*argv);
2418           binary_input = binary_output = 1;
2419           argc--; argv++;
2420         }
2421       else if (!strcmp (*argv, "--curve"))
2422         {
2423           argc--; argv++;
2424           if (!argc)
2425             usage (0);
2426           curve_string = *argv;
2427           argc--; argv++;
2428         }
2429       else if (!strcmp (*argv, "--pkcs1"))
2430         {
2431           use_pkcs1 = 1;
2432           argc--; argv++;
2433         }
2434       else if (!strcmp (*argv, "--pss"))
2435         {
2436           use_pss = 1;
2437           argc--; argv++;
2438         }
2439       else if (!strcmp (*argv, "--mct-server"))
2440         {
2441           mct_server = 1;
2442           argc--; argv++;
2443         }
2444       else if (!strcmp (*argv, "--standalone"))
2445         {
2446           standalone_mode = 1;
2447           argc--; argv++;
2448         }
2449     }
2450
2451   if (!argc || argc > 2)
2452     usage (0);
2453
2454   mode_string = *argv;
2455
2456   if (use_pkcs1 && use_pss)
2457     die ("Only one of --pkcs or --pss may be given\n");
2458
2459   if (!strcmp (mode_string, "rsa-derive"))
2460     binary_input = 1;
2461
2462   if (argc == 2 && strcmp (argv[1], "-"))
2463     {
2464       input = fopen (argv[1], binary_input? "rb":"r");
2465       if (!input)
2466         die ("can't open `%s': %s\n", argv[1], strerror (errno));
2467     }
2468   else
2469     input = stdin;
2470
2471 #ifndef HAVE_W32_SYSTEM
2472   if (loop_mode)
2473     signal (SIGPIPE, SIG_IGN);
2474 #endif
2475
2476   if (verbose)
2477     fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
2478
2479   xgcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
2480   if (!no_fips)
2481     xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
2482   if (!gcry_check_version ("1.4.3"))
2483     die ("Libgcrypt is not sufficient enough\n");
2484   if (verbose)
2485     fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
2486   if (no_fips)
2487     xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
2488   xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
2489
2490   /* Most operations need some input data.  */
2491   if (!chunksize
2492       && !mct_server
2493       && strcmp (mode_string, "random")
2494       && strcmp (mode_string, "rsa-gen")
2495       && strcmp (mode_string, "rsa-keygen")
2496       && strcmp (mode_string, "rsa-keygen-kat")
2497       && strcmp (mode_string, "dsa-gen")
2498       && strcmp (mode_string, "ecdsa-gen-key") )
2499     {
2500       data = read_file (input, !binary_input, &datalen);
2501       if (!data)
2502         die ("error reading%s input\n", binary_input?"":" and decoding");
2503       if (verbose)
2504         fprintf (stderr, PGM ": %u bytes of input data\n",
2505                  (unsigned int)datalen);
2506     }
2507   else
2508     {
2509       data = NULL;
2510       datalen = 0;
2511     }
2512
2513
2514   if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
2515     {
2516       int cipher_algo, cipher_mode;
2517       void  *iv_buffer = NULL;
2518       void *key_buffer = NULL;
2519       size_t iv_buflen,  key_buflen;
2520
2521       if (!algo_string)
2522         die ("option --algo is required in this mode\n");
2523       cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
2524       if (!cipher_algo)
2525         die ("cipher algorithm `%s' is not supported\n", algo_string);
2526       if (mct_server)
2527         {
2528           int iterations;
2529
2530           for (;;)
2531             {
2532               gcry_free (key_buffer); key_buffer = NULL;
2533               gcry_free (iv_buffer); iv_buffer = NULL;
2534               gcry_free (data); data = NULL;
2535               if (!(key_buffer = read_textline (input)))
2536                 {
2537                   if (feof (input))
2538                     break;
2539                   die ("no version info in input\n");
2540                 }
2541               if (atoi (key_buffer) != 1)
2542                 die ("unsupported input version %s\n",
2543                      (const char*)key_buffer);
2544               gcry_free (key_buffer);
2545               if (!(key_buffer = read_textline (input)))
2546                 die ("no iteration count in input\n");
2547               iterations = atoi (key_buffer);
2548               gcry_free (key_buffer);
2549               if (!(key_buffer = read_hexline (input, &key_buflen)))
2550                 die ("no key in input\n");
2551               if (!(iv_buffer = read_hexline (input, &iv_buflen)))
2552                 die ("no IV in input\n");
2553               if (!(data = read_hexline (input, &datalen)))
2554                 die ("no data in input\n");
2555               skip_to_empty_line (input);
2556
2557               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           if (cipher_mode != GCRY_CIPHER_MODE_ECB)
2567             {
2568               if (!iv_string)
2569                 die ("option --iv is required in this mode\n");
2570               iv_buffer = hex2buffer (iv_string, &iv_buflen);
2571               if (!iv_buffer)
2572                 die ("invalid value for IV\n");
2573             }
2574           else
2575             {
2576               iv_buffer = NULL;
2577               iv_buflen = 0;
2578             }
2579           if (!key_string)
2580             die ("option --key is required in this mode\n");
2581           key_buffer = hex2buffer (key_string, &key_buflen);
2582           if (!key_buffer)
2583             die ("invalid value for KEY\n");
2584
2585           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       gcry_free (key_buffer);
2592       gcry_free (iv_buffer);
2593     }
2594   else if (!strcmp (mode_string, "digest"))
2595     {
2596       int algo;
2597
2598       if (!algo_string)
2599         die ("option --algo is required in this mode\n");
2600       algo = gcry_md_map_name (algo_string);
2601       if (!algo)
2602         die ("digest algorithm `%s' is not supported\n", algo_string);
2603       if (!data)
2604         die ("no data available (do not use --chunk)\n");
2605
2606       run_digest (algo, data, datalen);
2607     }
2608   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       size_t count = 0;
2616
2617       if (!key_string || hex2bin (key_string, key, 16) < 0 )
2618         die ("value for --key are not 32 hex digits\n");
2619       if (!iv_string || hex2bin (iv_string, seed, 16) < 0 )
2620         die ("value for --iv are not 32 hex digits\n");
2621       if (!dt_string || hex2bin (dt_string, dt, 16) < 0 )
2622         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       err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
2627       if (err)
2628         die ("init external RNG test failed: %s\n", gpg_strerror (err));
2629
2630       do
2631         {
2632           err = run_external_rng_test (context, buffer, sizeof buffer);
2633           if (err)
2634             die ("running external RNG test failed: %s\n", gpg_strerror (err));
2635           print_buffer (buffer, sizeof buffer);
2636           if (progress)
2637             {
2638               if (!(++count % 1000))
2639                 fprintf (stderr, PGM ": %lu random bytes so far\n",
2640                          (unsigned long int)(count * sizeof buffer));
2641             }
2642         }
2643       while (loop_mode);
2644
2645       if (progress)
2646         fprintf (stderr, PGM ": %lu random bytes\n",
2647                  (unsigned long int)(count * sizeof buffer));
2648
2649       deinit_external_rng_test (context);
2650     }
2651   else if (!strcmp (mode_string, "hmac-sha"))
2652     {
2653       int algo;
2654       void  *key_buffer;
2655       size_t key_buflen;
2656
2657       if (!data)
2658         die ("no data available (do not use --chunk)\n");
2659       if (!algo_string)
2660         die ("option --algo is required in this mode\n");
2661       switch (atoi (algo_string))
2662         {
2663         case 1:   algo = GCRY_MD_SHA1; break;
2664         case 224: algo = GCRY_MD_SHA224; break;
2665         case 256: algo = GCRY_MD_SHA256; break;
2666         case 384: algo = GCRY_MD_SHA384; break;
2667         case 512: algo = GCRY_MD_SHA512; break;
2668         default:  algo = 0; break;
2669         }
2670       if (!algo)
2671         die ("no digest algorithm found for hmac type `%s'\n", algo_string);
2672       if (!key_string)
2673         die ("option --key is required in this mode\n");
2674       key_buffer = hex2buffer (key_string, &key_buflen);
2675       if (!key_buffer)
2676         die ("invalid value for KEY\n");
2677
2678       run_hmac (algo, key_buffer, key_buflen, data, datalen);
2679
2680       gcry_free (key_buffer);
2681     }
2682   else if (!strcmp (mode_string, "rsa-derive"))
2683     {
2684       if (!data)
2685         die ("no data available (do not use --chunk)\n");
2686       run_rsa_derive (data, datalen);
2687     }
2688   else if (!strcmp (mode_string, "rsa-keygen"))
2689     {
2690       data = read_file (input, 0, &datalen);
2691       if (!data)
2692         die ("no data available (do not use --chunk)\n");
2693       run_rsa_keygen (data, datalen, 0);
2694     }
2695   else if (!strcmp (mode_string, "rsa-keygen-kat"))
2696     {
2697       data = read_file (input, 0, &datalen);
2698       if (!data)
2699         die ("no data available (do not use --chunk)\n");
2700       run_rsa_keygen (data, datalen, 1);
2701     }
2702   else if (!strcmp (mode_string, "rsa-gen"))
2703     {
2704       int keysize;
2705
2706       if (!binary_output)
2707         base64_output = 1;
2708
2709       keysize = keysize_string? atoi (keysize_string) : 0;
2710       if (keysize < 128 || keysize > 16384)
2711         die ("invalid keysize specified; needs to be 128 .. 16384\n");
2712       run_rsa_gen (keysize, 65537);
2713     }
2714   else if (!strcmp (mode_string, "rsa-sign"))
2715     {
2716       int algo;
2717
2718       if (!key_string)
2719         die ("option --key is required in this mode\n");
2720       if (access (key_string, R_OK))
2721         die ("option --key needs to specify an existing keyfile\n");
2722       if (!algo_string)
2723         die ("option --algo is required in this mode\n");
2724       algo = gcry_md_map_name (algo_string);
2725       if (!algo)
2726         die ("digest algorithm `%s' is not supported\n", algo_string);
2727       if (!data)
2728         die ("no data available (do not use --chunk)\n");
2729
2730       run_rsa_sign (data, datalen, algo, use_pkcs1, use_pss, key_string);
2731
2732     }
2733   else if (!strcmp (mode_string, "rsa-verify"))
2734     {
2735       int algo;
2736
2737       if (!key_string)
2738         die ("option --key is required in this mode\n");
2739       if (access (key_string, R_OK))
2740         die ("option --key needs to specify an existing keyfile\n");
2741       if (!algo_string)
2742         die ("option --algo is required in this mode\n");
2743       algo = gcry_md_map_name (algo_string);
2744       if (!algo)
2745         die ("digest algorithm `%s' is not supported\n", algo_string);
2746       if (!data)
2747         die ("no data available (do not use --chunk)\n");
2748       if (!signature_string)
2749         die ("option --signature is required in this mode\n");
2750       if (access (signature_string, R_OK))
2751         die ("option --signature needs to specify an existing file\n");
2752
2753       run_rsa_verify (data, datalen, algo, use_pkcs1, use_pss, key_string,
2754                       signature_string);
2755
2756     }
2757   else if (!strcmp (mode_string, "dsa-pqg-gen"))
2758     {
2759       int keysize;
2760
2761       keysize = keysize_string? atoi (keysize_string) : 0;
2762       if (keysize < 1024 || keysize > 3072)
2763         die ("invalid keysize specified; needs to be 1024 .. 3072\n");
2764       run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen);
2765     }
2766   else if (!strcmp (mode_string, "dsa-gen"))
2767     {
2768       int keysize;
2769
2770       keysize = keysize_string? atoi (keysize_string) : 0;
2771       if (keysize < 1024 || keysize > 3072)
2772         die ("invalid keysize specified; needs to be 1024 .. 3072\n");
2773       if (!key_string)
2774         die ("option --key is required in this mode\n");
2775       run_dsa_gen (keysize, key_string);
2776     }
2777   else if (!strcmp (mode_string, "dsa-sign"))
2778     {
2779       if (!key_string)
2780         die ("option --key is required in this mode\n");
2781       if (access (key_string, R_OK))
2782         die ("option --key needs to specify an existing keyfile\n");
2783       if (!data)
2784         die ("no data available (do not use --chunk)\n");
2785
2786       run_dsa_sign (data, datalen, key_string);
2787     }
2788   else if (!strcmp (mode_string, "dsa-verify"))
2789     {
2790       if (!key_string)
2791         die ("option --key is required in this mode\n");
2792       if (access (key_string, R_OK))
2793         die ("option --key needs to specify an existing keyfile\n");
2794       if (!data)
2795         die ("no data available (do not use --chunk)\n");
2796       if (!signature_string)
2797         die ("option --signature is required in this mode\n");
2798       if (access (signature_string, R_OK))
2799         die ("option --signature needs to specify an existing file\n");
2800
2801       run_dsa_verify (data, datalen, key_string, signature_string);
2802     }
2803   else if (!strcmp (mode_string, "ecdsa-gen-key"))
2804     {
2805       if (!curve_string)
2806         die ("option --curve containing name of the specified curve is required in this mode\n");
2807       run_ecdsa_gen_key (curve_string);
2808     }
2809   else if (!strcmp (mode_string, "ecdsa-sign"))
2810     {
2811       int algo;
2812
2813       if (!key_string)
2814         die ("option --key is required in this mode\n");
2815       if (access (key_string, R_OK))
2816         die ("option --key needs to specify an existing keyfile\n");
2817       if (!algo_string)
2818         die ("use --algo to specify the digest algorithm\n");
2819       algo = gcry_md_map_name (algo_string);
2820       if (!algo)
2821         die ("digest algorithm `%s' is not supported\n", algo_string);
2822
2823       if (!data)
2824         die ("no data available (do not use --chunk)\n");
2825
2826       run_ecdsa_sign (data, datalen, key_string, algo);
2827     }
2828   else if (!strcmp (mode_string, "ecdsa-verify"))
2829     {
2830       int algo;
2831
2832       if (!key_string)
2833         die ("option --key is required in this mode\n");
2834       if (access (key_string, R_OK))
2835         die ("option --key needs to specify an existing keyfile\n");
2836       if (!algo_string)
2837         die ("use --algo to specify the digest algorithm\n");
2838       algo = gcry_md_map_name (algo_string);
2839       if (!algo)
2840         die ("digest algorithm `%s' is not supported\n", algo_string);
2841       if (!data)
2842         die ("no data available (do not use --chunk)\n");
2843       if (!signature_string)
2844         die ("option --signature is required in this mode\n");
2845       if (access (signature_string, R_OK))
2846         die ("option --signature needs to specify an existing file\n");
2847
2848       run_ecdsa_verify (data, datalen, key_string, algo, signature_string);
2849     }
2850   else
2851     usage (0);
2852
2853   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   if (!no_fips && !gcry_fips_mode_active ())
2859     die ("FIPS mode is not anymore active\n");
2860
2861   if (verbose)
2862     fputs (PGM ": ready\n", stderr);
2863
2864   return 0;
2865 }