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

Generated by: LCOV version 1.11