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

Generated by: LCOV version 1.11