LCOV - code coverage report
Current view: top level - tests - fipsdrv.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1412 0.0 %
Date: 2017-03-02 16:44:37 Functions: 0 47 0.0 %

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

Generated by: LCOV version 1.13