Add CAVS test.
[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 #include <gcrypt.h>
36
37 #define PGM "fipsdrv"
38
39 #define my_isascii(c) (!((c) & 0x80))
40 #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
41 #define hexdigitp(a) (digitp (a)                     \
42                       || (*(a) >= 'A' && *(a) <= 'F')  \
43                       || (*(a) >= 'a' && *(a) <= 'f'))
44 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
45                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
46 #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
47 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
48 #define DIMof(type,member)   DIM(((type *)0)->member)
49
50
51 /* Verbose mode flag.  */
52 static int verbose;
53
54 /* Binary input flag.  */
55 static int binary_input;
56
57 /* Binary output flag.  */
58 static int binary_output;
59
60 /* Base64 output flag.  */
61 static int base64_output;
62
63 /* We need to know whetehr we are in loop_mode.  */
64 static int loop_mode;
65
66 /* ASN.1 classes.  */
67 enum
68 {
69   UNIVERSAL = 0,
70   APPLICATION = 1,
71   ASNCONTEXT = 2,
72   PRIVATE = 3
73 };
74
75
76 /* ASN.1 tags.  */
77 enum
78 {
79   TAG_NONE = 0,
80   TAG_BOOLEAN = 1,
81   TAG_INTEGER = 2,
82   TAG_BIT_STRING = 3,
83   TAG_OCTET_STRING = 4,
84   TAG_NULL = 5,
85   TAG_OBJECT_ID = 6,
86   TAG_OBJECT_DESCRIPTOR = 7,
87   TAG_EXTERNAL = 8,
88   TAG_REAL = 9,
89   TAG_ENUMERATED = 10,
90   TAG_EMBEDDED_PDV = 11,
91   TAG_UTF8_STRING = 12,
92   TAG_REALTIVE_OID = 13,
93   TAG_SEQUENCE = 16,
94   TAG_SET = 17,
95   TAG_NUMERIC_STRING = 18,
96   TAG_PRINTABLE_STRING = 19,
97   TAG_TELETEX_STRING = 20,
98   TAG_VIDEOTEX_STRING = 21,
99   TAG_IA5_STRING = 22,
100   TAG_UTC_TIME = 23,
101   TAG_GENERALIZED_TIME = 24,
102   TAG_GRAPHIC_STRING = 25,
103   TAG_VISIBLE_STRING = 26,
104   TAG_GENERAL_STRING = 27,
105   TAG_UNIVERSAL_STRING = 28,
106   TAG_CHARACTER_STRING = 29,
107   TAG_BMP_STRING = 30
108 };
109
110 /* ASN.1 Parser object.  */
111 struct tag_info 
112 {
113   int class;             /* Object class.  */
114   unsigned long tag;     /* The tag of the object.  */
115   unsigned long length;  /* Length of the values.  */
116   int nhdr;              /* Length of the header (TL).  */
117   unsigned int ndef:1;   /* The object has an indefinite length.  */
118   unsigned int cons:1;   /* This is a constructed object.  */ 
119 };
120
121
122
123 /* Print a error message and exit the process with an error code.  */
124 static void
125 die (const char *format, ...)
126 {
127   va_list arg_ptr;
128
129   va_start (arg_ptr, format);
130   fputs (PGM ": ", stderr);
131   vfprintf (stderr, format, arg_ptr);
132   va_end (arg_ptr);
133   exit (1);
134 }
135
136
137 static void
138 showhex (const char *prefix, const void *buffer, size_t length)
139 {
140   const unsigned char *p = buffer;
141
142   if (prefix)
143     fprintf (stderr, PGM ": %s: ", prefix);
144   while (length-- )
145     fprintf (stderr, "%02X", *p++);
146   if (prefix)
147     putc ('\n', stderr);
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 /* Read a file from stream FP into a newly allocated buffer and return
205    that buffer.  The valid length of the buffer is stored at R_LENGTH.
206    Returns NULL on failure.  If decode is set, the file is assumed to
207    be hex encoded and the decoded content is returned. */
208 static void *
209 read_file (FILE *fp, int decode, size_t *r_length)
210 {
211   char *buffer;
212   size_t buflen;
213   size_t nread, bufsize = 0;
214
215   *r_length = 0;
216 #define NCHUNK 8192
217 #ifdef HAVE_DOSISH_SYSTEM
218   setmode (fileno(fp), O_BINARY);
219 #endif
220   buffer = NULL;
221   buflen = 0;
222   do 
223     {
224       bufsize += NCHUNK;
225       if (!buffer)
226         buffer = gcry_xmalloc (bufsize);
227       else
228         buffer = gcry_xrealloc (buffer, bufsize);
229       
230       nread = fread (buffer + buflen, 1, NCHUNK, fp);
231       if (nread < NCHUNK && ferror (fp))
232         {
233           gcry_free (buffer);
234           return NULL;
235         }
236       buflen += nread;
237     }
238   while (nread == NCHUNK);
239 #undef NCHUNK
240   if (decode)
241     {
242       const char *s;
243       char *p;
244
245       for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 )
246         {
247           if (!hexdigitp (s) || !hexdigitp (s+1))
248             {
249               gcry_free (buffer);
250               return NULL;  /* Invalid hex digits. */
251             }
252           *(unsigned char*)p++ = xtoi_2 (s);
253         }
254       if (nread != buflen)
255         {
256           gcry_free (buffer);
257           return NULL;  /* Odd number of hex digits. */
258         }
259       buflen = p - buffer;
260     }
261
262   *r_length = buflen;
263   return buffer;
264 }
265
266 /* Do in-place decoding of base-64 data of LENGTH in BUFFER.  Returns
267    the new length of the buffer.  Dies on error.  */
268 static size_t
269 base64_decode (char *buffer, size_t length)
270 {
271   static unsigned char const asctobin[128] = 
272     {
273       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
274       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
275       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
276       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
277       0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
278       0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
279       0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
280       0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
281       0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
282       0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
283       0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff 
284     };
285
286   int idx = 0;
287   unsigned char val = 0;
288   int c = 0;
289   char *d, *s;
290   int lfseen = 1;
291
292   /* Find BEGIN line.  */
293   for (s=buffer; length; length--, s++)
294     {
295       if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11))
296         {
297           for (; length && *s != '\n'; length--, s++)
298             ;
299           break;
300         } 
301       lfseen = (*s == '\n');
302     }
303
304   /* Decode until pad character or END line.  */
305   for (d=buffer; length; length--, s++)
306     {
307       if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9))
308         break;
309       if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t')
310         continue;
311       if (*s == '=')
312         {
313           /* Pad character: stop */
314           if (idx == 1)
315             *d++ = val;
316           break;
317         }
318
319       if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff)
320         die ("invalid base64 character %02X at pos %d detected\n",
321              *(unsigned char*)s, (int)(s-buffer));
322
323       switch (idx)
324         {
325         case 0:
326           val = c << 2;
327           break;
328         case 1:
329           val |= (c>>4)&3;
330           *d++ = val;
331           val = (c<<4)&0xf0;
332           break;
333         case 2:
334           val |= (c>>2)&15;
335           *d++ = val;
336           val = (c<<6)&0xc0;
337           break;
338         case 3:
339           val |= c&0x3f;
340           *d++ = val;
341           break;
342         }
343       idx = (idx+1) % 4;
344     }
345
346   return d - buffer;
347 }
348
349
350 /* Parse the buffer at the address BUFFER which consists of the number
351    of octets as stored at BUFLEN.  Return the tag and the length part
352    from the TLV triplet.  Update BUFFER and BUFLEN on success.  Checks
353    that the encoded length does not exhaust the length of the provided
354    buffer. */
355 static int 
356 parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti)
357 {
358   int c;
359   unsigned long tag;
360   const unsigned char *buf = *buffer;
361   size_t length = *buflen;
362
363   ti->length = 0;
364   ti->ndef = 0;
365   ti->nhdr = 0;
366
367   /* Get the tag */
368   if (!length)
369     return -1; /* Premature EOF.  */
370   c = *buf++; length--;
371   ti->nhdr++;
372
373   ti->class = (c & 0xc0) >> 6;
374   ti->cons  = !!(c & 0x20);
375   tag       = (c & 0x1f);
376
377   if (tag == 0x1f)
378     {
379       tag = 0;
380       do
381         {
382           tag <<= 7;
383           if (!length)
384             return -1; /* Premature EOF.  */
385           c = *buf++; length--;
386           ti->nhdr++;
387           tag |= (c & 0x7f);
388         }
389       while ( (c & 0x80) );
390     }
391   ti->tag = tag;
392
393   /* Get the length */
394   if (!length)
395     return -1; /* Premature EOF. */
396   c = *buf++; length--;
397   ti->nhdr++;
398
399   if ( !(c & 0x80) )
400     ti->length = c;
401   else if (c == 0x80)
402     ti->ndef = 1;
403   else if (c == 0xff)
404     return -1; /* Forbidden length value.  */
405   else
406     {
407       unsigned long len = 0;
408       int count = c & 0x7f;
409
410       for (; count; count--)
411         {
412           len <<= 8;
413           if (!length)
414             return -1; /* Premature EOF.  */
415           c = *buf++; length--;
416           ti->nhdr++;
417           len |= (c & 0xff);
418         }
419       ti->length = len;
420     }
421   
422   if (ti->class == UNIVERSAL && !ti->tag)
423     ti->length = 0;
424
425   if (ti->length > length)
426     return -1; /* Data larger than buffer.  */
427   
428   *buffer = buf;
429   *buflen = length;
430   return 0;
431 }
432
433
434 /* Read the file FNAME assuming it is a PEM encoded private key file
435    and return an S-expression.  With SHOW set, the key parameters are
436    printed.  */
437 static gcry_sexp_t
438 read_key_file (const char *fname, int show)
439 {
440   gcry_error_t err;
441   FILE *fp;
442   char *buffer;
443   size_t buflen;
444   const unsigned char *der;
445   size_t derlen;
446   struct tag_info ti;
447   gcry_mpi_t keyparms[8];
448   int idx;
449   gcry_sexp_t s_key;
450
451   fp = fopen (fname, binary_input?"rb":"r");
452   if (!fp)
453     die ("can't open `%s': %s\n", fname, strerror (errno));
454   buffer = read_file (fp, 0, &buflen);
455   if (!buffer)
456     die ("error reading `%s'\n", fname);
457   fclose (fp);
458
459   buflen = base64_decode (buffer, buflen);
460   
461   /* Parse the ASN.1 structure.  */
462   der = (const unsigned char*)buffer;
463   derlen = buflen;
464   if ( parse_tag (&der, &derlen, &ti)
465        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
466     goto bad_asn1;
467   if ( parse_tag (&der, &derlen, &ti)
468        || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
469     goto bad_asn1;
470   if (ti.length != 1 || *der)
471     goto bad_asn1;  /* The value of the first integer is no 0. */
472   der += ti.length; derlen += ti.length;
473
474   for (idx=0; idx < DIM(keyparms); idx++)
475     {
476       if ( parse_tag (&der, &derlen, &ti)
477            || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
478         goto bad_asn1;
479       if (show)
480         {
481           char prefix[2];
482
483           prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
484           prefix[1] = 0;
485           showhex (prefix, der, ti.length);
486         }
487       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
488       if (err)
489         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
490       der += ti.length; derlen += ti.length;
491     }
492   if (idx != DIM(keyparms))
493     die ("not enough RSA key parameters\n");
494
495   gcry_free (buffer);
496
497   /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
498   /* First check that p < q; if not swap p and q and recompute u.  */ 
499   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
500     {
501       gcry_mpi_swap (keyparms[3], keyparms[4]);
502       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
503     }
504
505   /* Build the S-expression.  */
506   err = gcry_sexp_build (&s_key, NULL,
507                         "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
508                          keyparms[0], keyparms[1], keyparms[2],
509                          keyparms[3], keyparms[4], keyparms[7] );
510   if (err)
511     die ("error building S-expression: %s\n", gpg_strerror (err));
512
513   for (idx=0; idx < DIM(keyparms); idx++)
514     gcry_mpi_release (keyparms[idx]);
515
516   return s_key;
517
518  bad_asn1:
519   die ("invalid ASN.1 structure in `%s'\n", fname);
520   return NULL; /*NOTREACHED*/
521 }
522
523
524 static void
525 print_buffer (const void *buffer, size_t length)
526 {
527   int writerr = 0;
528
529   if (base64_output)
530     {
531       static const unsigned char bintoasc[64+1] = 
532         ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
533          "abcdefghijklmnopqrstuvwxyz" 
534          "0123456789+/"); 
535       const unsigned char *p;
536       unsigned char inbuf[4];
537       char outbuf[4];
538       int idx, quads;
539
540       idx = quads = 0;
541       for (p = buffer; length; p++, length--)
542         {
543           inbuf[idx++] = *p;
544           if (idx > 2)
545             {
546               outbuf[0] = bintoasc[(*inbuf>>2)&077];
547               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
548                                     |((inbuf[1] >> 4)&017))&077];
549               outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
550                                     |((inbuf[2]>>6)&03))&077];
551               outbuf[3] = bintoasc[inbuf[2]&077];
552               if (fwrite (outbuf, 4, 1, stdout) != 1)
553                 writerr = 1;
554               idx = 0;
555               if (++quads >= (64/4)) 
556                 {
557                   if (fwrite ("\n", 1, 1, stdout) != 1)
558                     writerr = 1;
559                   quads = 0;
560                 }
561             }
562         }
563       if (idx)
564         {
565           outbuf[0] = bintoasc[(*inbuf>>2)&077];
566           if (idx == 1)
567             {
568               outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
569               outbuf[2] = outbuf[3] = '=';
570             }
571           else 
572             { 
573               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
574                                     |((inbuf[1]>>4)&017))&077];
575               outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
576               outbuf[3] = '=';
577             }
578           if (fwrite (outbuf, 4, 1, stdout) != 1)
579             writerr = 1;
580           quads++;
581         }
582       if (quads && fwrite ("\n", 1, 1, stdout) != 1)
583         writerr = 1;
584     }
585   else if (binary_output)
586     {
587       if (fwrite (buffer, length, 1, stdout) != 1)
588         writerr++;
589     }
590   else
591     {
592       const unsigned char *p = buffer;
593       
594       while (length-- && !ferror (stdout) )
595         printf ("%02X", *p++);
596       if (ferror (stdout))
597         writerr++;
598     }
599   if (!writerr && fflush (stdout) == EOF)
600     writerr++;
601   if (writerr)
602     {
603 #ifndef HAVE_W32_SYSTEM
604       if (loop_mode && errno == EPIPE)
605         loop_mode = 0;
606       else
607 #endif
608         die ("writing output failed: %s\n", strerror (errno));
609     }
610 }
611
612
613
614 static gcry_error_t
615 init_external_rng_test (void **r_context, 
616                     unsigned int flags,
617                     const void *key, size_t keylen,
618                     const void *seed, size_t seedlen,
619                     const void *dt, size_t dtlen)
620 {
621   return gcry_control (58, 
622                        r_context, flags,
623                        key, keylen,
624                        seed, seedlen,
625                        dt, dtlen);
626 }
627
628 static gcry_error_t
629 run_external_rng_test (void *context, void *buffer, size_t buflen)
630 {
631   return gcry_control (59, context, buffer, buflen);
632 }
633
634 static void
635 deinit_external_rng_test (void *context)
636 {
637   gcry_control (60, context);
638 }
639
640
641 /* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm
642    identified and store the libgcrypt mode at R_MODE.  Returns 0 on
643    error.  */
644 static int 
645 map_openssl_cipher_name (const char *name, int *r_mode)
646 {
647   static struct {
648     const char *name;
649     int algo;
650     int mode;
651   } table[] = 
652     {
653       { "bf-cbc",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
654       { "bf",           GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
655       { "bf-cfb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
656       { "bf-ecb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
657       { "bf-ofb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
658
659       { "cast-cbc",     GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
660       { "cast",         GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
661       { "cast5-cbc",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
662       { "cast5-cfb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
663       { "cast5-ecb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
664       { "cast5-ofb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
665
666       { "des-cbc",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
667       { "des",          GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
668       { "des-cfb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
669       { "des-ofb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
670       { "des-ecb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
671
672       { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
673       { "des-ede3    ", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
674       { "des3        ", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
675       { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
676       { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
677
678       { "rc4",          GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
679
680       { "aes-128-cbc",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
681       { "aes-128",      GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
682       { "aes-128-cfb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
683       { "aes-128-ecb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
684       { "aes-128-ofb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
685
686       { "aes-192-cbc",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
687       { "aes-192",      GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
688       { "aes-192-cfb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
689       { "aes-192-ecb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
690       { "aes-192-ofb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
691       
692       { "aes-256-cbc",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
693       { "aes-256",      GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
694       { "aes-256-cfb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
695       { "aes-256-ecb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
696       { "aes-256-ofb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
697
698       { NULL, 0 , 0 }
699     };
700   int idx;
701
702   for (idx=0; table[idx].name; idx++)
703     if (!strcmp (name, table[idx].name))
704       {
705         *r_mode = table[idx].mode;
706         return table[idx].algo;
707       }
708   *r_mode = 0;
709   return 0;
710 }
711
712
713 \f
714 /* Run an encrypt or decryption operations.  If DATA is NULL the
715    function reads its input in chunks of size DATALEN from fp and
716    processes it and writes it out until EOF.  */
717 static void
718 run_encrypt_decrypt (int encrypt_mode,
719                      int cipher_algo, int cipher_mode, 
720                      const void *iv_buffer, size_t iv_buflen,
721                      const void *key_buffer, size_t key_buflen,
722                      const void *data, size_t datalen, FILE *fp)
723 {
724   gpg_error_t err;
725   gcry_cipher_hd_t hd;
726   void *outbuf;
727   size_t outbuflen;
728   void *inbuf;
729   size_t inbuflen;
730
731   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
732   if (err)
733     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", 
734          cipher_algo, cipher_mode, gpg_strerror (err));
735
736   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
737   if (err)
738     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
739          (unsigned int)key_buflen, gpg_strerror (err));
740
741   err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
742   if (err)
743     die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
744          (unsigned int)iv_buflen, gpg_strerror (err));
745
746   inbuf = data? NULL : gcry_xmalloc (datalen);
747   outbuflen = datalen;
748   outbuf = gcry_xmalloc (outbuflen);
749
750   do
751     {
752       if (inbuf)
753         {
754           int nread = fread (inbuf, 1, datalen, fp);
755           if (nread < (int)datalen && ferror (fp))
756             die ("error reading input\n");
757           data = inbuf;
758           inbuflen = nread;
759         }
760       else
761         inbuflen = datalen;
762
763       if (encrypt_mode)
764         err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
765       else
766         err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
767       if (err)
768         die ("gcry_cipher_%scrypt failed: %s\n",
769              encrypt_mode? "en":"de", gpg_strerror (err));
770       print_buffer (outbuf, outbuflen);
771     }
772   while (inbuf);
773
774   gcry_cipher_close (hd);
775   gcry_free (outbuf);
776   gcry_free (inbuf);
777 }
778
779
780 \f
781 /* Run a digest operation.  */
782 static void
783 run_digest (int digest_algo,  const void *data, size_t datalen)
784 {
785   gpg_error_t err;
786   gcry_md_hd_t hd;
787   const unsigned char *digest;
788   unsigned int digestlen;
789
790   err = gcry_md_open (&hd, digest_algo, 0);
791   if (err)
792     die ("gcry_md_open failed for algo %d: %s\n", 
793          digest_algo,  gpg_strerror (err));
794
795   gcry_md_write (hd, data, datalen);
796   digest = gcry_md_read (hd, digest_algo);
797   digestlen = gcry_md_get_algo_dlen (digest_algo);
798   print_buffer (digest, digestlen);
799   gcry_md_close (hd);
800 }
801
802 \f
803 /* Run a HMAC operation.  */
804 static void
805 run_hmac (int digest_algo, const void *key, size_t keylen, 
806           const void *data, size_t datalen)
807 {
808   gpg_error_t err;
809   gcry_md_hd_t hd;
810   const unsigned char *digest;
811   unsigned int digestlen;
812
813   err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
814   if (err)
815     die ("gcry_md_open failed for HMAC algo %d: %s\n", 
816          digest_algo,  gpg_strerror (err));
817
818   gcry_md_setkey (hd, key, keylen);
819   if (err)
820     die ("gcry_md_setkey failed for HMAC algo %d: %s\n", 
821          digest_algo,  gpg_strerror (err));
822
823   gcry_md_write (hd, data, datalen);
824   digest = gcry_md_read (hd, digest_algo);
825   digestlen = gcry_md_get_algo_dlen (digest_algo);
826   print_buffer (digest, digestlen);
827   gcry_md_close (hd);
828 }
829
830 \f
831 static size_t
832 compute_tag_length (size_t n)
833 {     
834   int needed = 0;
835
836   if (n < 128)
837     needed += 2; /* Tag and one length byte.  */
838   else if (n < 256)
839     needed += 3; /* Tag, number of length bytes, 1 length byte.  */
840   else if (n < 65536)
841     needed += 4; /* Tag, number of length bytes, 2 length bytes.  */
842   else
843     die ("DER object too long to encode\n");
844
845   return needed;
846 }
847
848 static unsigned char *
849 store_tag_length (unsigned char *p, int tag, size_t n)
850 {     
851   if (tag == TAG_SEQUENCE)
852     tag |= 0x20; /* constructed */
853
854   *p++ = tag;
855   if (n < 128)
856     *p++ = n;
857   else if (n < 256)
858     {
859       *p++ = 0x81;
860       *p++ = n;
861     }
862   else if (n < 65536)
863     {
864       *p++ = 0x82;
865       *p++ = n >> 8;
866       *p++ = n;
867     }
868
869   return p;
870 }
871
872
873 /* Generate an RSA key of size KEYSIZE using the public exponent
874    PUBEXP and print it to stdout in the OpenSSL format.  The format
875    is:
876
877        SEQUENCE {
878          INTEGER (0)  -- Unknown constant. 
879          INTEGER      -- n
880          INTEGER      -- e
881          INTEGER      -- d
882          INTEGER      -- p     
883          INTEGER      -- q      (with p < q)
884          INTEGER      -- dmp1 = d mod (p-1)
885          INTEGER      -- dmq1 = d mod (q-1)
886          INTEGER      -- u    = p^{-1} mod q
887        }
888
889 */
890 static void
891 run_rsa_gen (int keysize, int pubexp)
892 {
893   gpg_error_t err;
894   gcry_sexp_t keyspec, key, l1;
895   const char keyelems[] = "nedpq..u";
896   gcry_mpi_t keyparms[8];
897   size_t     keyparmslen[8];
898   int idx;
899   size_t derlen, needed, n;
900   unsigned char *derbuf, *der;
901
902   err = gcry_sexp_build (&keyspec, NULL, 
903                          "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
904                          keysize, pubexp);
905   if (err)
906     die ("gcry_sexp_build failed for RSA key generation: %s\n",
907          gpg_strerror (err));
908
909   err = gcry_pk_genkey (&key, keyspec);
910   if (err)
911     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
912   
913   gcry_sexp_release (keyspec);
914
915   l1 = gcry_sexp_find_token (key, "private-key", 0);
916   if (!l1)
917     die ("private key not found in genkey result\n");
918   gcry_sexp_release (key);
919   key = l1;
920
921   l1 = gcry_sexp_find_token (key, "rsa", 0);
922   if (!l1)
923     die ("returned private key not formed as expected\n");
924   gcry_sexp_release (key);
925   key = l1;
926
927   /* Extract the parameters from the S-expression and store them in a
928      well defined order in KEYPARMS.  */
929   for (idx=0; idx < DIM(keyparms); idx++) 
930     {
931       if (keyelems[idx] == '.')
932         {
933           keyparms[idx] = gcry_mpi_new (0);
934           continue;
935         }
936       l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
937       if (!l1)
938         die ("no %c parameter in returned private key\n", keyelems[idx]);
939       keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
940       if (!keyparms[idx])
941         die ("no value for %c parameter in returned private key\n",
942              keyelems[idx]);
943       gcry_sexp_release (l1);
944     }
945
946   gcry_sexp_release (key);
947
948   /* Check that p < q; if not swap p and q and recompute u.  */ 
949   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
950     {
951       gcry_mpi_swap (keyparms[3], keyparms[4]);
952       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
953     }
954
955   /* Compute the additional parameters.  */
956   gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
957   gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
958   gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
959   gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
960
961   /* Compute the length of the DER encoding.  */
962   needed = compute_tag_length (1) + 1;  
963   for (idx=0; idx < DIM(keyparms); idx++) 
964     {
965       err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
966       if (err)
967         die ("error formatting parameter: %s\n", gpg_strerror (err));
968       keyparmslen[idx] = n;
969       needed += compute_tag_length (n) + n;
970     }
971   
972   /* Store the key parameters. */
973   derlen = compute_tag_length (needed) + needed;
974   der = derbuf = gcry_xmalloc (derlen);
975
976   der = store_tag_length (der, TAG_SEQUENCE, needed);
977   der = store_tag_length (der, TAG_INTEGER, 1);
978   *der++ = 0;
979   for (idx=0; idx < DIM(keyparms); idx++) 
980     {
981       der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
982       err = gcry_mpi_print (GCRYMPI_FMT_STD, der, 
983                            keyparmslen[idx], NULL, keyparms[idx]);
984       if (err)
985         die ("error formatting parameter: %s\n", gpg_strerror (err));
986       der += keyparmslen[idx];
987     }
988
989   /* Print the stuff.  */
990   for (idx=0; idx < DIM(keyparms); idx++) 
991     gcry_mpi_release (keyparms[idx]);
992
993   assert (der - derbuf == derlen);
994
995   if (base64_output)
996     puts ("-----BEGIN RSA PRIVATE KEY-----");
997   print_buffer (derbuf, derlen);
998   if (base64_output)
999     puts ("-----END RSA PRIVATE KEY-----");
1000
1001   gcry_free (derbuf);
1002 }
1003
1004
1005 \f
1006 /* Sign DATA of length DATALEN using the key taken from the PEM
1007    encoded KEYFILE and the hash algorithm HASHALGO.  */
1008 static void
1009 run_rsa_sign (const void *data, size_t datalen,
1010               int hashalgo, int pkcs1, const char *keyfile)
1011
1012 {
1013   gpg_error_t err;
1014   gcry_sexp_t s_data, s_key, s_sig, s_tmp;
1015   gcry_mpi_t sig_mpi = NULL;
1016   unsigned char *outbuf;
1017   size_t outlen;
1018   
1019 /*   showhex ("D", data, datalen); */
1020
1021   if (pkcs1)
1022     err = gcry_sexp_build (&s_data, NULL,
1023                            "(data (flags pkcs1)(hash %s %b))",
1024                            gcry_md_algo_name (hashalgo), (int)datalen, data);
1025   else
1026     {
1027       gcry_mpi_t tmp;
1028
1029       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1030       if (!err)
1031         {
1032           err = gcry_sexp_build (&s_data, NULL,
1033                                  "(data (flags raw)(value %m))", tmp);
1034           gcry_mpi_release (tmp);
1035         }
1036     }
1037   if (err)
1038     die ("gcry_sexp_build failed for RSA data input: %s\n",
1039          gpg_strerror (err));
1040
1041   s_key = read_key_file (keyfile, 0);
1042
1043   err = gcry_pk_sign (&s_sig, s_data, s_key);
1044   if (err)
1045     {
1046       gcry_sexp_release (read_key_file (keyfile, 1));
1047       die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
1048            (int)datalen, keyfile, gpg_strerror (err));
1049     }
1050   gcry_sexp_release (s_key);
1051   gcry_sexp_release (s_data);
1052
1053   s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
1054   if (s_tmp)
1055     {
1056       gcry_sexp_release (s_sig);
1057       s_sig = s_tmp;
1058       s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
1059       if (s_tmp)
1060         {
1061           gcry_sexp_release (s_sig);
1062           s_sig = s_tmp;
1063           s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
1064           if (s_tmp)
1065             {
1066               gcry_sexp_release (s_sig);
1067               s_sig = s_tmp;
1068               sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
1069             }
1070         }
1071     }
1072   gcry_sexp_release (s_sig);
1073               
1074   if (!sig_mpi)
1075     die ("no value in returned S-expression\n");
1076   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
1077   if (err)
1078     die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
1079   gcry_mpi_release (sig_mpi);
1080
1081   print_buffer (outbuf, outlen);
1082   gcry_free (outbuf);
1083 }
1084
1085
1086
1087 \f
1088 static void
1089 usage (int show_help)
1090 {
1091   if (!show_help)
1092     {
1093       fputs ("usage: " PGM 
1094              " [OPTION] [FILE] (try --help for more information)\n", stderr);
1095       exit (2);
1096     }
1097   fputs
1098     ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
1099      "Run a crypto operation using hex encoded input and output.\n"
1100      "MODE:\n"
1101      "  encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify}\n"
1102      "OPTIONS:\n"
1103      "  --verbose       print additional information\n"
1104      "  --binary        input and output is in binary form\n"
1105      "  --no-fips       do not force FIPS mode\n"
1106      "  --key KEY       use the hex encoded KEY\n"
1107      "  --iv IV         use the hex encoded IV\n"
1108      "  --dt DT         use the hex encoded DT for the RNG\n"
1109      "  --algo NAME     use algorithm NAME\n"
1110      "  --keysize N     use a keysize of N bits\n"
1111      "  --chunk N       read in chunks of N bytes (implies --binary)\n"
1112      "  --pkcs1         use PKCS#1 encoding\n"
1113      "  --loop          enable random loop mode\n"
1114      "  --progress      print pogress indicators\n"
1115      "  --help          print this text\n"
1116      "With no FILE, or when FILE is -, read standard input.\n"
1117      "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
1118   exit (0);
1119 }
1120
1121 int
1122 main (int argc, char **argv)
1123 {
1124   int last_argc = -1;
1125   gpg_error_t err;
1126   int no_fips = 0;
1127   int progress = 0;
1128   int use_pkcs1 = 0;
1129   const char *mode_string;
1130   const char *key_string = NULL;
1131   const char *iv_string = NULL;
1132   const char *dt_string = NULL;
1133   const char *algo_string = NULL;
1134   const char *keysize_string = NULL;
1135   FILE *input;
1136   void *data;
1137   size_t datalen;
1138   size_t chunksize = 0;
1139
1140
1141   if (argc)
1142     { argc--; argv++; }
1143
1144   while (argc && last_argc != argc )
1145     {
1146       last_argc = argc;
1147       if (!strcmp (*argv, "--"))
1148         {
1149           argc--; argv++;
1150           break;
1151         }
1152       else if (!strcmp (*argv, "--help"))
1153         {
1154           usage (1);
1155         }
1156       else if (!strcmp (*argv, "--version"))
1157         {
1158           fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
1159           exit (0);
1160         }
1161       else if (!strcmp (*argv, "--verbose"))
1162         {
1163           verbose++;
1164           argc--; argv++;
1165         }
1166       else if (!strcmp (*argv, "--binary"))
1167         {
1168           binary_input = binary_output = 1;
1169           argc--; argv++;
1170         }
1171       else if (!strcmp (*argv, "--no-fips"))
1172         {
1173           no_fips++;
1174           argc--; argv++;
1175         }
1176       else if (!strcmp (*argv, "--loop"))
1177         {
1178           loop_mode = 1;
1179           argc--; argv++;
1180         }
1181       else if (!strcmp (*argv, "--progress"))
1182         {
1183           progress = 1;
1184           argc--; argv++;
1185         }
1186       else if (!strcmp (*argv, "--key"))
1187         {
1188           argc--; argv++;
1189           if (!argc)
1190             usage (0);
1191           key_string = *argv;
1192           argc--; argv++;
1193         }
1194       else if (!strcmp (*argv, "--iv"))
1195         {
1196           argc--; argv++;
1197           if (!argc)
1198             usage (0);
1199           iv_string = *argv;
1200           argc--; argv++;
1201         }
1202       else if (!strcmp (*argv, "--dt"))
1203         {
1204           argc--; argv++;
1205           if (!argc)
1206             usage (0);
1207           dt_string = *argv;
1208           argc--; argv++;
1209         }
1210       else if (!strcmp (*argv, "--algo"))
1211         {
1212           argc--; argv++;
1213           if (!argc)
1214             usage (0);
1215           algo_string = *argv;
1216           argc--; argv++;
1217         }
1218       else if (!strcmp (*argv, "--keysize"))
1219         {
1220           argc--; argv++;
1221           if (!argc)
1222             usage (0);
1223           keysize_string = *argv;
1224           argc--; argv++;
1225         }
1226       else if (!strcmp (*argv, "--chunk"))
1227         {
1228           argc--; argv++;
1229           if (!argc)
1230             usage (0);
1231           chunksize = atoi (*argv);
1232           binary_input = binary_output = 1;
1233           argc--; argv++;
1234         }
1235       else if (!strcmp (*argv, "--pkcs1"))
1236         {
1237           use_pkcs1 = 1;
1238           argc--; argv++;
1239         }
1240     }          
1241
1242   if (!argc || argc > 2)
1243     usage (0);
1244   mode_string = *argv;
1245   if (argc == 2 && strcmp (argv[1], "-"))
1246     {
1247       input = fopen (argv[1], binary_input? "rb":"r");
1248       if (!input)
1249         die ("can't open `%s': %s\n", argv[1], strerror (errno));
1250     }
1251   else
1252     input = stdin;
1253
1254 #ifndef HAVE_W32_SYSTEM
1255   if (loop_mode)
1256     signal (SIGPIPE, SIG_IGN);
1257 #endif
1258
1259   if (verbose)
1260     fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
1261
1262   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
1263   if (!no_fips)
1264     gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
1265   if (!gcry_check_version ("1.4.3"))
1266     die ("Libgcrypt is not sufficient enough\n");
1267   if (verbose)
1268     fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
1269   if (no_fips)
1270     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1271   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1272
1273   /* Most operations need some input data.  */
1274   if (!chunksize
1275       && strcmp (mode_string, "random")
1276       && strcmp (mode_string, "rsa-gen") )
1277     {
1278       data = read_file (input, !binary_input, &datalen);
1279       if (!data)
1280         die ("error reading%s input\n", binary_input?"":" and decoding");
1281       if (verbose)
1282         fprintf (stderr, PGM ": %u bytes of input data\n", 
1283                  (unsigned int)datalen);
1284     }
1285   else
1286     {
1287       data = NULL;
1288       datalen = 0;
1289     }
1290
1291
1292   if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
1293     {
1294       int cipher_algo, cipher_mode;
1295       void  *iv_buffer, *key_buffer;
1296       size_t iv_buflen,  key_buflen;
1297
1298       if (!algo_string)
1299         die ("option --algo is required in this mode\n");
1300       cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
1301       if (!cipher_algo)
1302         die ("cipher algorithm `%s' is not supported\n", algo_string);
1303       if (!iv_string)
1304         die ("option --iv is required in this mode\n");
1305       iv_buffer = hex2buffer (iv_string, &iv_buflen);
1306       if (!iv_buffer)
1307         die ("invalid value for IV\n");
1308       if (!key_string)
1309         die ("option --key is required in this mode\n");
1310       key_buffer = hex2buffer (key_string, &key_buflen);
1311       if (!key_buffer)
1312         die ("invalid value for KEY\n");
1313
1314       run_encrypt_decrypt ((*mode_string == 'e'),
1315                            cipher_algo, cipher_mode,
1316                            iv_buffer, iv_buflen,
1317                            key_buffer, key_buflen,
1318                            data, data? datalen:chunksize, input);
1319       gcry_free (key_buffer);
1320       gcry_free (iv_buffer);
1321     }
1322   else if (!strcmp (mode_string, "digest"))
1323     {
1324       int algo;
1325
1326       if (!algo_string)
1327         die ("option --algo is required in this mode\n");
1328       algo = gcry_md_map_name (algo_string);
1329       if (!algo)
1330         die ("digest algorithm `%s' is not supported\n", algo_string);
1331
1332       run_digest (algo, data, datalen);
1333     }
1334   else if (!strcmp (mode_string, "random"))
1335     {
1336       void *context;
1337       unsigned char key[16];
1338       unsigned char seed[16];
1339       unsigned char dt[16];
1340       unsigned char buffer[16];
1341       size_t count = 0;
1342
1343       if (hex2bin (key_string, key, 16) < 0 )
1344         die ("value for --key are not 32 hex digits\n");
1345       if (hex2bin (iv_string, seed, 16) < 0 )
1346         die ("value for --iv are not 32 hex digits\n");
1347       if (hex2bin (dt_string, dt, 16) < 0 )
1348         die ("value for --dt are not 32 hex digits\n");
1349
1350       /* The flag value 1 disables the dup check, so that the RNG
1351          returns all generated data.  */
1352       err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
1353       if (err)
1354         die ("init external RNG test failed: %s\n", gpg_strerror (err));
1355
1356       do 
1357         {
1358           err = run_external_rng_test (context, buffer, sizeof buffer);
1359           if (err)
1360             die ("running external RNG test failed: %s\n", gpg_strerror (err));
1361           print_buffer (buffer, sizeof buffer);
1362           if (progress)
1363             {
1364               if (!(++count % 1000))
1365                 fprintf (stderr, PGM ": %lu random bytes so far\n", 
1366                          (unsigned long int)count * sizeof buffer);
1367             }
1368         }
1369       while (loop_mode);
1370       
1371       if (progress)
1372         fprintf (stderr, PGM ": %lu random bytes\n",
1373                          (unsigned long int)count * sizeof buffer);
1374
1375       deinit_external_rng_test (context);
1376     }
1377   else if (!strcmp (mode_string, "hmac-sha"))
1378     {
1379       int algo;
1380       void  *key_buffer;
1381       size_t key_buflen;
1382
1383       if (!data)
1384         die ("no data available (do not use --chunk)\n");
1385       if (!algo_string)
1386         die ("option --algo is required in this mode\n");
1387       switch (atoi (algo_string))
1388         {
1389         case 1:   algo = GCRY_MD_SHA1; break;
1390         case 224: algo = GCRY_MD_SHA224; break;
1391         case 256: algo = GCRY_MD_SHA256; break;
1392         case 384: algo = GCRY_MD_SHA384; break;
1393         case 512: algo = GCRY_MD_SHA512; break;
1394         default:  algo = 0; break;
1395         }
1396       if (!algo)
1397         die ("no digest algorithm found for hmac type `%s'\n", algo_string);
1398       if (!key_string)
1399         die ("option --key is required in this mode\n");
1400       key_buffer = hex2buffer (key_string, &key_buflen);
1401       if (!key_buffer)
1402         die ("invalid value for KEY\n");
1403
1404       run_hmac (algo, key_buffer, key_buflen, data, datalen);
1405
1406       gcry_free (key_buffer);
1407     }
1408   else if (!strcmp (mode_string, "rsa-gen"))
1409     {
1410       int keysize;
1411       
1412       if (!binary_output)
1413         base64_output = 1;
1414
1415       keysize = keysize_string? atoi (keysize_string) : 0;
1416       if (keysize < 128 || keysize > 16384)
1417         die ("invalid keysize specified; needs to be 128 .. 16384\n");
1418       run_rsa_gen (keysize, 65537);
1419     }
1420   else if (!strcmp (mode_string, "rsa-sign"))
1421     {
1422       int algo;
1423
1424       if (!key_string)
1425         die ("option --key is required in this mode\n");
1426       if (access (key_string, R_OK))
1427         die ("option --key needs to specify an existing keyfile\n");
1428       if (!algo_string)
1429         die ("option --algo is required in this mode\n");
1430       algo = gcry_md_map_name (algo_string);
1431       if (!algo)
1432         die ("digest algorithm `%s' is not supported\n", algo_string);
1433       if (!data)
1434         die ("no data available (do not use --chunk)\n");
1435
1436       run_rsa_sign (data, datalen, algo, use_pkcs1, key_string);
1437
1438     }
1439   else if (!strcmp (mode_string, "rsa-verify"))
1440     {
1441     }
1442   else
1443     usage (0);
1444
1445   gcry_free (data);
1446
1447   /* Because Libgcrypt does not enforce FIPS mode in all cases we let
1448      the process die if Libgcrypt is not anymore in FIPS mode after
1449      the actual operation.  */
1450   if (!no_fips && !gcry_fips_mode_active ())
1451     die ("FIPS mode is not anymore active\n");
1452
1453   if (verbose)
1454     fputs (PGM ": ready\n", stderr);
1455
1456   return 0;
1457 }
1458