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