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