4eec29e7611d3986e85dd234822837cd0116ae04
[openssl.git] / fips-1.0 / dsa / fips_dssvs.c
1 #include <openssl/opensslconf.h>
2
3 #ifndef OPENSSL_FIPS
4 #include <stdio.h>
5
6 int main()
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/fips_sha.h>
18 #include <string.h>
19 #include <ctype.h>
20
21 static int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf)
22         {
23         char *keyword, *value, *p, *q;
24         strcpy(linebuf, olinebuf);
25         keyword = linebuf;
26         /* Skip leading space */
27         while (isspace((unsigned char)*keyword))
28                 keyword++;
29
30         /* Look for = sign */
31         p = strchr(linebuf, '=');
32
33         /* If no '=' exit */
34         if (!p)
35                 return 0;
36
37         q = p - 1;
38
39         /* Remove trailing space */
40         while (isspace((unsigned char)*q))
41                 *q-- = 0;
42
43         *p = 0;
44         value = p + 1;
45
46         /* Remove leading space from value */
47         while (isspace((unsigned char)*value))
48                 value++;
49
50         /* Remove trailing space from value */
51         p = value + strlen(value) - 1;
52
53         while (*p == '\n' || isspace((unsigned char)*p))
54                 *p-- = 0;
55
56         *pkw = keyword;
57         *pval = value;
58         return 1;
59         }
60
61 int hex2bin(const char *in, unsigned char *out)
62     {
63     int n1, n2;
64     unsigned char ch;
65
66     for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
67         { /* first byte */
68         if ((in[n1] >= '0') && (in[n1] <= '9'))
69             ch = in[n1++] - '0';
70         else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
71             ch = in[n1++] - 'A' + 10;
72         else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
73             ch = in[n1++] - 'a' + 10;
74         else
75             return -1;
76         if(!in[n1])
77             {
78             out[n2++]=ch;
79             break;
80             }
81         out[n2] = ch << 4;
82         /* second byte */
83         if ((in[n1] >= '0') && (in[n1] <= '9'))
84             ch = in[n1++] - '0';
85         else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
86             ch = in[n1++] - 'A' + 10;
87         else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
88             ch = in[n1++] - 'a' + 10;
89         else
90             return -1;
91         out[n2++] |= ch;
92         }
93     return n2;
94     }
95
96 BIGNUM *hex2bn(const char *in)
97     {
98     BIGNUM *p=BN_new();
99
100     BN_hex2bn(&p,in);
101
102     return p;
103     }
104
105 int bin2hex(const unsigned char *in,int len,char *out)
106     {
107     int n1, n2;
108     unsigned char ch;
109
110     for (n1=0,n2=0 ; n1 < len ; ++n1)
111         {
112         ch=in[n1] >> 4;
113         if (ch <= 0x09)
114             out[n2++]=ch+'0';
115         else
116             out[n2++]=ch-10+'a';
117         ch=in[n1] & 0x0f;
118         if(ch <= 0x09)
119             out[n2++]=ch+'0';
120         else
121             out[n2++]=ch-10+'a';
122         }
123     out[n2]='\0';
124     return n2;
125     }
126
127 void pv(const char *tag,const unsigned char *val,int len)
128     {
129     char obuf[2048];
130
131     bin2hex(val,len,obuf);
132     printf("%s = %s\n",tag,obuf);
133     }
134
135 void pbn(const char *tag,const BIGNUM *val)
136     {
137     printf("%s = %s\n",tag,BN_bn2hex(val));
138     }
139
140 void primes()
141     {
142     char buf[10240];
143     char lbuf[10240];
144     char *keyword, *value;
145
146     while(fgets(buf,sizeof buf,stdin) != NULL)
147         {
148         fputs(buf,stdout);
149         if (!parse_line(&keyword, &value, lbuf, buf))
150                 continue;
151         if(!strcmp(keyword,"Prime"))
152             {
153             BIGNUM *pp;
154
155             pp=BN_new();
156             BN_hex2bn(&pp,value);
157             printf("result= %c\n",
158                    BN_is_prime(pp,20,NULL,NULL,NULL) ? 'P' : 'F');
159             }       
160         }
161     }
162
163 void pqg()
164     {
165     char buf[1024];
166     char lbuf[1024];
167     char *keyword, *value;
168     int nmod=0;
169
170     while(fgets(buf,sizeof buf,stdin) != NULL)
171         {
172         if (!parse_line(&keyword, &value, lbuf, buf))
173                 {
174                 fputs(buf,stdout);
175                 continue;
176                 }
177         if(!strcmp(keyword,"[mod"))
178             nmod=atoi(value);
179         else if(!strcmp(keyword,"N"))
180             {
181             int n=atoi(value);
182
183             printf("[mod = %d]\n\n",nmod);
184
185             while(n--)
186                 {
187                 unsigned char seed[20];
188                 DSA *dsa;
189                 int counter;
190                 unsigned long h;
191
192                 dsa=DSA_generate_parameters(nmod,seed,0,&counter,&h,NULL,NULL);
193                 printf("P = %s\n",BN_bn2hex(dsa->p));
194                 printf("Q = %s\n",BN_bn2hex(dsa->q));
195                 printf("G = %s\n",BN_bn2hex(dsa->g));
196                 pv("Seed",seed,20);
197                 printf("c = %d\n",counter);
198                 printf("H = %lx\n",h);
199                 putc('\n',stdout);
200                 }
201             }
202         else
203             fputs(buf,stdout);
204         }
205     }
206
207 void pqgver()
208     {
209     char buf[1024];
210     char lbuf[1024];
211     char *keyword, *value;
212     BIGNUM *p = NULL, *q = NULL, *g = NULL;
213     int counter, counter2;
214     unsigned long h, h2;
215     DSA *dsa=NULL;
216     int nmod=0;
217     unsigned char seed[1024];
218
219     while(fgets(buf,sizeof buf,stdin) != NULL)
220         {
221         if (!parse_line(&keyword, &value, lbuf, buf))
222                 {
223                 fputs(buf,stdout);
224                 continue;
225                 }
226         if(!strcmp(keyword,"[mod"))
227             nmod=atoi(value);
228         else if(!strcmp(keyword,"P"))
229             p=hex2bn(value);
230         else if(!strcmp(keyword,"Q"))
231             q=hex2bn(value);
232         else if(!strcmp(keyword,"G"))
233             g=hex2bn(value);
234         else if(!strcmp(keyword,"Seed"))
235             {
236             int slen = hex2bin(value, seed);
237             if (slen != 20)
238                 {
239                 fprintf(stderr, "Seed parse length error\n");
240                 exit (1);
241                 }
242             }
243         else if(!strcmp(keyword,"c"))
244             counter =atoi(buf+4);
245         else if(!strcmp(keyword,"H"))
246             {
247             h = atoi(value);
248             if (!p || !q || !g)
249                 {
250                 fprintf(stderr, "Parse Error\n");
251                 exit (1);
252                 }
253             pbn("P",p);
254             pbn("Q",q);
255             pbn("G",g);
256             pv("Seed",seed,20);
257             printf("c = %d\n",counter);
258             printf("H = %lx\n",h);
259             dsa=DSA_generate_parameters(nmod,seed,20,&counter2,&h2,NULL,NULL);
260             if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
261                 || (counter != counter2) || (h != h2))
262                 printf("Result = F\n");
263             else
264                 printf("Result = T\n");
265             BN_free(p);
266             BN_free(q);
267             BN_free(g);
268             p = NULL;
269             q = NULL;
270             g = NULL;
271             DSA_free(dsa);
272             dsa = NULL;
273             }
274         }
275     }
276
277 void keypair()
278     {
279     char buf[1024];
280     char lbuf[1024];
281     char *keyword, *value;
282     int nmod=0;
283
284     while(fgets(buf,sizeof buf,stdin) != NULL)
285         {
286         if (!parse_line(&keyword, &value, lbuf, buf))
287                 {
288                 fputs(buf,stdout);
289                 continue;
290                 }
291         if(!strcmp(keyword,"[mod"))
292             nmod=atoi(value);
293         else if(!strcmp(keyword,"N"))
294             {
295             DSA *dsa;
296             int n=atoi(value);
297
298             printf("[mod = %d]\n\n",nmod);
299
300             dsa=DSA_generate_parameters(nmod,NULL,0,NULL,NULL,NULL,NULL);
301             pbn("P",dsa->p);
302             pbn("Q",dsa->q);
303             pbn("G",dsa->g);
304             putc('\n',stdout);
305
306             while(n--)
307                 {
308                 DSA_generate_key(dsa);
309
310                 pbn("X",dsa->priv_key);
311                 pbn("Y",dsa->pub_key);
312                 putc('\n',stdout);
313                 }
314             }
315         }
316     }
317
318 void siggen()
319     {
320     char buf[1024];
321     char lbuf[1024];
322     char *keyword, *value;
323     int nmod=0;
324     DSA *dsa=NULL;
325
326     while(fgets(buf,sizeof buf,stdin) != NULL)
327         {
328         if (!parse_line(&keyword, &value, lbuf, buf))
329                 {
330                 fputs(buf,stdout);
331                 continue;
332                 }
333         if(!strcmp(keyword,"[mod"))
334             {
335             nmod=atoi(value);
336             printf("[mod = %d]\n\n",nmod);
337
338             dsa=DSA_generate_parameters(nmod,NULL,0,NULL,NULL,NULL,NULL);
339             pbn("P",dsa->p);
340             pbn("Q",dsa->q);
341             pbn("G",dsa->g);
342             putc('\n',stdout);
343             }
344         else if(!strcmp(keyword,"Msg"))
345             {
346             unsigned char msg[1024];
347             unsigned char hash[20];
348             int n;
349             DSA_SIG *sig;
350
351             n=hex2bin(value,msg);
352             pv("Msg",msg,n);
353
354             DSA_generate_key(dsa);
355             pbn("Y",dsa->pub_key);
356
357             SHA1(msg,n,hash);
358             sig=DSA_do_sign(hash,sizeof hash,dsa);
359             pbn("R",sig->r);
360             pbn("S",sig->s);
361             putc('\n',stdout);
362             }
363         }
364     }
365
366 void sigver()
367     {
368     DSA *dsa=NULL;
369     char buf[1024];
370     char lbuf[1024];
371     char *keyword, *value;
372     int nmod=0;
373     unsigned char hash[20];
374     DSA_SIG sg, *sig = &sg;
375
376     sig->r = NULL;
377     sig->s = NULL;
378
379     while(fgets(buf,sizeof buf,stdin) != NULL)
380         {
381         if (!parse_line(&keyword, &value, lbuf, buf))
382                 {
383                 fputs(buf,stdout);
384                 continue;
385                 }
386         if(!strcmp(keyword,"[mod"))
387             {
388             nmod=atoi(value);
389             if(dsa)
390                 DSA_free(dsa);
391             dsa=DSA_new();
392             }
393         else if(!strcmp(keyword,"P"))
394             dsa->p=hex2bn(value);
395         else if(!strcmp(keyword,"Q"))
396             dsa->q=hex2bn(value);
397         else if(!strcmp(keyword,"G"))
398             {
399             dsa->g=hex2bn(value);
400
401             printf("[mod = %d]\n\n",nmod);
402             pbn("P",dsa->p);
403             pbn("Q",dsa->q);
404             pbn("G",dsa->g);
405             putc('\n',stdout);
406             }
407         else if(!strcmp(keyword,"Msg"))
408             {
409             unsigned char msg[1024];
410             int n;
411
412             n=hex2bin(value,msg);
413             pv("Msg",msg,n);
414             SHA1(msg,n,hash);
415             }
416         else if(!strcmp(keyword,"Y"))
417             dsa->pub_key=hex2bn(value);
418         else if(!strcmp(keyword,"R"))
419             sig->r=hex2bn(value);
420         else if(!strcmp(keyword,"S"))
421             {
422             sig->s=hex2bn(value);
423         
424             pbn("Y",dsa->pub_key);
425             pbn("R",sig->r);
426             pbn("S",sig->s);
427             printf("Result = %c\n",DSA_do_verify(hash,sizeof hash,sig,dsa)
428                    ? 'P' : 'F');
429             putc('\n',stdout);
430             }
431         }
432     }
433
434 int main(int argc,char **argv)
435     {
436     if(argc != 2)
437         {
438         fprintf(stderr,"%s [prime|pqg]\n",argv[0]);
439         exit(1);
440         }
441     if(!FIPS_mode_set(1))
442         {
443         ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
444         exit(1);
445         }
446     if(!strcmp(argv[1],"prime"))
447         primes();
448     else if(!strcmp(argv[1],"pqg"))
449         pqg();
450     else if(!strcmp(argv[1],"pqgver"))
451         pqgver();
452     else if(!strcmp(argv[1],"keypair"))
453         keypair();
454     else if(!strcmp(argv[1],"siggen"))
455         siggen();
456     else if(!strcmp(argv[1],"sigver"))
457         sigver();
458     else
459         {
460         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
461         exit(1);
462         }
463
464     return 0;
465     }
466
467 #endif