]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/fips/dsa/fips_dssvs.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / fips / dsa / fips_dssvs.c
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         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 }
41
42 static void primes()
43 {
44     char buf[10240];
45     char lbuf[10240];
46     char *keyword, *value;
47
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         }
60     }
61 }
62
63 static void pqg()
64 {
65     char buf[1024];
66     char lbuf[1024];
67     char *keyword, *value;
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);
104     }
105 }
106
107 static void pqgver()
108 {
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;
115     DSA *dsa = NULL;
116     int nmod = 0;
117     unsigned char seed[1024];
118
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             }
153             if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
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         }
167     }
168 }
169
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.
174  */
175
176 static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
177                           BN_CTX *ctx)
178 {
179     BIGNUM *rem = NULL;
180     if (BN_num_bits(p) != nmod)
181         return 0;
182     if (BN_num_bits(q) != 160)
183         return 0;
184     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
185         return 0;
186     if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
187         return 0;
188     rem = BN_new();
189     if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
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     }
195     /* Todo: check g */
196     BN_free(rem);
197     return 1;
198 }
199
200 static void keyver()
201 {
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;
208     int nmod = 0, paramcheck = 0;
209
210     ctx = BN_CTX_new();
211     Y2 = BN_new();
212
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         }
268     }
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 }
278
279 static void keypair()
280 {
281     char buf[1024];
282     char lbuf[1024];
283     char *keyword, *value;
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         }
320     }
321 }
322
323 static void siggen()
324 {
325     char buf[1024];
326     char lbuf[1024];
327     char *keyword, *value;
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         }
385     }
386     if (dsa)
387         FIPS_dsa_free(dsa);
388 }
389
390 static void sigver()
391 {
392     DSA *dsa = NULL;
393     char buf[1024];
394     char lbuf[1024];
395     unsigned char msg[1024];
396     char *keyword, *value;
397     int nmod = 0, n = 0;
398     DSA_SIG sg, *sig = &sg;
399
400     sig->r = NULL;
401     sig->s = NULL;
402
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         }
456     }
457 }
458
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     }
488
489     return 0;
490 }
491
492 #endif