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