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