]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssl/fips/rsa/fips_rsavtest.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / openssl / 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 #include <stdio.h>
60 #include <ctype.h>
61 #include <string.h>
62 #include <openssl/bio.h>
63 #include <openssl/evp.h>
64 #include <openssl/hmac.h>
65 #include <openssl/err.h>
66 #include <openssl/x509v3.h>
67 #include <openssl/bn.h>
68
69 #ifndef OPENSSL_FIPS
70
71 int main(int argc, char *argv[])
72 {
73     printf("No FIPS RSA support\n");
74     return(0);
75 }
76
77 #else
78
79 #include <openssl/rsa.h>
80
81 #include "fips_utl.h"
82
83 int rsa_test(FILE *out, FILE *in, int saltlen);
84 static int rsa_printver(FILE *out,
85                 BIGNUM *n, BIGNUM *e,
86                 const EVP_MD *dgst,
87                 unsigned char *Msg, long Msglen,
88                 unsigned char *S, long Slen, int Saltlen);
89
90 int main(int argc, char **argv)
91         {
92         FILE *in = NULL, *out = NULL;
93
94         int ret = 1;
95         int Saltlen = -1;
96
97         if(!FIPS_mode_set(1))
98                 {
99                 do_print_errors();
100                 goto end;
101                 }
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 (ret)
154                 do_print_errors();
155
156         if (in && (in != stdin))
157                 fclose(in);
158         if (out && (out != stdout))
159                 fclose(out);
160
161         return ret;
162
163         }
164
165 #define RSA_TEST_MAXLINELEN     10240
166
167 int rsa_test(FILE *out, FILE *in, int Saltlen)
168         {
169         char *linebuf, *olinebuf, *p, *q;
170         char *keyword, *value;
171         const EVP_MD *dgst = NULL;
172         BIGNUM *n = NULL, *e = NULL;
173         unsigned char *Msg = NULL, *S = NULL;
174         long Msglen, Slen;
175         int ret = 0;
176         int lnum = 0;
177
178         olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
179         linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
180
181         if (!linebuf || !olinebuf)
182                 goto error;
183
184         while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
185                 {
186                 lnum++;
187                 strcpy(linebuf, olinebuf);
188                 keyword = linebuf;
189                 /* Skip leading space */
190                 while (isspace((unsigned char)*keyword))
191                         keyword++;
192
193                 /* Look for = sign */
194                 p = strchr(linebuf, '=');
195
196                 /* If no = or starts with [ (for [foo = bar] line) just copy */
197                 if (!p || *keyword=='[')
198                         {
199                         if (fputs(olinebuf, out) < 0)
200                                 goto error;
201                         continue;
202                         }
203
204                 q = p - 1;
205
206                 /* Remove trailing space */
207                 while (isspace((unsigned char)*q))
208                         *q-- = 0;
209
210                 *p = 0;
211                 value = p + 1;
212
213                 /* Remove leading space from value */
214                 while (isspace((unsigned char)*value))
215                         value++;
216
217                 /* Remove trailing space from value */
218                 p = value + strlen(value) - 1;
219
220                 while (*p == '\n' || isspace((unsigned char)*p))
221                         *p-- = 0;
222
223                 if (!strcmp(keyword, "n"))
224                         {
225                         if (!do_hex2bn(&n,value))
226                                 goto parse_error;
227                         }
228                 else if (!strcmp(keyword, "e"))
229                         {
230                         if (!do_hex2bn(&e,value))
231                                 goto parse_error;
232                         }
233                 else if (!strcmp(keyword, "SHAAlg"))
234                         {
235                         if (!strcmp(value, "SHA1"))
236                                 dgst = EVP_sha1();
237                         else if (!strcmp(value, "SHA224"))
238                                 dgst = EVP_sha224();
239                         else if (!strcmp(value, "SHA256"))
240                                 dgst = EVP_sha256();
241                         else if (!strcmp(value, "SHA384"))
242                                 dgst = EVP_sha384();
243                         else if (!strcmp(value, "SHA512"))
244                                 dgst = EVP_sha512();
245                         else
246                                 {
247                                 fprintf(stderr,
248                                         "FATAL: unsupported algorithm \"%s\"\n",
249                                                                 value);
250                                 goto parse_error;
251                                 }
252                         }
253                 else if (!strcmp(keyword, "Msg"))
254                         {
255                         if (Msg)
256                                 goto parse_error;
257                         if (strlen(value) & 1)
258                                 *(--value) = '0';
259                         Msg = hex2bin_m(value, &Msglen);
260                         if (!Msg)
261                                 goto parse_error;
262                         }
263                 else if (!strcmp(keyword, "S"))
264                         {
265                         if (S)
266                                 goto parse_error;
267                         if (strlen(value) & 1)
268                                 *(--value) = '0';
269                         S = hex2bin_m(value, &Slen);
270                         if (!S)
271                                 goto parse_error;
272                         }
273                 else if (!strcmp(keyword, "Result"))
274                         continue;
275                 else
276                         goto parse_error;
277
278                 fputs(olinebuf, out);
279
280                 if (n && e && Msg && S && dgst)
281                         {
282                         if (!rsa_printver(out, n, e, dgst,
283                                         Msg, Msglen, S, Slen, Saltlen))
284                                 goto error;
285                         OPENSSL_free(Msg);
286                         Msg = NULL;
287                         OPENSSL_free(S);
288                         S = NULL;
289                         }
290
291                 }
292
293
294         ret = 1;
295
296
297         error:
298
299         if (olinebuf)
300                 OPENSSL_free(olinebuf);
301         if (linebuf)
302                 OPENSSL_free(linebuf);
303         if (n)
304                 BN_free(n);
305         if (e)
306                 BN_free(e);
307
308         return ret;
309
310         parse_error:
311
312         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
313
314         goto error;
315
316         }
317
318 static int rsa_printver(FILE *out,
319                 BIGNUM *n, BIGNUM *e,
320                 const EVP_MD *dgst,
321                 unsigned char *Msg, long Msglen,
322                 unsigned char *S, long Slen, int Saltlen)
323         {
324         int ret = 0, r;
325         /* Setup RSA and EVP_PKEY structures */
326         RSA *rsa_pubkey = NULL;
327         EVP_PKEY pk;
328         EVP_MD_CTX ctx;
329         unsigned char *buf = NULL;
330         rsa_pubkey = FIPS_rsa_new();
331         if (!rsa_pubkey)
332                 goto error;
333         rsa_pubkey->n = BN_dup(n);
334         rsa_pubkey->e = BN_dup(e);
335         if (!rsa_pubkey->n || !rsa_pubkey->e)
336                 goto error;
337         pk.type = EVP_PKEY_RSA;
338         pk.pkey.rsa = rsa_pubkey;
339
340         EVP_MD_CTX_init(&ctx);
341
342         if (Saltlen >= 0)
343                 {
344                 M_EVP_MD_CTX_set_flags(&ctx,
345                         EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16));
346                 }
347         else if (Saltlen == -2)
348                 M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931);
349         if (!EVP_VerifyInit_ex(&ctx, dgst, NULL))
350                 goto error;
351         if (!EVP_VerifyUpdate(&ctx, Msg, Msglen))
352                 goto error;
353
354         r = EVP_VerifyFinal(&ctx, S, Slen, &pk);
355
356
357         EVP_MD_CTX_cleanup(&ctx);
358
359         if (r < 0)
360                 goto error;
361         ERR_clear_error();
362
363         if (r == 0)
364                 fputs("Result = F\n", out);
365         else
366                 fputs("Result = P\n", out);
367
368         ret = 1;
369
370         error:
371         if (rsa_pubkey)
372                 FIPS_rsa_free(rsa_pubkey);
373         if (buf)
374                 OPENSSL_free(buf);
375
376         return ret;
377         }
378 #endif