Add release dates to NEWS
[openssl.git] / fips / rsa / fips_rsagtest.c
1 /* fips_rsagtest.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2005.
4  */
5 /* ====================================================================
6  * Copyright (c) 2005,2007 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #define OPENSSL_FIPSAPI
60
61 #include <stdio.h>
62 #include <ctype.h>
63 #include <string.h>
64 #include <openssl/bio.h>
65 #include <openssl/evp.h>
66 #include <openssl/hmac.h>
67 #include <openssl/err.h>
68 #include <openssl/bn.h>
69
70 #ifndef OPENSSL_FIPS
71
72 int main(int argc, char *argv[])
73 {
74     printf("No FIPS RSA support\n");
75     return(0);
76 }
77
78 #else
79
80 #include <openssl/rsa.h>
81 #include <openssl/fips.h>
82 #include "fips_utl.h"
83
84 int rsa_test(FILE *out, FILE *in);
85 static int rsa_printkey1(FILE *out, RSA *rsa,
86                 BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
87                 BIGNUM *e);
88 static int rsa_printkey2(FILE *out, RSA *rsa,
89                 BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq);
90
91 #ifdef FIPS_ALGVS
92 int fips_rsagtest_main(int argc, char **argv)
93 #else
94 int main(int argc, char **argv)
95 #endif
96         {
97         FILE *in = NULL, *out = NULL;
98
99         int ret = 1;
100
101         fips_algtest_init();
102
103         if (argc == 1)
104                 in = stdin;
105         else
106                 in = fopen(argv[1], "r");
107
108         if (argc < 2)
109                 out = stdout;
110         else
111                 out = fopen(argv[2], "w");
112
113         if (!in)
114                 {
115                 fprintf(stderr, "FATAL input initialization error\n");
116                 goto end;
117                 }
118
119         if (!out)
120                 {
121                 fprintf(stderr, "FATAL output initialization error\n");
122                 goto end;
123                 }
124
125         if (!rsa_test(out, in))
126                 {
127                 fprintf(stderr, "FATAL RSAGTEST file processing error\n");
128                 goto end;
129                 }
130         else
131                 ret = 0;
132
133         end:
134
135         if (in && (in != stdin))
136                 fclose(in);
137         if (out && (out != stdout))
138                 fclose(out);
139
140         return ret;
141
142         }
143
144 #define RSA_TEST_MAXLINELEN     10240
145
146 int rsa_test(FILE *out, FILE *in)
147         {
148         char *linebuf, *olinebuf, *p, *q;
149         char *keyword, *value;
150         RSA *rsa = NULL;
151         BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL;
152         BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL;
153         BIGNUM *e = NULL;
154         int ret = 0;
155         int lnum = 0;
156
157         olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
158         linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
159
160         if (!linebuf || !olinebuf)
161                 goto error;
162
163         while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
164                 {
165                 lnum++;
166                 strcpy(linebuf, olinebuf);
167                 keyword = linebuf;
168                 /* Skip leading space */
169                 while (isspace((unsigned char)*keyword))
170                         keyword++;
171
172                 /* Look for = sign */
173                 p = strchr(linebuf, '=');
174
175                 /* If no = or starts with [ (for [foo = bar] line) just copy */
176                 if (!p || *keyword=='[')
177                         {
178                         if (fputs(olinebuf, out) < 0)
179                                 goto error;
180                         continue;
181                         }
182
183                 q = p - 1;
184
185                 /* Remove trailing space */
186                 while (isspace((unsigned char)*q))
187                         *q-- = 0;
188
189                 *p = 0;
190                 value = p + 1;
191
192                 /* Remove leading space from value */
193                 while (isspace((unsigned char)*value))
194                         value++;
195
196                 /* Remove trailing space from value */
197                 p = value + strlen(value) - 1;
198
199                 while (*p == '\n' || isspace((unsigned char)*p))
200                         *p-- = 0;
201
202                 if (!strcmp(keyword, "xp1"))
203                         {
204                         if (Xp1 || !do_hex2bn(&Xp1,value))
205                                 goto parse_error;
206                         }
207                 else if (!strcmp(keyword, "xp2"))
208                         {
209                         if (Xp2 || !do_hex2bn(&Xp2,value))
210                                 goto parse_error;
211                         }
212                 else if (!strcmp(keyword, "Xp"))
213                         {
214                         if (Xp || !do_hex2bn(&Xp,value))
215                                 goto parse_error;
216                         }
217                 else if (!strcmp(keyword, "xq1"))
218                         {
219                         if (Xq1 || !do_hex2bn(&Xq1,value))
220                                 goto parse_error;
221                         }
222                 else if (!strcmp(keyword, "xq2"))
223                         {
224                         if (Xq2 || !do_hex2bn(&Xq2,value))
225                                 goto parse_error;
226                         }
227                 else if (!strcmp(keyword, "Xq"))
228                         {
229                         if (Xq || !do_hex2bn(&Xq,value))
230                                 goto parse_error;
231                         }
232                 else if (!strcmp(keyword, "e"))
233                         {
234                         if (e || !do_hex2bn(&e,value))
235                                 goto parse_error;
236                         }
237                 else if (!strcmp(keyword, "p1"))
238                         continue;
239                 else if (!strcmp(keyword, "p2"))
240                         continue;
241                 else if (!strcmp(keyword, "p"))
242                         continue;
243                 else if (!strcmp(keyword, "q1"))
244                         continue;
245                 else if (!strcmp(keyword, "q2"))
246                         continue;
247                 else if (!strcmp(keyword, "q"))
248                         continue;
249                 else if (!strcmp(keyword, "n"))
250                         continue;
251                 else if (!strcmp(keyword, "d"))
252                         continue;
253                 else
254                         goto parse_error;
255
256                 fputs(olinebuf, out);
257
258                 if (e && Xp1 && Xp2 && Xp)
259                         {
260                         rsa = FIPS_rsa_new();
261                         if (!rsa)
262                                 goto error;
263                         if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e))
264                                 goto error;
265                         BN_free(Xp1);
266                         Xp1 = NULL;
267                         BN_free(Xp2);
268                         Xp2 = NULL;
269                         BN_free(Xp);
270                         Xp = NULL;
271                         BN_free(e);
272                         e = NULL;
273                         }
274
275                 if (rsa && Xq1 && Xq2 && Xq)
276                         {
277                         if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq))
278                                 goto error;
279                         BN_free(Xq1);
280                         Xq1 = NULL;
281                         BN_free(Xq2);
282                         Xq2 = NULL;
283                         BN_free(Xq);
284                         Xq = NULL;
285                         FIPS_rsa_free(rsa);
286                         rsa = NULL;
287                         }
288                 }
289
290         ret = 1;
291
292         error:
293
294         if (olinebuf)
295                 OPENSSL_free(olinebuf);
296         if (linebuf)
297                 OPENSSL_free(linebuf);
298
299         if (Xp1)
300                 BN_free(Xp1);
301         if (Xp2)
302                 BN_free(Xp2);
303         if (Xp)
304                 BN_free(Xp);
305         if (Xq1)
306                 BN_free(Xq1);
307         if (Xq1)
308                 BN_free(Xq1);
309         if (Xq2)
310                 BN_free(Xq2);
311         if (Xq)
312                 BN_free(Xq);
313         if (e)
314                 BN_free(e);
315         if (rsa)
316                 FIPS_rsa_free(rsa);
317
318         return ret;
319
320         parse_error:
321
322         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
323
324         goto error;
325
326         }
327
328 static int rsa_printkey1(FILE *out, RSA *rsa,
329                 BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
330                 BIGNUM *e)
331         {
332         int ret = 0;
333         BIGNUM *p1 = NULL, *p2 = NULL;
334         p1 = BN_new();
335         p2 = BN_new();
336         if (!p1 || !p2)
337                 goto error;
338
339         if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp,
340                                                 NULL, NULL, NULL, e, NULL))
341                 goto error;
342
343         do_bn_print_name(out, "p1", p1);
344         do_bn_print_name(out, "p2", p2);
345         do_bn_print_name(out, "p", rsa->p);
346
347         ret = 1;
348
349         error:
350         if (p1)
351                 BN_free(p1);
352         if (p2)
353                 BN_free(p2);
354
355         return ret;
356         }
357
358 static int rsa_printkey2(FILE *out, RSA *rsa,
359                 BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq)
360         {
361         int ret = 0;
362         BIGNUM *q1 = NULL, *q2 = NULL;
363         q1 = BN_new();
364         q2 = BN_new();
365         if (!q1 || !q2)
366                 goto error;
367
368         if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL,
369                                                 Xq1, Xq2, Xq, NULL, NULL))
370                 goto error;
371
372         do_bn_print_name(out, "q1", q1);
373         do_bn_print_name(out, "q2", q2);
374         do_bn_print_name(out, "q", rsa->q);
375         do_bn_print_name(out, "n", rsa->n);
376         do_bn_print_name(out, "d", rsa->d);
377
378         ret = 1;
379
380         error:
381         if (q1)
382                 BN_free(q1);
383         if (q2)
384                 BN_free(q2);
385
386         return ret;
387         }
388
389 #endif