fips_rsastest.c revision 296465
1226890Sdim/* fips_rsastest.c */ 2193326Sed/* 3193326Sed * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4193326Sed * 2005. 5193326Sed */ 6193326Sed/* ==================================================================== 7193326Sed * Copyright (c) 2005 The OpenSSL Project. All rights reserved. 8193326Sed * 9193326Sed * Redistribution and use in source and binary forms, with or without 10193326Sed * modification, are permitted provided that the following conditions 11226890Sdim * are met: 12193326Sed * 13193326Sed * 1. Redistributions of source code must retain the above copyright 14193326Sed * notice, this list of conditions and the following disclaimer. 15212904Sdim * 16212904Sdim * 2. Redistributions in binary form must reproduce the above copyright 17193326Sed * notice, this list of conditions and the following disclaimer in 18223017Sdim * the documentation and/or other materials provided with the 19193326Sed * distribution. 20193326Sed * 21212904Sdim * 3. All advertising materials mentioning features or use of this 22193326Sed * software must display the following acknowledgment: 23193326Sed * "This product includes software developed by the OpenSSL Project 24193326Sed * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25193326Sed * 26193326Sed * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27193326Sed * endorse or promote products derived from this software without 28193326Sed * prior written permission. For written permission, please contact 29193326Sed * licensing@OpenSSL.org. 30193326Sed * 31193326Sed * 5. Products derived from this software may not be called "OpenSSL" 32193326Sed * nor may "OpenSSL" appear in their names without prior written 33193326Sed * permission of the OpenSSL Project. 34198092Srdivacky * 35193326Sed * 6. Redistributions of any form whatsoever must retain the following 36193326Sed * acknowledgment: 37193326Sed * "This product includes software developed by the OpenSSL Project 38193326Sed * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39193326Sed * 40193326Sed * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41193326Sed * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42193326Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43193326Sed * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44198092Srdivacky * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45235633Sdim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46208600Srdivacky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47198092Srdivacky * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48235633Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49208600Srdivacky * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50208600Srdivacky * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51208600Srdivacky * OF THE POSSIBILITY OF SUCH DAMAGE. 52208600Srdivacky * ==================================================================== 53193326Sed * 54193326Sed * This product includes cryptographic software written by Eric Young 55198092Srdivacky * (eay@cryptsoft.com). This product includes software written by Tim 56208600Srdivacky * Hudson (tjh@cryptsoft.com). 57208600Srdivacky * 58208600Srdivacky */ 59193326Sed 60198092Srdivacky#include <stdio.h> 61226890Sdim#include <ctype.h> 62193326Sed#include <string.h> 63226890Sdim#include <openssl/bio.h> 64208600Srdivacky#include <openssl/evp.h> 65226890Sdim#include <openssl/hmac.h> 66226890Sdim#include <openssl/err.h> 67193326Sed#include <openssl/bn.h> 68193326Sed#include <openssl/x509v3.h> 69193326Sed 70210299Sed#ifndef OPENSSL_FIPS 71224145Sdim 72224145Sdimint main(int argc, char *argv[]) 73224145Sdim{ 74224145Sdim printf("No FIPS RSA support\n"); 75193326Sed return (0); 76208600Srdivacky} 77235633Sdim 78208600Srdivacky#else 79218893Sdim 80226890Sdim# include <openssl/rsa.h> 81235633Sdim# include "fips_utl.h" 82235633Sdim 83208600Srdivackystatic int rsa_stest(FILE *out, FILE *in, int Saltlen); 84208600Srdivackystatic int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, 85193326Sed unsigned char *Msg, long Msglen, int Saltlen); 86193326Sed 87193326Sedint main(int argc, char **argv) 88193326Sed{ 89193326Sed FILE *in = NULL, *out = NULL; 90193326Sed 91208600Srdivacky int ret = 1, Saltlen = -1; 92198092Srdivacky 93193326Sed if (!FIPS_mode_set(1)) { 94193326Sed do_print_errors(); 95224145Sdim goto end; 96224145Sdim } 97198092Srdivacky 98193326Sed if ((argc > 2) && !strcmp("-saltlen", argv[1])) { 99193326Sed Saltlen = atoi(argv[2]); 100208600Srdivacky if (Saltlen < 0) { 101193326Sed fprintf(stderr, "FATAL: Invalid salt length\n"); 102198092Srdivacky goto end; 103208600Srdivacky } 104208600Srdivacky argc -= 2; 105208600Srdivacky argv += 2; 106208600Srdivacky } else if ((argc > 1) && !strcmp("-x931", argv[1])) { 107208600Srdivacky Saltlen = -2; 108208600Srdivacky argc--; 109208600Srdivacky argv++; 110208600Srdivacky } 111208600Srdivacky 112208600Srdivacky if (argc == 1) 113208600Srdivacky in = stdin; 114208600Srdivacky else 115208600Srdivacky in = fopen(argv[1], "r"); 116208600Srdivacky 117208600Srdivacky if (argc < 2) 118208600Srdivacky out = stdout; 119208600Srdivacky else 120224145Sdim out = fopen(argv[2], "w"); 121224145Sdim 122193326Sed if (!in) { 123193326Sed fprintf(stderr, "FATAL input initialization error\n"); 124224145Sdim goto end; 125193326Sed } 126245431Sdim 127193326Sed if (!out) { 128208600Srdivacky fprintf(stderr, "FATAL output initialization error\n"); 129208600Srdivacky goto end; 130224145Sdim } 131224145Sdim 132224145Sdim if (!rsa_stest(out, in, Saltlen)) { 133224145Sdim fprintf(stderr, "FATAL RSASTEST file processing error\n"); 134224145Sdim goto end; 135224145Sdim } else 136224145Sdim ret = 0; 137224145Sdim 138235633Sdim end: 139224145Sdim 140224145Sdim if (ret) 141224145Sdim do_print_errors(); 142224145Sdim 143224145Sdim if (in && (in != stdin)) 144224145Sdim fclose(in); 145224145Sdim if (out && (out != stdout)) 146224145Sdim fclose(out); 147224145Sdim 148224145Sdim return ret; 149224145Sdim 150224145Sdim} 151224145Sdim 152235633Sdim# define RSA_TEST_MAXLINELEN 10240 153235633Sdim 154224145Sdimint rsa_stest(FILE *out, FILE *in, int Saltlen) 155224145Sdim{ 156224145Sdim char *linebuf, *olinebuf, *p, *q; 157224145Sdim char *keyword, *value; 158224145Sdim RSA *rsa = NULL; 159224145Sdim const EVP_MD *dgst = NULL; 160224145Sdim unsigned char *Msg = NULL; 161224145Sdim long Msglen = -1; 162224145Sdim int keylen = -1, current_keylen = -1; 163224145Sdim int ret = 0; 164224145Sdim int lnum = 0; 165224145Sdim 166224145Sdim olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); 167245431Sdim linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); 168245431Sdim 169245431Sdim if (!linebuf || !olinebuf) 170224145Sdim goto error; 171245431Sdim 172245431Sdim while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) { 173245431Sdim lnum++; 174224145Sdim strcpy(linebuf, olinebuf); 175245431Sdim keyword = linebuf; 176245431Sdim /* Skip leading space */ 177224145Sdim while (isspace((unsigned char)*keyword)) 178245431Sdim keyword++; 179245431Sdim 180224145Sdim /* Look for = sign */ 181245431Sdim p = strchr(linebuf, '='); 182245431Sdim 183245431Sdim /* If no = just copy */ 184224145Sdim if (!p) { 185245431Sdim if (fputs(olinebuf, out) < 0) 186245431Sdim goto error; 187245431Sdim continue; 188245431Sdim } 189245431Sdim 190245431Sdim q = p - 1; 191245431Sdim 192245431Sdim /* Remove trailing space */ 193245431Sdim while (isspace((unsigned char)*q)) 194245431Sdim *q-- = 0; 195245431Sdim 196245431Sdim *p = 0; 197245431Sdim value = p + 1; 198245431Sdim 199245431Sdim /* Remove leading space from value */ 200245431Sdim while (isspace((unsigned char)*value)) 201245431Sdim value++; 202245431Sdim 203245431Sdim /* Remove trailing space from value */ 204245431Sdim p = value + strlen(value) - 1; 205245431Sdim 206245431Sdim while (*p == '\n' || isspace((unsigned char)*p)) 207245431Sdim *p-- = 0; 208210299Sed 209245431Sdim /* Look for [mod = XXX] for key length */ 210245431Sdim 211208600Srdivacky if (!strcmp(keyword, "[mod")) { 212245431Sdim p = value + strlen(value) - 1; 213245431Sdim if (*p != ']') 214208600Srdivacky goto parse_error; 215208600Srdivacky *p = 0; 216208600Srdivacky keylen = atoi(value); 217193326Sed if (keylen < 0) 218224145Sdim goto parse_error; 219193326Sed } else if (!strcmp(keyword, "SHAAlg")) { 220198092Srdivacky if (!strcmp(value, "SHA1")) 221221345Sdim dgst = EVP_sha1(); 222221345Sdim else if (!strcmp(value, "SHA224")) 223224145Sdim dgst = EVP_sha224(); 224221345Sdim else if (!strcmp(value, "SHA256")) 225221345Sdim dgst = EVP_sha256(); 226224145Sdim else if (!strcmp(value, "SHA384")) 227193326Sed dgst = EVP_sha384(); 228193326Sed else if (!strcmp(value, "SHA512")) 229210299Sed dgst = EVP_sha512(); 230210299Sed else { 231210299Sed fprintf(stderr, 232224145Sdim "FATAL: unsupported algorithm \"%s\"\n", value); 233210299Sed goto parse_error; 234210299Sed } 235210299Sed } else if (!strcmp(keyword, "Msg")) { 236210299Sed if (Msg) 237210299Sed goto parse_error; 238210299Sed if (strlen(value) & 1) 239210299Sed *(--value) = '0'; 240210299Sed Msg = hex2bin_m(value, &Msglen); 241210299Sed if (!Msg) 242210299Sed goto parse_error; 243210299Sed } 244210299Sed 245193326Sed fputs(olinebuf, out); 246224145Sdim 247224145Sdim /* 248224145Sdim * If key length has changed, generate and output public key 249224145Sdim * components of new RSA private key. 250224145Sdim */ 251224145Sdim 252224145Sdim if (keylen != current_keylen) { 253224145Sdim BIGNUM *bn_e; 254224145Sdim if (rsa) 255224145Sdim FIPS_rsa_free(rsa); 256224145Sdim rsa = FIPS_rsa_new(); 257224145Sdim if (!rsa) 258224145Sdim goto error; 259224145Sdim bn_e = BN_new(); 260224145Sdim if (!bn_e || !BN_set_word(bn_e, 0x1001)) 261224145Sdim goto error; 262224145Sdim if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL)) 263224145Sdim goto error; 264224145Sdim BN_free(bn_e); 265224145Sdim fputs("n = ", out); 266224145Sdim do_bn_print(out, rsa->n); 267224145Sdim fputs("\ne = ", out); 268224145Sdim do_bn_print(out, rsa->e); 269224145Sdim fputs("\n", out); 270224145Sdim current_keylen = keylen; 271224145Sdim } 272235633Sdim 273224145Sdim if (Msg && dgst) { 274224145Sdim if (!rsa_printsig(out, rsa, dgst, Msg, Msglen, Saltlen)) 275224145Sdim goto error; 276224145Sdim OPENSSL_free(Msg); 277224145Sdim Msg = NULL; 278224145Sdim } 279224145Sdim 280224145Sdim } 281224145Sdim 282224145Sdim ret = 1; 283193326Sed 284193326Sed error: 285193326Sed 286193326Sed if (olinebuf) 287224145Sdim OPENSSL_free(olinebuf); 288224145Sdim if (linebuf) 289224145Sdim OPENSSL_free(linebuf); 290224145Sdim if (rsa) 291224145Sdim FIPS_rsa_free(rsa); 292224145Sdim 293224145Sdim return ret; 294224145Sdim 295210299Sed parse_error: 296210299Sed 297193326Sed fprintf(stderr, "FATAL parse error processing line %d\n", lnum); 298208600Srdivacky 299208600Srdivacky goto error; 300208600Srdivacky 301208600Srdivacky} 302208600Srdivacky 303208600Srdivackystatic int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, 304218893Sdim unsigned char *Msg, long Msglen, int Saltlen) 305218893Sdim{ 306218893Sdim int ret = 0; 307218893Sdim unsigned char *sigbuf = NULL; 308218893Sdim int i, siglen; 309218893Sdim /* EVP_PKEY structure */ 310218893Sdim EVP_PKEY pk; 311218893Sdim EVP_MD_CTX ctx; 312218893Sdim pk.type = EVP_PKEY_RSA; 313218893Sdim pk.pkey.rsa = rsa; 314218893Sdim 315208600Srdivacky siglen = RSA_size(rsa); 316208600Srdivacky sigbuf = OPENSSL_malloc(siglen); 317208600Srdivacky if (!sigbuf) 318208600Srdivacky goto error; 319210299Sed 320210299Sed EVP_MD_CTX_init(&ctx); 321210299Sed 322210299Sed if (Saltlen >= 0) { 323210299Sed M_EVP_MD_CTX_set_flags(&ctx, 324210299Sed EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); 325210299Sed } else if (Saltlen == -2) 326210299Sed M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); 327210299Sed if (!EVP_SignInit_ex(&ctx, dgst, NULL)) 328208600Srdivacky goto error; 329193326Sed if (!EVP_SignUpdate(&ctx, Msg, Msglen)) 330193326Sed goto error; 331193326Sed if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) 332193326Sed goto error; 333208600Srdivacky 334208600Srdivacky EVP_MD_CTX_cleanup(&ctx); 335245431Sdim 336245431Sdim fputs("S = ", out); 337245431Sdim 338245431Sdim for (i = 0; i < siglen; i++) 339245431Sdim fprintf(out, "%02X", sigbuf[i]); 340245431Sdim 341245431Sdim fputs("\n", out); 342245431Sdim 343245431Sdim ret = 1; 344245431Sdim 345245431Sdim error: 346245431Sdim 347245431Sdim return ret; 348245431Sdim} 349245431Sdim#endif 350245431Sdim