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