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