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