diff options
Diffstat (limited to 'plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c')
-rw-r--r-- | plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c | 2526 |
1 files changed, 0 insertions, 2526 deletions
diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c deleted file mode 100644 index f80e30c844..0000000000 --- a/plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c +++ /dev/null @@ -1,2526 +0,0 @@ -/* fipsdrv.c - A driver to help with FIPS CAVS tests. - Copyright (C) 2008 Free Software Foundation, Inc. - - This file is part of Libgcrypt. - - Libgcrypt is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - Libgcrypt is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <errno.h> -#include <ctype.h> -#ifdef HAVE_W32_SYSTEM -# include <fcntl.h> /* We need setmode(). */ -#else -# include <signal.h> -#endif -#include <assert.h> -#include <unistd.h> - -#ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" -#else -# include <gcrypt.h> -# define PACKAGE_BUGREPORT "devnull@example.org" -# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" -#endif - - -#define PGM "fipsdrv" - -#define my_isascii(c) (!((c) & 0x80)) -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) - - -#define PRIV_CTL_INIT_EXTRNG_TEST 58 -#define PRIV_CTL_RUN_EXTRNG_TEST 59 -#define PRIV_CTL_DEINIT_EXTRNG_TEST 60 -#define PRIV_CTL_DISABLE_WEAK_KEY 61 -#define PRIV_CTL_GET_INPUT_VECTOR 62 - - -/* Verbose mode flag. */ -static int verbose; - -/* Binary input flag. */ -static int binary_input; - -/* Binary output flag. */ -static int binary_output; - -/* Base64 output flag. */ -static int base64_output; - -/* We need to know whether we are in loop_mode. */ -static int loop_mode; - -/* If true some functions are modified to print the output in the CAVS - response file format. */ -static int standalone_mode; - - -/* ASN.1 classes. */ -enum -{ - UNIVERSAL = 0, - APPLICATION = 1, - ASNCONTEXT = 2, - PRIVATE = 3 -}; - - -/* ASN.1 tags. */ -enum -{ - TAG_NONE = 0, - TAG_BOOLEAN = 1, - TAG_INTEGER = 2, - TAG_BIT_STRING = 3, - TAG_OCTET_STRING = 4, - TAG_NULL = 5, - TAG_OBJECT_ID = 6, - TAG_OBJECT_DESCRIPTOR = 7, - TAG_EXTERNAL = 8, - TAG_REAL = 9, - TAG_ENUMERATED = 10, - TAG_EMBEDDED_PDV = 11, - TAG_UTF8_STRING = 12, - TAG_REALTIVE_OID = 13, - TAG_SEQUENCE = 16, - TAG_SET = 17, - TAG_NUMERIC_STRING = 18, - TAG_PRINTABLE_STRING = 19, - TAG_TELETEX_STRING = 20, - TAG_VIDEOTEX_STRING = 21, - TAG_IA5_STRING = 22, - TAG_UTC_TIME = 23, - TAG_GENERALIZED_TIME = 24, - TAG_GRAPHIC_STRING = 25, - TAG_VISIBLE_STRING = 26, - TAG_GENERAL_STRING = 27, - TAG_UNIVERSAL_STRING = 28, - TAG_CHARACTER_STRING = 29, - TAG_BMP_STRING = 30 -}; - -/* ASN.1 Parser object. */ -struct tag_info -{ - int class; /* Object class. */ - unsigned long tag; /* The tag of the object. */ - unsigned long length; /* Length of the values. */ - int nhdr; /* Length of the header (TL). */ - unsigned int ndef:1; /* The object has an indefinite length. */ - unsigned int cons:1; /* This is a constructed object. */ -}; - - - -/* Print a error message and exit the process with an error code. */ -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format); - fputs (PGM ": ", stderr); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - exit (1); -} - - -static void -showhex (const char *prefix, const void *buffer, size_t length) -{ - const unsigned char *p = buffer; - - if (prefix) - fprintf (stderr, PGM ": %s: ", prefix); - while (length-- ) - fprintf (stderr, "%02X", *p++); - if (prefix) - putc ('\n', stderr); -} - -/* static void */ -/* show_sexp (const char *prefix, gcry_sexp_t a) */ -/* { */ -/* char *buf; */ -/* size_t size; */ - -/* if (prefix) */ -/* fputs (prefix, stderr); */ -/* size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */ -/* buf = gcry_xmalloc (size); */ - -/* gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */ -/* fprintf (stderr, "%.*s", (int)size, buf); */ -/* gcry_free (buf); */ -/* } */ - - -/* Convert STRING consisting of hex characters into its binary - representation and store that at BUFFER. BUFFER needs to be of - LENGTH bytes. The function checks that the STRING will convert - exactly to LENGTH bytes. The string is delimited by either end of - string or a white space character. The function returns -1 on - error or the length of the parsed string. */ -static int -hex2bin (const char *string, void *buffer, size_t length) -{ - int i; - const char *s = string; - - for (i=0; i < length; ) - { - if (!hexdigitp (s) || !hexdigitp (s+1)) - return -1; /* Invalid hex digits. */ - ((unsigned char*)buffer)[i++] = xtoi_2 (s); - s += 2; - } - if (*s && (!my_isascii (*s) || !isspace (*s)) ) - return -1; /* Not followed by Nul or white space. */ - if (i != length) - return -1; /* Not of expected length. */ - if (*s) - s++; /* Skip the delimiter. */ - return s - string; -} - - -/* Convert STRING consisting of hex characters into its binary - representation and return it as an allocated buffer. The valid - length of the buffer is returned at R_LENGTH. The string is - delimited by end of string. The function returns NULL on - error. */ -static void * -hex2buffer (const char *string, size_t *r_length) -{ - const char *s; - unsigned char *buffer; - size_t length; - - buffer = gcry_xmalloc (strlen(string)/2+1); - length = 0; - for (s=string; *s; s +=2 ) - { - if (!hexdigitp (s) || !hexdigitp (s+1)) - return NULL; /* Invalid hex digits. */ - ((unsigned char*)buffer)[length++] = xtoi_2 (s); - } - *r_length = length; - return buffer; -} - - -static char * -read_textline (FILE *fp) -{ - char line[256]; - char *p; - int any = 0; - - /* Read line but skip over initial empty lines. */ - do - { - do - { - if (!fgets (line, sizeof line, fp)) - { - if (feof (fp)) - return NULL; - die ("error reading input line: %s\n", strerror (errno)); - } - p = strchr (line, '\n'); - if (p) - *p = 0; - p = line + (*line? (strlen (line)-1):0); - for ( ;p > line; p--) - if (my_isascii (*p) && isspace (*p)) - *p = 0; - } - while (!any && !*line); - any = 1; - } - while (*line == '#'); /* Always skip comment lines. */ - if (verbose > 1) - fprintf (stderr, PGM ": received line: %s\n", line); - return gcry_xstrdup (line); -} - -static char * -read_hexline (FILE *fp, size_t *retlen) -{ - char *line, *p; - - line = read_textline (fp); - if (!line) - return NULL; - p = hex2buffer (line, retlen); - if (!p) - die ("error decoding hex string on input\n"); - gcry_free (line); - return p; -} - -static void -skip_to_empty_line (FILE *fp) -{ - char line[256]; - char *p; - - do - { - if (!fgets (line, sizeof line, fp)) - { - if (feof (fp)) - return; - die ("error reading input line: %s\n", strerror (errno)); - } - p = strchr (line, '\n'); - if (p) - *p =0; - } - while (*line); -} - - - -/* Read a file from stream FP into a newly allocated buffer and return - that buffer. The valid length of the buffer is stored at R_LENGTH. - Returns NULL on failure. If decode is set, the file is assumed to - be hex encoded and the decoded content is returned. */ -static void * -read_file (FILE *fp, int decode, size_t *r_length) -{ - char *buffer; - size_t buflen; - size_t nread, bufsize = 0; - - *r_length = 0; -#define NCHUNK 8192 -#ifdef HAVE_DOSISH_SYSTEM - setmode (fileno(fp), O_BINARY); -#endif - buffer = NULL; - buflen = 0; - do - { - bufsize += NCHUNK; - if (!buffer) - buffer = gcry_xmalloc (bufsize); - else - buffer = gcry_xrealloc (buffer, bufsize); - - nread = fread (buffer + buflen, 1, NCHUNK, fp); - if (nread < NCHUNK && ferror (fp)) - { - gcry_free (buffer); - return NULL; - } - buflen += nread; - } - while (nread == NCHUNK); -#undef NCHUNK - if (decode) - { - const char *s; - char *p; - - for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 ) - { - if (!hexdigitp (s) || !hexdigitp (s+1)) - { - gcry_free (buffer); - return NULL; /* Invalid hex digits. */ - } - *(unsigned char*)p++ = xtoi_2 (s); - } - if (nread != buflen) - { - gcry_free (buffer); - return NULL; /* Odd number of hex digits. */ - } - buflen = p - buffer; - } - - *r_length = buflen; - return buffer; -} - -/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Returns - the new length of the buffer. Dies on error. */ -static size_t -base64_decode (char *buffer, size_t length) -{ - static unsigned char const asctobin[128] = - { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - int idx = 0; - unsigned char val = 0; - int c = 0; - char *d, *s; - int lfseen = 1; - - /* Find BEGIN line. */ - for (s=buffer; length; length--, s++) - { - if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11)) - { - for (; length && *s != '\n'; length--, s++) - ; - break; - } - lfseen = (*s == '\n'); - } - - /* Decode until pad character or END line. */ - for (d=buffer; length; length--, s++) - { - if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9)) - break; - if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t') - continue; - if (*s == '=') - { - /* Pad character: stop */ - if (idx == 1) - *d++ = val; - break; - } - - if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff) - die ("invalid base64 character %02X at pos %d detected\n", - *(unsigned char*)s, (int)(s-buffer)); - - switch (idx) - { - case 0: - val = c << 2; - break; - case 1: - val |= (c>>4)&3; - *d++ = val; - val = (c<<4)&0xf0; - break; - case 2: - val |= (c>>2)&15; - *d++ = val; - val = (c<<6)&0xc0; - break; - case 3: - val |= c&0x3f; - *d++ = val; - break; - } - idx = (idx+1) % 4; - } - - return d - buffer; -} - - -/* Parse the buffer at the address BUFFER which consists of the number - of octets as stored at BUFLEN. Return the tag and the length part - from the TLV triplet. Update BUFFER and BUFLEN on success. Checks - that the encoded length does not exhaust the length of the provided - buffer. */ -static int -parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti) -{ - int c; - unsigned long tag; - const unsigned char *buf = *buffer; - size_t length = *buflen; - - ti->length = 0; - ti->ndef = 0; - ti->nhdr = 0; - - /* Get the tag */ - if (!length) - return -1; /* Premature EOF. */ - c = *buf++; length--; - ti->nhdr++; - - ti->class = (c & 0xc0) >> 6; - ti->cons = !!(c & 0x20); - tag = (c & 0x1f); - - if (tag == 0x1f) - { - tag = 0; - do - { - tag <<= 7; - if (!length) - return -1; /* Premature EOF. */ - c = *buf++; length--; - ti->nhdr++; - tag |= (c & 0x7f); - } - while ( (c & 0x80) ); - } - ti->tag = tag; - - /* Get the length */ - if (!length) - return -1; /* Premature EOF. */ - c = *buf++; length--; - ti->nhdr++; - - if ( !(c & 0x80) ) - ti->length = c; - else if (c == 0x80) - ti->ndef = 1; - else if (c == 0xff) - return -1; /* Forbidden length value. */ - else - { - unsigned long len = 0; - int count = c & 0x7f; - - for (; count; count--) - { - len <<= 8; - if (!length) - return -1; /* Premature EOF. */ - c = *buf++; length--; - ti->nhdr++; - len |= (c & 0xff); - } - ti->length = len; - } - - if (ti->class == UNIVERSAL && !ti->tag) - ti->length = 0; - - if (ti->length > length) - return -1; /* Data larger than buffer. */ - - *buffer = buf; - *buflen = length; - return 0; -} - - -/* Read the file FNAME assuming it is a PEM encoded private key file - and return an S-expression. With SHOW set, the key parameters are - printed. */ -static gcry_sexp_t -read_private_key_file (const char *fname, int show) -{ - gcry_error_t err; - FILE *fp; - char *buffer; - size_t buflen; - const unsigned char *der; - size_t derlen; - struct tag_info ti; - gcry_mpi_t keyparms[8]; - int n_keyparms = 8; - int idx; - gcry_sexp_t s_key; - - fp = fopen (fname, binary_input?"rb":"r"); - if (!fp) - die ("can't open `%s': %s\n", fname, strerror (errno)); - buffer = read_file (fp, 0, &buflen); - if (!buffer) - die ("error reading `%s'\n", fname); - fclose (fp); - - buflen = base64_decode (buffer, buflen); - - /* Parse the ASN.1 structure. */ - der = (const unsigned char*)buffer; - derlen = buflen; - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) - goto bad_asn1; - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) - goto bad_asn1; - if (ti.length != 1 || *der) - goto bad_asn1; /* The value of the first integer is no 0. */ - der += ti.length; derlen -= ti.length; - - for (idx=0; idx < n_keyparms; idx++) - { - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) - goto bad_asn1; - if (show) - { - char prefix[2]; - - prefix[0] = idx < 8? "nedpq12u"[idx] : '?'; - prefix[1] = 0; - showhex (prefix, der, ti.length); - } - err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL); - if (err) - die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err)); - der += ti.length; derlen -= ti.length; - } - if (idx != n_keyparms) - die ("not enough RSA key parameters\n"); - - gcry_free (buffer); - - /* Convert from OpenSSL parameter ordering to the OpenPGP order. */ - /* First check that p < q; if not swap p and q and recompute u. */ - if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) - { - gcry_mpi_swap (keyparms[3], keyparms[4]); - gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]); - } - - /* Build the S-expression. */ - err = gcry_sexp_build (&s_key, NULL, - "(private-key(rsa(n%m)(e%m)" - /**/ "(d%m)(p%m)(q%m)(u%m)))", - keyparms[0], keyparms[1], keyparms[2], - keyparms[3], keyparms[4], keyparms[7] ); - if (err) - die ("error building S-expression: %s\n", gpg_strerror (err)); - - for (idx=0; idx < n_keyparms; idx++) - gcry_mpi_release (keyparms[idx]); - - return s_key; - - bad_asn1: - die ("invalid ASN.1 structure in `%s'\n", fname); - return NULL; /*NOTREACHED*/ -} - - -/* Read the file FNAME assuming it is a PEM encoded public key file - and return an S-expression. With SHOW set, the key parameters are - printed. */ -static gcry_sexp_t -read_public_key_file (const char *fname, int show) -{ - gcry_error_t err; - FILE *fp; - char *buffer; - size_t buflen; - const unsigned char *der; - size_t derlen; - struct tag_info ti; - gcry_mpi_t keyparms[2]; - int n_keyparms = 2; - int idx; - gcry_sexp_t s_key; - - fp = fopen (fname, binary_input?"rb":"r"); - if (!fp) - die ("can't open `%s': %s\n", fname, strerror (errno)); - buffer = read_file (fp, 0, &buflen); - if (!buffer) - die ("error reading `%s'\n", fname); - fclose (fp); - - buflen = base64_decode (buffer, buflen); - - /* Parse the ASN.1 structure. */ - der = (const unsigned char*)buffer; - derlen = buflen; - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) - goto bad_asn1; - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) - goto bad_asn1; - /* We skip the description of the key parameters and assume it is RSA. */ - der += ti.length; derlen -= ti.length; - - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef) - goto bad_asn1; - if (ti.length < 1 || *der) - goto bad_asn1; /* The number of unused bits needs to be 0. */ - der += 1; derlen -= 1; - - /* Parse the BIT string. */ - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) - goto bad_asn1; - - for (idx=0; idx < n_keyparms; idx++) - { - if ( parse_tag (&der, &derlen, &ti) - || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) - goto bad_asn1; - if (show) - { - char prefix[2]; - - prefix[0] = idx < 2? "ne"[idx] : '?'; - prefix[1] = 0; - showhex (prefix, der, ti.length); - } - err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL); - if (err) - die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err)); - der += ti.length; derlen -= ti.length; - } - if (idx != n_keyparms) - die ("not enough RSA key parameters\n"); - - gcry_free (buffer); - - /* Build the S-expression. */ - err = gcry_sexp_build (&s_key, NULL, - "(public-key(rsa(n%m)(e%m)))", - keyparms[0], keyparms[1] ); - if (err) - die ("error building S-expression: %s\n", gpg_strerror (err)); - - for (idx=0; idx < n_keyparms; idx++) - gcry_mpi_release (keyparms[idx]); - - return s_key; - - bad_asn1: - die ("invalid ASN.1 structure in `%s'\n", fname); - return NULL; /*NOTREACHED*/ -} - - - -/* Read the file FNAME assuming it is a binary signature result and - return an an S-expression suitable for gcry_pk_verify. */ -static gcry_sexp_t -read_sig_file (const char *fname) -{ - gcry_error_t err; - FILE *fp; - char *buffer; - size_t buflen; - gcry_mpi_t tmpmpi; - gcry_sexp_t s_sig; - - fp = fopen (fname, "rb"); - if (!fp) - die ("can't open `%s': %s\n", fname, strerror (errno)); - buffer = read_file (fp, 0, &buflen); - if (!buffer) - die ("error reading `%s'\n", fname); - fclose (fp); - - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL); - if (!err) - err = gcry_sexp_build (&s_sig, NULL, - "(sig-val(rsa(s %m)))", tmpmpi); - if (err) - die ("error building S-expression: %s\n", gpg_strerror (err)); - gcry_mpi_release (tmpmpi); - gcry_free (buffer); - - return s_sig; -} - - -/* Read an S-expression from FNAME. */ -static gcry_sexp_t -read_sexp_from_file (const char *fname) -{ - gcry_error_t err; - FILE *fp; - char *buffer; - size_t buflen; - gcry_sexp_t sexp; - - fp = fopen (fname, "rb"); - if (!fp) - die ("can't open `%s': %s\n", fname, strerror (errno)); - buffer = read_file (fp, 0, &buflen); - if (!buffer) - die ("error reading `%s'\n", fname); - fclose (fp); - if (!buflen) - die ("error: file `%s' is empty\n", fname); - - err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free); - if (err) - die ("error parsing `%s': %s\n", fname, gpg_strerror (err)); - - return sexp; -} - - -static void -print_buffer (const void *buffer, size_t length) -{ - int writerr = 0; - - if (base64_output) - { - static const unsigned char bintoasc[64+1] = - ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"); - const unsigned char *p; - unsigned char inbuf[4]; - char outbuf[4]; - int idx, quads; - - idx = quads = 0; - for (p = buffer; length; p++, length--) - { - inbuf[idx++] = *p; - if (idx > 2) - { - outbuf[0] = bintoasc[(*inbuf>>2)&077]; - outbuf[1] = bintoasc[(((*inbuf<<4)&060) - |((inbuf[1] >> 4)&017))&077]; - outbuf[2] = bintoasc[(((inbuf[1]<<2)&074) - |((inbuf[2]>>6)&03))&077]; - outbuf[3] = bintoasc[inbuf[2]&077]; - if (fwrite (outbuf, 4, 1, stdout) != 1) - writerr = 1; - idx = 0; - if (++quads >= (64/4)) - { - if (fwrite ("\n", 1, 1, stdout) != 1) - writerr = 1; - quads = 0; - } - } - } - if (idx) - { - outbuf[0] = bintoasc[(*inbuf>>2)&077]; - if (idx == 1) - { - outbuf[1] = bintoasc[((*inbuf<<4)&060)&077]; - outbuf[2] = outbuf[3] = '='; - } - else - { - outbuf[1] = bintoasc[(((*inbuf<<4)&060) - |((inbuf[1]>>4)&017))&077]; - outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077]; - outbuf[3] = '='; - } - if (fwrite (outbuf, 4, 1, stdout) != 1) - writerr = 1; - quads++; - } - if (quads && fwrite ("\n", 1, 1, stdout) != 1) - writerr = 1; - } - else if (binary_output) - { - if (fwrite (buffer, length, 1, stdout) != 1) - writerr++; - } - else - { - const unsigned char *p = buffer; - - if (verbose > 1) - showhex ("sent line", buffer, length); - while (length-- && !ferror (stdout) ) - printf ("%02X", *p++); - if (ferror (stdout)) - writerr++; - } - if (!writerr && fflush (stdout) == EOF) - writerr++; - if (writerr) - { -#ifndef HAVE_W32_SYSTEM - if (loop_mode && errno == EPIPE) - loop_mode = 0; - else -#endif - die ("writing output failed: %s\n", strerror (errno)); - } -} - - -/* Print an MPI on a line. */ -static void -print_mpi_line (gcry_mpi_t a, int no_lz) -{ - unsigned char *buf, *p; - gcry_error_t err; - int writerr = 0; - - err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); - if (err) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - - p = buf; - if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p += 2; - - printf ("%s\n", p); - if (ferror (stdout)) - writerr++; - if (!writerr && fflush (stdout) == EOF) - writerr++; - if (writerr) - die ("writing output failed: %s\n", strerror (errno)); - gcry_free (buf); -} - - -/* Print some data on hex format on a line. */ -static void -print_data_line (const void *data, size_t datalen) -{ - const unsigned char *p = data; - int writerr = 0; - - while (data && datalen-- && !ferror (stdout) ) - printf ("%02X", *p++); - putchar ('\n'); - if (ferror (stdout)) - writerr++; - if (!writerr && fflush (stdout) == EOF) - writerr++; - if (writerr) - die ("writing output failed: %s\n", strerror (errno)); -} - -/* Print the S-expression A to the stream FP. */ -static void -print_sexp (gcry_sexp_t a, FILE *fp) -{ - char *buf; - size_t size; - - size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); - buf = gcry_xmalloc (size); - gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); - if (fwrite (buf, size, 1, fp) != 1) - die ("error writing to stream: %s\n", strerror (errno)); - gcry_free (buf); -} - - - - -static gcry_error_t -init_external_rng_test (void **r_context, - unsigned int flags, - const void *key, size_t keylen, - const void *seed, size_t seedlen, - const void *dt, size_t dtlen) -{ - return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST, - r_context, flags, - key, keylen, - seed, seedlen, - dt, dtlen); -} - -static gcry_error_t -run_external_rng_test (void *context, void *buffer, size_t buflen) -{ - return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen); -} - -static void -deinit_external_rng_test (void *context) -{ - gcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context); -} - - -/* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm - identified and store the libgcrypt mode at R_MODE. Returns 0 on - error. */ -static int -map_openssl_cipher_name (const char *name, int *r_mode) -{ - static struct { - const char *name; - int algo; - int mode; - } table[] = - { - { "bf-cbc", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC }, - { "bf", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC }, - { "bf-cfb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB }, - { "bf-ecb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB }, - { "bf-ofb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB }, - - { "cast-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, - { "cast", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, - { "cast5-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, - { "cast5-cfb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB }, - { "cast5-ecb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB }, - { "cast5-ofb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB }, - - { "des-cbc", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC }, - { "des", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC }, - { "des-cfb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB }, - { "des-ofb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB }, - { "des-ecb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB }, - - { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC }, - { "des-ede3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB }, - { "des3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC }, - { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB }, - { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB }, - - { "rc4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM }, - - { "aes-128-cbc", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC }, - { "aes-128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC }, - { "aes-128-cfb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB }, - { "aes-128-ecb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB }, - { "aes-128-ofb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB }, - - { "aes-192-cbc", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC }, - { "aes-192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC }, - { "aes-192-cfb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB }, - { "aes-192-ecb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB }, - { "aes-192-ofb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB }, - - { "aes-256-cbc", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC }, - { "aes-256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC }, - { "aes-256-cfb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB }, - { "aes-256-ecb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB }, - { "aes-256-ofb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB }, - - { NULL, 0 , 0 } - }; - int idx; - - for (idx=0; table[idx].name; idx++) - if (!strcmp (name, table[idx].name)) - { - *r_mode = table[idx].mode; - return table[idx].algo; - } - *r_mode = 0; - return 0; -} - - - -/* Run an encrypt or decryption operations. If DATA is NULL the - function reads its input in chunks of size DATALEN from fp and - processes it and writes it out until EOF. */ -static void -run_encrypt_decrypt (int encrypt_mode, - int cipher_algo, int cipher_mode, - const void *iv_buffer, size_t iv_buflen, - const void *key_buffer, size_t key_buflen, - const void *data, size_t datalen, FILE *fp) -{ - gpg_error_t err; - gcry_cipher_hd_t hd; - void *outbuf; - size_t outbuflen; - void *inbuf; - size_t inbuflen; - size_t blocklen; - - err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0); - if (err) - die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", - cipher_algo, cipher_mode, gpg_strerror (err)); - - blocklen = gcry_cipher_get_algo_blklen (cipher_algo); - assert (blocklen); - - gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0); - - err = gcry_cipher_setkey (hd, key_buffer, key_buflen); - if (err) - die ("gcry_cipher_setkey failed with keylen %u: %s\n", - (unsigned int)key_buflen, gpg_strerror (err)); - - if (iv_buffer) - { - err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen); - if (err) - die ("gcry_cipher_setiv failed with ivlen %u: %s\n", - (unsigned int)iv_buflen, gpg_strerror (err)); - } - - inbuf = data? NULL : gcry_xmalloc (datalen); - outbuflen = datalen; - outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen); - - do - { - if (inbuf) - { - int nread = fread (inbuf, 1, datalen, fp); - if (nread < (int)datalen && ferror (fp)) - die ("error reading input\n"); - data = inbuf; - inbuflen = nread; - } - else - inbuflen = datalen; - - if (encrypt_mode) - err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen); - else - err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen); - if (err) - die ("gcry_cipher_%scrypt failed: %s\n", - encrypt_mode? "en":"de", gpg_strerror (err)); - - print_buffer (outbuf, outbuflen); - } - while (inbuf); - - gcry_cipher_close (hd); - gcry_free (outbuf); - gcry_free (inbuf); -} - - -static void -get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen) -{ - unsigned char tmp[17]; - - if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR, tmp, sizeof tmp)) - die ("error getting current input vector\n"); - if (buflen > *tmp) - die ("buffer too short to store the current input vector\n"); - memcpy (buffer, tmp+1, *tmp); -} - -/* Run the inner loop of the CAVS monte carlo test. */ -static void -run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode, - const void *iv_buffer, size_t iv_buflen, - const void *key_buffer, size_t key_buflen, - const void *data, size_t datalen, int iterations) -{ - gpg_error_t err; - gcry_cipher_hd_t hd; - size_t blocklen; - int count; - char input[16]; - char output[16]; - char last_output[16]; - char last_last_output[16]; - char last_iv[16]; - - - err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0); - if (err) - die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", - cipher_algo, cipher_mode, gpg_strerror (err)); - - blocklen = gcry_cipher_get_algo_blklen (cipher_algo); - if (!blocklen || blocklen > sizeof output) - die ("invalid block length %d\n", blocklen); - - - gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0); - - err = gcry_cipher_setkey (hd, key_buffer, key_buflen); - if (err) - die ("gcry_cipher_setkey failed with keylen %u: %s\n", - (unsigned int)key_buflen, gpg_strerror (err)); - - if (iv_buffer) - { - err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen); - if (err) - die ("gcry_cipher_setiv failed with ivlen %u: %s\n", - (unsigned int)iv_buflen, gpg_strerror (err)); - } - - if (datalen != blocklen) - die ("length of input (%u) does not match block length (%u)\n", - (unsigned int)datalen, (unsigned int)blocklen); - memcpy (input, data, datalen); - memset (output, 0, sizeof output); - for (count=0; count < iterations; count++) - { - memcpy (last_last_output, last_output, sizeof last_output); - memcpy (last_output, output, sizeof output); - - get_current_iv (hd, last_iv, blocklen); - - if (encrypt_mode) - err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen); - else - err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen); - if (err) - die ("gcry_cipher_%scrypt failed: %s\n", - encrypt_mode? "en":"de", gpg_strerror (err)); - - - if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB - || cipher_mode == GCRY_CIPHER_MODE_CBC)) - memcpy (input, last_iv, blocklen); - else if (cipher_mode == GCRY_CIPHER_MODE_OFB) - memcpy (input, last_iv, blocklen); - else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) - { - /* Reconstruct the output vector. */ - int i; - for (i=0; i < blocklen; i++) - input[i] ^= output[i]; - } - else - memcpy (input, output, blocklen); - } - - print_buffer (output, blocklen); - putchar ('\n'); - print_buffer (last_output, blocklen); - putchar ('\n'); - print_buffer (last_last_output, blocklen); - putchar ('\n'); - get_current_iv (hd, last_iv, blocklen); - print_buffer (last_iv, blocklen); /* Last output vector. */ - putchar ('\n'); - print_buffer (input, blocklen); /* Next input text. */ - putchar ('\n'); - if (verbose > 1) - showhex ("sent line", "", 0); - putchar ('\n'); - fflush (stdout); - - gcry_cipher_close (hd); -} - - - -/* Run a digest operation. */ -static void -run_digest (int digest_algo, const void *data, size_t datalen) -{ - gpg_error_t err; - gcry_md_hd_t hd; - const unsigned char *digest; - unsigned int digestlen; - - err = gcry_md_open (&hd, digest_algo, 0); - if (err) - die ("gcry_md_open failed for algo %d: %s\n", - digest_algo, gpg_strerror (err)); - - gcry_md_write (hd, data, datalen); - digest = gcry_md_read (hd, digest_algo); - digestlen = gcry_md_get_algo_dlen (digest_algo); - print_buffer (digest, digestlen); - gcry_md_close (hd); -} - - -/* Run a HMAC operation. */ -static void -run_hmac (int digest_algo, const void *key, size_t keylen, - const void *data, size_t datalen) -{ - gpg_error_t err; - gcry_md_hd_t hd; - const unsigned char *digest; - unsigned int digestlen; - - err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC); - if (err) - die ("gcry_md_open failed for HMAC algo %d: %s\n", - digest_algo, gpg_strerror (err)); - - gcry_md_setkey (hd, key, keylen); - if (err) - die ("gcry_md_setkey failed for HMAC algo %d: %s\n", - digest_algo, gpg_strerror (err)); - - gcry_md_write (hd, data, datalen); - digest = gcry_md_read (hd, digest_algo); - digestlen = gcry_md_get_algo_dlen (digest_algo); - print_buffer (digest, digestlen); - gcry_md_close (hd); -} - - - -/* Derive an RSA key using the S-expression in (DATA,DATALEN). This - S-expression is used directly as input to gcry_pk_genkey. The - result is printed to stdout with one parameter per line in hex - format and in this order: p, q, n, d. */ -static void -run_rsa_derive (const void *data, size_t datalen) -{ - gpg_error_t err; - gcry_sexp_t s_keyspec, s_key, s_top, l1; - gcry_mpi_t mpi; - const char *parmlist; - int idx; - - if (!datalen) - err = gpg_error (GPG_ERR_NO_DATA); - else - err = gcry_sexp_new (&s_keyspec, data, datalen, 1); - if (err) - die ("gcry_sexp_new failed for RSA key derive: %s\n", - gpg_strerror (err)); - - err = gcry_pk_genkey (&s_key, s_keyspec); - if (err) - die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (s_keyspec); - - /* P and Q might have been swapped but we need to to return them in - the proper order. Build the parameter list accordingly. */ - parmlist = "pqnd"; - s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0); - if (s_top) - { - l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0); - if (l1) - parmlist = "qpnd"; - gcry_sexp_release (l1); - gcry_sexp_release (s_top); - } - - /* Parse and print the parameters. */ - l1 = gcry_sexp_find_token (s_key, "private-key", 0); - s_top = gcry_sexp_find_token (l1, "rsa", 0); - gcry_sexp_release (l1); - if (!s_top) - die ("private-key part not found in result\n"); - - for (idx=0; parmlist[idx]; idx++) - { - l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); - mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l1); - if (!mpi) - die ("parameter %c missing in private-key\n", parmlist[idx]); - print_mpi_line (mpi, 1); - gcry_mpi_release (mpi); - } - - gcry_sexp_release (s_top); - gcry_sexp_release (s_key); -} - - - -static size_t -compute_tag_length (size_t n) -{ - int needed = 0; - - if (n < 128) - needed += 2; /* Tag and one length byte. */ - else if (n < 256) - needed += 3; /* Tag, number of length bytes, 1 length byte. */ - else if (n < 65536) - needed += 4; /* Tag, number of length bytes, 2 length bytes. */ - else - die ("DER object too long to encode\n"); - - return needed; -} - -static unsigned char * -store_tag_length (unsigned char *p, int tag, size_t n) -{ - if (tag == TAG_SEQUENCE) - tag |= 0x20; /* constructed */ - - *p++ = tag; - if (n < 128) - *p++ = n; - else if (n < 256) - { - *p++ = 0x81; - *p++ = n; - } - else if (n < 65536) - { - *p++ = 0x82; - *p++ = n >> 8; - *p++ = n; - } - - return p; -} - - -/* Generate an RSA key of size KEYSIZE using the public exponent - PUBEXP and print it to stdout in the OpenSSL format. The format - is: - - SEQUENCE { - INTEGER (0) -- Unknown constant. - INTEGER -- n - INTEGER -- e - INTEGER -- d - INTEGER -- p - INTEGER -- q (with p < q) - INTEGER -- dmp1 = d mod (p-1) - INTEGER -- dmq1 = d mod (q-1) - INTEGER -- u = p^{-1} mod q - } - -*/ -static void -run_rsa_gen (int keysize, int pubexp) -{ - gpg_error_t err; - gcry_sexp_t keyspec, key, l1; - const char keyelems[] = "nedpq..u"; - gcry_mpi_t keyparms[8]; - size_t keyparmslen[8]; - int idx; - size_t derlen, needed, n; - unsigned char *derbuf, *der; - - err = gcry_sexp_build (&keyspec, NULL, - "(genkey (rsa (nbits %d)(rsa-use-e %d)))", - keysize, pubexp); - if (err) - die ("gcry_sexp_build failed for RSA key generation: %s\n", - gpg_strerror (err)); - - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - - l1 = gcry_sexp_find_token (key, "private-key", 0); - if (!l1) - die ("private key not found in genkey result\n"); - gcry_sexp_release (key); - key = l1; - - l1 = gcry_sexp_find_token (key, "rsa", 0); - if (!l1) - die ("returned private key not formed as expected\n"); - gcry_sexp_release (key); - key = l1; - - /* Extract the parameters from the S-expression and store them in a - well defined order in KEYPARMS. */ - for (idx=0; idx < DIM(keyparms); idx++) - { - if (keyelems[idx] == '.') - { - keyparms[idx] = gcry_mpi_new (0); - continue; - } - l1 = gcry_sexp_find_token (key, keyelems+idx, 1); - if (!l1) - die ("no %c parameter in returned private key\n", keyelems[idx]); - keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); - if (!keyparms[idx]) - die ("no value for %c parameter in returned private key\n", - keyelems[idx]); - gcry_sexp_release (l1); - } - - gcry_sexp_release (key); - - /* Check that p < q; if not swap p and q and recompute u. */ - if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) - { - gcry_mpi_swap (keyparms[3], keyparms[4]); - gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]); - } - - /* Compute the additional parameters. */ - gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1); - gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]); - gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1); - gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]); - - /* Compute the length of the DER encoding. */ - needed = compute_tag_length (1) + 1; - for (idx=0; idx < DIM(keyparms); idx++) - { - err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]); - if (err) - die ("error formatting parameter: %s\n", gpg_strerror (err)); - keyparmslen[idx] = n; - needed += compute_tag_length (n) + n; - } - - /* Store the key parameters. */ - derlen = compute_tag_length (needed) + needed; - der = derbuf = gcry_xmalloc (derlen); - - der = store_tag_length (der, TAG_SEQUENCE, needed); - der = store_tag_length (der, TAG_INTEGER, 1); - *der++ = 0; - for (idx=0; idx < DIM(keyparms); idx++) - { - der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]); - err = gcry_mpi_print (GCRYMPI_FMT_STD, der, - keyparmslen[idx], NULL, keyparms[idx]); - if (err) - die ("error formatting parameter: %s\n", gpg_strerror (err)); - der += keyparmslen[idx]; - } - - /* Print the stuff. */ - for (idx=0; idx < DIM(keyparms); idx++) - gcry_mpi_release (keyparms[idx]); - - assert (der - derbuf == derlen); - - if (base64_output) - puts ("-----BEGIN RSA PRIVATE KEY-----"); - print_buffer (derbuf, derlen); - if (base64_output) - puts ("-----END RSA PRIVATE KEY-----"); - - gcry_free (derbuf); -} - - - -/* Sign DATA of length DATALEN using the key taken from the PEM - encoded KEYFILE and the hash algorithm HASHALGO. */ -static void -run_rsa_sign (const void *data, size_t datalen, - int hashalgo, int pkcs1, const char *keyfile) - -{ - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp; - gcry_mpi_t sig_mpi = NULL; - unsigned char *outbuf; - size_t outlen; - -/* showhex ("D", data, datalen); */ - if (pkcs1) - { - unsigned char hash[64]; - unsigned int hashsize; - - hashsize = gcry_md_get_algo_dlen (hashalgo); - if (!hashsize || hashsize > sizeof hash) - die ("digest too long for buffer or unknown hash algorithm\n"); - gcry_md_hash_buffer (hashalgo, hash, data, datalen); - err = gcry_sexp_build (&s_data, NULL, - "(data (flags pkcs1)(hash %s %b))", - gcry_md_algo_name (hashalgo), - (int)hashsize, hash); - } - else - { - gcry_mpi_t tmp; - - err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, - "(data (flags raw)(value %m))", tmp); - gcry_mpi_release (tmp); - } - } - if (err) - die ("gcry_sexp_build failed for RSA data input: %s\n", - gpg_strerror (err)); - - s_key = read_private_key_file (keyfile, 0); - - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { - gcry_sexp_release (read_private_key_file (keyfile, 1)); - die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", - (int)datalen, keyfile, gpg_strerror (err)); - } - gcry_sexp_release (s_key); - gcry_sexp_release (s_data); - - s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); - if (s_tmp) - { - gcry_sexp_release (s_sig); - s_sig = s_tmp; - s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0); - if (s_tmp) - { - gcry_sexp_release (s_sig); - s_sig = s_tmp; - s_tmp = gcry_sexp_find_token (s_sig, "s", 0); - if (s_tmp) - { - gcry_sexp_release (s_sig); - s_sig = s_tmp; - sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG); - } - } - } - gcry_sexp_release (s_sig); - - if (!sig_mpi) - die ("no value in returned S-expression\n"); - err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi); - if (err) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (sig_mpi); - - print_buffer (outbuf, outlen); - gcry_free (outbuf); -} - - - -/* Verify DATA of length DATALEN using the public key taken from the - PEM encoded KEYFILE and the hash algorithm HASHALGO against the - binary signature in SIGFILE. */ -static void -run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1, - const char *keyfile, const char *sigfile) - -{ - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; - - if (pkcs1) - { - unsigned char hash[64]; - unsigned int hashsize; - - hashsize = gcry_md_get_algo_dlen (hashalgo); - if (!hashsize || hashsize > sizeof hash) - die ("digest too long for buffer or unknown hash algorithm\n"); - gcry_md_hash_buffer (hashalgo, hash, data, datalen); - err = gcry_sexp_build (&s_data, NULL, - "(data (flags pkcs1)(hash %s %b))", - gcry_md_algo_name (hashalgo), - (int)hashsize, hash); - } - else - { - gcry_mpi_t tmp; - - err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, - "(data (flags raw)(value %m))", tmp); - gcry_mpi_release (tmp); - } - } - if (err) - die ("gcry_sexp_build failed for RSA data input: %s\n", - gpg_strerror (err)); - - s_key = read_public_key_file (keyfile, 0); - - s_sig = read_sig_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); - if (!err) - puts ("GOOD signature"); - else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) - puts ("BAD signature"); - else - printf ("ERROR (%s)\n", gpg_strerror (err)); - - gcry_sexp_release (s_sig); - gcry_sexp_release (s_key); - gcry_sexp_release (s_data); -} - - - -/* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ -static gcry_sexp_t -dsa_gen (int keysize) -{ - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, - "(genkey (dsa (nbits %d)(use-fips186-2)))", - keysize); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); - - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - - return key; -} - - -/* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ -static gcry_sexp_t -dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) -{ - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, - "(genkey" - " (dsa" - " (nbits %d)" - " (use-fips186-2)" - " (derive-parms" - " (seed %b))))", - keysize, (int)seedlen, seed); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); - - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - - return key; -} - - -/* Print the domain parameter as well as the derive information. KEY - is the complete key as returned by dsa_gen. We print to stdout - with one parameter per line in hex format using this order: p, q, - g, seed, counter, h. */ -static void -print_dsa_domain_parameters (gcry_sexp_t key) -{ - gcry_sexp_t l1, l2; - gcry_mpi_t mpi; - int idx; - const void *data; - size_t datalen; - char *string; - - l1 = gcry_sexp_find_token (key, "public-key", 0); - if (!l1) - die ("public key not found in genkey result\n"); - - l2 = gcry_sexp_find_token (l1, "dsa", 0); - if (!l2) - die ("returned public key not formed as expected\n"); - gcry_sexp_release (l1); - l1 = l2; - - /* Extract the parameters from the S-expression and print them to stdout. */ - for (idx=0; "pqg"[idx]; idx++) - { - l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1); - if (!l2) - die ("no %c parameter in returned public key\n", "pqg"[idx]); - mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - if (!mpi) - die ("no value for %c parameter in returned public key\n","pqg"[idx]); - gcry_sexp_release (l2); - if (standalone_mode) - printf ("%c = ", "PQG"[idx]); - print_mpi_line (mpi, 1); - gcry_mpi_release (mpi); - } - gcry_sexp_release (l1); - - /* Extract the seed values. */ - l1 = gcry_sexp_find_token (key, "misc-key-info", 0); - if (!l1) - die ("misc-key-info not found in genkey result\n"); - - l2 = gcry_sexp_find_token (l1, "seed-values", 0); - if (!l2) - die ("no seed-values in returned key\n"); - gcry_sexp_release (l1); - l1 = l2; - - l2 = gcry_sexp_find_token (l1, "seed", 0); - if (!l2) - die ("no seed value in returned key\n"); - data = gcry_sexp_nth_data (l2, 1, &datalen); - if (!data) - die ("no seed value in returned key\n"); - if (standalone_mode) - printf ("Seed = "); - print_data_line (data, datalen); - gcry_sexp_release (l2); - - l2 = gcry_sexp_find_token (l1, "counter", 0); - if (!l2) - die ("no counter value in returned key\n"); - string = gcry_sexp_nth_string (l2, 1); - if (!string) - die ("no counter value in returned key\n"); - if (standalone_mode) - printf ("c = %ld\n", strtoul (string, NULL, 10)); - else - printf ("%lX\n", strtoul (string, NULL, 10)); - gcry_free (string); - gcry_sexp_release (l2); - - l2 = gcry_sexp_find_token (l1, "h", 0); - if (!l2) - die ("no n value in returned key\n"); - mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - if (!mpi) - die ("no h value in returned key\n"); - if (standalone_mode) - printf ("H = "); - print_mpi_line (mpi, 1); - gcry_mpi_release (mpi); - gcry_sexp_release (l2); - - gcry_sexp_release (l1); -} - - -/* Generate DSA domain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex - format and in this order: p, q, g, seed, counter, h. If SEED is - not NULL this seed value will be used for the generation. */ -static void -run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) -{ - gcry_sexp_t key; - - if (seed) - key = dsa_gen_with_seed (keysize, seed, seedlen); - else - key = dsa_gen (keysize); - print_dsa_domain_parameters (key); - gcry_sexp_release (key); -} - - -/* Generate a DSA key of size of KEYSIZE and write the private key to - FILENAME. Also write the parameters to stdout in the same way as - run_dsa_pqg_gen. */ -static void -run_dsa_gen (int keysize, const char *filename) -{ - gcry_sexp_t key, private_key; - FILE *fp; - - key = dsa_gen (keysize); - private_key = gcry_sexp_find_token (key, "private-key", 0); - if (!private_key) - die ("private key not found in genkey result\n"); - print_dsa_domain_parameters (key); - - fp = fopen (filename, "wb"); - if (!fp) - die ("can't create `%s': %s\n", filename, strerror (errno)); - print_sexp (private_key, fp); - fclose (fp); - - gcry_sexp_release (private_key); - gcry_sexp_release (key); -} - - - -/* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ -static void -run_dsa_sign (const void *data, size_t datalen, const char *keyfile) - -{ - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; - char hash[20]; - gcry_mpi_t tmpmpi; - - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, - "(data (flags raw)(value %m))", tmpmpi); - gcry_mpi_release (tmpmpi); - } - if (err) - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - - s_key = read_sexp_from_file (keyfile); - - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { - gcry_sexp_release (read_private_key_file (keyfile, 1)); - die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", - (int)datalen, keyfile, gpg_strerror (err)); - } - gcry_sexp_release (s_data); - - /* We need to return the Y parameter first. */ - s_tmp = gcry_sexp_find_token (s_key, "private-key", 0); - if (!s_tmp) - die ("private key part not found in provided key\n"); - - s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0); - if (!s_tmp2) - die ("private key part is not a DSA key\n"); - gcry_sexp_release (s_tmp); - - s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0); - tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); - if (!tmpmpi) - die ("no y parameter in DSA key\n"); - print_mpi_line (tmpmpi, 1); - gcry_mpi_release (tmpmpi); - gcry_sexp_release (s_tmp); - - gcry_sexp_release (s_key); - - - /* Now return the actual signature. */ - s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); - if (!s_tmp) - die ("no sig-val element in returned S-expression\n"); - - gcry_sexp_release (s_sig); - s_sig = s_tmp; - s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0); - if (!s_tmp) - die ("no dsa element in returned S-expression\n"); - - gcry_sexp_release (s_sig); - s_sig = s_tmp; - - s_tmp = gcry_sexp_find_token (s_sig, "r", 0); - tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); - if (!tmpmpi) - die ("no r parameter in returned S-expression\n"); - print_mpi_line (tmpmpi, 1); - gcry_mpi_release (tmpmpi); - gcry_sexp_release (s_tmp); - - s_tmp = gcry_sexp_find_token (s_sig, "s", 0); - tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); - if (!tmpmpi) - die ("no s parameter in returned S-expression\n"); - print_mpi_line (tmpmpi, 1); - gcry_mpi_release (tmpmpi); - gcry_sexp_release (s_tmp); - - gcry_sexp_release (s_sig); -} - - - -/* Verify DATA of length DATALEN using the public key taken from the - S-expression in KEYFILE against the S-expression formatted - signature in SIGFILE. */ -static void -run_dsa_verify (const void *data, size_t datalen, - const char *keyfile, const char *sigfile) - -{ - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; - char hash[20]; - gcry_mpi_t tmpmpi; - - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, - "(data (flags raw)(value %m))", tmpmpi); - gcry_mpi_release (tmpmpi); - } - if (err) - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - - s_key = read_sexp_from_file (keyfile); - s_sig = read_sexp_from_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); - if (!err) - puts ("GOOD signature"); - else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) - puts ("BAD signature"); - else - printf ("ERROR (%s)\n", gpg_strerror (err)); - - gcry_sexp_release (s_sig); - gcry_sexp_release (s_key); - gcry_sexp_release (s_data); -} - - - - -static void -usage (int show_help) -{ - if (!show_help) - { - fputs ("usage: " PGM - " [OPTION] [FILE] (try --help for more information)\n", stderr); - exit (2); - } - fputs - ("Usage: " PGM " [OPTIONS] MODE [FILE]\n" - "Run a crypto operation using hex encoded input and output.\n" - "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha,\n" - " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" - "OPTIONS:\n" - " --verbose Print additional information\n" - " --binary Input and output is in binary form\n" - " --no-fips Do not force FIPS mode\n" - " --key KEY Use the hex encoded KEY\n" - " --iv IV Use the hex encoded IV\n" - " --dt DT Use the hex encoded DT for the RNG\n" - " --algo NAME Use algorithm NAME\n" - " --keysize N Use a keysize of N bits\n" - " --signature NAME Take signature from file NAME\n" - " --chunk N Read in chunks of N bytes (implies --binary)\n" - " --pkcs1 Use PKCS#1 encoding\n" - " --mct-server Run a monte carlo test server\n" - " --loop Enable random loop mode\n" - " --progress Print pogress indicators\n" - " --help Print this text\n" - "With no FILE, or when FILE is -, read standard input.\n" - "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout); - exit (0); -} - -int -main (int argc, char **argv) -{ - int last_argc = -1; - gpg_error_t err; - int no_fips = 0; - int progress = 0; - int use_pkcs1 = 0; - const char *mode_string; - const char *key_string = NULL; - const char *iv_string = NULL; - const char *dt_string = NULL; - const char *algo_string = NULL; - const char *keysize_string = NULL; - const char *signature_string = NULL; - FILE *input; - void *data; - size_t datalen; - size_t chunksize = 0; - int mct_server = 0; - - - if (argc) - { argc--; argv++; } - - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--help")) - { - usage (1); - } - else if (!strcmp (*argv, "--version")) - { - fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout); - exit (0); - } - else if (!strcmp (*argv, "--verbose")) - { - verbose++; - argc--; argv++; - } - else if (!strcmp (*argv, "--binary")) - { - binary_input = binary_output = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--no-fips")) - { - no_fips++; - argc--; argv++; - } - else if (!strcmp (*argv, "--loop")) - { - loop_mode = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--progress")) - { - progress = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--key")) - { - argc--; argv++; - if (!argc) - usage (0); - key_string = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--iv")) - { - argc--; argv++; - if (!argc) - usage (0); - iv_string = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--dt")) - { - argc--; argv++; - if (!argc) - usage (0); - dt_string = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--algo")) - { - argc--; argv++; - if (!argc) - usage (0); - algo_string = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--keysize")) - { - argc--; argv++; - if (!argc) - usage (0); - keysize_string = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--signature")) - { - argc--; argv++; - if (!argc) - usage (0); - signature_string = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--chunk")) - { - argc--; argv++; - if (!argc) - usage (0); - chunksize = atoi (*argv); - binary_input = binary_output = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--pkcs1")) - { - use_pkcs1 = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--mct-server")) - { - mct_server = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--standalone")) - { - standalone_mode = 1; - argc--; argv++; - } - } - - if (!argc || argc > 2) - usage (0); - mode_string = *argv; - - if (!strcmp (mode_string, "rsa-derive")) - binary_input = 1; - - if (argc == 2 && strcmp (argv[1], "-")) - { - input = fopen (argv[1], binary_input? "rb":"r"); - if (!input) - die ("can't open `%s': %s\n", argv[1], strerror (errno)); - } - else - input = stdin; - -#ifndef HAVE_W32_SYSTEM - if (loop_mode) - signal (SIGPIPE, SIG_IGN); -#endif - - if (verbose) - fprintf (stderr, PGM ": started (mode=%s)\n", mode_string); - - gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); - if (!no_fips) - gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_check_version ("1.4.3")) - die ("Libgcrypt is not sufficient enough\n"); - if (verbose) - fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL)); - if (no_fips) - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); - - /* Most operations need some input data. */ - if (!chunksize - && !mct_server - && strcmp (mode_string, "random") - && strcmp (mode_string, "rsa-gen") - && strcmp (mode_string, "dsa-gen") ) - { - data = read_file (input, !binary_input, &datalen); - if (!data) - die ("error reading%s input\n", binary_input?"":" and decoding"); - if (verbose) - fprintf (stderr, PGM ": %u bytes of input data\n", - (unsigned int)datalen); - } - else - { - data = NULL; - datalen = 0; - } - - - if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt")) - { - int cipher_algo, cipher_mode; - void *iv_buffer = NULL; - void *key_buffer = NULL; - size_t iv_buflen, key_buflen; - - if (!algo_string) - die ("option --algo is required in this mode\n"); - cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode); - if (!cipher_algo) - die ("cipher algorithm `%s' is not supported\n", algo_string); - if (mct_server) - { - int iterations; - - for (;;) - { - gcry_free (key_buffer); key_buffer = NULL; - gcry_free (iv_buffer); iv_buffer = NULL; - gcry_free (data); data = NULL; - if (!(key_buffer = read_textline (input))) - { - if (feof (input)) - break; - die ("no version info in input\n"); - } - if (atoi (key_buffer) != 1) - die ("unsupported input version %s\n", key_buffer); - gcry_free (key_buffer); - if (!(key_buffer = read_textline (input))) - die ("no iteration count in input\n"); - iterations = atoi (key_buffer); - gcry_free (key_buffer); - if (!(key_buffer = read_hexline (input, &key_buflen))) - die ("no key in input\n"); - if (!(iv_buffer = read_hexline (input, &iv_buflen))) - die ("no IV in input\n"); - if (!(data = read_hexline (input, &datalen))) - die ("no data in input\n"); - skip_to_empty_line (input); - - run_cipher_mct_loop ((*mode_string == 'e'), - cipher_algo, cipher_mode, - iv_buffer, iv_buflen, - key_buffer, key_buflen, - data, datalen, iterations); - } - } - else - { - if (cipher_mode != GCRY_CIPHER_MODE_ECB) - { - if (!iv_string) - die ("option --iv is required in this mode\n"); - iv_buffer = hex2buffer (iv_string, &iv_buflen); - if (!iv_buffer) - die ("invalid value for IV\n"); - } - else - { - iv_buffer = NULL; - iv_buflen = 0; - } - if (!key_string) - die ("option --key is required in this mode\n"); - key_buffer = hex2buffer (key_string, &key_buflen); - if (!key_buffer) - die ("invalid value for KEY\n"); - - run_encrypt_decrypt ((*mode_string == 'e'), - cipher_algo, cipher_mode, - iv_buffer, iv_buflen, - key_buffer, key_buflen, - data, data? datalen:chunksize, input); - } - gcry_free (key_buffer); - gcry_free (iv_buffer); - } - else if (!strcmp (mode_string, "digest")) - { - int algo; - - if (!algo_string) - die ("option --algo is required in this mode\n"); - algo = gcry_md_map_name (algo_string); - if (!algo) - die ("digest algorithm `%s' is not supported\n", algo_string); - if (!data) - die ("no data available (do not use --chunk)\n"); - - run_digest (algo, data, datalen); - } - else if (!strcmp (mode_string, "random")) - { - void *context; - unsigned char key[16]; - unsigned char seed[16]; - unsigned char dt[16]; - unsigned char buffer[16]; - size_t count = 0; - - if (hex2bin (key_string, key, 16) < 0 ) - die ("value for --key are not 32 hex digits\n"); - if (hex2bin (iv_string, seed, 16) < 0 ) - die ("value for --iv are not 32 hex digits\n"); - if (hex2bin (dt_string, dt, 16) < 0 ) - die ("value for --dt are not 32 hex digits\n"); - - /* The flag value 1 disables the dup check, so that the RNG - returns all generated data. */ - err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16); - if (err) - die ("init external RNG test failed: %s\n", gpg_strerror (err)); - - do - { - err = run_external_rng_test (context, buffer, sizeof buffer); - if (err) - die ("running external RNG test failed: %s\n", gpg_strerror (err)); - print_buffer (buffer, sizeof buffer); - if (progress) - { - if (!(++count % 1000)) - fprintf (stderr, PGM ": %lu random bytes so far\n", - (unsigned long int)count * sizeof buffer); - } - } - while (loop_mode); - - if (progress) - fprintf (stderr, PGM ": %lu random bytes\n", - (unsigned long int)count * sizeof buffer); - - deinit_external_rng_test (context); - } - else if (!strcmp (mode_string, "hmac-sha")) - { - int algo; - void *key_buffer; - size_t key_buflen; - - if (!data) - die ("no data available (do not use --chunk)\n"); - if (!algo_string) - die ("option --algo is required in this mode\n"); - switch (atoi (algo_string)) - { - case 1: algo = GCRY_MD_SHA1; break; - case 224: algo = GCRY_MD_SHA224; break; - case 256: algo = GCRY_MD_SHA256; break; - case 384: algo = GCRY_MD_SHA384; break; - case 512: algo = GCRY_MD_SHA512; break; - default: algo = 0; break; - } - if (!algo) - die ("no digest algorithm found for hmac type `%s'\n", algo_string); - if (!key_string) - die ("option --key is required in this mode\n"); - key_buffer = hex2buffer (key_string, &key_buflen); - if (!key_buffer) - die ("invalid value for KEY\n"); - - run_hmac (algo, key_buffer, key_buflen, data, datalen); - - gcry_free (key_buffer); - } - else if (!strcmp (mode_string, "rsa-derive")) - { - if (!data) - die ("no data available (do not use --chunk)\n"); - run_rsa_derive (data, datalen); - } - else if (!strcmp (mode_string, "rsa-gen")) - { - int keysize; - - if (!binary_output) - base64_output = 1; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 128 || keysize > 16384) - die ("invalid keysize specified; needs to be 128 .. 16384\n"); - run_rsa_gen (keysize, 65537); - } - else if (!strcmp (mode_string, "rsa-sign")) - { - int algo; - - if (!key_string) - die ("option --key is required in this mode\n"); - if (access (key_string, R_OK)) - die ("option --key needs to specify an existing keyfile\n"); - if (!algo_string) - die ("option --algo is required in this mode\n"); - algo = gcry_md_map_name (algo_string); - if (!algo) - die ("digest algorithm `%s' is not supported\n", algo_string); - if (!data) - die ("no data available (do not use --chunk)\n"); - - run_rsa_sign (data, datalen, algo, use_pkcs1, key_string); - - } - else if (!strcmp (mode_string, "rsa-verify")) - { - int algo; - - if (!key_string) - die ("option --key is required in this mode\n"); - if (access (key_string, R_OK)) - die ("option --key needs to specify an existing keyfile\n"); - if (!algo_string) - die ("option --algo is required in this mode\n"); - algo = gcry_md_map_name (algo_string); - if (!algo) - die ("digest algorithm `%s' is not supported\n", algo_string); - if (!data) - die ("no data available (do not use --chunk)\n"); - if (!signature_string) - die ("option --signature is required in this mode\n"); - if (access (signature_string, R_OK)) - die ("option --signature needs to specify an existing file\n"); - - run_rsa_verify (data, datalen, algo, use_pkcs1, key_string, - signature_string); - - } - else if (!strcmp (mode_string, "dsa-pqg-gen")) - { - int keysize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); - run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); - } - else if (!strcmp (mode_string, "dsa-gen")) - { - int keysize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); - if (!key_string) - die ("option --key is required in this mode\n"); - run_dsa_gen (keysize, key_string); - } - else if (!strcmp (mode_string, "dsa-sign")) - { - if (!key_string) - die ("option --key is required in this mode\n"); - if (access (key_string, R_OK)) - die ("option --key needs to specify an existing keyfile\n"); - if (!data) - die ("no data available (do not use --chunk)\n"); - - run_dsa_sign (data, datalen, key_string); - } - else if (!strcmp (mode_string, "dsa-verify")) - { - if (!key_string) - die ("option --key is required in this mode\n"); - if (access (key_string, R_OK)) - die ("option --key needs to specify an existing keyfile\n"); - if (!data) - die ("no data available (do not use --chunk)\n"); - if (!signature_string) - die ("option --signature is required in this mode\n"); - if (access (signature_string, R_OK)) - die ("option --signature needs to specify an existing file\n"); - - run_dsa_verify (data, datalen, key_string, signature_string); - } - else - usage (0); - - gcry_free (data); - - /* Because Libgcrypt does not enforce FIPS mode in all cases we let - the process die if Libgcrypt is not anymore in FIPS mode after - the actual operation. */ - if (!no_fips && !gcry_fips_mode_active ()) - die ("FIPS mode is not anymore active\n"); - - if (verbose) - fputs (PGM ": ready\n", stderr); - - return 0; -} - |