Add sign/verify digest API to handle an explicit digest instead of finalising
[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 #include <openssl/x509v3.h>
70
71 #ifndef OPENSSL_FIPS
72
73 int main(int argc, char *argv[])
74 {
75     printf("No FIPS RSA support\n");
76     return(0);
77 }
78
79 #else
80
81 #include <openssl/rsa.h>
82 #include <openssl/fips.h>
83 #include "fips_utl.h"
84
85 int rsa_test(FILE *out, FILE *in);
86 static int rsa_printkey1(FILE *out, RSA *rsa,
87                 BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
88                 BIGNUM *e);
89 static int rsa_printkey2(FILE *out, RSA *rsa,
90                 BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq);
91
92 int main(int argc, char **argv)
93         {
94         FILE *in = NULL, *out = NULL;
95
96         int ret = 1;
97
98         fips_set_error_print();
99         if(!FIPS_mode_set(1))
100                 goto end;
101
102         if (argc == 1)
103                 in = stdin;
104         else
105                 in = fopen(argv[1], "r");
106
107         if (argc < 2)
108                 out = stdout;
109         else
110                 out = fopen(argv[2], "w");
111
112         if (!in)
113                 {
114                 fprintf(stderr, "FATAL input initialization error\n");
115                 goto end;
116                 }
117
118         if (!out)
119                 {
120                 fprintf(stderr, "FATAL output initialization error\n");
121                 goto end;
122                 }
123
124         if (!rsa_test(out, in))
125                 {
126                 fprintf(stderr, "FATAL RSAGTEST file processing error\n");
127                 goto end;
128                 }
129         else
130                 ret = 0;
131
132         end:
133
134         if (in && (in != stdin))
135                 fclose(in);
136         if (out && (out != stdout))
137                 fclose(out);
138
139         return ret;
140
141         }
142
143 #define RSA_TEST_MAXLINELEN     10240
144
145 int rsa_test(FILE *out, FILE *in)
146         {
147         char *linebuf, *olinebuf, *p, *q;
148         char *keyword, *value;
149         RSA *rsa = NULL;
150         BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL;
151         BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL;
152         BIGNUM *e = NULL;
153         int ret = 0;
154         int lnum = 0;
155
156         olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
157         linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
158
159         if (!linebuf || !olinebuf)
160                 goto error;
161
162         while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
163                 {
164                 lnum++;
165                 strcpy(linebuf, olinebuf);
166                 keyword = linebuf;
167                 /* Skip leading space */
168                 while (isspace((unsigned char)*keyword))
169                         keyword++;
170
171                 /* Look for = sign */
172                 p = strchr(linebuf, '=');
173
174                 /* If no = or starts with [ (for [foo = bar] line) just copy */
175                 if (!p || *keyword=='[')
176                         {
177                         if (fputs(olinebuf, out) < 0)
178                                 goto error;
179                         continue;
180                         }
181
182                 q = p - 1;
183
184                 /* Remove trailing space */
185                 while (isspace((unsigned char)*q))
186                         *q-- = 0;
187
188                 *p = 0;
189                 value = p + 1;
190
191                 /* Remove leading space from value */
192                 while (isspace((unsigned char)*value))
193                         value++;
194
195                 /* Remove trailing space from value */
196                 p = value + strlen(value) - 1;
197
198                 while (*p == '\n' || isspace((unsigned char)*p))
199                         *p-- = 0;
200
201                 if (!strcmp(keyword, "xp1"))
202                         {
203                         if (Xp1 || !do_hex2bn(&Xp1,value))
204                                 goto parse_error;
205                         }
206                 else if (!strcmp(keyword, "xp2"))
207                         {
208                         if (Xp2 || !do_hex2bn(&Xp2,value))
209                                 goto parse_error;
210                         }
211                 else if (!strcmp(keyword, "Xp"))
212                         {
213                         if (Xp || !do_hex2bn(&Xp,value))
214                                 goto parse_error;
215                         }
216                 else if (!strcmp(keyword, "xq1"))
217                         {
218                         if (Xq1 || !do_hex2bn(&Xq1,value))
219                                 goto parse_error;
220                         }
221                 else if (!strcmp(keyword, "xq2"))
222                         {
223                         if (Xq2 || !do_hex2bn(&Xq2,value))
224                                 goto parse_error;
225                         }
226                 else if (!strcmp(keyword, "Xq"))
227                         {
228                         if (Xq || !do_hex2bn(&Xq,value))
229                                 goto parse_error;
230                         }
231                 else if (!strcmp(keyword, "e"))
232                         {
233                         if (e || !do_hex2bn(&e,value))
234                                 goto parse_error;
235                         }
236                 else if (!strcmp(keyword, "p1"))
237                         continue;
238                 else if (!strcmp(keyword, "p2"))
239                         continue;
240                 else if (!strcmp(keyword, "p"))
241                         continue;
242                 else if (!strcmp(keyword, "q1"))
243                         continue;
244                 else if (!strcmp(keyword, "q2"))
245                         continue;
246                 else if (!strcmp(keyword, "q"))
247                         continue;
248                 else if (!strcmp(keyword, "n"))
249                         continue;
250                 else if (!strcmp(keyword, "d"))
251                         continue;
252                 else
253                         goto parse_error;
254
255                 fputs(olinebuf, out);
256
257                 if (e && Xp1 && Xp2 && Xp)
258                         {
259                         rsa = FIPS_rsa_new();
260                         if (!rsa)
261                                 goto error;
262                         if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e))
263                                 goto error;
264                         BN_free(Xp1);
265                         Xp1 = NULL;
266                         BN_free(Xp2);
267                         Xp2 = NULL;
268                         BN_free(Xp);
269                         Xp = NULL;
270                         BN_free(e);
271                         e = NULL;
272                         }
273
274                 if (rsa && Xq1 && Xq2 && Xq)
275                         {
276                         if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq))
277                                 goto error;
278                         BN_free(Xq1);
279                         Xq1 = NULL;
280                         BN_free(Xq2);
281                         Xq2 = NULL;
282                         BN_free(Xq);
283                         Xq = NULL;
284                         FIPS_rsa_free(rsa);
285                         rsa = NULL;
286                         }
287                 }
288
289         ret = 1;
290
291         error:
292
293         if (olinebuf)
294                 OPENSSL_free(olinebuf);
295         if (linebuf)
296                 OPENSSL_free(linebuf);
297
298         if (Xp1)
299                 BN_free(Xp1);
300         if (Xp2)
301                 BN_free(Xp2);
302         if (Xp)
303                 BN_free(Xp);
304         if (Xq1)
305                 BN_free(Xq1);
306         if (Xq1)
307                 BN_free(Xq1);
308         if (Xq2)
309                 BN_free(Xq2);
310         if (Xq)
311                 BN_free(Xq);
312         if (e)
313                 BN_free(e);
314         if (rsa)
315                 FIPS_rsa_free(rsa);
316
317         return ret;
318
319         parse_error:
320
321         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
322
323         goto error;
324
325         }
326
327 static int rsa_printkey1(FILE *out, RSA *rsa,
328                 BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
329                 BIGNUM *e)
330         {
331         int ret = 0;
332         BIGNUM *p1 = NULL, *p2 = NULL;
333         p1 = BN_new();
334         p2 = BN_new();
335         if (!p1 || !p2)
336                 goto error;
337
338         if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp,
339                                                 NULL, NULL, NULL, e, NULL))
340                 goto error;
341
342         do_bn_print_name(out, "p1", p1);
343         do_bn_print_name(out, "p2", p2);
344         do_bn_print_name(out, "p", rsa->p);
345
346         ret = 1;
347
348         error:
349         if (p1)
350                 BN_free(p1);
351         if (p2)
352                 BN_free(p2);
353
354         return ret;
355         }
356
357 static int rsa_printkey2(FILE *out, RSA *rsa,
358                 BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq)
359         {
360         int ret = 0;
361         BIGNUM *q1 = NULL, *q2 = NULL;
362         q1 = BN_new();
363         q2 = BN_new();
364         if (!q1 || !q2)
365                 goto error;
366
367         if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL,
368                                                 Xq1, Xq2, Xq, NULL, NULL))
369                 goto error;
370
371         do_bn_print_name(out, "q1", q1);
372         do_bn_print_name(out, "q2", q2);
373         do_bn_print_name(out, "q", rsa->q);
374         do_bn_print_name(out, "n", rsa->n);
375         do_bn_print_name(out, "d", rsa->d);
376
377         ret = 1;
378
379         error:
380         if (q1)
381                 BN_free(q1);
382         if (q2)
383                 BN_free(q2);
384
385         return ret;
386         }
387
388 #endif