]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssl/fips/rsa/fips_rsastest.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_rsastest.c
1 /* fips_rsastest.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/bn.h>
67 #include <openssl/x509v3.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 #include "fips_utl.h"
81
82 static int rsa_stest(FILE *out, FILE *in, int Saltlen);
83 static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
84                 unsigned char *Msg, long Msglen, int Saltlen);
85
86 int main(int argc, char **argv)
87         {
88         FILE *in = NULL, *out = NULL;
89
90         int ret = 1, Saltlen = -1;
91
92         if(!FIPS_mode_set(1))
93                 {
94                 do_print_errors();
95                 goto end;
96                 }
97
98         if ((argc > 2) && !strcmp("-saltlen", argv[1]))
99                 {
100                 Saltlen = atoi(argv[2]);
101                 if (Saltlen < 0)
102                         {
103                         fprintf(stderr, "FATAL: Invalid salt length\n");
104                         goto end;
105                         }
106                 argc -= 2;
107                 argv += 2;
108                 }
109         else if ((argc > 1) && !strcmp("-x931", argv[1]))
110                 {
111                 Saltlen = -2;
112                 argc--;
113                 argv++;
114                 }
115
116         if (argc == 1)
117                 in = stdin;
118         else
119                 in = fopen(argv[1], "r");
120
121         if (argc < 2)
122                 out = stdout;
123         else
124                 out = fopen(argv[2], "w");
125
126         if (!in)
127                 {
128                 fprintf(stderr, "FATAL input initialization error\n");
129                 goto end;
130                 }
131
132         if (!out)
133                 {
134                 fprintf(stderr, "FATAL output initialization error\n");
135                 goto end;
136                 }
137
138         if (!rsa_stest(out, in, Saltlen))
139                 {
140                 fprintf(stderr, "FATAL RSASTEST file processing error\n");
141                 goto end;
142                 }
143         else
144                 ret = 0;
145
146         end:
147
148         if (ret)
149                 do_print_errors();
150
151         if (in && (in != stdin))
152                 fclose(in);
153         if (out && (out != stdout))
154                 fclose(out);
155
156         return ret;
157
158         }
159
160 #define RSA_TEST_MAXLINELEN     10240
161
162 int rsa_stest(FILE *out, FILE *in, int Saltlen)
163         {
164         char *linebuf, *olinebuf, *p, *q;
165         char *keyword, *value;
166         RSA *rsa = NULL;
167         const EVP_MD *dgst = NULL;
168         unsigned char *Msg = NULL;
169         long Msglen = -1;
170         int keylen = -1, current_keylen = -1;
171         int ret = 0;
172         int lnum = 0;
173
174         olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
175         linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
176
177         if (!linebuf || !olinebuf)
178                 goto error;
179
180         while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
181                 {
182                 lnum++;
183                 strcpy(linebuf, olinebuf);
184                 keyword = linebuf;
185                 /* Skip leading space */
186                 while (isspace((unsigned char)*keyword))
187                         keyword++;
188
189                 /* Look for = sign */
190                 p = strchr(linebuf, '=');
191
192                 /* If no = just copy */
193                 if (!p)
194                         {
195                         if (fputs(olinebuf, out) < 0)
196                                 goto error;
197                         continue;
198                         }
199
200                 q = p - 1;
201
202                 /* Remove trailing space */
203                 while (isspace((unsigned char)*q))
204                         *q-- = 0;
205
206                 *p = 0;
207                 value = p + 1;
208
209                 /* Remove leading space from value */
210                 while (isspace((unsigned char)*value))
211                         value++;
212
213                 /* Remove trailing space from value */
214                 p = value + strlen(value) - 1;
215
216                 while (*p == '\n' || isspace((unsigned char)*p))
217                         *p-- = 0;
218
219                 /* Look for [mod = XXX] for key length */
220
221                 if (!strcmp(keyword, "[mod"))
222                         {
223                         p = value + strlen(value) - 1;
224                         if (*p != ']')
225                                 goto parse_error;
226                         *p = 0;
227                         keylen = atoi(value);
228                         if (keylen < 0)
229                                 goto parse_error;
230                         }
231                 else if (!strcmp(keyword, "SHAAlg"))
232                         {
233                         if (!strcmp(value, "SHA1"))
234                                 dgst = EVP_sha1();
235                         else if (!strcmp(value, "SHA224"))
236                                 dgst = EVP_sha224();
237                         else if (!strcmp(value, "SHA256"))
238                                 dgst = EVP_sha256();
239                         else if (!strcmp(value, "SHA384"))
240                                 dgst = EVP_sha384();
241                         else if (!strcmp(value, "SHA512"))
242                                 dgst = EVP_sha512();
243                         else
244                                 {
245                                 fprintf(stderr,
246                                         "FATAL: unsupported algorithm \"%s\"\n",
247                                                                 value);
248                                 goto parse_error;
249                                 }
250                         }
251                 else if (!strcmp(keyword, "Msg"))
252                         {
253                         if (Msg)
254                                 goto parse_error;
255                         if (strlen(value) & 1)
256                                 *(--value) = '0';
257                         Msg = hex2bin_m(value, &Msglen);
258                         if (!Msg)
259                                 goto parse_error;
260                         }
261
262                 fputs(olinebuf, out);
263
264                 /* If key length has changed, generate and output public
265                  * key components of new RSA private key.
266                  */
267
268                 if (keylen != current_keylen)
269                         {
270                         BIGNUM *bn_e;
271                         if (rsa)
272                                 FIPS_rsa_free(rsa);
273                         rsa = FIPS_rsa_new();
274                         if (!rsa)
275                                 goto error;
276                         bn_e = BN_new();
277                         if (!bn_e || !BN_set_word(bn_e, 0x1001))
278                                 goto error;
279                         if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL))
280                                 goto error;
281                         BN_free(bn_e);
282                         fputs("n = ", out);
283                         do_bn_print(out, rsa->n);
284                         fputs("\ne = ", out);
285                         do_bn_print(out, rsa->e);
286                         fputs("\n", out);
287                         current_keylen = keylen;
288                         }
289
290                 if (Msg && dgst)
291                         {
292                         if (!rsa_printsig(out, rsa, dgst, Msg, Msglen,
293                                                                 Saltlen))
294                                 goto error;
295                         OPENSSL_free(Msg);
296                         Msg = NULL;
297                         }
298
299                 }
300
301         ret = 1;
302
303         error:
304
305         if (olinebuf)
306                 OPENSSL_free(olinebuf);
307         if (linebuf)
308                 OPENSSL_free(linebuf);
309         if (rsa)
310                 FIPS_rsa_free(rsa);
311
312         return ret;
313
314         parse_error:
315
316         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
317
318         goto error;
319
320         }
321
322 static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
323                 unsigned char *Msg, long Msglen, int Saltlen)
324         {
325         int ret = 0;
326         unsigned char *sigbuf = NULL;
327         int i, siglen;
328         /* EVP_PKEY structure */
329         EVP_PKEY pk;
330         EVP_MD_CTX ctx;
331         pk.type = EVP_PKEY_RSA;
332         pk.pkey.rsa = rsa;
333
334         siglen = RSA_size(rsa);
335         sigbuf = OPENSSL_malloc(siglen);
336         if (!sigbuf)
337                 goto error;
338
339         EVP_MD_CTX_init(&ctx);
340
341         if (Saltlen >= 0)
342                 {
343                 M_EVP_MD_CTX_set_flags(&ctx,
344                         EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16));
345                 }
346         else if (Saltlen == -2)
347                 M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931);
348         if (!EVP_SignInit_ex(&ctx, dgst, NULL))
349                 goto error;
350         if (!EVP_SignUpdate(&ctx, Msg, Msglen))
351                 goto error;
352         if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk))
353                 goto error;
354
355         EVP_MD_CTX_cleanup(&ctx);
356
357         fputs("S = ", out);
358
359         for (i = 0; i < siglen; i++)
360                 fprintf(out, "%02X", sigbuf[i]);
361
362         fputs("\n", out);
363
364         ret = 1;
365
366         error:
367
368         return ret;
369         }
370 #endif