OLD | NEW |
| (Empty) |
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 | |
OLD | NEW |