Fix last moi-pow.c change.
[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 #ifndef HAVE_W32_SYSTEM
30 # include <signal.h>
31 #endif
32 #include <assert.h>
33 #include <unistd.h>
34
35 #ifdef _GCRYPT_IN_LIBGCRYPT
36 # include "../src/gcrypt.h"
37 #else
38 # include <gcrypt.h>
39 # define PACKAGE_BUGREPORT "devnull@example.org"
40 # define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
41 #endif
42
43
44 #define PGM "fipsdrv"
45
46 #define my_isascii(c) (!((c) & 0x80))
47 #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
48 #define hexdigitp(a) (digitp (a)                     \
49                       || (*(a) >= 'A' && *(a) <= 'F')  \
50                       || (*(a) >= 'a' && *(a) <= 'f'))
51 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
52                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
53 #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
54 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
55 #define DIMof(type,member)   DIM(((type *)0)->member)
56
57
58 #define PRIV_CTL_INIT_EXTRNG_TEST   58
59 #define PRIV_CTL_RUN_EXTRNG_TEST    59
60 #define PRIV_CTL_DEINIT_EXTRNG_TEST 60
61 #define PRIV_CTL_DISABLE_WEAK_KEY   61
62 #define PRIV_CTL_GET_INPUT_VECTOR   62
63
64
65 /* Verbose mode flag.  */
66 static int verbose;
67
68 /* Binary input flag.  */
69 static int binary_input;
70
71 /* Binary output flag.  */
72 static int binary_output;
73
74 /* Base64 output flag.  */
75 static int base64_output;
76
77 /* We need to know whetehr we are in loop_mode.  */
78 static int loop_mode;
79
80
81 /* ASN.1 classes.  */
82 enum
83 {
84   UNIVERSAL = 0,
85   APPLICATION = 1,
86   ASNCONTEXT = 2,
87   PRIVATE = 3
88 };
89
90
91 /* ASN.1 tags.  */
92 enum
93 {
94   TAG_NONE = 0,
95   TAG_BOOLEAN = 1,
96   TAG_INTEGER = 2,
97   TAG_BIT_STRING = 3,
98   TAG_OCTET_STRING = 4,
99   TAG_NULL = 5,
100   TAG_OBJECT_ID = 6,
101   TAG_OBJECT_DESCRIPTOR = 7,
102   TAG_EXTERNAL = 8,
103   TAG_REAL = 9,
104   TAG_ENUMERATED = 10,
105   TAG_EMBEDDED_PDV = 11,
106   TAG_UTF8_STRING = 12,
107   TAG_REALTIVE_OID = 13,
108   TAG_SEQUENCE = 16,
109   TAG_SET = 17,
110   TAG_NUMERIC_STRING = 18,
111   TAG_PRINTABLE_STRING = 19,
112   TAG_TELETEX_STRING = 20,
113   TAG_VIDEOTEX_STRING = 21,
114   TAG_IA5_STRING = 22,
115   TAG_UTC_TIME = 23,
116   TAG_GENERALIZED_TIME = 24,
117   TAG_GRAPHIC_STRING = 25,
118   TAG_VISIBLE_STRING = 26,
119   TAG_GENERAL_STRING = 27,
120   TAG_UNIVERSAL_STRING = 28,
121   TAG_CHARACTER_STRING = 29,
122   TAG_BMP_STRING = 30
123 };
124
125 /* ASN.1 Parser object.  */
126 struct tag_info 
127 {
128   int class;             /* Object class.  */
129   unsigned long tag;     /* The tag of the object.  */
130   unsigned long length;  /* Length of the values.  */
131   int nhdr;              /* Length of the header (TL).  */
132   unsigned int ndef:1;   /* The object has an indefinite length.  */
133   unsigned int cons:1;   /* This is a constructed object.  */ 
134 };
135
136
137
138 /* Print a error message and exit the process with an error code.  */
139 static void
140 die (const char *format, ...)
141 {
142   va_list arg_ptr;
143
144   va_start (arg_ptr, format);
145   fputs (PGM ": ", stderr);
146   vfprintf (stderr, format, arg_ptr);
147   va_end (arg_ptr);
148   exit (1);
149 }
150
151
152 static void
153 showhex (const char *prefix, const void *buffer, size_t length)
154 {
155   const unsigned char *p = buffer;
156
157   if (prefix)
158     fprintf (stderr, PGM ": %s: ", prefix);
159   while (length-- )
160     fprintf (stderr, "%02X", *p++);
161   if (prefix)
162     putc ('\n', stderr);
163 }
164
165
166 /* Convert STRING consisting of hex characters into its binary
167    representation and store that at BUFFER.  BUFFER needs to be of
168    LENGTH bytes.  The function checks that the STRING will convert
169    exactly to LENGTH bytes. The string is delimited by either end of
170    string or a white space character.  The function returns -1 on
171    error or the length of the parsed string.  */
172 static int
173 hex2bin (const char *string, void *buffer, size_t length)
174 {
175   int i;
176   const char *s = string;
177
178   for (i=0; i < length; )
179     {
180       if (!hexdigitp (s) || !hexdigitp (s+1))
181         return -1;           /* Invalid hex digits. */
182       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
183       s += 2;
184     }
185   if (*s && (!my_isascii (*s) || !isspace (*s)) )
186     return -1;             /* Not followed by Nul or white space.  */
187   if (i != length)
188     return -1;             /* Not of expected length.  */
189   if (*s)
190     s++; /* Skip the delimiter. */
191   return s - string;
192 }
193
194
195 /* Convert STRING consisting of hex characters into its binary
196    representation and return it as an allocated buffer. The valid
197    length of the buffer is returned at R_LENGTH.  The string is
198    delimited by end of string.  The function returns NULL on
199    error.  */
200 static void *
201 hex2buffer (const char *string, size_t *r_length)
202 {
203   const char *s;
204   unsigned char *buffer;
205   size_t length;
206
207   buffer = gcry_xmalloc (strlen(string)/2+1);
208   length = 0;
209   for (s=string; *s; s +=2 )
210     {
211       if (!hexdigitp (s) || !hexdigitp (s+1))
212         return NULL;           /* Invalid hex digits. */
213       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
214     }
215   *r_length = length;
216   return buffer;
217 }
218
219
220 static char *
221 read_textline (FILE *fp)
222 {
223   char line[256];
224   char *p;
225   int any = 0;
226
227   /* Read line but skip over initial empty lines.  */
228   do
229     {
230       do 
231         {
232           if (!fgets (line, sizeof line, fp))
233             {
234               if (feof (fp))
235                 return NULL;
236               die ("error reading input line: %s\n", strerror (errno));
237             }
238           p = strchr (line, '\n');
239           if (p)
240             *p = 0;
241           p = line + (*line? (strlen (line)-1):0);
242           for ( ;p > line; p--)
243             if (my_isascii (*p) && isspace (*p))
244               *p = 0;
245         }
246       while (!any && !*line);
247       any = 1;
248     }
249   while (*line == '#');  /* Always skip comment lines.  */
250   if (verbose > 1)
251     fprintf (stderr, PGM ": received line: %s\n", line);
252   return gcry_xstrdup (line);
253 }
254
255 static char *
256 read_hexline (FILE *fp, size_t *retlen)
257 {
258   char *line, *p;
259
260   line = read_textline (fp);
261   if (!line)
262     return NULL;
263   p = hex2buffer (line, retlen);
264   if (!p)
265     die ("error decoding hex string on input\n");
266   gcry_free (line);
267   return p;
268 }
269
270 static void
271 skip_to_empty_line (FILE *fp)
272 {
273   char line[256];
274   char *p;
275
276   do
277     {
278       if (!fgets (line, sizeof line, fp))
279         {
280           if (feof (fp))
281             return;
282           die ("error reading input line: %s\n", strerror (errno));
283         }
284       p = strchr (line, '\n');
285       if (p)
286         *p =0;
287     }
288   while (*line);
289 }
290
291
292
293 /* Read a file from stream FP into a newly allocated buffer and return
294    that buffer.  The valid length of the buffer is stored at R_LENGTH.
295    Returns NULL on failure.  If decode is set, the file is assumed to
296    be hex encoded and the decoded content is returned. */
297 static void *
298 read_file (FILE *fp, int decode, size_t *r_length)
299 {
300   char *buffer;
301   size_t buflen;
302   size_t nread, bufsize = 0;
303
304   *r_length = 0;
305 #define NCHUNK 8192
306 #ifdef HAVE_DOSISH_SYSTEM
307   setmode (fileno(fp), O_BINARY);
308 #endif
309   buffer = NULL;
310   buflen = 0;
311   do 
312     {
313       bufsize += NCHUNK;
314       if (!buffer)
315         buffer = gcry_xmalloc (bufsize);
316       else
317         buffer = gcry_xrealloc (buffer, bufsize);
318       
319       nread = fread (buffer + buflen, 1, NCHUNK, fp);
320       if (nread < NCHUNK && ferror (fp))
321         {
322           gcry_free (buffer);
323           return NULL;
324         }
325       buflen += nread;
326     }
327   while (nread == NCHUNK);
328 #undef NCHUNK
329   if (decode)
330     {
331       const char *s;
332       char *p;
333
334       for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 )
335         {
336           if (!hexdigitp (s) || !hexdigitp (s+1))
337             {
338               gcry_free (buffer);
339               return NULL;  /* Invalid hex digits. */
340             }
341           *(unsigned char*)p++ = xtoi_2 (s);
342         }
343       if (nread != buflen)
344         {
345           gcry_free (buffer);
346           return NULL;  /* Odd number of hex digits. */
347         }
348       buflen = p - buffer;
349     }
350
351   *r_length = buflen;
352   return buffer;
353 }
354
355 /* Do in-place decoding of base-64 data of LENGTH in BUFFER.  Returns
356    the new length of the buffer.  Dies on error.  */
357 static size_t
358 base64_decode (char *buffer, size_t length)
359 {
360   static unsigned char const asctobin[128] = 
361     {
362       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
363       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
364       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
365       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
366       0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
367       0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
368       0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
369       0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
370       0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
371       0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
372       0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff 
373     };
374
375   int idx = 0;
376   unsigned char val = 0;
377   int c = 0;
378   char *d, *s;
379   int lfseen = 1;
380
381   /* Find BEGIN line.  */
382   for (s=buffer; length; length--, s++)
383     {
384       if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11))
385         {
386           for (; length && *s != '\n'; length--, s++)
387             ;
388           break;
389         } 
390       lfseen = (*s == '\n');
391     }
392
393   /* Decode until pad character or END line.  */
394   for (d=buffer; length; length--, s++)
395     {
396       if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9))
397         break;
398       if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t')
399         continue;
400       if (*s == '=')
401         {
402           /* Pad character: stop */
403           if (idx == 1)
404             *d++ = val;
405           break;
406         }
407
408       if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff)
409         die ("invalid base64 character %02X at pos %d detected\n",
410              *(unsigned char*)s, (int)(s-buffer));
411
412       switch (idx)
413         {
414         case 0:
415           val = c << 2;
416           break;
417         case 1:
418           val |= (c>>4)&3;
419           *d++ = val;
420           val = (c<<4)&0xf0;
421           break;
422         case 2:
423           val |= (c>>2)&15;
424           *d++ = val;
425           val = (c<<6)&0xc0;
426           break;
427         case 3:
428           val |= c&0x3f;
429           *d++ = val;
430           break;
431         }
432       idx = (idx+1) % 4;
433     }
434
435   return d - buffer;
436 }
437
438
439 /* Parse the buffer at the address BUFFER which consists of the number
440    of octets as stored at BUFLEN.  Return the tag and the length part
441    from the TLV triplet.  Update BUFFER and BUFLEN on success.  Checks
442    that the encoded length does not exhaust the length of the provided
443    buffer. */
444 static int 
445 parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti)
446 {
447   int c;
448   unsigned long tag;
449   const unsigned char *buf = *buffer;
450   size_t length = *buflen;
451
452   ti->length = 0;
453   ti->ndef = 0;
454   ti->nhdr = 0;
455
456   /* Get the tag */
457   if (!length)
458     return -1; /* Premature EOF.  */
459   c = *buf++; length--;
460   ti->nhdr++;
461
462   ti->class = (c & 0xc0) >> 6;
463   ti->cons  = !!(c & 0x20);
464   tag       = (c & 0x1f);
465
466   if (tag == 0x1f)
467     {
468       tag = 0;
469       do
470         {
471           tag <<= 7;
472           if (!length)
473             return -1; /* Premature EOF.  */
474           c = *buf++; length--;
475           ti->nhdr++;
476           tag |= (c & 0x7f);
477         }
478       while ( (c & 0x80) );
479     }
480   ti->tag = tag;
481
482   /* Get the length */
483   if (!length)
484     return -1; /* Premature EOF. */
485   c = *buf++; length--;
486   ti->nhdr++;
487
488   if ( !(c & 0x80) )
489     ti->length = c;
490   else if (c == 0x80)
491     ti->ndef = 1;
492   else if (c == 0xff)
493     return -1; /* Forbidden length value.  */
494   else
495     {
496       unsigned long len = 0;
497       int count = c & 0x7f;
498
499       for (; count; count--)
500         {
501           len <<= 8;
502           if (!length)
503             return -1; /* Premature EOF.  */
504           c = *buf++; length--;
505           ti->nhdr++;
506           len |= (c & 0xff);
507         }
508       ti->length = len;
509     }
510   
511   if (ti->class == UNIVERSAL && !ti->tag)
512     ti->length = 0;
513
514   if (ti->length > length)
515     return -1; /* Data larger than buffer.  */
516   
517   *buffer = buf;
518   *buflen = length;
519   return 0;
520 }
521
522
523 /* Read the file FNAME assuming it is a PEM encoded private key file
524    and return an S-expression.  With SHOW set, the key parameters are
525    printed.  */
526 static gcry_sexp_t
527 read_private_key_file (const char *fname, int show)
528 {
529   gcry_error_t err;
530   FILE *fp;
531   char *buffer;
532   size_t buflen;
533   const unsigned char *der;
534   size_t derlen;
535   struct tag_info ti;
536   gcry_mpi_t keyparms[8];
537   int n_keyparms = 8;
538   int idx;
539   gcry_sexp_t s_key;
540
541   fp = fopen (fname, binary_input?"rb":"r");
542   if (!fp)
543     die ("can't open `%s': %s\n", fname, strerror (errno));
544   buffer = read_file (fp, 0, &buflen);
545   if (!buffer)
546     die ("error reading `%s'\n", fname);
547   fclose (fp);
548
549   buflen = base64_decode (buffer, buflen);
550   
551   /* Parse the ASN.1 structure.  */
552   der = (const unsigned char*)buffer;
553   derlen = buflen;
554   if ( parse_tag (&der, &derlen, &ti)
555        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
556     goto bad_asn1;
557   if ( parse_tag (&der, &derlen, &ti)
558        || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
559     goto bad_asn1;
560   if (ti.length != 1 || *der)
561     goto bad_asn1;  /* The value of the first integer is no 0. */
562   der += ti.length; derlen -= ti.length;
563
564   for (idx=0; idx < n_keyparms; idx++)
565     {
566       if ( parse_tag (&der, &derlen, &ti)
567            || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
568         goto bad_asn1;
569       if (show)
570         {
571           char prefix[2];
572
573           prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
574           prefix[1] = 0;
575           showhex (prefix, der, ti.length);
576         }
577       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
578       if (err)
579         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
580       der += ti.length; derlen -= ti.length;
581     }
582   if (idx != n_keyparms)
583     die ("not enough RSA key parameters\n");
584
585   gcry_free (buffer);
586
587   /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
588   /* First check that p < q; if not swap p and q and recompute u.  */ 
589   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
590     {
591       gcry_mpi_swap (keyparms[3], keyparms[4]);
592       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
593     }
594   
595   /* Build the S-expression.  */
596   err = gcry_sexp_build (&s_key, NULL,
597                          "(private-key(rsa(n%m)(e%m)"
598                          /**/            "(d%m)(p%m)(q%m)(u%m)))",
599                          keyparms[0], keyparms[1], keyparms[2],
600                          keyparms[3], keyparms[4], keyparms[7] );
601   if (err)
602     die ("error building S-expression: %s\n", gpg_strerror (err));
603   
604   for (idx=0; idx < n_keyparms; idx++)
605     gcry_mpi_release (keyparms[idx]);
606   
607   return s_key;
608   
609  bad_asn1:
610   die ("invalid ASN.1 structure in `%s'\n", fname);
611   return NULL; /*NOTREACHED*/
612 }
613
614
615 /* Read the file FNAME assuming it is a PEM encoded public key file
616    and return an S-expression.  With SHOW set, the key parameters are
617    printed.  */
618 static gcry_sexp_t
619 read_public_key_file (const char *fname, int show)
620 {
621   gcry_error_t err;
622   FILE *fp;
623   char *buffer;
624   size_t buflen;
625   const unsigned char *der;
626   size_t derlen;
627   struct tag_info ti;
628   gcry_mpi_t keyparms[2];
629   int n_keyparms = 2;
630   int idx;
631   gcry_sexp_t s_key;
632
633   fp = fopen (fname, binary_input?"rb":"r");
634   if (!fp)
635     die ("can't open `%s': %s\n", fname, strerror (errno));
636   buffer = read_file (fp, 0, &buflen);
637   if (!buffer)
638     die ("error reading `%s'\n", fname);
639   fclose (fp);
640
641   buflen = base64_decode (buffer, buflen);
642   
643   /* Parse the ASN.1 structure.  */
644   der = (const unsigned char*)buffer;
645   derlen = buflen;
646   if ( parse_tag (&der, &derlen, &ti)
647        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
648     goto bad_asn1;
649   if ( parse_tag (&der, &derlen, &ti)
650        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
651     goto bad_asn1;
652   /* We skip the description of the key parameters and assume it is RSA.  */
653   der += ti.length; derlen -= ti.length;
654   
655   if ( parse_tag (&der, &derlen, &ti)
656        || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
657     goto bad_asn1;
658   if (ti.length < 1 || *der)
659     goto bad_asn1;  /* The number of unused bits needs to be 0. */
660   der += 1; derlen -= 1;
661
662   /* Parse the BIT string.  */
663   if ( parse_tag (&der, &derlen, &ti)
664        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
665     goto bad_asn1;
666
667   for (idx=0; idx < n_keyparms; idx++)
668     {
669       if ( parse_tag (&der, &derlen, &ti)
670            || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
671         goto bad_asn1;
672       if (show)
673         {
674           char prefix[2];
675
676           prefix[0] = idx < 2? "ne"[idx] : '?';
677           prefix[1] = 0;
678           showhex (prefix, der, ti.length);
679         }
680       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
681       if (err)
682         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
683       der += ti.length; derlen -= ti.length;
684     }
685   if (idx != n_keyparms)
686     die ("not enough RSA key parameters\n");
687
688   gcry_free (buffer);
689
690   /* Build the S-expression.  */
691   err = gcry_sexp_build (&s_key, NULL,
692                          "(public-key(rsa(n%m)(e%m)))",
693                          keyparms[0], keyparms[1] );
694   if (err)
695     die ("error building S-expression: %s\n", gpg_strerror (err));
696   
697   for (idx=0; idx < n_keyparms; idx++)
698     gcry_mpi_release (keyparms[idx]);
699   
700   return s_key;
701   
702  bad_asn1:
703   die ("invalid ASN.1 structure in `%s'\n", fname);
704   return NULL; /*NOTREACHED*/
705 }
706
707
708
709 /* Read the file FNAME assuming it is a binary signature result and
710    return an an S-expression suitable for gcry_pk_verify.  */
711 static gcry_sexp_t
712 read_sig_file (const char *fname)
713 {
714   gcry_error_t err;
715   FILE *fp;
716   char *buffer;
717   size_t buflen;
718   gcry_mpi_t tmpmpi;
719   gcry_sexp_t s_sig;
720
721   fp = fopen (fname, "rb");
722   if (!fp)
723     die ("can't open `%s': %s\n", fname, strerror (errno));
724   buffer = read_file (fp, 0, &buflen);
725   if (!buffer)
726     die ("error reading `%s'\n", fname);
727   fclose (fp);
728
729   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL);
730   if (!err)
731     err = gcry_sexp_build (&s_sig, NULL,
732                            "(sig-val(rsa(s %m)))", tmpmpi);
733   if (err)
734     die ("error building S-expression: %s\n", gpg_strerror (err));
735   gcry_mpi_release (tmpmpi);
736   gcry_free (buffer);
737
738   return s_sig;
739 }
740
741
742 static void
743 print_buffer (const void *buffer, size_t length)
744 {
745   int writerr = 0;
746
747   if (base64_output)
748     {
749       static const unsigned char bintoasc[64+1] = 
750         ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
751          "abcdefghijklmnopqrstuvwxyz" 
752          "0123456789+/"); 
753       const unsigned char *p;
754       unsigned char inbuf[4];
755       char outbuf[4];
756       int idx, quads;
757
758       idx = quads = 0;
759       for (p = buffer; length; p++, length--)
760         {
761           inbuf[idx++] = *p;
762           if (idx > 2)
763             {
764               outbuf[0] = bintoasc[(*inbuf>>2)&077];
765               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
766                                     |((inbuf[1] >> 4)&017))&077];
767               outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
768                                     |((inbuf[2]>>6)&03))&077];
769               outbuf[3] = bintoasc[inbuf[2]&077];
770               if (fwrite (outbuf, 4, 1, stdout) != 1)
771                 writerr = 1;
772               idx = 0;
773               if (++quads >= (64/4)) 
774                 {
775                   if (fwrite ("\n", 1, 1, stdout) != 1)
776                     writerr = 1;
777                   quads = 0;
778                 }
779             }
780         }
781       if (idx)
782         {
783           outbuf[0] = bintoasc[(*inbuf>>2)&077];
784           if (idx == 1)
785             {
786               outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
787               outbuf[2] = outbuf[3] = '=';
788             }
789           else 
790             { 
791               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
792                                     |((inbuf[1]>>4)&017))&077];
793               outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
794               outbuf[3] = '=';
795             }
796           if (fwrite (outbuf, 4, 1, stdout) != 1)
797             writerr = 1;
798           quads++;
799         }
800       if (quads && fwrite ("\n", 1, 1, stdout) != 1)
801         writerr = 1;
802     }
803   else if (binary_output)
804     {
805       if (fwrite (buffer, length, 1, stdout) != 1)
806         writerr++;
807     }
808   else
809     {
810       const unsigned char *p = buffer;
811       
812       if (verbose > 1)
813         showhex ("sent line", buffer, length);
814       while (length-- && !ferror (stdout) )
815         printf ("%02X", *p++);
816       if (ferror (stdout))
817         writerr++;
818     }
819   if (!writerr && fflush (stdout) == EOF)
820     writerr++;
821   if (writerr)
822     {
823 #ifndef HAVE_W32_SYSTEM
824       if (loop_mode && errno == EPIPE)
825         loop_mode = 0;
826       else
827 #endif
828         die ("writing output failed: %s\n", strerror (errno));
829     }
830 }
831
832
833 /* Print an MPI on a line.  */
834 static void
835 print_mpi_line (gcry_mpi_t a, int no_lz)
836 {
837   unsigned char *buf, *p;
838   gcry_error_t err;
839   int writerr = 0;
840
841   err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
842   if (err)
843     die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
844
845   p = buf;
846   if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
847     p +=2;
848     
849   printf ("%s\n", p);
850   if (ferror (stdout))
851     writerr++;
852   if (!writerr && fflush (stdout) == EOF)
853     writerr++;
854   if (writerr)
855     die ("writing output failed: %s\n", strerror (errno));
856   gcry_free (buf);
857 }
858
859
860 /* Print some data on hex format on a line.  */
861 static void
862 print_data_line (const void *data, size_t datalen)
863 {
864   const unsigned char *p = data;
865   int writerr = 0;
866       
867   while (data && datalen-- && !ferror (stdout) )
868     printf ("%02X", *p++);
869   putchar ('\n');
870   if (ferror (stdout))
871     writerr++;
872   if (!writerr && fflush (stdout) == EOF)
873     writerr++;
874   if (writerr)
875     die ("writing output failed: %s\n", strerror (errno));
876 }
877
878
879
880
881 static gcry_error_t
882 init_external_rng_test (void **r_context, 
883                     unsigned int flags,
884                     const void *key, size_t keylen,
885                     const void *seed, size_t seedlen,
886                     const void *dt, size_t dtlen)
887 {
888   return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST, 
889                        r_context, flags,
890                        key, keylen,
891                        seed, seedlen,
892                        dt, dtlen);
893 }
894
895 static gcry_error_t
896 run_external_rng_test (void *context, void *buffer, size_t buflen)
897 {
898   return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen);
899 }
900
901 static void
902 deinit_external_rng_test (void *context)
903 {
904   gcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context);
905 }
906
907
908 /* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm
909    identified and store the libgcrypt mode at R_MODE.  Returns 0 on
910    error.  */
911 static int 
912 map_openssl_cipher_name (const char *name, int *r_mode)
913 {
914   static struct {
915     const char *name;
916     int algo;
917     int mode;
918   } table[] = 
919     {
920       { "bf-cbc",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
921       { "bf",           GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
922       { "bf-cfb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
923       { "bf-ecb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
924       { "bf-ofb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
925
926       { "cast-cbc",     GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
927       { "cast",         GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
928       { "cast5-cbc",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
929       { "cast5-cfb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
930       { "cast5-ecb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
931       { "cast5-ofb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
932
933       { "des-cbc",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
934       { "des",          GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
935       { "des-cfb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
936       { "des-ofb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
937       { "des-ecb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
938
939       { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
940       { "des-ede3",     GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
941       { "des3",         GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
942       { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
943       { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
944
945       { "rc4",          GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
946
947       { "aes-128-cbc",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
948       { "aes-128",      GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
949       { "aes-128-cfb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
950       { "aes-128-ecb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
951       { "aes-128-ofb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
952
953       { "aes-192-cbc",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
954       { "aes-192",      GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
955       { "aes-192-cfb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
956       { "aes-192-ecb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
957       { "aes-192-ofb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
958       
959       { "aes-256-cbc",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
960       { "aes-256",      GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
961       { "aes-256-cfb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
962       { "aes-256-ecb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
963       { "aes-256-ofb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
964
965       { NULL, 0 , 0 }
966     };
967   int idx;
968
969   for (idx=0; table[idx].name; idx++)
970     if (!strcmp (name, table[idx].name))
971       {
972         *r_mode = table[idx].mode;
973         return table[idx].algo;
974       }
975   *r_mode = 0;
976   return 0;
977 }
978
979
980 \f
981 /* Run an encrypt or decryption operations.  If DATA is NULL the
982    function reads its input in chunks of size DATALEN from fp and
983    processes it and writes it out until EOF.  */
984 static void
985 run_encrypt_decrypt (int encrypt_mode,
986                      int cipher_algo, int cipher_mode, 
987                      const void *iv_buffer, size_t iv_buflen,
988                      const void *key_buffer, size_t key_buflen,
989                      const void *data, size_t datalen, FILE *fp)
990 {
991   gpg_error_t err;
992   gcry_cipher_hd_t hd;
993   void *outbuf;
994   size_t outbuflen;
995   void *inbuf;
996   size_t inbuflen;
997   size_t blocklen;
998
999   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
1000   if (err)
1001     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", 
1002          cipher_algo, cipher_mode, gpg_strerror (err));
1003
1004   blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
1005   assert (blocklen);
1006
1007   gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
1008
1009   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
1010   if (err)
1011     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
1012          (unsigned int)key_buflen, gpg_strerror (err));
1013
1014   if (iv_buffer)
1015     {
1016       err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
1017       if (err)
1018         die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
1019              (unsigned int)iv_buflen, gpg_strerror (err));
1020     }
1021
1022   inbuf = data? NULL : gcry_xmalloc (datalen);
1023   outbuflen = datalen;
1024   outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen);
1025
1026   do
1027     {
1028       if (inbuf)
1029         {
1030           int nread = fread (inbuf, 1, datalen, fp);
1031           if (nread < (int)datalen && ferror (fp))
1032             die ("error reading input\n");
1033           data = inbuf;
1034           inbuflen = nread;
1035         }
1036       else
1037         inbuflen = datalen;
1038
1039       if (encrypt_mode)
1040         err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
1041       else
1042         err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
1043       if (err)
1044         die ("gcry_cipher_%scrypt failed: %s\n",
1045              encrypt_mode? "en":"de", gpg_strerror (err));
1046       
1047       print_buffer (outbuf, outbuflen);
1048     }
1049   while (inbuf);
1050
1051   gcry_cipher_close (hd);
1052   gcry_free (outbuf);
1053   gcry_free (inbuf);
1054 }
1055
1056
1057 static void
1058 get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen)
1059 {
1060   unsigned char tmp[17];
1061
1062   if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
1063     die ("error getting current input vector\n");
1064   if (buflen > *tmp)
1065     die ("buffer too short to store the current input vector\n");
1066   memcpy (buffer, tmp+1, *tmp);
1067 }
1068
1069 /* Run the inner loop of the CAVS monte carlo test.  */
1070 static void
1071 run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode, 
1072                      const void *iv_buffer, size_t iv_buflen,
1073                      const void *key_buffer, size_t key_buflen,
1074                      const void *data, size_t datalen, int iterations)
1075 {
1076   gpg_error_t err;
1077   gcry_cipher_hd_t hd;
1078   size_t blocklen;
1079   int count;
1080   char input[16];
1081   char output[16];
1082   char last_output[16];
1083   char last_last_output[16];
1084   char last_iv[16]; 
1085
1086
1087   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
1088   if (err)
1089     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", 
1090          cipher_algo, cipher_mode, gpg_strerror (err));
1091
1092   blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
1093   if (!blocklen || blocklen > sizeof output)
1094     die ("invalid block length %d\n", blocklen);
1095
1096
1097   gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
1098
1099   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
1100   if (err)
1101     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
1102          (unsigned int)key_buflen, gpg_strerror (err));
1103
1104   if (iv_buffer)
1105     {
1106       err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
1107       if (err)
1108         die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
1109              (unsigned int)iv_buflen, gpg_strerror (err));
1110     }
1111
1112   if (datalen != blocklen)
1113     die ("length of input (%u) does not match block length (%u)\n", 
1114          (unsigned int)datalen, (unsigned int)blocklen);
1115   memcpy (input, data, datalen);
1116   memset (output, 0, sizeof output);
1117   for (count=0; count < iterations; count++)
1118     {
1119       memcpy (last_last_output, last_output, sizeof last_output);
1120       memcpy (last_output, output, sizeof output);
1121
1122       get_current_iv (hd, last_iv, blocklen);
1123
1124       if (encrypt_mode)
1125         err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen);
1126       else
1127         err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen);
1128       if (err)
1129         die ("gcry_cipher_%scrypt failed: %s\n",
1130              encrypt_mode? "en":"de", gpg_strerror (err));
1131
1132   
1133       if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB
1134                            || cipher_mode == GCRY_CIPHER_MODE_CBC))
1135         memcpy (input, last_iv, blocklen);
1136       else if (cipher_mode == GCRY_CIPHER_MODE_OFB)
1137         memcpy (input, last_iv, blocklen);
1138       else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB)
1139         {
1140           /* Reconstruct the output vector.  */
1141           int i;
1142           for (i=0; i < blocklen; i++)
1143             input[i] ^= output[i];
1144         }
1145       else
1146         memcpy (input, output, blocklen);
1147     }
1148
1149   print_buffer (output, blocklen);
1150   putchar ('\n');
1151   print_buffer (last_output, blocklen);
1152   putchar ('\n');
1153   print_buffer (last_last_output, blocklen);
1154   putchar ('\n');
1155   get_current_iv (hd, last_iv, blocklen);
1156   print_buffer (last_iv, blocklen); /* Last output vector.  */
1157   putchar ('\n');
1158   print_buffer (input, blocklen);   /* Next input text. */
1159   putchar ('\n');
1160   if (verbose > 1)
1161     showhex ("sent line", "", 0);
1162   putchar ('\n');
1163   fflush (stdout);
1164
1165   gcry_cipher_close (hd);
1166 }
1167
1168
1169 \f
1170 /* Run a digest operation.  */
1171 static void
1172 run_digest (int digest_algo,  const void *data, size_t datalen)
1173 {
1174   gpg_error_t err;
1175   gcry_md_hd_t hd;
1176   const unsigned char *digest;
1177   unsigned int digestlen;
1178
1179   err = gcry_md_open (&hd, digest_algo, 0);
1180   if (err)
1181     die ("gcry_md_open failed for algo %d: %s\n", 
1182          digest_algo,  gpg_strerror (err));
1183
1184   gcry_md_write (hd, data, datalen);
1185   digest = gcry_md_read (hd, digest_algo);
1186   digestlen = gcry_md_get_algo_dlen (digest_algo);
1187   print_buffer (digest, digestlen);
1188   gcry_md_close (hd);
1189 }
1190
1191 \f
1192 /* Run a HMAC operation.  */
1193 static void
1194 run_hmac (int digest_algo, const void *key, size_t keylen, 
1195           const void *data, size_t datalen)
1196 {
1197   gpg_error_t err;
1198   gcry_md_hd_t hd;
1199   const unsigned char *digest;
1200   unsigned int digestlen;
1201
1202   err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
1203   if (err)
1204     die ("gcry_md_open failed for HMAC algo %d: %s\n", 
1205          digest_algo,  gpg_strerror (err));
1206
1207   gcry_md_setkey (hd, key, keylen);
1208   if (err)
1209     die ("gcry_md_setkey failed for HMAC 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 static size_t
1221 compute_tag_length (size_t n)
1222 {     
1223   int needed = 0;
1224
1225   if (n < 128)
1226     needed += 2; /* Tag and one length byte.  */
1227   else if (n < 256)
1228     needed += 3; /* Tag, number of length bytes, 1 length byte.  */
1229   else if (n < 65536)
1230     needed += 4; /* Tag, number of length bytes, 2 length bytes.  */
1231   else
1232     die ("DER object too long to encode\n");
1233
1234   return needed;
1235 }
1236
1237 static unsigned char *
1238 store_tag_length (unsigned char *p, int tag, size_t n)
1239 {     
1240   if (tag == TAG_SEQUENCE)
1241     tag |= 0x20; /* constructed */
1242
1243   *p++ = tag;
1244   if (n < 128)
1245     *p++ = n;
1246   else if (n < 256)
1247     {
1248       *p++ = 0x81;
1249       *p++ = n;
1250     }
1251   else if (n < 65536)
1252     {
1253       *p++ = 0x82;
1254       *p++ = n >> 8;
1255       *p++ = n;
1256     }
1257
1258   return p;
1259 }
1260
1261
1262 /* Generate an RSA key of size KEYSIZE using the public exponent
1263    PUBEXP and print it to stdout in the OpenSSL format.  The format
1264    is:
1265
1266        SEQUENCE {
1267          INTEGER (0)  -- Unknown constant. 
1268          INTEGER      -- n
1269          INTEGER      -- e
1270          INTEGER      -- d
1271          INTEGER      -- p     
1272          INTEGER      -- q      (with p < q)
1273          INTEGER      -- dmp1 = d mod (p-1)
1274          INTEGER      -- dmq1 = d mod (q-1)
1275          INTEGER      -- u    = p^{-1} mod q
1276        }
1277
1278 */
1279 static void
1280 run_rsa_gen (int keysize, int pubexp)
1281 {
1282   gpg_error_t err;
1283   gcry_sexp_t keyspec, key, l1;
1284   const char keyelems[] = "nedpq..u";
1285   gcry_mpi_t keyparms[8];
1286   size_t     keyparmslen[8];
1287   int idx;
1288   size_t derlen, needed, n;
1289   unsigned char *derbuf, *der;
1290
1291   err = gcry_sexp_build (&keyspec, NULL, 
1292                          "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
1293                          keysize, pubexp);
1294   if (err)
1295     die ("gcry_sexp_build failed for RSA key generation: %s\n",
1296          gpg_strerror (err));
1297
1298   err = gcry_pk_genkey (&key, keyspec);
1299   if (err)
1300     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1301   
1302   gcry_sexp_release (keyspec);
1303
1304   l1 = gcry_sexp_find_token (key, "private-key", 0);
1305   if (!l1)
1306     die ("private key not found in genkey result\n");
1307   gcry_sexp_release (key);
1308   key = l1;
1309
1310   l1 = gcry_sexp_find_token (key, "rsa", 0);
1311   if (!l1)
1312     die ("returned private key not formed as expected\n");
1313   gcry_sexp_release (key);
1314   key = l1;
1315
1316   /* Extract the parameters from the S-expression and store them in a
1317      well defined order in KEYPARMS.  */
1318   for (idx=0; idx < DIM(keyparms); idx++) 
1319     {
1320       if (keyelems[idx] == '.')
1321         {
1322           keyparms[idx] = gcry_mpi_new (0);
1323           continue;
1324         }
1325       l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
1326       if (!l1)
1327         die ("no %c parameter in returned private key\n", keyelems[idx]);
1328       keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1329       if (!keyparms[idx])
1330         die ("no value for %c parameter in returned private key\n",
1331              keyelems[idx]);
1332       gcry_sexp_release (l1);
1333     }
1334
1335   gcry_sexp_release (key);
1336
1337   /* Check that p < q; if not swap p and q and recompute u.  */ 
1338   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
1339     {
1340       gcry_mpi_swap (keyparms[3], keyparms[4]);
1341       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
1342     }
1343
1344   /* Compute the additional parameters.  */
1345   gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
1346   gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
1347   gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
1348   gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
1349
1350   /* Compute the length of the DER encoding.  */
1351   needed = compute_tag_length (1) + 1;  
1352   for (idx=0; idx < DIM(keyparms); idx++) 
1353     {
1354       err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
1355       if (err)
1356         die ("error formatting parameter: %s\n", gpg_strerror (err));
1357       keyparmslen[idx] = n;
1358       needed += compute_tag_length (n) + n;
1359     }
1360   
1361   /* Store the key parameters. */
1362   derlen = compute_tag_length (needed) + needed;
1363   der = derbuf = gcry_xmalloc (derlen);
1364
1365   der = store_tag_length (der, TAG_SEQUENCE, needed);
1366   der = store_tag_length (der, TAG_INTEGER, 1);
1367   *der++ = 0;
1368   for (idx=0; idx < DIM(keyparms); idx++) 
1369     {
1370       der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
1371       err = gcry_mpi_print (GCRYMPI_FMT_STD, der, 
1372                            keyparmslen[idx], NULL, keyparms[idx]);
1373       if (err)
1374         die ("error formatting parameter: %s\n", gpg_strerror (err));
1375       der += keyparmslen[idx];
1376     }
1377
1378   /* Print the stuff.  */
1379   for (idx=0; idx < DIM(keyparms); idx++) 
1380     gcry_mpi_release (keyparms[idx]);
1381
1382   assert (der - derbuf == derlen);
1383
1384   if (base64_output)
1385     puts ("-----BEGIN RSA PRIVATE KEY-----");
1386   print_buffer (derbuf, derlen);
1387   if (base64_output)
1388     puts ("-----END RSA PRIVATE KEY-----");
1389
1390   gcry_free (derbuf);
1391 }
1392
1393
1394 \f
1395 /* Sign DATA of length DATALEN using the key taken from the PEM
1396    encoded KEYFILE and the hash algorithm HASHALGO.  */
1397 static void
1398 run_rsa_sign (const void *data, size_t datalen,
1399               int hashalgo, int pkcs1, const char *keyfile)
1400
1401 {
1402   gpg_error_t err;
1403   gcry_sexp_t s_data, s_key, s_sig, s_tmp;
1404   gcry_mpi_t sig_mpi = NULL;
1405   unsigned char *outbuf;
1406   size_t outlen;
1407   
1408 /*   showhex ("D", data, datalen); */
1409   if (pkcs1)
1410     {
1411       unsigned char hash[64];
1412       unsigned int hashsize;
1413
1414       hashsize = gcry_md_get_algo_dlen (hashalgo);
1415       if (!hashsize || hashsize > sizeof hash)
1416         die ("digest too long for buffer or unknown hash algorithm\n");
1417       gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1418       err = gcry_sexp_build (&s_data, NULL,
1419                              "(data (flags pkcs1)(hash %s %b))",
1420                              gcry_md_algo_name (hashalgo),
1421                              (int)hashsize, hash);
1422     }
1423   else
1424     {
1425       gcry_mpi_t tmp;
1426
1427       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1428       if (!err)
1429         {
1430           err = gcry_sexp_build (&s_data, NULL,
1431                                  "(data (flags raw)(value %m))", tmp);
1432           gcry_mpi_release (tmp);
1433         }
1434     }
1435   if (err)
1436     die ("gcry_sexp_build failed for RSA data input: %s\n",
1437          gpg_strerror (err));
1438
1439   s_key = read_private_key_file (keyfile, 0);
1440
1441   err = gcry_pk_sign (&s_sig, s_data, s_key);
1442   if (err)
1443     {
1444       gcry_sexp_release (read_private_key_file (keyfile, 1));
1445       die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
1446            (int)datalen, keyfile, gpg_strerror (err));
1447     }
1448   gcry_sexp_release (s_key);
1449   gcry_sexp_release (s_data);
1450
1451   s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
1452   if (s_tmp)
1453     {
1454       gcry_sexp_release (s_sig);
1455       s_sig = s_tmp;
1456       s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
1457       if (s_tmp)
1458         {
1459           gcry_sexp_release (s_sig);
1460           s_sig = s_tmp;
1461           s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
1462           if (s_tmp)
1463             {
1464               gcry_sexp_release (s_sig);
1465               s_sig = s_tmp;
1466               sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
1467             }
1468         }
1469     }
1470   gcry_sexp_release (s_sig);
1471               
1472   if (!sig_mpi)
1473     die ("no value in returned S-expression\n");
1474   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
1475   if (err)
1476     die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
1477   gcry_mpi_release (sig_mpi);
1478
1479   print_buffer (outbuf, outlen);
1480   gcry_free (outbuf);
1481 }
1482
1483
1484 \f
1485 /* Verify DATA of length DATALEN using the public key taken from the
1486    PEM encoded KEYFILE and the hash algorithm HASHALGO against the
1487    binary signature in SIGFILE.  */
1488 static void
1489 run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
1490                 const char *keyfile, const char *sigfile)
1491
1492 {
1493   gpg_error_t err;
1494   gcry_sexp_t s_data, s_key, s_sig;
1495   
1496   if (pkcs1)
1497     {
1498       unsigned char hash[64];
1499       unsigned int hashsize;
1500
1501       hashsize = gcry_md_get_algo_dlen (hashalgo);
1502       if (!hashsize || hashsize > sizeof hash)
1503         die ("digest too long for buffer or unknown hash algorithm\n");
1504       gcry_md_hash_buffer (hashalgo, hash, data, datalen);
1505       err = gcry_sexp_build (&s_data, NULL,
1506                              "(data (flags pkcs1)(hash %s %b))",
1507                              gcry_md_algo_name (hashalgo),
1508                              (int)hashsize, hash);
1509     }
1510   else
1511     {
1512       gcry_mpi_t tmp;
1513
1514       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1515       if (!err)
1516         {
1517           err = gcry_sexp_build (&s_data, NULL,
1518                                  "(data (flags raw)(value %m))", tmp);
1519           gcry_mpi_release (tmp);
1520         }
1521     }
1522   if (err)
1523     die ("gcry_sexp_build failed for RSA data input: %s\n",
1524          gpg_strerror (err));
1525
1526   s_key = read_public_key_file (keyfile, 0);
1527
1528   s_sig = read_sig_file (sigfile);
1529
1530   err = gcry_pk_verify (s_sig, s_data, s_key);
1531   if (!err)
1532     puts ("GOOD signature");
1533   else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
1534     puts ("BAD signature");
1535   else
1536     printf ("ERROR (%s)\n", gpg_strerror (err));
1537
1538   gcry_sexp_release (s_sig);
1539   gcry_sexp_release (s_key);
1540   gcry_sexp_release (s_data);
1541 }
1542
1543
1544 \f
1545 /* Generate DSA donmain parameters for a modulus size of KEYSIZE.  The
1546    result is printed to stdout with one parameter per line in hex
1547    format and in this order: p, q, g, seed, counter, h.  */
1548 static void
1549 run_dsa_pqg_gen (int keysize)
1550 {
1551   gpg_error_t err;
1552   gcry_sexp_t keyspec, key, l1, l2;
1553   gcry_mpi_t mpi;
1554   int idx;
1555   const void *data;
1556   size_t datalen;
1557   char *string;
1558
1559   /* Note that we create a complete key but don't return the x and y
1560      values.  */
1561   err = gcry_sexp_build (&keyspec, NULL, 
1562                          "(genkey (dsa (nbits %d)(use-fips186-2)))",
1563                          keysize);
1564   if (err)
1565     die ("gcry_sexp_build failed for DSA domain parameter generation: %s\n",
1566          gpg_strerror (err));
1567
1568   err = gcry_pk_genkey (&key, keyspec);
1569   if (err)
1570     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
1571   
1572   gcry_sexp_release (keyspec);
1573
1574   l1 = gcry_sexp_find_token (key, "private-key", 0);
1575   if (!l1)
1576     die ("private key not found in genkey result\n");
1577
1578   l2 = gcry_sexp_find_token (l1, "dsa", 0);
1579   if (!l2)
1580     die ("returned private key not formed as expected\n");
1581   gcry_sexp_release (l1);
1582   l1 = l2;
1583
1584   /* Extract the parameters from the S-expression and print them to stdout.  */
1585   for (idx=0; "pqg"[idx]; idx++) 
1586     {
1587       l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1);
1588       if (!l2)
1589         die ("no %c parameter in returned private key\n", "pqg"[idx]);
1590       mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1591       if (!mpi)
1592         die ("no value for %c parameter in returned private key\n","pqg"[idx]);
1593       gcry_sexp_release (l2);
1594       print_mpi_line (mpi, 1);
1595       gcry_mpi_release (mpi);
1596     }
1597   gcry_sexp_release (l1);
1598
1599   /* Extract the seed values.  */
1600   l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
1601   if (!l1)
1602     die ("misc-key-info not found in genkey result\n");
1603
1604   l2 = gcry_sexp_find_token (l1, "seed-values", 0);
1605   if (!l2)
1606     die ("no seed-values in returned private key\n");
1607   gcry_sexp_release (l1);
1608   l1 = l2;
1609
1610   l2 = gcry_sexp_find_token (l1, "seed", 0);
1611   if (!l2)
1612     die ("no seed value in returned private key\n");
1613   data = gcry_sexp_nth_data (l2, 1, &datalen);
1614   if (!data)
1615     die ("no seed value in returned private key\n");
1616   print_data_line (data, datalen);
1617   gcry_sexp_release (l2);
1618
1619   l2 = gcry_sexp_find_token (l1, "counter", 0);
1620   if (!l2)
1621     die ("no counter value in returned private key\n");
1622   string = gcry_sexp_nth_string (l2, 1);
1623   if (!string)
1624     die ("no counter value in returned private key\n");
1625   printf ("%lX\n", strtoul (string, NULL, 10));
1626   gcry_free (string);
1627   gcry_sexp_release (l2);
1628
1629   l2 = gcry_sexp_find_token (l1, "h", 0);
1630   if (!l2)
1631     die ("no n value in returned private key\n");
1632   mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1633   if (!mpi)
1634     die ("no h value in returned private key\n");
1635   print_mpi_line (mpi, 1);
1636   gcry_mpi_release (mpi);
1637   gcry_sexp_release (l2);
1638
1639   gcry_sexp_release (l1);
1640   gcry_sexp_release (key);
1641 }
1642
1643
1644 \f
1645 static void
1646 usage (int show_help)
1647 {
1648   if (!show_help)
1649     {
1650       fputs ("usage: " PGM 
1651              " [OPTION] [FILE] (try --help for more information)\n", stderr);
1652       exit (2);
1653     }
1654   fputs
1655     ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
1656      "Run a crypto operation using hex encoded input and output.\n"
1657      "MODE:\n"
1658      "  encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify},\n"
1659      "  dsa-pqg-gen\n"
1660      "OPTIONS:\n"
1661      "  --verbose        Print additional information\n"
1662      "  --binary         Input and output is in binary form\n"
1663      "  --no-fips        Do not force FIPS mode\n"
1664      "  --key KEY        Use the hex encoded KEY\n"
1665      "  --iv IV          Use the hex encoded IV\n"
1666      "  --dt DT          Use the hex encoded DT for the RNG\n"
1667      "  --algo NAME      Use algorithm NAME\n"
1668      "  --keysize N      Use a keysize of N bits\n"
1669      "  --signature NAME Take signature from file NAME\n"
1670      "  --chunk N        Read in chunks of N bytes (implies --binary)\n"
1671      "  --pkcs1          Use PKCS#1 encoding\n"
1672      "  --mct-server     Run a monte carlo test server\n"
1673      "  --loop           Enable random loop mode\n"
1674      "  --progress       Print pogress indicators\n"
1675      "  --help           Print this text\n"
1676      "With no FILE, or when FILE is -, read standard input.\n"
1677      "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
1678   exit (0);
1679 }
1680
1681 int
1682 main (int argc, char **argv)
1683 {
1684   int last_argc = -1;
1685   gpg_error_t err;
1686   int no_fips = 0;
1687   int progress = 0;
1688   int use_pkcs1 = 0;
1689   const char *mode_string;
1690   const char *key_string = NULL;
1691   const char *iv_string = NULL;
1692   const char *dt_string = NULL;
1693   const char *algo_string = NULL;
1694   const char *keysize_string = NULL;
1695   const char *signature_string = NULL;
1696   FILE *input;
1697   void *data;
1698   size_t datalen;
1699   size_t chunksize = 0;
1700   int mct_server = 0;
1701
1702
1703   if (argc)
1704     { argc--; argv++; }
1705
1706   while (argc && last_argc != argc )
1707     {
1708       last_argc = argc;
1709       if (!strcmp (*argv, "--"))
1710         {
1711           argc--; argv++;
1712           break;
1713         }
1714       else if (!strcmp (*argv, "--help"))
1715         {
1716           usage (1);
1717         }
1718       else if (!strcmp (*argv, "--version"))
1719         {
1720           fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
1721           exit (0);
1722         }
1723       else if (!strcmp (*argv, "--verbose"))
1724         {
1725           verbose++;
1726           argc--; argv++;
1727         }
1728       else if (!strcmp (*argv, "--binary"))
1729         {
1730           binary_input = binary_output = 1;
1731           argc--; argv++;
1732         }
1733       else if (!strcmp (*argv, "--no-fips"))
1734         {
1735           no_fips++;
1736           argc--; argv++;
1737         }
1738       else if (!strcmp (*argv, "--loop"))
1739         {
1740           loop_mode = 1;
1741           argc--; argv++;
1742         }
1743       else if (!strcmp (*argv, "--progress"))
1744         {
1745           progress = 1;
1746           argc--; argv++;
1747         }
1748       else if (!strcmp (*argv, "--key"))
1749         {
1750           argc--; argv++;
1751           if (!argc)
1752             usage (0);
1753           key_string = *argv;
1754           argc--; argv++;
1755         }
1756       else if (!strcmp (*argv, "--iv"))
1757         {
1758           argc--; argv++;
1759           if (!argc)
1760             usage (0);
1761           iv_string = *argv;
1762           argc--; argv++;
1763         }
1764       else if (!strcmp (*argv, "--dt"))
1765         {
1766           argc--; argv++;
1767           if (!argc)
1768             usage (0);
1769           dt_string = *argv;
1770           argc--; argv++;
1771         }
1772       else if (!strcmp (*argv, "--algo"))
1773         {
1774           argc--; argv++;
1775           if (!argc)
1776             usage (0);
1777           algo_string = *argv;
1778           argc--; argv++;
1779         }
1780       else if (!strcmp (*argv, "--keysize"))
1781         {
1782           argc--; argv++;
1783           if (!argc)
1784             usage (0);
1785           keysize_string = *argv;
1786           argc--; argv++;
1787         }
1788       else if (!strcmp (*argv, "--signature"))
1789         {
1790           argc--; argv++;
1791           if (!argc)
1792             usage (0);
1793           signature_string = *argv;
1794           argc--; argv++;
1795         }
1796       else if (!strcmp (*argv, "--chunk"))
1797         {
1798           argc--; argv++;
1799           if (!argc)
1800             usage (0);
1801           chunksize = atoi (*argv);
1802           binary_input = binary_output = 1;
1803           argc--; argv++;
1804         }
1805       else if (!strcmp (*argv, "--pkcs1"))
1806         {
1807           use_pkcs1 = 1;
1808           argc--; argv++;
1809         }
1810       else if (!strcmp (*argv, "--mct-server"))
1811         {
1812           mct_server = 1;
1813           argc--; argv++;
1814         }
1815     }          
1816
1817   if (!argc || argc > 2)
1818     usage (0);
1819   mode_string = *argv;
1820   if (argc == 2 && strcmp (argv[1], "-"))
1821     {
1822       input = fopen (argv[1], binary_input? "rb":"r");
1823       if (!input)
1824         die ("can't open `%s': %s\n", argv[1], strerror (errno));
1825     }
1826   else
1827     input = stdin;
1828
1829 #ifndef HAVE_W32_SYSTEM
1830   if (loop_mode)
1831     signal (SIGPIPE, SIG_IGN);
1832 #endif
1833
1834   if (verbose)
1835     fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
1836
1837   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
1838   if (!no_fips)
1839     gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
1840   if (!gcry_check_version ("1.4.3"))
1841     die ("Libgcrypt is not sufficient enough\n");
1842   if (verbose)
1843     fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
1844   if (no_fips)
1845     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1846   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1847
1848   /* Most operations need some input data.  */
1849   if (!chunksize
1850       && !mct_server
1851       && strcmp (mode_string, "random")
1852       && strcmp (mode_string, "rsa-gen")
1853       && strcmp (mode_string, "dsa-pqg-gen") )
1854     {
1855       data = read_file (input, !binary_input, &datalen);
1856       if (!data)
1857         die ("error reading%s input\n", binary_input?"":" and decoding");
1858       if (verbose)
1859         fprintf (stderr, PGM ": %u bytes of input data\n", 
1860                  (unsigned int)datalen);
1861     }
1862   else
1863     {
1864       data = NULL;
1865       datalen = 0;
1866     }
1867
1868
1869   if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
1870     {
1871       int cipher_algo, cipher_mode;
1872       void  *iv_buffer = NULL;
1873       void *key_buffer = NULL;
1874       size_t iv_buflen,  key_buflen;
1875
1876       if (!algo_string)
1877         die ("option --algo is required in this mode\n");
1878       cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
1879       if (!cipher_algo)
1880         die ("cipher algorithm `%s' is not supported\n", algo_string);
1881       if (mct_server)
1882         {
1883           int iterations;
1884
1885           for (;;)
1886             {
1887               gcry_free (key_buffer); key_buffer = NULL;
1888               gcry_free (iv_buffer); iv_buffer = NULL;
1889               gcry_free (data); data = NULL;
1890               if (!(key_buffer = read_textline (input)))
1891                 {
1892                   if (feof (input))
1893                     break;
1894                   die ("no version info in input\n");
1895                 }
1896               if (atoi (key_buffer) != 1)
1897                 die ("unsupported input version %s\n", key_buffer);
1898               gcry_free (key_buffer);
1899               if (!(key_buffer = read_textline (input)))
1900                 die ("no iteration count in input\n");
1901               iterations = atoi (key_buffer);
1902               gcry_free (key_buffer);
1903               if (!(key_buffer = read_hexline (input, &key_buflen)))
1904                 die ("no key in input\n");
1905               if (!(iv_buffer = read_hexline (input, &iv_buflen)))
1906                 die ("no IV in input\n");
1907               if (!(data = read_hexline (input, &datalen)))
1908                 die ("no data in input\n");
1909               skip_to_empty_line (input);
1910               
1911               run_cipher_mct_loop ((*mode_string == 'e'),
1912                                    cipher_algo, cipher_mode,
1913                                    iv_buffer, iv_buflen,
1914                                    key_buffer, key_buflen,
1915                                    data, datalen, iterations);
1916             }
1917         }
1918       else
1919         {
1920           if (cipher_mode != GCRY_CIPHER_MODE_ECB)
1921             {
1922               if (!iv_string)
1923                 die ("option --iv is required in this mode\n");
1924               iv_buffer = hex2buffer (iv_string, &iv_buflen);
1925               if (!iv_buffer)
1926                 die ("invalid value for IV\n");
1927             }
1928           else
1929             {
1930               iv_buffer = NULL;
1931               iv_buflen = 0;
1932             }
1933           if (!key_string)
1934             die ("option --key is required in this mode\n");
1935           key_buffer = hex2buffer (key_string, &key_buflen);
1936           if (!key_buffer)
1937             die ("invalid value for KEY\n");
1938
1939           run_encrypt_decrypt ((*mode_string == 'e'),
1940                                cipher_algo, cipher_mode,
1941                                iv_buffer, iv_buflen,
1942                                key_buffer, key_buflen,
1943                                data, data? datalen:chunksize, input);
1944         }
1945       gcry_free (key_buffer);
1946       gcry_free (iv_buffer);
1947     }
1948   else if (!strcmp (mode_string, "digest"))
1949     {
1950       int algo;
1951
1952       if (!algo_string)
1953         die ("option --algo is required in this mode\n");
1954       algo = gcry_md_map_name (algo_string);
1955       if (!algo)
1956         die ("digest algorithm `%s' is not supported\n", algo_string);
1957       if (!data)
1958         die ("no data available (do not use --chunk)\n");
1959
1960       run_digest (algo, data, datalen);
1961     }
1962   else if (!strcmp (mode_string, "random"))
1963     {
1964       void *context;
1965       unsigned char key[16];
1966       unsigned char seed[16];
1967       unsigned char dt[16];
1968       unsigned char buffer[16];
1969       size_t count = 0;
1970
1971       if (hex2bin (key_string, key, 16) < 0 )
1972         die ("value for --key are not 32 hex digits\n");
1973       if (hex2bin (iv_string, seed, 16) < 0 )
1974         die ("value for --iv are not 32 hex digits\n");
1975       if (hex2bin (dt_string, dt, 16) < 0 )
1976         die ("value for --dt are not 32 hex digits\n");
1977
1978       /* The flag value 1 disables the dup check, so that the RNG
1979          returns all generated data.  */
1980       err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
1981       if (err)
1982         die ("init external RNG test failed: %s\n", gpg_strerror (err));
1983
1984       do 
1985         {
1986           err = run_external_rng_test (context, buffer, sizeof buffer);
1987           if (err)
1988             die ("running external RNG test failed: %s\n", gpg_strerror (err));
1989           print_buffer (buffer, sizeof buffer);
1990           if (progress)
1991             {
1992               if (!(++count % 1000))
1993                 fprintf (stderr, PGM ": %lu random bytes so far\n", 
1994                          (unsigned long int)count * sizeof buffer);
1995             }
1996         }
1997       while (loop_mode);
1998       
1999       if (progress)
2000         fprintf (stderr, PGM ": %lu random bytes\n",
2001                          (unsigned long int)count * sizeof buffer);
2002
2003       deinit_external_rng_test (context);
2004     }
2005   else if (!strcmp (mode_string, "hmac-sha"))
2006     {
2007       int algo;
2008       void  *key_buffer;
2009       size_t key_buflen;
2010
2011       if (!data)
2012         die ("no data available (do not use --chunk)\n");
2013       if (!algo_string)
2014         die ("option --algo is required in this mode\n");
2015       switch (atoi (algo_string))
2016         {
2017         case 1:   algo = GCRY_MD_SHA1; break;
2018         case 224: algo = GCRY_MD_SHA224; break;
2019         case 256: algo = GCRY_MD_SHA256; break;
2020         case 384: algo = GCRY_MD_SHA384; break;
2021         case 512: algo = GCRY_MD_SHA512; break;
2022         default:  algo = 0; break;
2023         }
2024       if (!algo)
2025         die ("no digest algorithm found for hmac type `%s'\n", algo_string);
2026       if (!key_string)
2027         die ("option --key is required in this mode\n");
2028       key_buffer = hex2buffer (key_string, &key_buflen);
2029       if (!key_buffer)
2030         die ("invalid value for KEY\n");
2031
2032       run_hmac (algo, key_buffer, key_buflen, data, datalen);
2033
2034       gcry_free (key_buffer);
2035     }
2036   else if (!strcmp (mode_string, "rsa-gen"))
2037     {
2038       int keysize;
2039       
2040       if (!binary_output)
2041         base64_output = 1;
2042
2043       keysize = keysize_string? atoi (keysize_string) : 0;
2044       if (keysize < 128 || keysize > 16384)
2045         die ("invalid keysize specified; needs to be 128 .. 16384\n");
2046       run_rsa_gen (keysize, 65537);
2047     }
2048   else if (!strcmp (mode_string, "rsa-sign"))
2049     {
2050       int algo;
2051
2052       if (!key_string)
2053         die ("option --key is required in this mode\n");
2054       if (access (key_string, R_OK))
2055         die ("option --key needs to specify an existing keyfile\n");
2056       if (!algo_string)
2057         die ("option --algo is required in this mode\n");
2058       algo = gcry_md_map_name (algo_string);
2059       if (!algo)
2060         die ("digest algorithm `%s' is not supported\n", algo_string);
2061       if (!data)
2062         die ("no data available (do not use --chunk)\n");
2063
2064       run_rsa_sign (data, datalen, algo, use_pkcs1, key_string);
2065
2066     }
2067   else if (!strcmp (mode_string, "rsa-verify"))
2068     {
2069       int algo;
2070
2071       if (!key_string)
2072         die ("option --key is required in this mode\n");
2073       if (access (key_string, R_OK))
2074         die ("option --key needs to specify an existing keyfile\n");
2075       if (!algo_string)
2076         die ("option --algo is required in this mode\n");
2077       algo = gcry_md_map_name (algo_string);
2078       if (!algo)
2079         die ("digest algorithm `%s' is not supported\n", algo_string);
2080       if (!data)
2081         die ("no data available (do not use --chunk)\n");
2082       if (!signature_string)
2083         die ("option --signature is required in this mode\n");
2084       if (access (signature_string, R_OK))
2085         die ("option --signature needs to specify an existing file\n");
2086
2087       run_rsa_verify (data, datalen, algo, use_pkcs1, key_string,
2088                       signature_string);
2089
2090     }
2091   else if (!strcmp (mode_string, "dsa-pqg-gen"))
2092     {
2093       int keysize;
2094       
2095       keysize = keysize_string? atoi (keysize_string) : 0;
2096       if (keysize < 1024 || keysize > 3072)
2097         die ("invalid keysize specified; needs to be 1024 .. 3072\n");
2098       run_dsa_pqg_gen (keysize);
2099     }
2100   else
2101     usage (0);
2102
2103   gcry_free (data);
2104
2105   /* Because Libgcrypt does not enforce FIPS mode in all cases we let
2106      the process die if Libgcrypt is not anymore in FIPS mode after
2107      the actual operation.  */
2108   if (!no_fips && !gcry_fips_mode_active ())
2109     die ("FIPS mode is not anymore active\n");
2110
2111   if (verbose)
2112     fputs (PGM ": ready\n", stderr);
2113
2114   return 0;
2115 }
2116