]> git.ipfire.org Git - thirdparty/openssl.git/blob - fips/dsa/fips_dssvs.c
Provisional, experimental support for DSA2 parameter generation algorithm.
[thirdparty/openssl.git] / fips / dsa / fips_dssvs.c
1
2 #define OPENSSL_FIPSAPI
3 #include <openssl/opensslconf.h>
4
5 #ifndef OPENSSL_FIPS
6 #include <stdio.h>
7
8 int main(int argc, char **argv)
9 {
10 printf("No FIPS DSA support\n");
11 return(0);
12 }
13 #else
14
15 #include <openssl/bn.h>
16 #include <openssl/dsa.h>
17 #include <openssl/fips.h>
18 #include <openssl/err.h>
19 #include <openssl/evp.h>
20 #include <string.h>
21 #include <ctype.h>
22
23 #include "fips_utl.h"
24
25 static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
26 const EVP_MD **pmd)
27 {
28 char lbuf[10240];
29 char *keyword, *value;
30
31 char *p;
32 p = strchr(line, ',');
33 if (!p)
34 {
35 *pL = atoi(line);
36 *pdsa2 = 0;
37 *pN = 160;
38 *pmd = EVP_sha1();
39 return 1;
40 }
41 *pdsa2 = 1;
42 *p = 0;
43 if (!parse_line(&keyword, &value, lbuf, line))
44 return 0;
45 if (strcmp(keyword, "L"))
46 return 0;
47 *pL = atoi(value);
48 strcpy(line, p + 1);
49 p = strchr(line, ',');
50 if (!p)
51 return 0;
52 *p = 0;
53 if (!parse_line(&keyword, &value, lbuf, line))
54 return 0;
55 if (strcmp(keyword, "N"))
56 return 0;
57 *pN = atoi(value);
58 strcpy(line, p + 1);
59 p = strchr(line, ']');
60 if (!p)
61 return 0;
62 *p = 0;
63 p = line;
64 while(isspace(*p))
65 p++;
66 if (!strcmp(p, "SHA-1"))
67 *pmd = EVP_sha1();
68 else if (!strcmp(p, "SHA-224"))
69 *pmd = EVP_sha224();
70 else if (!strcmp(p, "SHA-256"))
71 *pmd = EVP_sha256();
72 else if (!strcmp(p, "SHA-384"))
73 *pmd = EVP_sha384();
74 else if (!strcmp(p, "SHA-512"))
75 *pmd = EVP_sha512();
76 else
77 return 0;
78 return 1;
79 }
80
81
82
83 static void pbn(const char *name, BIGNUM *bn)
84 {
85 int len, i;
86 unsigned char *tmp;
87 len = BN_num_bytes(bn);
88 tmp = OPENSSL_malloc(len);
89 if (!tmp)
90 {
91 fprintf(stderr, "Memory allocation error\n");
92 return;
93 }
94 BN_bn2bin(bn, tmp);
95 printf("%s = ", name);
96 for (i = 0; i < len; i++)
97 printf("%02X", tmp[i]);
98 fputs("\n", stdout);
99 OPENSSL_free(tmp);
100 return;
101 }
102
103 static void primes()
104 {
105 char buf[10240];
106 char lbuf[10240];
107 char *keyword, *value;
108
109 while(fgets(buf,sizeof buf,stdin) != NULL)
110 {
111 fputs(buf,stdout);
112 if (!parse_line(&keyword, &value, lbuf, buf))
113 continue;
114 if(!strcmp(keyword,"Prime"))
115 {
116 BIGNUM *pp;
117
118 pp=BN_new();
119 do_hex2bn(&pp,value);
120 printf("result= %c\n",
121 BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
122 }
123 }
124 }
125
126 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
127 const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
128 unsigned char *seed_out,
129 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
130 int dsa_builtin_paramgen2(DSA *ret, size_t bits, size_t qbits,
131 const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
132 unsigned char *seed_out,
133 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
134
135 static void pqg()
136 {
137 char buf[1024];
138 char lbuf[1024];
139 char *keyword, *value;
140 int nmod=0;
141
142 while(fgets(buf,sizeof buf,stdin) != NULL)
143 {
144 if (!parse_line(&keyword, &value, lbuf, buf))
145 {
146 fputs(buf,stdout);
147 continue;
148 }
149 if(!strcmp(keyword,"[mod"))
150 {
151 nmod=atoi(value);
152 }
153 else if(!strcmp(keyword,"N"))
154 {
155 int n=atoi(value);
156
157 printf("[mod = %d]\n\n",nmod);
158
159 while(n--)
160 {
161 unsigned char seed[EVP_MAX_MD_SIZE];
162 DSA *dsa;
163 int counter;
164 unsigned long h;
165 dsa = FIPS_dsa_new();
166
167 if (!dsa_builtin_paramgen(dsa, nmod, 160, NULL, NULL, 0,
168 seed,&counter,&h,NULL))
169 exit(1);
170 pbn("P",dsa->p);
171 pbn("Q",dsa->q);
172 pbn("G",dsa->g);
173 pv("Seed",seed,20);
174 printf("c = %d\n",counter);
175 printf("H = %lx\n",h);
176 putc('\n',stdout);
177 }
178 }
179 else
180 fputs(buf,stdout);
181 }
182 }
183
184 static void pqgver()
185 {
186 char buf[1024];
187 char lbuf[1024];
188 char *keyword, *value;
189 BIGNUM *p = NULL, *q = NULL, *g = NULL;
190 int counter, counter2;
191 unsigned long h, h2;
192 DSA *dsa=NULL;
193 int dsa2, L, N;
194 const EVP_MD *md = NULL;
195 int seedlen;
196 unsigned char seed[1024];
197
198 while(fgets(buf,sizeof buf,stdin) != NULL)
199 {
200 if (!parse_line(&keyword, &value, lbuf, buf))
201 {
202 fputs(buf,stdout);
203 continue;
204 }
205 fputs(buf, stdout);
206 if(!strcmp(keyword,"[mod"))
207 {
208 if (!parse_mod(value, &dsa2, &L, &N, &md))
209 {
210 fprintf(stderr, "Mod Parse Error\n");
211 exit (1);
212 }
213 }
214 else if(!strcmp(keyword,"P"))
215 p=hex2bn(value);
216 else if(!strcmp(keyword,"Q"))
217 q=hex2bn(value);
218 else if(!strcmp(keyword,"G"))
219 g=hex2bn(value);
220 else if(!strcmp(keyword,"Seed"))
221 {
222 seedlen = hex2bin(value, seed);
223 if (!dsa2 && seedlen != 20)
224 {
225 fprintf(stderr, "Seed parse length error\n");
226 exit (1);
227 }
228 }
229 else if(!strcmp(keyword,"c"))
230 counter =atoi(buf+4);
231 else if(!strcmp(keyword,"H"))
232 {
233 h = atoi(value);
234 if (!p || !q || !g)
235 {
236 fprintf(stderr, "Parse Error\n");
237 exit (1);
238 }
239 dsa = FIPS_dsa_new();
240 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
241 seed, seedlen, NULL,
242 &counter2, &h2, NULL))
243 {
244 fprintf(stderr, "Parameter Generation error\n");
245 exit(1);
246 }
247 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
248 seed, seedlen, NULL,
249 &counter2, &h2, NULL) < 0)
250 {
251 fprintf(stderr, "Parameter Generation error\n");
252 exit(1);
253 }
254 if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
255 || (counter != counter2) || (h != h2))
256 printf("Result = F\n");
257 else
258 printf("Result = P\n");
259 BN_free(p);
260 BN_free(q);
261 BN_free(g);
262 p = NULL;
263 q = NULL;
264 g = NULL;
265 FIPS_dsa_free(dsa);
266 dsa = NULL;
267 }
268 }
269 }
270
271 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
272 * algorithm tests. It is an additional test to perform sanity checks on the
273 * output of the KeyPair test.
274 */
275
276 static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
277 BN_CTX *ctx)
278 {
279 BIGNUM *rem = NULL;
280 if (BN_num_bits(p) != nmod)
281 return 0;
282 if (BN_num_bits(q) != 160)
283 return 0;
284 if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
285 return 0;
286 if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
287 return 0;
288 rem = BN_new();
289 if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
290 || (BN_cmp(g, BN_value_one()) <= 0)
291 || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
292 {
293 BN_free(rem);
294 return 0;
295 }
296 /* Todo: check g */
297 BN_free(rem);
298 return 1;
299 }
300
301 static void keyver()
302 {
303 char buf[1024];
304 char lbuf[1024];
305 char *keyword, *value;
306 BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
307 BIGNUM *Y2;
308 BN_CTX *ctx = NULL;
309 int nmod=0, paramcheck = 0;
310
311 ctx = BN_CTX_new();
312 Y2 = BN_new();
313
314 while(fgets(buf,sizeof buf,stdin) != NULL)
315 {
316 if (!parse_line(&keyword, &value, lbuf, buf))
317 {
318 fputs(buf,stdout);
319 continue;
320 }
321 if(!strcmp(keyword,"[mod"))
322 {
323 if (p)
324 BN_free(p);
325 p = NULL;
326 if (q)
327 BN_free(q);
328 q = NULL;
329 if (g)
330 BN_free(g);
331 g = NULL;
332 paramcheck = 0;
333 nmod=atoi(value);
334 }
335 else if(!strcmp(keyword,"P"))
336 p=hex2bn(value);
337 else if(!strcmp(keyword,"Q"))
338 q=hex2bn(value);
339 else if(!strcmp(keyword,"G"))
340 g=hex2bn(value);
341 else if(!strcmp(keyword,"X"))
342 X=hex2bn(value);
343 else if(!strcmp(keyword,"Y"))
344 {
345 Y=hex2bn(value);
346 if (!p || !q || !g || !X || !Y)
347 {
348 fprintf(stderr, "Parse Error\n");
349 exit (1);
350 }
351 pbn("P",p);
352 pbn("Q",q);
353 pbn("G",g);
354 pbn("X",X);
355 pbn("Y",Y);
356 if (!paramcheck)
357 {
358 if (dss_paramcheck(nmod, p, q, g, ctx))
359 paramcheck = 1;
360 else
361 paramcheck = -1;
362 }
363 if (paramcheck != 1)
364 printf("Result = F\n");
365 else
366 {
367 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
368 printf("Result = F\n");
369 else
370 printf("Result = P\n");
371 }
372 BN_free(X);
373 BN_free(Y);
374 X = NULL;
375 Y = NULL;
376 }
377 }
378 if (p)
379 BN_free(p);
380 if (q)
381 BN_free(q);
382 if (g)
383 BN_free(g);
384 if (Y2)
385 BN_free(Y2);
386 }
387
388 static void keypair()
389 {
390 char buf[1024];
391 char lbuf[1024];
392 char *keyword, *value;
393 int nmod=0;
394
395 while(fgets(buf,sizeof buf,stdin) != NULL)
396 {
397 if (!parse_line(&keyword, &value, lbuf, buf))
398 {
399 fputs(buf,stdout);
400 continue;
401 }
402 if(!strcmp(keyword,"[mod"))
403 nmod=atoi(value);
404 else if(!strcmp(keyword,"N"))
405 {
406 DSA *dsa;
407 int n=atoi(value);
408
409 printf("[mod = %d]\n\n",nmod);
410 dsa = FIPS_dsa_new();
411 if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
412 exit(1);
413 pbn("P",dsa->p);
414 pbn("Q",dsa->q);
415 pbn("G",dsa->g);
416 putc('\n',stdout);
417
418 while(n--)
419 {
420 if (!DSA_generate_key(dsa))
421 exit(1);
422
423 pbn("X",dsa->priv_key);
424 pbn("Y",dsa->pub_key);
425 putc('\n',stdout);
426 }
427 }
428 }
429 }
430
431 static void siggen()
432 {
433 char buf[1024];
434 char lbuf[1024];
435 char *keyword, *value;
436 int nmod=0;
437 DSA *dsa=NULL;
438
439 while(fgets(buf,sizeof buf,stdin) != NULL)
440 {
441 if (!parse_line(&keyword, &value, lbuf, buf))
442 {
443 fputs(buf,stdout);
444 continue;
445 }
446 if(!strcmp(keyword,"[mod"))
447 {
448 nmod=atoi(value);
449 printf("[mod = %d]\n\n",nmod);
450 if (dsa)
451 FIPS_dsa_free(dsa);
452 dsa = FIPS_dsa_new();
453 if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
454 exit(1);
455 pbn("P",dsa->p);
456 pbn("Q",dsa->q);
457 pbn("G",dsa->g);
458 putc('\n',stdout);
459 }
460 else if(!strcmp(keyword,"Msg"))
461 {
462 unsigned char msg[1024];
463 int n;
464 EVP_MD_CTX mctx;
465 DSA_SIG *sig;
466 EVP_MD_CTX_init(&mctx);
467
468 n=hex2bin(value,msg);
469 pv("Msg",msg,n);
470
471 if (!DSA_generate_key(dsa))
472 exit(1);
473 pbn("Y",dsa->pub_key);
474
475 EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
476 EVP_DigestUpdate(&mctx, msg, n);
477 sig = FIPS_dsa_sign_ctx(dsa, &mctx);
478
479 pbn("R",sig->r);
480 pbn("S",sig->s);
481 putc('\n',stdout);
482 DSA_SIG_free(sig);
483 EVP_MD_CTX_cleanup(&mctx);
484 }
485 }
486 if (dsa)
487 FIPS_dsa_free(dsa);
488 }
489
490 static void sigver()
491 {
492 DSA *dsa=NULL;
493 char buf[1024];
494 char lbuf[1024];
495 unsigned char msg[1024];
496 char *keyword, *value;
497 int nmod=0, n=0;
498 DSA_SIG sg, *sig = &sg;
499
500 sig->r = NULL;
501 sig->s = NULL;
502
503 while(fgets(buf,sizeof buf,stdin) != NULL)
504 {
505 if (!parse_line(&keyword, &value, lbuf, buf))
506 {
507 fputs(buf,stdout);
508 continue;
509 }
510 if(!strcmp(keyword,"[mod"))
511 {
512 nmod=atoi(value);
513 if(dsa)
514 FIPS_dsa_free(dsa);
515 dsa=FIPS_dsa_new();
516 }
517 else if(!strcmp(keyword,"P"))
518 dsa->p=hex2bn(value);
519 else if(!strcmp(keyword,"Q"))
520 dsa->q=hex2bn(value);
521 else if(!strcmp(keyword,"G"))
522 {
523 dsa->g=hex2bn(value);
524
525 printf("[mod = %d]\n\n",nmod);
526 pbn("P",dsa->p);
527 pbn("Q",dsa->q);
528 pbn("G",dsa->g);
529 putc('\n',stdout);
530 }
531 else if(!strcmp(keyword,"Msg"))
532 {
533 n=hex2bin(value,msg);
534 pv("Msg",msg,n);
535 }
536 else if(!strcmp(keyword,"Y"))
537 dsa->pub_key=hex2bn(value);
538 else if(!strcmp(keyword,"R"))
539 sig->r=hex2bn(value);
540 else if(!strcmp(keyword,"S"))
541 {
542 EVP_MD_CTX mctx;
543 int r;
544 EVP_MD_CTX_init(&mctx);
545 sig->s=hex2bn(value);
546
547 pbn("Y",dsa->pub_key);
548 pbn("R",sig->r);
549 pbn("S",sig->s);
550 EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
551 EVP_DigestUpdate(&mctx, msg, n);
552 no_err = 1;
553 r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
554 no_err = 0;
555 EVP_MD_CTX_cleanup(&mctx);
556
557 printf("Result = %c\n", r == 1 ? 'P' : 'F');
558 putc('\n',stdout);
559 }
560 }
561 }
562
563 int main(int argc,char **argv)
564 {
565 if(argc != 2)
566 {
567 fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]);
568 exit(1);
569 }
570 fips_set_error_print();
571 if(!FIPS_mode_set(1))
572 exit(1);
573 if(!strcmp(argv[1],"prime"))
574 primes();
575 else if(!strcmp(argv[1],"pqg"))
576 pqg();
577 else if(!strcmp(argv[1],"pqgver"))
578 pqgver();
579 else if(!strcmp(argv[1],"keypair"))
580 keypair();
581 else if(!strcmp(argv[1],"keyver"))
582 keyver();
583 else if(!strcmp(argv[1],"siggen"))
584 siggen();
585 else if(!strcmp(argv[1],"sigver"))
586 sigver();
587 else
588 {
589 fprintf(stderr,"Don't know how to %s.\n",argv[1]);
590 exit(1);
591 }
592
593 return 0;
594 }
595
596 #endif