Initial perl script to filter out unneeded files for a fips tarball.
[openssl.git] / fips / rsa / fips_rsavtest.c
1 /* fips_rsavtest.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2005.
4  */
5 /* ====================================================================
6  * Copyright (c) 2005 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
83 #include "fips_utl.h"
84
85 int rsa_test(FILE *out, FILE *in, int saltlen);
86 static int rsa_printver(FILE *out,
87                 BIGNUM *n, BIGNUM *e,
88                 const EVP_MD *dgst,
89                 unsigned char *Msg, long Msglen,
90                 unsigned char *S, long Slen, int Saltlen);
91
92 int main(int argc, char **argv)
93         {
94         FILE *in = NULL, *out = NULL;
95
96         int ret = 1;
97         int Saltlen = -1;
98
99         fips_set_error_print();
100         if(!FIPS_mode_set(1))
101                 goto end;
102
103         if ((argc > 2) && !strcmp("-saltlen", argv[1]))
104                 {
105                 Saltlen = atoi(argv[2]);
106                 if (Saltlen < 0)
107                         {
108                         fprintf(stderr, "FATAL: Invalid salt length\n");
109                         goto end;
110                         }
111                 argc -= 2;
112                 argv += 2;
113                 }
114         else if ((argc > 1) && !strcmp("-x931", argv[1]))
115                 {
116                 Saltlen = -2;
117                 argc--;
118                 argv++;
119                 }
120
121         if (argc == 1)
122                 in = stdin;
123         else
124                 in = fopen(argv[1], "r");
125
126         if (argc < 2)
127                 out = stdout;
128         else
129                 out = fopen(argv[2], "w");
130
131         if (!in)
132                 {
133                 fprintf(stderr, "FATAL input initialization error\n");
134                 goto end;
135                 }
136
137         if (!out)
138                 {
139                 fprintf(stderr, "FATAL output initialization error\n");
140                 goto end;
141                 }
142
143         if (!rsa_test(out, in, Saltlen))
144                 {
145                 fprintf(stderr, "FATAL RSAVTEST file processing error\n");
146                 goto end;
147                 }
148         else
149                 ret = 0;
150
151         end:
152
153         if (in && (in != stdin))
154                 fclose(in);
155         if (out && (out != stdout))
156                 fclose(out);
157
158         return ret;
159
160         }
161
162 #define RSA_TEST_MAXLINELEN     10240
163
164 int rsa_test(FILE *out, FILE *in, int Saltlen)
165         {
166         char *linebuf, *olinebuf, *p, *q;
167         char *keyword, *value;
168         const EVP_MD *dgst = NULL;
169         BIGNUM *n = NULL, *e = NULL;
170         unsigned char *Msg = NULL, *S = NULL;
171         long Msglen, Slen;
172         int ret = 0;
173         int lnum = 0;
174
175         olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
176         linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
177
178         if (!linebuf || !olinebuf)
179                 goto error;
180
181         while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
182                 {
183                 lnum++;
184                 strcpy(linebuf, olinebuf);
185                 keyword = linebuf;
186                 /* Skip leading space */
187                 while (isspace((unsigned char)*keyword))
188                         keyword++;
189
190                 /* Look for = sign */
191                 p = strchr(linebuf, '=');
192
193                 /* If no = or starts with [ (for [foo = bar] line) just copy */
194                 if (!p || *keyword=='[')
195                         {
196                         if (fputs(olinebuf, out) < 0)
197                                 goto error;
198                         continue;
199                         }
200
201                 q = p - 1;
202
203                 /* Remove trailing space */
204                 while (isspace((unsigned char)*q))
205                         *q-- = 0;
206
207                 *p = 0;
208                 value = p + 1;
209
210                 /* Remove leading space from value */
211                 while (isspace((unsigned char)*value))
212                         value++;
213
214                 /* Remove trailing space from value */
215                 p = value + strlen(value) - 1;
216
217                 while (*p == '\n' || isspace((unsigned char)*p))
218                         *p-- = 0;
219
220                 if (!strcmp(keyword, "n"))
221                         {
222                         if (!do_hex2bn(&n,value))
223                                 goto parse_error;
224                         }
225                 else if (!strcmp(keyword, "e"))
226                         {
227                         if (!do_hex2bn(&e,value))
228                                 goto parse_error;
229                         }
230                 else if (!strcmp(keyword, "SHAAlg"))
231                         {
232                         if (!strcmp(value, "SHA1"))
233                                 dgst = EVP_sha1();
234                         else if (!strcmp(value, "SHA224"))
235                                 dgst = EVP_sha224();
236                         else if (!strcmp(value, "SHA256"))
237                                 dgst = EVP_sha256();
238                         else if (!strcmp(value, "SHA384"))
239                                 dgst = EVP_sha384();
240                         else if (!strcmp(value, "SHA512"))
241                                 dgst = EVP_sha512();
242                         else
243                                 {
244                                 fprintf(stderr,
245                                         "FATAL: unsupported algorithm \"%s\"\n",
246                                                                 value);
247                                 goto parse_error;
248                                 }
249                         }
250                 else if (!strcmp(keyword, "Msg"))
251                         {
252                         if (Msg)
253                                 goto parse_error;
254                         if (strlen(value) & 1)
255                                 *(--value) = '0';
256                         Msg = hex2bin_m(value, &Msglen);
257                         if (!Msg)
258                                 goto parse_error;
259                         }
260                 else if (!strcmp(keyword, "S"))
261                         {
262                         if (S)
263                                 goto parse_error;
264                         if (strlen(value) & 1)
265                                 *(--value) = '0';
266                         S = hex2bin_m(value, &Slen);
267                         if (!S)
268                                 goto parse_error;
269                         }
270                 else if (!strcmp(keyword, "Result"))
271                         continue;
272                 else
273                         goto parse_error;
274
275                 fputs(olinebuf, out);
276
277                 if (n && e && Msg && S && dgst)
278                         {
279                         if (!rsa_printver(out, n, e, dgst,
280                                         Msg, Msglen, S, Slen, Saltlen))
281                                 goto error;
282                         OPENSSL_free(Msg);
283                         Msg = NULL;
284                         OPENSSL_free(S);
285                         S = NULL;
286                         }
287
288                 }
289
290
291         ret = 1;
292
293
294         error:
295
296         if (olinebuf)
297                 OPENSSL_free(olinebuf);
298         if (linebuf)
299                 OPENSSL_free(linebuf);
300         if (n)
301                 BN_free(n);
302         if (e)
303                 BN_free(e);
304
305         return ret;
306
307         parse_error:
308
309         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
310
311         goto error;
312
313         }
314
315 static int rsa_printver(FILE *out,
316                 BIGNUM *n, BIGNUM *e,
317                 const EVP_MD *dgst,
318                 unsigned char *Msg, long Msglen,
319                 unsigned char *S, long Slen, int Saltlen)
320         {
321         int ret = 0, r, pad_mode;
322         /* Setup RSA and EVP_PKEY structures */
323         RSA *rsa_pubkey = NULL;
324         EVP_MD_CTX ctx;
325         unsigned char *buf = NULL;
326         rsa_pubkey = FIPS_rsa_new();
327         if (!rsa_pubkey)
328                 goto error;
329         rsa_pubkey->n = BN_dup(n);
330         rsa_pubkey->e = BN_dup(e);
331         if (!rsa_pubkey->n || !rsa_pubkey->e)
332                 goto error;
333
334         FIPS_md_ctx_init(&ctx);
335
336         if (Saltlen >= 0)
337                 pad_mode = RSA_PKCS1_PSS_PADDING;
338         else if (Saltlen == -2)
339                 pad_mode = RSA_X931_PADDING;
340         else
341                 pad_mode = RSA_PKCS1_PADDING;
342
343         if (!FIPS_digestinit(&ctx, dgst))
344                 goto error;
345         if (!FIPS_digestupdate(&ctx, Msg, Msglen))
346                 goto error;
347
348         no_err = 1;
349         r = FIPS_rsa_verify_ctx(rsa_pubkey, &ctx,
350                                 pad_mode, Saltlen, NULL, S, Slen);
351         no_err = 0;
352
353
354         FIPS_md_ctx_cleanup(&ctx);
355
356         if (r < 0)
357                 goto error;
358
359         if (r == 0)
360                 fputs("Result = F\n", out);
361         else
362                 fputs("Result = P\n", out);
363
364         ret = 1;
365
366         error:
367         if (rsa_pubkey)
368                 FIPS_rsa_free(rsa_pubkey);
369         if (buf)
370                 OPENSSL_free(buf);
371
372         return ret;
373         }
374 #endif