From 2b4b28dc32ce7623f6169b43cd18585174de6b20 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 26 Jan 2011 00:56:19 +0000 Subject: And so it begins... again. Initial FIPS 140-2 code ported to HEAD. Doesn't even compile yet, may have missing files, extraneous files and other nastiness. In other words: it's experimental ATM, OK? --- fips/rsa/fips_rsa_lib.c | 101 ++++++++++ fips/rsa/fips_rsa_selftest.c | 434 +++++++++++++++++++++++++++++++++++++++++++ fips/rsa/fips_rsa_sign.c | 399 +++++++++++++++++++++++++++++++++++++++ fips/rsa/fips_rsa_x931g.c | 280 ++++++++++++++++++++++++++++ fips/rsa/fips_rsagtest.c | 388 ++++++++++++++++++++++++++++++++++++++ fips/rsa/fips_rsastest.c | 366 ++++++++++++++++++++++++++++++++++++ fips/rsa/fips_rsavtest.c | 375 +++++++++++++++++++++++++++++++++++++ 7 files changed, 2343 insertions(+) create mode 100644 fips/rsa/fips_rsa_lib.c create mode 100644 fips/rsa/fips_rsa_selftest.c create mode 100644 fips/rsa/fips_rsa_sign.c create mode 100644 fips/rsa/fips_rsa_x931g.c create mode 100644 fips/rsa/fips_rsagtest.c create mode 100644 fips/rsa/fips_rsastest.c create mode 100644 fips/rsa/fips_rsavtest.c (limited to 'fips/rsa') diff --git a/fips/rsa/fips_rsa_lib.c b/fips/rsa/fips_rsa_lib.c new file mode 100644 index 0000000000..a37ad3e540 --- /dev/null +++ b/fips/rsa/fips_rsa_lib.c @@ -0,0 +1,101 @@ +/* fips_rsa_sign.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include + +/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to + * reduce external dependencies. + */ + +RSA *FIPS_rsa_new(void) + { + RSA *ret; + ret = OPENSSL_malloc(sizeof(RSA)); + if (!ret) + return NULL; + memset(ret, 0, sizeof(RSA)); + ret->meth = RSA_PKCS1_SSLeay(); + if (ret->meth->init) + ret->meth->init(ret); + return ret; + } + +void FIPS_rsa_free(RSA *r) + { + if (!r) + return; + if (r->meth->finish) + r->meth->finish(r); + if (r->n != NULL) BN_clear_free(r->n); + if (r->e != NULL) BN_clear_free(r->e); + if (r->d != NULL) BN_clear_free(r->d); + if (r->p != NULL) BN_clear_free(r->p); + if (r->q != NULL) BN_clear_free(r->q); + if (r->dmp1 != NULL) BN_clear_free(r->dmp1); + if (r->dmq1 != NULL) BN_clear_free(r->dmq1); + if (r->iqmp != NULL) BN_clear_free(r->iqmp); + if (r->blinding != NULL) BN_BLINDING_free(r->blinding); + if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); + if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); + OPENSSL_free(r); + } + diff --git a/fips/rsa/fips_rsa_selftest.c b/fips/rsa/fips_rsa_selftest.c new file mode 100644 index 0000000000..8dae877eed --- /dev/null +++ b/fips/rsa/fips_rsa_selftest.c @@ -0,0 +1,434 @@ +/* ==================================================================== + * Copyright (c) 2003-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define OPENSSL_FIPS_EVP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +static unsigned char n[] = +"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" +"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" +"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD" +"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80" +"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25" +"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39" +"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68" +"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" +"\xCB"; + + +static int setrsakey(RSA *key) + { + static const unsigned char e[] = "\x11"; + + static const unsigned char d[] = +"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD" +"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41" +"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69" +"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA" +"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94" +"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A" +"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" +"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" +"\xC1"; + + static const unsigned char p[] = +"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" +"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" +"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" +"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" +"\x99"; + + static const unsigned char q[] = +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" +"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" +"\x03"; + + static const unsigned char dmp1[] = +"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" +"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" +"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" +"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"; + + static const unsigned char dmq1[] = +"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" +"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" +"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" +"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"; + + static const unsigned char iqmp[] = +"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" +"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" +"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" +"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" +"\xF7"; + + key->n = BN_bin2bn(n, sizeof(n)-1, key->n); + key->e = BN_bin2bn(e, sizeof(e)-1, key->e); + key->d = BN_bin2bn(d, sizeof(d)-1, key->d); + key->p = BN_bin2bn(p, sizeof(p)-1, key->p); + key->q = BN_bin2bn(q, sizeof(q)-1, key->q); + key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); + key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); + key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); + return 1; + } + +void FIPS_corrupt_rsa() + { + n[0]++; + } + +/* Known Answer Test (KAT) data for the above RSA private key signing + * kat_tbs. + */ + +static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT"; + +static const unsigned char kat_RSA_PSS_SHA1[] = { + 0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F, + 0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB, + 0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3, + 0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C, + 0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7, + 0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5, + 0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45, + 0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31, + 0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8, + 0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84, + 0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9 +}; + +static const unsigned char kat_RSA_PSS_SHA224[] = { + 0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7, + 0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA, + 0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57, + 0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89, + 0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE, + 0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22, + 0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5, + 0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49, + 0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D, + 0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00, + 0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0 +}; + +static const unsigned char kat_RSA_PSS_SHA256[] = { + 0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89, + 0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F, + 0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28, + 0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E, + 0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05, + 0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA, + 0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6, + 0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F, + 0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D, + 0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6, + 0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C +}; + +static const unsigned char kat_RSA_PSS_SHA384[] = { + 0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2, + 0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E, + 0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD, + 0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F, + 0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C, + 0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB, + 0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F, + 0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89, + 0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F, + 0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55, + 0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1 +}; + +static const unsigned char kat_RSA_PSS_SHA512[] = { + 0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C, + 0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A, + 0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD, + 0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39, + 0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7, + 0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61, + 0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13, + 0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63, + 0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE, + 0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88, + 0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B +}; + +static const unsigned char kat_RSA_SHA1[] = { + 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, + 0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, + 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF, + 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8, + 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, + 0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, + 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E, + 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F, + 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, + 0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, + 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4 +}; + +static const unsigned char kat_RSA_SHA224[] = { + 0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9, + 0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D, + 0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89, + 0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD, + 0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5, + 0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC, + 0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B, + 0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2, + 0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35, + 0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC, + 0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D +}; + +static const unsigned char kat_RSA_SHA256[] = { + 0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23, + 0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23, + 0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35, + 0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E, + 0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18, + 0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30, + 0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A, + 0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38, + 0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA, + 0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90, + 0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A +}; + +static const unsigned char kat_RSA_SHA384[] = { + 0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F, + 0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7, + 0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C, + 0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55, + 0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF, + 0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2, + 0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C, + 0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD, + 0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1, + 0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04, + 0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF +}; + +static const unsigned char kat_RSA_SHA512[] = { + 0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF, + 0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A, + 0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1, + 0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8, + 0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5, + 0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B, + 0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6, + 0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05, + 0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D, + 0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91, + 0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84 +}; + +static const unsigned char kat_RSA_X931_SHA1[] = { + 0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF, + 0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75, + 0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC, + 0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97, + 0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6, + 0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19, + 0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7, + 0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99, + 0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76, + 0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67, + 0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49 +}; + +static const unsigned char kat_RSA_X931_SHA256[] = { + 0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89, + 0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD, + 0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF, + 0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B, + 0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B, + 0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98, + 0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC, + 0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C, + 0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD, + 0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC, + 0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80 +}; + +static const unsigned char kat_RSA_X931_SHA384[] = { + 0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B, + 0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB, + 0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3, + 0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6, + 0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31, + 0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1, + 0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79, + 0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF, + 0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35, + 0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D, + 0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28 +}; + +static const unsigned char kat_RSA_X931_SHA512[] = { + 0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63, + 0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC, + 0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7, + 0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28, + 0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5, + 0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF, + 0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0, + 0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09, + 0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C, + 0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B, + 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3 +}; + + +int FIPS_selftest_rsa() + { + int ret = 0; + RSA *key = NULL; + EVP_PKEY pk; + key=FIPS_rsa_new(); + setrsakey(key); + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA1, sizeof(kat_RSA_SHA1), + EVP_sha1(), RSA_PKCS1_PADDING, + "RSA SHA1 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA224, sizeof(kat_RSA_SHA224), + EVP_sha224(), RSA_PKCS1_PADDING, + "RSA SHA224 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA256, sizeof(kat_RSA_SHA256), + EVP_sha256(), RSA_PKCS1_PADDING, + "RSA SHA256 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA384, sizeof(kat_RSA_SHA384), + EVP_sha384(), RSA_PKCS1_PADDING, + "RSA SHA384 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA512, sizeof(kat_RSA_SHA512), + EVP_sha512(), RSA_PKCS1_PADDING, + "RSA SHA512 PKCS#1")) + goto err; + + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1), + EVP_sha1(), RSA_PKCS1_PSS_PADDING, + "RSA SHA1 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224), + EVP_sha224(), RSA_PKCS1_PSS_PADDING, + "RSA SHA224 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256), + EVP_sha256(), RSA_PKCS1_PSS_PADDING, + "RSA SHA256 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384), + EVP_sha384(), RSA_PKCS1_PSS_PADDING, + "RSA SHA384 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512), + EVP_sha512(), RSA_PKCS1_PSS_PADDING, + "RSA SHA512 PSS")) + goto err; + + + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1), + EVP_sha1(), RSA_X931_PADDING, + "RSA SHA1 X931")) + goto err; + /* NB: SHA224 not supported in X9.31 */ + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256), + EVP_sha256(), RSA_X931_PADDING, + "RSA SHA256 X931")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384), + EVP_sha384(), RSA_X931_PADDING, + "RSA SHA384 X931")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512), + EVP_sha512(), RSA_X931_PADDING, + "RSA SHA512 X931")) + goto err; + + + ret = 1; + + err: + FIPS_rsa_free(key); + return ret; + } + +#endif /* def OPENSSL_FIPS */ diff --git a/fips/rsa/fips_rsa_sign.c b/fips/rsa/fips_rsa_sign.c new file mode 100644 index 0000000000..a7f73f5121 --- /dev/null +++ b/fips/rsa/fips_rsa_sign.c @@ -0,0 +1,399 @@ +/* fips_rsa_sign.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_FIPSEVP + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +/* FIPS versions of RSA_sign() and RSA_verify(). + * These will only have to deal with SHA* signatures and by including + * pregenerated encodings all ASN1 dependencies can be avoided + */ + +/* Standard encodings including NULL parameter */ + +static const unsigned char sha1_bin[] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14 +}; + +static const unsigned char sha224_bin[] = { + 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c +}; + +static const unsigned char sha256_bin[] = { + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; + +static const unsigned char sha384_bin[] = { + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 +}; + +static const unsigned char sha512_bin[] = { + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 +}; + +/* Alternate encodings with absent parameters. We don't generate signature + * using this format but do tolerate received signatures of this form. + */ + +static unsigned char sha1_nn_bin[] = { + 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, + 0x14 +}; + +static unsigned char sha224_nn_bin[] = { + 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x04, 0x1c +}; + +static unsigned char sha256_nn_bin[] = { + 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x04, 0x20 +}; + +static unsigned char sha384_nn_bin[] = { + 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x04, 0x30 +}; + +static unsigned char sha512_nn_bin[] = { + 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x04, 0x40 +}; + + +static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len) + { + switch (nid) + { + + case NID_sha1: + *len = sizeof(sha1_bin); + return sha1_bin; + + case NID_sha224: + *len = sizeof(sha224_bin); + return sha224_bin; + + case NID_sha256: + *len = sizeof(sha256_bin); + return sha256_bin; + + case NID_sha384: + *len = sizeof(sha384_bin); + return sha384_bin; + + case NID_sha512: + *len = sizeof(sha512_bin); + return sha512_bin; + + default: + return NULL; + + } + } + +static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len) + { + switch (nid) + { + + case NID_sha1: + *len = sizeof(sha1_nn_bin); + return sha1_nn_bin; + + case NID_sha224: + *len = sizeof(sha224_nn_bin); + return sha224_nn_bin; + + case NID_sha256: + *len = sizeof(sha256_nn_bin); + return sha256_nn_bin; + + case NID_sha384: + *len = sizeof(sha384_nn_bin); + return sha384_nn_bin; + + case NID_sha512: + *len = sizeof(sha512_nn_bin); + return sha512_nn_bin; + + default: + return NULL; + + } + } + + +int FIPS_rsa_sign_ctx(RSA *rsa, EVP_MD_CTX *ctx, + int rsa_pad_mode, int saltlen, const EVP_MD *mgf1Hash, + unsigned char *sigret, unsigned int *siglen) + { + int i=0,j,ret=0; + unsigned int dlen; + const unsigned char *der; + unsigned int m_len; + const EVP_MD *mhash; + int md_type; + /* Largest DigestInfo: 19 (max encoding) + max MD */ + unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE]; + unsigned char md[EVP_MAX_MD_SIZE + 1]; + + EVP_DigestFinal_ex(ctx, md, &m_len); + + mhash = M_EVP_MD_CTX_md(ctx); + md_type = M_EVP_MD_type(mhash); + + if (rsa_pad_mode == RSA_X931_PADDING) + { + int hash_id; + memcpy(tmpdinfo, md, m_len); + hash_id = RSA_X931_hash_id(md_type); + if (hash_id == -1) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + tmpdinfo[m_len] = (unsigned char)hash_id; + i = m_len + 1; + } + else if (rsa_pad_mode == RSA_PKCS1_PADDING) + { + + der = fips_digestinfo_encoding(md_type, &dlen); + + if (!der) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + memcpy(tmpdinfo, der, dlen); + memcpy(tmpdinfo + dlen, md, m_len); + + i = dlen + m_len; + + } + else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING) + { + unsigned char *sbuf; + i = RSA_size(rsa); + sbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!sbuf) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE); + goto psserr; + } + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, sbuf, md, mhash, + mgf1Hash, saltlen)) + goto psserr; + j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING); + if (j > 0) + { + ret=1; + *siglen=j; + } + psserr: + OPENSSL_cleanse(md,m_len); + OPENSSL_cleanse(sbuf, i); + OPENSSL_free(sbuf); + return ret; + } + + j=RSA_size(rsa); + if (i > (j-RSA_PKCS1_PADDING_SIZE)) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + goto done; + } + /* NB: call underlying method directly to avoid FIPS blocking */ + j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode); + if (j > 0) + { + ret=1; + *siglen=j; + } + + done: + OPENSSL_cleanse(tmpdinfo,i); + OPENSSL_cleanse(md,m_len); + return ret; + } + +int FIPS_rsa_verify_ctx(RSA *rsa, EVP_MD_CTX *ctx, + int rsa_pad_mode, int saltlen, const EVP_MD *mgf1Hash, + unsigned char *sigbuf, unsigned int siglen) + { + int i,ret=0; + unsigned int dlen, diglen; + unsigned char *s; + const unsigned char *der; + unsigned char dig[EVP_MAX_MD_SIZE]; + const EVP_MD *mhash; + int md_type; + int rsa_dec_pad_mode; + + if (siglen != (unsigned int)RSA_size(rsa)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); + return(0); + } + + mhash = M_EVP_MD_CTX_md(ctx); + md_type = M_EVP_MD_type(mhash); + + EVP_DigestFinal_ex(ctx, dig, &diglen); + + s= OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING) + rsa_dec_pad_mode = RSA_NO_PADDING; + else + rsa_dec_pad_mode = rsa_pad_mode; + + /* NB: call underlying method directly to avoid FIPS blocking */ + i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_dec_pad_mode); + + if (i <= 0) goto err; + + if (rsa_pad_mode == RSA_X931_PADDING) + { + int hash_id; + if (i != (int)(diglen + 1)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + hash_id = RSA_X931_hash_id(md_type); + if (hash_id == -1) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE); + goto err; + } + if (s[diglen] != (unsigned char)hash_id) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + if (memcmp(s, dig, diglen)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; + } + else if (rsa_pad_mode == RSA_PKCS1_PADDING) + { + + der = fips_digestinfo_encoding(md_type, &dlen); + + if (!der) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return(0); + } + + /* Compare, DigestInfo length, DigestInfo header and finally + * digest value itself + */ + + /* If length mismatch try alternate encoding */ + if (i != (int)(dlen + diglen)) + der = fips_digestinfo_nn_encoding(md_type, &dlen); + + if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen) + || memcmp(s + dlen, dig, diglen)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; + + } + else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING) + { + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, dig, mhash, mgf1Hash, + s, saltlen); + if (ret < 0) + ret = 0; + } +err: + if (s != NULL) + { + OPENSSL_cleanse(s, siglen); + OPENSSL_free(s); + } + return(ret); + } + +#endif diff --git a/fips/rsa/fips_rsa_x931g.c b/fips/rsa/fips_rsa_x931g.c new file mode 100644 index 0000000000..d9f9a81235 --- /dev/null +++ b/fips/rsa/fips_rsa_x931g.c @@ -0,0 +1,280 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +extern int fips_check_rsa(RSA *rsa); + + +/* X9.31 RSA key derivation and generation */ + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, + const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL; + BN_CTX *ctx=NULL,*ctx2=NULL; + + if (!rsa) + goto err; + + ctx = BN_CTX_new(); + BN_CTX_start(ctx); + if (!ctx) + goto err; + + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + + if (r3 == NULL) + goto err; + if (!rsa->e) + { + rsa->e = BN_dup(e); + if (!rsa->e) + goto err; + } + else + e = rsa->e; + + /* If not all parameters present only calculate what we can. + * This allows test programs to output selective parameters. + */ + + if (Xp && !rsa->p) + { + rsa->p = BN_new(); + if (!rsa->p) + goto err; + + if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, + Xp, Xp1, Xp2, e, ctx, cb)) + goto err; + } + + if (Xq && !rsa->q) + { + rsa->q = BN_new(); + if (!rsa->q) + goto err; + if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, + Xq, Xq1, Xq2, e, ctx, cb)) + goto err; + } + + if (!rsa->p || !rsa->q) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 2; + } + + /* Since both primes are set we can now calculate all remaining + * components. + */ + + /* calculate n */ + rsa->n=BN_new(); + if (rsa->n == NULL) + goto err; + if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1,rsa->p,BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2,rsa->q,BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0,r1,r2,ctx)) + goto err; /* (p-1)(q-1) */ + + if (!BN_gcd(r3, r1, r2, ctx)) + goto err; + + if (!BN_div(r0, NULL, r0, r3, ctx)) + goto err; /* LCM((p-1)(q-1)) */ + + ctx2 = BN_CTX_new(); + if (!ctx2) + goto err; + + rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ + if (rsa->d == NULL) + goto err; + + /* calculate d mod (p-1) */ + rsa->dmp1=BN_new(); + if (rsa->dmp1 == NULL) + goto err; + if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) + goto err; + + /* calculate d mod (q-1) */ + rsa->dmq1=BN_new(); + if (rsa->dmq1 == NULL) + goto err; + if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) + goto err; + + /* calculate inverse of q mod p */ + rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); + + err: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ctx2) + BN_CTX_free(ctx2); + /* If this is set all calls successful */ + if (rsa->iqmp != NULL) + return 1; + + return 0; + + } + +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb) + { + int ok = 0; + BIGNUM *Xp = NULL, *Xq = NULL; + BN_CTX *ctx = NULL; + + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + if (bits & 0xff) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH); + return 0; + } + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + ctx = BN_CTX_new(); + if (!ctx) + goto error; + + BN_CTX_start(ctx); + Xp = BN_CTX_get(ctx); + Xq = BN_CTX_get(ctx); + if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) + goto error; + + rsa->p = BN_new(); + rsa->q = BN_new(); + if (!rsa->p || !rsa->q) + goto error; + + /* Generate two primes from Xp, Xq */ + + if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, + e, ctx, cb)) + goto error; + + if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, + e, ctx, cb)) + goto error; + + /* Since rsa->p and rsa->q are valid this call will just derive + * remaining RSA components. + */ + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) + goto error; + + if(!fips_check_rsa(rsa)) + goto error; + + ok = 1; + + error: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (ok) + return 1; + + return 0; + + } + +#endif diff --git a/fips/rsa/fips_rsagtest.c b/fips/rsa/fips_rsagtest.c new file mode 100644 index 0000000000..1b79ffa70f --- /dev/null +++ b/fips/rsa/fips_rsagtest.c @@ -0,0 +1,388 @@ +/* fips_rsagtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005,2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_FIPSEVP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include +#include +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in); +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e); +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + fips_set_error_print(); + if(!FIPS_mode_set(1)) + goto end; + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in)) + { + fprintf(stderr, "FATAL RSAGTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL; + BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL; + BIGNUM *e = NULL; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "xp1")) + { + if (Xp1 || !do_hex2bn(&Xp1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xp2")) + { + if (Xp2 || !do_hex2bn(&Xp2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xp")) + { + if (Xp || !do_hex2bn(&Xp,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq1")) + { + if (Xq1 || !do_hex2bn(&Xq1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq2")) + { + if (Xq2 || !do_hex2bn(&Xq2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xq")) + { + if (Xq || !do_hex2bn(&Xq,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (e || !do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "p1")) + continue; + else if (!strcmp(keyword, "p2")) + continue; + else if (!strcmp(keyword, "p")) + continue; + else if (!strcmp(keyword, "q1")) + continue; + else if (!strcmp(keyword, "q2")) + continue; + else if (!strcmp(keyword, "q")) + continue; + else if (!strcmp(keyword, "n")) + continue; + else if (!strcmp(keyword, "d")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (e && Xp1 && Xp2 && Xp) + { + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e)) + goto error; + BN_free(Xp1); + Xp1 = NULL; + BN_free(Xp2); + Xp2 = NULL; + BN_free(Xp); + Xp = NULL; + BN_free(e); + e = NULL; + } + + if (rsa && Xq1 && Xq2 && Xq) + { + if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq)) + goto error; + BN_free(Xq1); + Xq1 = NULL; + BN_free(Xq2); + Xq2 = NULL; + BN_free(Xq); + Xq = NULL; + FIPS_rsa_free(rsa); + rsa = NULL; + } + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + + if (Xp1) + BN_free(Xp1); + if (Xp2) + BN_free(Xp2); + if (Xp) + BN_free(Xp); + if (Xq1) + BN_free(Xq1); + if (Xq1) + BN_free(Xq1); + if (Xq2) + BN_free(Xq2); + if (Xq) + BN_free(Xq); + if (e) + BN_free(e); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e) + { + int ret = 0; + BIGNUM *p1 = NULL, *p2 = NULL; + p1 = BN_new(); + p2 = BN_new(); + if (!p1 || !p2) + goto error; + + if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp, + NULL, NULL, NULL, e, NULL)) + goto error; + + do_bn_print_name(out, "p1", p1); + do_bn_print_name(out, "p2", p2); + do_bn_print_name(out, "p", rsa->p); + + ret = 1; + + error: + if (p1) + BN_free(p1); + if (p2) + BN_free(p2); + + return ret; + } + +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq) + { + int ret = 0; + BIGNUM *q1 = NULL, *q2 = NULL; + q1 = BN_new(); + q2 = BN_new(); + if (!q1 || !q2) + goto error; + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL, + Xq1, Xq2, Xq, NULL, NULL)) + goto error; + + do_bn_print_name(out, "q1", q1); + do_bn_print_name(out, "q2", q2); + do_bn_print_name(out, "q", rsa->q); + do_bn_print_name(out, "n", rsa->n); + do_bn_print_name(out, "d", rsa->d); + + ret = 1; + + error: + if (q1) + BN_free(q1); + if (q2) + BN_free(q2); + + return ret; + } + +#endif diff --git a/fips/rsa/fips_rsastest.c b/fips/rsa/fips_rsastest.c new file mode 100644 index 0000000000..2a125ae02d --- /dev/null +++ b/fips/rsa/fips_rsastest.c @@ -0,0 +1,366 @@ +/* fips_rsastest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_FIPSEVP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include +#include +#include "fips_utl.h" + +static int rsa_stest(FILE *out, FILE *in, int Saltlen); +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1, Saltlen = -1; + + fips_set_error_print(); + if(!FIPS_mode_set(1)) + goto end; + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_stest(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSASTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_stest(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + const EVP_MD *dgst = NULL; + unsigned char *Msg = NULL; + long Msglen = -1; + int keylen = -1, current_keylen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = just copy */ + if (!p) + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + /* Look for [mod = XXX] for key length */ + + if (!strcmp(keyword, "[mod")) + { + p = value + strlen(value) - 1; + if (*p != ']') + goto parse_error; + *p = 0; + keylen = atoi(value); + if (keylen < 0) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + + fputs(olinebuf, out); + + /* If key length has changed, generate and output public + * key components of new RSA private key. + */ + + if (keylen != current_keylen) + { + BIGNUM *bn_e; + if (rsa) + FIPS_rsa_free(rsa); + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + bn_e = BN_new(); + if (!bn_e || !BN_set_word(bn_e, 0x1001)) + goto error; + if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL)) + goto error; + BN_free(bn_e); + fputs("n = ", out); + do_bn_print(out, rsa->n); + fputs("\ne = ", out); + do_bn_print(out, rsa->e); + fputs("\n", out); + current_keylen = keylen; + } + + if (Msg && dgst) + { + if (!rsa_printsig(out, rsa, dgst, Msg, Msglen, + Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + } + + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen) + { + int ret = 0; + unsigned char *sigbuf = NULL; + int i, siglen, pad_mode; + /* EVP_PKEY structure */ + EVP_MD_CTX ctx; + + siglen = RSA_size(rsa); + sigbuf = OPENSSL_malloc(siglen); + if (!sigbuf) + goto error; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + pad_mode = RSA_PKCS1_PSS_PADDING; + else if (Saltlen == -2) + pad_mode = RSA_X931_PADDING; + else + pad_mode = RSA_PKCS1_PADDING; + + if (!EVP_DigestInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_DigestUpdate(&ctx, Msg, Msglen)) + goto error; + if (!FIPS_rsa_sign_ctx(rsa, &ctx, pad_mode, Saltlen, NULL, + sigbuf, (unsigned int *)&siglen)) + goto error; + + EVP_MD_CTX_cleanup(&ctx); + + fputs("S = ", out); + + for (i = 0; i < siglen; i++) + fprintf(out, "%02X", sigbuf[i]); + + fputs("\n", out); + + ret = 1; + + error: + + return ret; + } +#endif diff --git a/fips/rsa/fips_rsavtest.c b/fips/rsa/fips_rsavtest.c new file mode 100644 index 0000000000..0421807623 --- /dev/null +++ b/fips/rsa/fips_rsavtest.c @@ -0,0 +1,375 @@ +/* fips_rsavtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This produc