Add rsa verify function.
[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 or public
435    key file and return an S-expression.  With SHOW set, the key
436    parameters are printed.  */
437 static gcry_sexp_t
438 read_key_file (const char *fname, int private, 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 n_keyparms = private? 8 : 2;
449   int idx;
450   gcry_sexp_t s_key;
451
452   fp = fopen (fname, binary_input?"rb":"r");
453   if (!fp)
454     die ("can't open `%s': %s\n", fname, strerror (errno));
455   buffer = read_file (fp, 0, &buflen);
456   if (!buffer)
457     die ("error reading `%s'\n", fname);
458   fclose (fp);
459
460   buflen = base64_decode (buffer, buflen);
461   
462   /* Parse the ASN.1 structure.  */
463   der = (const unsigned char*)buffer;
464   derlen = buflen;
465   if ( parse_tag (&der, &derlen, &ti)
466        || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
467     goto bad_asn1;
468   if ( parse_tag (&der, &derlen, &ti)
469        || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
470     goto bad_asn1;
471   if (ti.length != 1 || *der)
472     goto bad_asn1;  /* The value of the first integer is no 0. */
473   der += ti.length; derlen += ti.length;
474
475   for (idx=0; idx < n_keyparms; idx++)
476     {
477       if ( parse_tag (&der, &derlen, &ti)
478            || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
479         goto bad_asn1;
480       if (show)
481         {
482           char prefix[2];
483
484           prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
485           prefix[1] = 0;
486           showhex (prefix, der, ti.length);
487         }
488       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
489       if (err)
490         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
491       der += ti.length; derlen += ti.length;
492     }
493   if (idx != n_keyparms)
494     die ("not enough RSA key parameters\n");
495
496   gcry_free (buffer);
497
498   if (private)
499     {
500       /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
501       /* First check that p < q; if not swap p and q and recompute u.  */ 
502       if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
503         {
504           gcry_mpi_swap (keyparms[3], keyparms[4]);
505           gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
506         }
507       
508       /* Build the S-expression.  */
509       err = gcry_sexp_build (&s_key, NULL,
510                              "(private-key(rsa(n%m)(e%m)"
511                              /**/            "(d%m)(p%m)(q%m)(u%m)))",
512                              keyparms[0], keyparms[1], keyparms[2],
513                              keyparms[3], keyparms[4], keyparms[7] );
514     }
515   else
516     {
517       err = gcry_sexp_build (&s_key, NULL,
518                              "(public-key(rsa(n%m)(e%m)))",
519                              keyparms[0], keyparms[1]);
520
521     }
522   if (err)
523     die ("error building S-expression: %s\n", gpg_strerror (err));
524   
525   for (idx=0; idx < n_keyparms; idx++)
526     gcry_mpi_release (keyparms[idx]);
527
528   return s_key;
529
530  bad_asn1:
531   die ("invalid ASN.1 structure in `%s'\n", fname);
532   return NULL; /*NOTREACHED*/
533 }
534
535
536 /* Read the file FNAME assuming it is a binary signature result and
537    return an an S-expression suitable for gcry_pk_verify.  */
538 static gcry_sexp_t
539 read_sig_file (const char *fname)
540 {
541   gcry_error_t err;
542   FILE *fp;
543   char *buffer;
544   size_t buflen;
545   gcry_mpi_t tmpmpi;
546   gcry_sexp_t s_sig;
547
548   fp = fopen (fname, "rb");
549   if (!fp)
550     die ("can't open `%s': %s\n", fname, strerror (errno));
551   buffer = read_file (fp, 0, &buflen);
552   if (!buffer)
553     die ("error reading `%s'\n", fname);
554   fclose (fp);
555
556   err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL);
557   if (!err)
558     err = gcry_sexp_build (&s_sig, NULL,
559                            "(sig-val(rsa(s %m)))", tmpmpi);
560   if (err)
561     die ("error building S-expression: %s\n", gpg_strerror (err));
562   gcry_mpi_release (tmpmpi);
563   gcry_free (buffer);
564
565   return s_sig;
566 }
567
568
569 static void
570 print_buffer (const void *buffer, size_t length)
571 {
572   int writerr = 0;
573
574   if (base64_output)
575     {
576       static const unsigned char bintoasc[64+1] = 
577         ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
578          "abcdefghijklmnopqrstuvwxyz" 
579          "0123456789+/"); 
580       const unsigned char *p;
581       unsigned char inbuf[4];
582       char outbuf[4];
583       int idx, quads;
584
585       idx = quads = 0;
586       for (p = buffer; length; p++, length--)
587         {
588           inbuf[idx++] = *p;
589           if (idx > 2)
590             {
591               outbuf[0] = bintoasc[(*inbuf>>2)&077];
592               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
593                                     |((inbuf[1] >> 4)&017))&077];
594               outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
595                                     |((inbuf[2]>>6)&03))&077];
596               outbuf[3] = bintoasc[inbuf[2]&077];
597               if (fwrite (outbuf, 4, 1, stdout) != 1)
598                 writerr = 1;
599               idx = 0;
600               if (++quads >= (64/4)) 
601                 {
602                   if (fwrite ("\n", 1, 1, stdout) != 1)
603                     writerr = 1;
604                   quads = 0;
605                 }
606             }
607         }
608       if (idx)
609         {
610           outbuf[0] = bintoasc[(*inbuf>>2)&077];
611           if (idx == 1)
612             {
613               outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
614               outbuf[2] = outbuf[3] = '=';
615             }
616           else 
617             { 
618               outbuf[1] = bintoasc[(((*inbuf<<4)&060)
619                                     |((inbuf[1]>>4)&017))&077];
620               outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
621               outbuf[3] = '=';
622             }
623           if (fwrite (outbuf, 4, 1, stdout) != 1)
624             writerr = 1;
625           quads++;
626         }
627       if (quads && fwrite ("\n", 1, 1, stdout) != 1)
628         writerr = 1;
629     }
630   else if (binary_output)
631     {
632       if (fwrite (buffer, length, 1, stdout) != 1)
633         writerr++;
634     }
635   else
636     {
637       const unsigned char *p = buffer;
638       
639       while (length-- && !ferror (stdout) )
640         printf ("%02X", *p++);
641       if (ferror (stdout))
642         writerr++;
643     }
644   if (!writerr && fflush (stdout) == EOF)
645     writerr++;
646   if (writerr)
647     {
648 #ifndef HAVE_W32_SYSTEM
649       if (loop_mode && errno == EPIPE)
650         loop_mode = 0;
651       else
652 #endif
653         die ("writing output failed: %s\n", strerror (errno));
654     }
655 }
656
657
658
659 static gcry_error_t
660 init_external_rng_test (void **r_context, 
661                     unsigned int flags,
662                     const void *key, size_t keylen,
663                     const void *seed, size_t seedlen,
664                     const void *dt, size_t dtlen)
665 {
666   return gcry_control (58, 
667                        r_context, flags,
668                        key, keylen,
669                        seed, seedlen,
670                        dt, dtlen);
671 }
672
673 static gcry_error_t
674 run_external_rng_test (void *context, void *buffer, size_t buflen)
675 {
676   return gcry_control (59, context, buffer, buflen);
677 }
678
679 static void
680 deinit_external_rng_test (void *context)
681 {
682   gcry_control (60, context);
683 }
684
685
686 /* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm
687    identified and store the libgcrypt mode at R_MODE.  Returns 0 on
688    error.  */
689 static int 
690 map_openssl_cipher_name (const char *name, int *r_mode)
691 {
692   static struct {
693     const char *name;
694     int algo;
695     int mode;
696   } table[] = 
697     {
698       { "bf-cbc",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
699       { "bf",           GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
700       { "bf-cfb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
701       { "bf-ecb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
702       { "bf-ofb",       GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
703
704       { "cast-cbc",     GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
705       { "cast",         GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
706       { "cast5-cbc",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
707       { "cast5-cfb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
708       { "cast5-ecb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
709       { "cast5-ofb",    GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
710
711       { "des-cbc",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
712       { "des",          GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
713       { "des-cfb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
714       { "des-ofb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
715       { "des-ecb",      GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
716
717       { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
718       { "des-ede3    ", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
719       { "des3        ", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
720       { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
721       { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
722
723       { "rc4",          GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
724
725       { "aes-128-cbc",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
726       { "aes-128",      GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
727       { "aes-128-cfb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
728       { "aes-128-ecb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
729       { "aes-128-ofb",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
730
731       { "aes-192-cbc",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
732       { "aes-192",      GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
733       { "aes-192-cfb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
734       { "aes-192-ecb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
735       { "aes-192-ofb",  GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
736       
737       { "aes-256-cbc",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
738       { "aes-256",      GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
739       { "aes-256-cfb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
740       { "aes-256-ecb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
741       { "aes-256-ofb",  GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
742
743       { NULL, 0 , 0 }
744     };
745   int idx;
746
747   for (idx=0; table[idx].name; idx++)
748     if (!strcmp (name, table[idx].name))
749       {
750         *r_mode = table[idx].mode;
751         return table[idx].algo;
752       }
753   *r_mode = 0;
754   return 0;
755 }
756
757
758 \f
759 /* Run an encrypt or decryption operations.  If DATA is NULL the
760    function reads its input in chunks of size DATALEN from fp and
761    processes it and writes it out until EOF.  */
762 static void
763 run_encrypt_decrypt (int encrypt_mode,
764                      int cipher_algo, int cipher_mode, 
765                      const void *iv_buffer, size_t iv_buflen,
766                      const void *key_buffer, size_t key_buflen,
767                      const void *data, size_t datalen, FILE *fp)
768 {
769   gpg_error_t err;
770   gcry_cipher_hd_t hd;
771   void *outbuf;
772   size_t outbuflen;
773   void *inbuf;
774   size_t inbuflen;
775
776   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
777   if (err)
778     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", 
779          cipher_algo, cipher_mode, gpg_strerror (err));
780
781   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
782   if (err)
783     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
784          (unsigned int)key_buflen, gpg_strerror (err));
785
786   err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
787   if (err)
788     die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
789          (unsigned int)iv_buflen, gpg_strerror (err));
790
791   inbuf = data? NULL : gcry_xmalloc (datalen);
792   outbuflen = datalen;
793   outbuf = gcry_xmalloc (outbuflen);
794
795   do
796     {
797       if (inbuf)
798         {
799           int nread = fread (inbuf, 1, datalen, fp);
800           if (nread < (int)datalen && ferror (fp))
801             die ("error reading input\n");
802           data = inbuf;
803           inbuflen = nread;
804         }
805       else
806         inbuflen = datalen;
807
808       if (encrypt_mode)
809         err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
810       else
811         err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
812       if (err)
813         die ("gcry_cipher_%scrypt failed: %s\n",
814              encrypt_mode? "en":"de", gpg_strerror (err));
815       print_buffer (outbuf, outbuflen);
816     }
817   while (inbuf);
818
819   gcry_cipher_close (hd);
820   gcry_free (outbuf);
821   gcry_free (inbuf);
822 }
823
824
825 \f
826 /* Run a digest operation.  */
827 static void
828 run_digest (int digest_algo,  const void *data, size_t datalen)
829 {
830   gpg_error_t err;
831   gcry_md_hd_t hd;
832   const unsigned char *digest;
833   unsigned int digestlen;
834
835   err = gcry_md_open (&hd, digest_algo, 0);
836   if (err)
837     die ("gcry_md_open failed for algo %d: %s\n", 
838          digest_algo,  gpg_strerror (err));
839
840   gcry_md_write (hd, data, datalen);
841   digest = gcry_md_read (hd, digest_algo);
842   digestlen = gcry_md_get_algo_dlen (digest_algo);
843   print_buffer (digest, digestlen);
844   gcry_md_close (hd);
845 }
846
847 \f
848 /* Run a HMAC operation.  */
849 static void
850 run_hmac (int digest_algo, const void *key, size_t keylen, 
851           const void *data, size_t datalen)
852 {
853   gpg_error_t err;
854   gcry_md_hd_t hd;
855   const unsigned char *digest;
856   unsigned int digestlen;
857
858   err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
859   if (err)
860     die ("gcry_md_open failed for HMAC algo %d: %s\n", 
861          digest_algo,  gpg_strerror (err));
862
863   gcry_md_setkey (hd, key, keylen);
864   if (err)
865     die ("gcry_md_setkey failed for HMAC algo %d: %s\n", 
866          digest_algo,  gpg_strerror (err));
867
868   gcry_md_write (hd, data, datalen);
869   digest = gcry_md_read (hd, digest_algo);
870   digestlen = gcry_md_get_algo_dlen (digest_algo);
871   print_buffer (digest, digestlen);
872   gcry_md_close (hd);
873 }
874
875 \f
876 static size_t
877 compute_tag_length (size_t n)
878 {     
879   int needed = 0;
880
881   if (n < 128)
882     needed += 2; /* Tag and one length byte.  */
883   else if (n < 256)
884     needed += 3; /* Tag, number of length bytes, 1 length byte.  */
885   else if (n < 65536)
886     needed += 4; /* Tag, number of length bytes, 2 length bytes.  */
887   else
888     die ("DER object too long to encode\n");
889
890   return needed;
891 }
892
893 static unsigned char *
894 store_tag_length (unsigned char *p, int tag, size_t n)
895 {     
896   if (tag == TAG_SEQUENCE)
897     tag |= 0x20; /* constructed */
898
899   *p++ = tag;
900   if (n < 128)
901     *p++ = n;
902   else if (n < 256)
903     {
904       *p++ = 0x81;
905       *p++ = n;
906     }
907   else if (n < 65536)
908     {
909       *p++ = 0x82;
910       *p++ = n >> 8;
911       *p++ = n;
912     }
913
914   return p;
915 }
916
917
918 /* Generate an RSA key of size KEYSIZE using the public exponent
919    PUBEXP and print it to stdout in the OpenSSL format.  The format
920    is:
921
922        SEQUENCE {
923          INTEGER (0)  -- Unknown constant. 
924          INTEGER      -- n
925          INTEGER      -- e
926          INTEGER      -- d
927          INTEGER      -- p     
928          INTEGER      -- q      (with p < q)
929          INTEGER      -- dmp1 = d mod (p-1)
930          INTEGER      -- dmq1 = d mod (q-1)
931          INTEGER      -- u    = p^{-1} mod q
932        }
933
934 */
935 static void
936 run_rsa_gen (int keysize, int pubexp)
937 {
938   gpg_error_t err;
939   gcry_sexp_t keyspec, key, l1;
940   const char keyelems[] = "nedpq..u";
941   gcry_mpi_t keyparms[8];
942   size_t     keyparmslen[8];
943   int idx;
944   size_t derlen, needed, n;
945   unsigned char *derbuf, *der;
946
947   err = gcry_sexp_build (&keyspec, NULL, 
948                          "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
949                          keysize, pubexp);
950   if (err)
951     die ("gcry_sexp_build failed for RSA key generation: %s\n",
952          gpg_strerror (err));
953
954   err = gcry_pk_genkey (&key, keyspec);
955   if (err)
956     die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
957   
958   gcry_sexp_release (keyspec);
959
960   l1 = gcry_sexp_find_token (key, "private-key", 0);
961   if (!l1)
962     die ("private key not found in genkey result\n");
963   gcry_sexp_release (key);
964   key = l1;
965
966   l1 = gcry_sexp_find_token (key, "rsa", 0);
967   if (!l1)
968     die ("returned private key not formed as expected\n");
969   gcry_sexp_release (key);
970   key = l1;
971
972   /* Extract the parameters from the S-expression and store them in a
973      well defined order in KEYPARMS.  */
974   for (idx=0; idx < DIM(keyparms); idx++) 
975     {
976       if (keyelems[idx] == '.')
977         {
978           keyparms[idx] = gcry_mpi_new (0);
979           continue;
980         }
981       l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
982       if (!l1)
983         die ("no %c parameter in returned private key\n", keyelems[idx]);
984       keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
985       if (!keyparms[idx])
986         die ("no value for %c parameter in returned private key\n",
987              keyelems[idx]);
988       gcry_sexp_release (l1);
989     }
990
991   gcry_sexp_release (key);
992
993   /* Check that p < q; if not swap p and q and recompute u.  */ 
994   if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
995     {
996       gcry_mpi_swap (keyparms[3], keyparms[4]);
997       gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
998     }
999
1000   /* Compute the additional parameters.  */
1001   gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
1002   gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
1003   gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
1004   gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
1005
1006   /* Compute the length of the DER encoding.  */
1007   needed = compute_tag_length (1) + 1;  
1008   for (idx=0; idx < DIM(keyparms); idx++) 
1009     {
1010       err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
1011       if (err)
1012         die ("error formatting parameter: %s\n", gpg_strerror (err));
1013       keyparmslen[idx] = n;
1014       needed += compute_tag_length (n) + n;
1015     }
1016   
1017   /* Store the key parameters. */
1018   derlen = compute_tag_length (needed) + needed;
1019   der = derbuf = gcry_xmalloc (derlen);
1020
1021   der = store_tag_length (der, TAG_SEQUENCE, needed);
1022   der = store_tag_length (der, TAG_INTEGER, 1);
1023   *der++ = 0;
1024   for (idx=0; idx < DIM(keyparms); idx++) 
1025     {
1026       der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
1027       err = gcry_mpi_print (GCRYMPI_FMT_STD, der, 
1028                            keyparmslen[idx], NULL, keyparms[idx]);
1029       if (err)
1030         die ("error formatting parameter: %s\n", gpg_strerror (err));
1031       der += keyparmslen[idx];
1032     }
1033
1034   /* Print the stuff.  */
1035   for (idx=0; idx < DIM(keyparms); idx++) 
1036     gcry_mpi_release (keyparms[idx]);
1037
1038   assert (der - derbuf == derlen);
1039
1040   if (base64_output)
1041     puts ("-----BEGIN RSA PRIVATE KEY-----");
1042   print_buffer (derbuf, derlen);
1043   if (base64_output)
1044     puts ("-----END RSA PRIVATE KEY-----");
1045
1046   gcry_free (derbuf);
1047 }
1048
1049
1050 \f
1051 /* Sign DATA of length DATALEN using the key taken from the PEM
1052    encoded KEYFILE and the hash algorithm HASHALGO.  */
1053 static void
1054 run_rsa_sign (const void *data, size_t datalen,
1055               int hashalgo, int pkcs1, const char *keyfile)
1056
1057 {
1058   gpg_error_t err;
1059   gcry_sexp_t s_data, s_key, s_sig, s_tmp;
1060   gcry_mpi_t sig_mpi = NULL;
1061   unsigned char *outbuf;
1062   size_t outlen;
1063   
1064 /*   showhex ("D", data, datalen); */
1065
1066   if (pkcs1)
1067     err = gcry_sexp_build (&s_data, NULL,
1068                            "(data (flags pkcs1)(hash %s %b))",
1069                            gcry_md_algo_name (hashalgo), (int)datalen, data);
1070   else
1071     {
1072       gcry_mpi_t tmp;
1073
1074       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1075       if (!err)
1076         {
1077           err = gcry_sexp_build (&s_data, NULL,
1078                                  "(data (flags raw)(value %m))", tmp);
1079           gcry_mpi_release (tmp);
1080         }
1081     }
1082   if (err)
1083     die ("gcry_sexp_build failed for RSA data input: %s\n",
1084          gpg_strerror (err));
1085
1086   s_key = read_key_file (keyfile, 1, 0);
1087
1088   err = gcry_pk_sign (&s_sig, s_data, s_key);
1089   if (err)
1090     {
1091       gcry_sexp_release (read_key_file (keyfile, 1, 1));
1092       die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
1093            (int)datalen, keyfile, gpg_strerror (err));
1094     }
1095   gcry_sexp_release (s_key);
1096   gcry_sexp_release (s_data);
1097
1098   s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
1099   if (s_tmp)
1100     {
1101       gcry_sexp_release (s_sig);
1102       s_sig = s_tmp;
1103       s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
1104       if (s_tmp)
1105         {
1106           gcry_sexp_release (s_sig);
1107           s_sig = s_tmp;
1108           s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
1109           if (s_tmp)
1110             {
1111               gcry_sexp_release (s_sig);
1112               s_sig = s_tmp;
1113               sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
1114             }
1115         }
1116     }
1117   gcry_sexp_release (s_sig);
1118               
1119   if (!sig_mpi)
1120     die ("no value in returned S-expression\n");
1121   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
1122   if (err)
1123     die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
1124   gcry_mpi_release (sig_mpi);
1125
1126   print_buffer (outbuf, outlen);
1127   gcry_free (outbuf);
1128 }
1129
1130
1131 \f
1132 /* Verify DATA of length DATALEN using the public key taken from the
1133    PEM encoded KEYFILE and the hash algorithm HASHALGO against the
1134    binary signature in SIGFILE.  */
1135 static void
1136 run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
1137                 const char *keyfile, const char *sigfile)
1138
1139 {
1140   gpg_error_t err;
1141   gcry_sexp_t s_data, s_key, s_sig;
1142   
1143   if (pkcs1)
1144     err = gcry_sexp_build (&s_data, NULL,
1145                            "(data (flags pkcs1)(hash %s %b))",
1146                            gcry_md_algo_name (hashalgo), (int)datalen, data);
1147   else
1148     {
1149       gcry_mpi_t tmp;
1150
1151       err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
1152       if (!err)
1153         {
1154           err = gcry_sexp_build (&s_data, NULL,
1155                                  "(data (flags raw)(value %m))", tmp);
1156           gcry_mpi_release (tmp);
1157         }
1158     }
1159   if (err)
1160     die ("gcry_sexp_build failed for RSA data input: %s\n",
1161          gpg_strerror (err));
1162
1163   s_key = read_key_file (keyfile, 0, 0);
1164
1165   s_sig = read_sig_file (sigfile);
1166
1167   err = gcry_pk_verify (s_sig, s_data, s_key);
1168   if (!err)
1169     puts ("GOOD signature\n");
1170   else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
1171     puts ("BAD signature\n");
1172   else
1173     printf ("ERROR (%s)\n", gpg_strerror (err));
1174
1175   gcry_sexp_release (s_sig);
1176   gcry_sexp_release (s_key);
1177   gcry_sexp_release (s_data);
1178 }
1179
1180
1181
1182 \f
1183 static void
1184 usage (int show_help)
1185 {
1186   if (!show_help)
1187     {
1188       fputs ("usage: " PGM 
1189              " [OPTION] [FILE] (try --help for more information)\n", stderr);
1190       exit (2);
1191     }
1192   fputs
1193     ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
1194      "Run a crypto operation using hex encoded input and output.\n"
1195      "MODE:\n"
1196      "  encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify}\n"
1197      "OPTIONS:\n"
1198      "  --verbose        print additional information\n"
1199      "  --binary         input and output is in binary form\n"
1200      "  --no-fips        do not force FIPS mode\n"
1201      "  --key KEY        use the hex encoded KEY\n"
1202      "  --iv IV          use the hex encoded IV\n"
1203      "  --dt DT          use the hex encoded DT for the RNG\n"
1204      "  --algo NAME      use algorithm NAME\n"
1205      "  --keysize N      use a keysize of N bits\n"
1206      "  --signature NAME take signature from file NAME\n"
1207      "  --chunk N        read in chunks of N bytes (implies --binary)\n"
1208      "  --pkcs1          use PKCS#1 encoding\n"
1209      "  --loop           enable random loop mode\n"
1210      "  --progress       print pogress indicators\n"
1211      "  --help           print this text\n"
1212      "With no FILE, or when FILE is -, read standard input.\n"
1213      "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
1214   exit (0);
1215 }
1216
1217 int
1218 main (int argc, char **argv)
1219 {
1220   int last_argc = -1;
1221   gpg_error_t err;
1222   int no_fips = 0;
1223   int progress = 0;
1224   int use_pkcs1 = 0;
1225   const char *mode_string;
1226   const char *key_string = NULL;
1227   const char *iv_string = NULL;
1228   const char *dt_string = NULL;
1229   const char *algo_string = NULL;
1230   const char *keysize_string = NULL;
1231   const char *signature_string = NULL;
1232   FILE *input;
1233   void *data;
1234   size_t datalen;
1235   size_t chunksize = 0;
1236
1237
1238   if (argc)
1239     { argc--; argv++; }
1240
1241   while (argc && last_argc != argc )
1242     {
1243       last_argc = argc;
1244       if (!strcmp (*argv, "--"))
1245         {
1246           argc--; argv++;
1247           break;
1248         }
1249       else if (!strcmp (*argv, "--help"))
1250         {
1251           usage (1);
1252         }
1253       else if (!strcmp (*argv, "--version"))
1254         {
1255           fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
1256           exit (0);
1257         }
1258       else if (!strcmp (*argv, "--verbose"))
1259         {
1260           verbose++;
1261           argc--; argv++;
1262         }
1263       else if (!strcmp (*argv, "--binary"))
1264         {
1265           binary_input = binary_output = 1;
1266           argc--; argv++;
1267         }
1268       else if (!strcmp (*argv, "--no-fips"))
1269         {
1270           no_fips++;
1271           argc--; argv++;
1272         }
1273       else if (!strcmp (*argv, "--loop"))
1274         {
1275           loop_mode = 1;
1276           argc--; argv++;
1277         }
1278       else if (!strcmp (*argv, "--progress"))
1279         {
1280           progress = 1;
1281           argc--; argv++;
1282         }
1283       else if (!strcmp (*argv, "--key"))
1284         {
1285           argc--; argv++;
1286           if (!argc)
1287             usage (0);
1288           key_string = *argv;
1289           argc--; argv++;
1290         }
1291       else if (!strcmp (*argv, "--iv"))
1292         {
1293           argc--; argv++;
1294           if (!argc)
1295             usage (0);
1296           iv_string = *argv;
1297           argc--; argv++;
1298         }
1299       else if (!strcmp (*argv, "--dt"))
1300         {
1301           argc--; argv++;
1302           if (!argc)
1303             usage (0);
1304           dt_string = *argv;
1305           argc--; argv++;
1306         }
1307       else if (!strcmp (*argv, "--algo"))
1308         {
1309           argc--; argv++;
1310           if (!argc)
1311             usage (0);
1312           algo_string = *argv;
1313           argc--; argv++;
1314         }
1315       else if (!strcmp (*argv, "--keysize"))
1316         {
1317           argc--; argv++;
1318           if (!argc)
1319             usage (0);
1320           keysize_string = *argv;
1321           argc--; argv++;
1322         }
1323       else if (!strcmp (*argv, "--signature"))
1324         {
1325           argc--; argv++;
1326           if (!argc)
1327             usage (0);
1328           signature_string = *argv;
1329           argc--; argv++;
1330         }
1331       else if (!strcmp (*argv, "--chunk"))
1332         {
1333           argc--; argv++;
1334           if (!argc)
1335             usage (0);
1336           chunksize = atoi (*argv);
1337           binary_input = binary_output = 1;
1338           argc--; argv++;
1339         }
1340       else if (!strcmp (*argv, "--pkcs1"))
1341         {
1342           use_pkcs1 = 1;
1343           argc--; argv++;
1344         }
1345     }          
1346
1347   if (!argc || argc > 2)
1348     usage (0);
1349   mode_string = *argv;
1350   if (argc == 2 && strcmp (argv[1], "-"))
1351     {
1352       input = fopen (argv[1], binary_input? "rb":"r");
1353       if (!input)
1354         die ("can't open `%s': %s\n", argv[1], strerror (errno));
1355     }
1356   else
1357     input = stdin;
1358
1359 #ifndef HAVE_W32_SYSTEM
1360   if (loop_mode)
1361     signal (SIGPIPE, SIG_IGN);
1362 #endif
1363
1364   if (verbose)
1365     fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
1366
1367   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
1368   if (!no_fips)
1369     gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
1370   if (!gcry_check_version ("1.4.3"))
1371     die ("Libgcrypt is not sufficient enough\n");
1372   if (verbose)
1373     fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
1374   if (no_fips)
1375     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1376   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1377
1378   /* Most operations need some input data.  */
1379   if (!chunksize
1380       && strcmp (mode_string, "random")
1381       && strcmp (mode_string, "rsa-gen") )
1382     {
1383       data = read_file (input, !binary_input, &datalen);
1384       if (!data)
1385         die ("error reading%s input\n", binary_input?"":" and decoding");
1386       if (verbose)
1387         fprintf (stderr, PGM ": %u bytes of input data\n", 
1388                  (unsigned int)datalen);
1389     }
1390   else
1391     {
1392       data = NULL;
1393       datalen = 0;
1394     }
1395
1396
1397   if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
1398     {
1399       int cipher_algo, cipher_mode;
1400       void  *iv_buffer, *key_buffer;
1401       size_t iv_buflen,  key_buflen;
1402
1403       if (!algo_string)
1404         die ("option --algo is required in this mode\n");
1405       cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
1406       if (!cipher_algo)
1407         die ("cipher algorithm `%s' is not supported\n", algo_string);
1408       if (!iv_string)
1409         die ("option --iv is required in this mode\n");
1410       iv_buffer = hex2buffer (iv_string, &iv_buflen);
1411       if (!iv_buffer)
1412         die ("invalid value for IV\n");
1413       if (!key_string)
1414         die ("option --key is required in this mode\n");
1415       key_buffer = hex2buffer (key_string, &key_buflen);
1416       if (!key_buffer)
1417         die ("invalid value for KEY\n");
1418
1419       run_encrypt_decrypt ((*mode_string == 'e'),
1420                            cipher_algo, cipher_mode,
1421                            iv_buffer, iv_buflen,
1422                            key_buffer, key_buflen,
1423                            data, data? datalen:chunksize, input);
1424       gcry_free (key_buffer);
1425       gcry_free (iv_buffer);
1426     }
1427   else if (!strcmp (mode_string, "digest"))
1428     {
1429       int algo;
1430
1431       if (!algo_string)
1432         die ("option --algo is required in this mode\n");
1433       algo = gcry_md_map_name (algo_string);
1434       if (!algo)
1435         die ("digest algorithm `%s' is not supported\n", algo_string);
1436
1437       run_digest (algo, data, datalen);
1438     }
1439   else if (!strcmp (mode_string, "random"))
1440     {
1441       void *context;
1442       unsigned char key[16];
1443       unsigned char seed[16];
1444       unsigned char dt[16];
1445       unsigned char buffer[16];
1446       size_t count = 0;
1447
1448       if (hex2bin (key_string, key, 16) < 0 )
1449         die ("value for --key are not 32 hex digits\n");
1450       if (hex2bin (iv_string, seed, 16) < 0 )
1451         die ("value for --iv are not 32 hex digits\n");
1452       if (hex2bin (dt_string, dt, 16) < 0 )
1453         die ("value for --dt are not 32 hex digits\n");
1454
1455       /* The flag value 1 disables the dup check, so that the RNG
1456          returns all generated data.  */
1457       err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
1458       if (err)
1459         die ("init external RNG test failed: %s\n", gpg_strerror (err));
1460
1461       do 
1462         {
1463           err = run_external_rng_test (context, buffer, sizeof buffer);
1464           if (err)
1465             die ("running external RNG test failed: %s\n", gpg_strerror (err));
1466           print_buffer (buffer, sizeof buffer);
1467           if (progress)
1468             {
1469               if (!(++count % 1000))
1470                 fprintf (stderr, PGM ": %lu random bytes so far\n", 
1471                          (unsigned long int)count * sizeof buffer);
1472             }
1473         }
1474       while (loop_mode);
1475       
1476       if (progress)
1477         fprintf (stderr, PGM ": %lu random bytes\n",
1478                          (unsigned long int)count * sizeof buffer);
1479
1480       deinit_external_rng_test (context);
1481     }
1482   else if (!strcmp (mode_string, "hmac-sha"))
1483     {
1484       int algo;
1485       void  *key_buffer;
1486       size_t key_buflen;
1487
1488       if (!data)
1489         die ("no data available (do not use --chunk)\n");
1490       if (!algo_string)
1491         die ("option --algo is required in this mode\n");
1492       switch (atoi (algo_string))
1493         {
1494         case 1:   algo = GCRY_MD_SHA1; break;
1495         case 224: algo = GCRY_MD_SHA224; break;
1496         case 256: algo = GCRY_MD_SHA256; break;
1497         case 384: algo = GCRY_MD_SHA384; break;
1498         case 512: algo = GCRY_MD_SHA512; break;
1499         default:  algo = 0; break;
1500         }
1501       if (!algo)
1502         die ("no digest algorithm found for hmac type `%s'\n", algo_string);
1503       if (!key_string)
1504         die ("option --key is required in this mode\n");
1505       key_buffer = hex2buffer (key_string, &key_buflen);
1506       if (!key_buffer)
1507         die ("invalid value for KEY\n");
1508
1509       run_hmac (algo, key_buffer, key_buflen, data, datalen);
1510
1511       gcry_free (key_buffer);
1512     }
1513   else if (!strcmp (mode_string, "rsa-gen"))
1514     {
1515       int keysize;
1516       
1517       if (!binary_output)
1518         base64_output = 1;
1519
1520       keysize = keysize_string? atoi (keysize_string) : 0;
1521       if (keysize < 128 || keysize > 16384)
1522         die ("invalid keysize specified; needs to be 128 .. 16384\n");
1523       run_rsa_gen (keysize, 65537);
1524     }
1525   else if (!strcmp (mode_string, "rsa-sign"))
1526     {
1527       int algo;
1528
1529       if (!key_string)
1530         die ("option --key is required in this mode\n");
1531       if (access (key_string, R_OK))
1532         die ("option --key needs to specify an existing keyfile\n");
1533       if (!algo_string)
1534         die ("option --algo is required in this mode\n");
1535       algo = gcry_md_map_name (algo_string);
1536       if (!algo)
1537         die ("digest algorithm `%s' is not supported\n", algo_string);
1538       if (!data)
1539         die ("no data available (do not use --chunk)\n");
1540
1541       run_rsa_sign (data, datalen, algo, use_pkcs1, key_string);
1542
1543     }
1544   else if (!strcmp (mode_string, "rsa-verify"))
1545     {
1546       int algo;
1547
1548       if (!key_string)
1549         die ("option --key is required in this mode\n");
1550       if (access (key_string, R_OK))
1551         die ("option --key needs to specify an existing keyfile\n");
1552       if (!algo_string)
1553         die ("option --algo is required in this mode\n");
1554       algo = gcry_md_map_name (algo_string);
1555       if (!algo)
1556         die ("digest algorithm `%s' is not supported\n", algo_string);
1557       if (!data)
1558         die ("no data available (do not use --chunk)\n");
1559       if (!signature_string)
1560         die ("option --signature is required in this mode\n");
1561       if (access (signature_string, R_OK))
1562         die ("option --signature needs to specify an existing file\n");
1563
1564       run_rsa_verify (data, datalen, algo, use_pkcs1, key_string,
1565                       signature_string);
1566
1567     }
1568   else
1569     usage (0);
1570
1571   gcry_free (data);
1572
1573   /* Because Libgcrypt does not enforce FIPS mode in all cases we let
1574      the process die if Libgcrypt is not anymore in FIPS mode after
1575      the actual operation.  */
1576   if (!no_fips && !gcry_fips_mode_active ())
1577     die ("FIPS mode is not anymore active\n");
1578
1579   if (verbose)
1580     fputs (PGM ": ready\n", stderr);
1581
1582   return 0;
1583 }
1584