a162f4289c97f40ee19fdfed2d5ca8abf08d4bd0
[openssl.git] / fips / ecdsa / fips_ecdsavs.c
1 #define OPENSSL_FIPSAPI
2 #include <openssl/opensslconf.h>
3
4 #ifndef OPENSSL_FIPS
5 #include <stdio.h>
6
7 int main(int argc, char **argv)
8 {
9     printf("No FIPS ECDSA support\n");
10     return(0);
11 }
12 #else
13
14 #include <string.h>
15 #include <ctype.h>
16 #include <openssl/err.h>
17 #include <openssl/bn.h>
18 #include <openssl/ecdsa.h>
19 #include <openssl/evp.h>
20 #include "fips_utl.h"
21
22 #include <openssl/objects.h>
23
24
25 static int lookup_curve(char *in, char *curve_name, const EVP_MD **pmd)
26         {
27         char *cname, *p;
28         /* Copy buffer as we will change it */
29         strcpy(curve_name, in);
30         cname = curve_name + 1;
31         p = strchr(cname, ']');
32         if (!p)
33                 {
34                 fprintf(stderr, "Parse error: missing ]\n");
35                 return NID_undef;
36                 }
37         *p = 0;
38         p = strchr(cname, ',');
39         if (p)
40                 {
41                 if (!pmd)
42                         {
43                         fprintf(stderr, "Parse error: unexpected digest\n");
44                         return NID_undef;
45                         }
46                 *p = 0;
47                 p++;
48
49                 if (!strcmp(p, "SHA-1"))
50                         *pmd = EVP_sha1();
51                 else if (!strcmp(p, "SHA-224"))
52                         *pmd = EVP_sha224();
53                 else if (!strcmp(p, "SHA-256"))
54                         *pmd = EVP_sha256();
55                 else if (!strcmp(p, "SHA-384"))
56                         *pmd = EVP_sha384();
57                 else if (!strcmp(p, "SHA-512"))
58                         *pmd = EVP_sha512();
59                 else
60                         {
61                         fprintf(stderr, "Unknown digest %s\n", p);
62                         return NID_undef;
63                         }
64                 }
65         else if(pmd)
66                 *pmd = EVP_sha1();
67
68         if (!strcmp(cname, "B-163"))
69                 return NID_sect163r2;
70         if (!strcmp(cname, "B-233"))
71                 return NID_sect233r1;
72         if (!strcmp(cname, "B-283"))
73                 return NID_sect283r1;
74         if (!strcmp(cname, "B-409"))
75                 return NID_sect409r1;
76         if (!strcmp(cname, "B-571"))
77                 return NID_sect571r1;
78         if (!strcmp(cname, "K-163"))
79                 return NID_sect163k1;
80         if (!strcmp(cname, "K-233"))
81                 return NID_sect233k1;
82         if (!strcmp(cname, "K-283"))
83                 return NID_sect283k1;
84         if (!strcmp(cname, "K-409"))
85                 return NID_sect409k1;
86         if (!strcmp(cname, "K-571"))
87                 return NID_sect571k1;
88         if (!strcmp(cname, "P-192"))
89                 return NID_X9_62_prime192v1;
90         if (!strcmp(cname, "P-224"))
91                 return NID_secp224r1;
92         if (!strcmp(cname, "P-256"))
93                 return NID_X9_62_prime256v1;
94         if (!strcmp(cname, "P-384"))
95                 return NID_secp384r1;
96         if (!strcmp(cname, "P-521"))
97                 return NID_secp521r1;
98
99         fprintf(stderr, "Unknown Curve name %s\n", cname);
100         return NID_undef;
101         }
102
103 static int ec_get_pubkey(EC_KEY *key, BIGNUM *x, BIGNUM *y)
104         {
105         const EC_POINT *pt;
106         const EC_GROUP *grp;
107         const EC_METHOD *meth;
108         int rv;
109         BN_CTX *ctx;
110         ctx = BN_CTX_new();
111         if (!ctx)
112                 return 0;
113         grp = EC_KEY_get0_group(key);
114         pt = EC_KEY_get0_public_key(key);
115         meth = EC_GROUP_method_of(grp);
116         if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
117                 rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, x, y, ctx);
118         else
119                 rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, x, y, ctx);
120
121         BN_CTX_free(ctx);
122
123         return rv;
124
125         }
126
127 static int KeyPair(void)
128         {
129         char buf[2048], lbuf[2048];
130         char *keyword, *value;
131         int curve_nid = NID_undef;
132         int i, count;
133         BIGNUM *Qx = NULL, *Qy = NULL;
134         const BIGNUM *d = NULL;
135         EC_KEY *key = NULL;
136         Qx = BN_new();
137         Qy = BN_new();
138         while(fgets(buf, sizeof buf, stdin) != NULL)
139                 {
140                 if (*buf == '[' && buf[2] == '-')
141                         {
142                         if (buf[2] == '-')
143                         curve_nid = lookup_curve(buf, lbuf, NULL);
144                         fputs(buf, stdout);
145                         continue;
146                         }
147                 if (!parse_line(&keyword, &value, lbuf, buf))
148                         {
149                         fputs(buf, stdout);
150                         continue;
151                         }
152                 if (!strcmp(keyword, "N"))
153                         {
154                         count = atoi(value);
155
156                         for (i = 0; i < count; i++)
157                                 {
158
159                                 key = EC_KEY_new_by_curve_name(curve_nid);
160                                 if (!EC_KEY_generate_key(key))
161                                         {
162                                         fprintf(stderr, "Error generating key\n");
163                                         return 0;
164                                         }
165
166                                 if (!ec_get_pubkey(key, Qx, Qy))
167                                         {
168                                         fprintf(stderr, "Error getting public key\n");
169                                         return 0;
170                                         }
171
172                                 d = EC_KEY_get0_private_key(key);
173
174                                 do_bn_print_name(stdout, "d", d);
175                                 do_bn_print_name(stdout, "Qx", Qx);
176                                 do_bn_print_name(stdout, "Qy", Qy);
177                                 fputs("\n", stdout);
178                                 EC_KEY_free(key);
179
180                                 }
181
182                         }
183
184                 }
185         BN_free(Qx);
186         BN_free(Qy);
187         return 1;
188         }
189
190 static int PKV(void)
191         {
192
193         char buf[2048], lbuf[2048];
194         char *keyword, *value;
195         int curve_nid = NID_undef;
196         BIGNUM *Qx = NULL, *Qy = NULL;
197         EC_KEY *key = NULL;
198         while(fgets(buf, sizeof buf, stdin) != NULL)
199                 {
200                 fputs(buf, stdout);
201                 if (*buf == '[' && buf[2] == '-')
202                         {
203                         curve_nid = lookup_curve(buf, lbuf, NULL);
204                         if (curve_nid == NID_undef)
205                                 return 0;
206                                 
207                         }
208                 if (!parse_line(&keyword, &value, lbuf, buf))
209                         continue;
210                 if (!strcmp(keyword, "Qx"))
211                         {
212                         if (!do_hex2bn(&Qx, value))
213                                 {
214                                 fprintf(stderr, "Invalid Qx value\n");
215                                 return 0;
216                                 }
217                         }
218                 if (!strcmp(keyword, "Qy"))
219                         {
220                         int rv;
221                         if (!do_hex2bn(&Qy, value))
222                                 {
223                                 fprintf(stderr, "Invalid Qy value\n");
224                                 return 0;
225                                 }
226                         key = EC_KEY_new_by_curve_name(curve_nid);
227                         rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);
228                         printf("Result = %s\n", rv ? "P":"F");
229                         }
230
231                 }
232         return 1;
233         }
234
235 static int SigGen(void)
236         {
237         char buf[2048], lbuf[2048];
238         char *keyword, *value;
239         unsigned char *msg;
240         int curve_nid = NID_undef;
241         long mlen;
242         BIGNUM *Qx = NULL, *Qy = NULL;
243         EC_KEY *key = NULL;
244         ECDSA_SIG *sig = NULL;
245         const EVP_MD *digest = NULL;
246         EVP_MD_CTX mctx;
247         EVP_MD_CTX_init(&mctx);
248         Qx = BN_new();
249         Qy = BN_new();
250         while(fgets(buf, sizeof buf, stdin) != NULL)
251                 {
252                 fputs(buf, stdout);
253                 if (*buf == '[')
254                         {
255                         curve_nid = lookup_curve(buf, lbuf, &digest);
256                         if (curve_nid == NID_undef)
257                                 return 0;
258                         }
259                 if (!parse_line(&keyword, &value, lbuf, buf))
260                         continue;
261                 if (!strcmp(keyword, "Msg"))
262                         {
263                         msg = hex2bin_m(value, &mlen);
264                         if (!msg)
265                                 {
266                                 fprintf(stderr, "Invalid Message\n");
267                                 return 0;
268                                 }
269
270                         key = EC_KEY_new_by_curve_name(curve_nid);
271                         if (!EC_KEY_generate_key(key))
272                                 {
273                                 fprintf(stderr, "Error generating key\n");
274                                 return 0;
275                                 }
276
277                         if (!ec_get_pubkey(key, Qx, Qy))
278                                 {
279                                 fprintf(stderr, "Error getting public key\n");
280                                 return 0;
281                                 }
282
283                         FIPS_digestinit(&mctx, digest);
284                         FIPS_digestupdate(&mctx, msg, mlen);
285                         sig = FIPS_ecdsa_sign_ctx(key, &mctx);
286
287                         if (!sig)
288                                 {
289                                 fprintf(stderr, "Error signing message\n");
290                                 return 0;
291                                 }
292
293                         do_bn_print_name(stdout, "Qx", Qx);
294                         do_bn_print_name(stdout, "Qy", Qy);
295                         do_bn_print_name(stdout, "R", sig->r);
296                         do_bn_print_name(stdout, "S", sig->s);
297
298                         EC_KEY_free(key);
299
300                         FIPS_ecdsa_sig_free(sig);
301
302                         }
303
304                 }
305         BN_free(Qx);
306         BN_free(Qy);
307         FIPS_md_ctx_cleanup(&mctx);
308         return 1;
309         }
310
311 static int SigVer(void)
312         {
313         char buf[2048], lbuf[2048];
314         char *keyword, *value;
315         unsigned char *msg;
316         int curve_nid = NID_undef;
317         long mlen;
318         BIGNUM *Qx = NULL, *Qy = NULL;
319         EC_KEY *key = NULL;
320         ECDSA_SIG sg, *sig = &sg;
321         const EVP_MD *digest = NULL;
322         EVP_MD_CTX mctx;
323         EVP_MD_CTX_init(&mctx);
324         sig->r = NULL;
325         sig->s = NULL;
326         while(fgets(buf, sizeof buf, stdin) != NULL)
327                 {
328                 fputs(buf, stdout);
329                 if (*buf == '[')
330                         {
331                         curve_nid = lookup_curve(buf, lbuf, &digest);
332                         if (curve_nid == NID_undef)
333                                 return 0;
334                         }
335                 if (!parse_line(&keyword, &value, lbuf, buf))
336                         continue;
337                 if (!strcmp(keyword, "Msg"))
338                         {
339                         msg = hex2bin_m(value, &mlen);
340                         if (!msg)
341                                 {
342                                 fprintf(stderr, "Invalid Message\n");
343                                 return 0;
344                                 }
345                         }
346                         
347                 if (!strcmp(keyword, "Qx"))
348                         {
349                         if (!do_hex2bn(&Qx, value))
350                                 {
351                                 fprintf(stderr, "Invalid Qx value\n");
352                                 return 0;
353                                 }
354                         }
355                 if (!strcmp(keyword, "Qy"))
356                         {
357                         if (!do_hex2bn(&Qy, value))
358                                 {
359                                 fprintf(stderr, "Invalid Qy value\n");
360                                 return 0;
361                                 }
362                         }
363                 if (!strcmp(keyword, "R"))
364                         {
365                         if (!do_hex2bn(&sig->r, value))
366                                 {
367                                 fprintf(stderr, "Invalid R value\n");
368                                 return 0;
369                                 }
370                         }
371                 if (!strcmp(keyword, "S"))
372                         {
373                         int rv;
374                         if (!do_hex2bn(&sig->s, value))
375                                 {
376                                 fprintf(stderr, "Invalid S value\n");
377                                 return 0;
378                                 }
379                         key = EC_KEY_new_by_curve_name(curve_nid);
380                         rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);
381
382                         if (rv != 1)
383                                 {
384                                 fprintf(stderr, "Error setting public key\n");
385                                 return 0;
386                                 }
387
388                         FIPS_digestinit(&mctx, digest);
389                         FIPS_digestupdate(&mctx, msg, mlen);
390                         no_err = 1;
391                         rv = FIPS_ecdsa_verify_ctx(key, &mctx, sig);
392                         no_err = 0;
393
394                         printf("Result = %s\n", rv ? "P":"F");
395                         }
396
397                 }
398         return 1;
399         }
400
401 int main(int argc, char **argv)
402         {
403         const char *cmd = argv[1];
404         int rv = 0;
405         fips_set_error_print();
406         if (!cmd)
407                 {
408                 fprintf(stderr, "fips_ecdsavs [KeyPair|PKV|SigGen|SigVer]\n");
409                 return 1;
410                 }
411         if (!strcmp(cmd, "KeyPair"))
412                 rv = KeyPair();
413         else if (!strcmp(cmd, "PKV"))
414                 rv = PKV();
415         else if (!strcmp(cmd, "SigVer"))
416                 rv = SigVer();
417         else if (!strcmp(cmd, "SigGen"))
418                 rv = SigGen();
419         else
420                 {
421                 fprintf(stderr, "Unknown command %s\n", cmd);
422                 return 1;
423                 }
424         if (rv <= 0)
425                 {
426                 fprintf(stderr, "Error running %s\n", cmd);
427                 return 1;
428                 }
429         return 0;
430         }
431
432 #endif