Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
openssl
openssl-1.0.1e-fips.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssl-1.0.1e-fips.patch of Package openssl
--- Configure | 11 Makefile.org | 6 apps/pkcs12.c | 8 apps/speed.c | 45 crypto/aes/aes_misc.c | 6 crypto/camellia/cmll_locl.h | 5 crypto/cmac/cmac.c | 20 crypto/crypto.h | 18 crypto/des/des.h | 3 crypto/des/set_key.c | 7 crypto/dh/dh.h | 2 crypto/dh/dh_gen.c | 19 crypto/dh/dh_key.c | 23 crypto/dh/dh_lib.c | 7 crypto/dsa/dsa.h | 26 crypto/dsa/dsa_err.c | 4 crypto/dsa/dsa_gen.c | 262 ++-- crypto/dsa/dsa_key.c | 50 crypto/dsa/dsa_lib.c | 7 crypto/dsa/dsa_locl.h | 1 crypto/dsa/dsa_ossl.c | 38 crypto/dsa/dsa_pmeth.c | 2 crypto/dsa/dsatest.c | 53 crypto/engine/eng_all.c | 14 crypto/evp/Makefile | 4 crypto/evp/c_allc.c | 61 crypto/evp/c_alld.c | 33 crypto/evp/digest.c | 80 - crypto/evp/e_aes.c | 6 crypto/evp/e_des3.c | 27 crypto/evp/e_null.c | 5 crypto/evp/evp.h | 18 crypto/evp/evp_enc.c | 86 + crypto/evp/evp_lib.c | 3 crypto/evp/evp_locl.h | 6 crypto/evp/m_dss.c | 4 crypto/evp/m_dss1.c | 5 crypto/evp/m_md2.c | 1 crypto/evp/m_sha1.c | 18 crypto/evp/p_sign.c | 17 crypto/evp/p_verify.c | 17 crypto/fips/Makefile | 340 +++++ crypto/fips/cavs/fips_aesavs.c | 939 ++++++++++++++ crypto/fips/cavs/fips_cmactest.c | 517 ++++++++ crypto/fips/cavs/fips_desmovs.c | 702 +++++++++++ crypto/fips/cavs/fips_dhvs.c | 292 ++++ crypto/fips/cavs/fips_drbgvs.c | 416 ++++++ crypto/fips/cavs/fips_dssvs.c | 537 ++++++++ crypto/fips/cavs/fips_gcmtest.c | 571 +++++++++ crypto/fips/cavs/fips_rngvs.c | 230 +++ crypto/fips/cavs/fips_rsagtest.c | 390 ++++++ crypto/fips/cavs/fips_rsastest.c | 370 +++++ crypto/fips/cavs/fips_rsavtest.c | 377 +++++ crypto/fips/cavs/fips_shatest.c | 388 ++++++ crypto/fips/cavs/fips_utl.h | 343 +++++ crypto/fips/fips.c | 489 +++++++ crypto/fips/fips.h | 279 ++++ crypto/fips/fips_aes_selftest.c | 359 +++++ crypto/fips/fips_cmac_selftest.c | 161 ++ crypto/fips/fips_des_selftest.c | 147 ++ crypto/fips/fips_drbg_ctr.c | 436 ++++++ crypto/fips/fips_drbg_hash.c | 378 +++++ crypto/fips/fips_drbg_hmac.c | 281 ++++ crypto/fips/fips_drbg_lib.c | 578 +++++++++ crypto/fips/fips_drbg_rand.c | 172 ++ crypto/fips/fips_drbg_selftest.c | 862 +++++++++++++ crypto/fips/fips_drbg_selftest.h | 2335 +++++++++++++++++++++++++++++++++++++ crypto/fips/fips_dsa_selftest.c | 193 +++ crypto/fips/fips_enc.c | 191 +++ crypto/fips/fips_hmac_selftest.c | 137 ++ crypto/fips/fips_locl.h | 71 + crypto/fips/fips_md.c | 145 ++ crypto/fips/fips_post.c | 205 +++ crypto/fips/fips_rand.c | 457 +++++++ crypto/fips/fips_rand.h | 145 ++ crypto/fips/fips_rand_lcl.h | 219 +++ crypto/fips/fips_rand_lib.c | 191 +++ crypto/fips/fips_rand_selftest.c | 183 ++ crypto/fips/fips_randtest.c | 250 +++ crypto/fips/fips_rsa_selftest.c | 444 +++++++ crypto/fips/fips_rsa_x931g.c | 282 ++++ crypto/fips/fips_sha_selftest.c | 140 ++ crypto/fips/fips_standalone_hmac.c | 180 ++ crypto/fips/fips_test_suite.c | 588 +++++++++ crypto/hmac/hmac.c | 27 crypto/md2/md2_dgst.c | 7 crypto/md4/md4_dgst.c | 2 crypto/md5/md5_dgst.c | 2 crypto/mdc2/mdc2dgst.c | 2 crypto/o_fips.c | 2 crypto/o_init.c | 48 crypto/opensslconf.h | 3 crypto/opensslconf.h.in | 15 crypto/pkcs12/p12_crt.c | 4 crypto/rand/md_rand.c | 5 crypto/rand/rand.h | 28 crypto/ripemd/rmd_dgst.c | 2 crypto/rsa/rsa.h | 28 crypto/rsa/rsa_crpt.c | 10 crypto/rsa/rsa_eay.c | 81 + crypto/rsa/rsa_err.c | 2 crypto/rsa/rsa_gen.c | 106 + crypto/rsa/rsa_lib.c | 35 crypto/rsa/rsa_pmeth.c | 29 crypto/rsa/rsa_sign.c | 10 crypto/sha/sha.h | 11 crypto/sha/sha256.c | 10 crypto/sha/sha512.c | 10 crypto/sha/sha_locl.h | 5 crypto/whrlpool/wp_dgst.c | 2 ssl/d1_srvr.c | 2 ssl/ssl_algs.c | 50 112 files changed, 18073 insertions(+), 403 deletions(-) Index: openssl-1.0.1h/Configure =================================================================== --- openssl-1.0.1h.orig/Configure +++ openssl-1.0.1h/Configure @@ -990,11 +990,6 @@ if (defined($disabled{"md5"}) || defined $disabled{"ssl2"} = "forced"; } -if ($fips && $fipslibdir eq "") - { - $fipslibdir = $fipsdir . "/lib/"; - } - # RSAX ENGINE sets default non-FIPS RSA method. if ($fips) { @@ -1469,7 +1464,6 @@ $cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($b if ($fips) { $openssl_other_defines.="#define OPENSSL_FIPS\n"; - $cflags .= " -I\$(FIPSDIR)/include"; } $cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/); @@ -1656,9 +1650,12 @@ while (<IN>) s/^FIPSDIR=.*/FIPSDIR=$fipsdir/; s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/; - s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips; s/^BASEADDR=.*/BASEADDR=$baseaddr/; + if ($fips) + { + s/^FIPS=.*/FIPS=yes/; + } s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/; s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/; s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared); Index: openssl-1.0.1h/Makefile.org =================================================================== --- openssl-1.0.1h.orig/Makefile.org +++ openssl-1.0.1h/Makefile.org @@ -136,6 +136,9 @@ FIPSCANLIB= BASEADDR= +# Non-empty if FIPS enabled +FIPS= + DIRS= crypto ssl engines apps test tools ENGDIRS= ccgost SHLIBDIRS= crypto ssl @@ -148,7 +151,7 @@ SDIRS= \ bn ec rsa dsa ecdsa dh ecdh dso engine \ buffer bio stack lhash rand err \ evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ - cms pqueue ts jpake srp store cmac + cms pqueue ts jpake srp store cmac fips # keep in mind that the above list is adjusted by ./Configure # according to no-xxx arguments... @@ -237,6 +240,7 @@ BUILDENV= PLATFORM='$(PLATFORM)' PROCESS FIPSLIBDIR='${FIPSLIBDIR}' \ FIPSDIR='${FIPSDIR}' \ FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}" \ + FIPS="$${FIPS:-$(FIPS)}" \ THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES= # MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors, # which in turn eliminates ambiguities in variable treatment with -e. Index: openssl-1.0.1h/apps/pkcs12.c =================================================================== --- openssl-1.0.1h.orig/apps/pkcs12.c +++ openssl-1.0.1h/apps/pkcs12.c @@ -67,6 +67,9 @@ #include <openssl/err.h> #include <openssl/pem.h> #include <openssl/pkcs12.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif #define PROG pkcs12_main @@ -137,6 +140,11 @@ int MAIN(int argc, char **argv) #endif cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + cert_pbe = key_pbe; /* cannot use RC2 in the FIPS mode */ +#endif + enc = EVP_des_ede3_cbc(); if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); Index: openssl-1.0.1h/apps/speed.c =================================================================== --- openssl-1.0.1h.orig/apps/speed.c +++ openssl-1.0.1h/apps/speed.c @@ -195,7 +195,6 @@ #ifdef OPENSSL_DOING_MAKEDEPEND #undef AES_set_encrypt_key #undef AES_set_decrypt_key -#undef DES_set_key_unchecked #endif #define BF_set_key private_BF_set_key #define CAST_set_key private_CAST_set_key @@ -203,7 +202,6 @@ #define SEED_set_key private_SEED_set_key #define RC2_set_key private_RC2_set_key #define RC4_set_key private_RC4_set_key -#define DES_set_key_unchecked private_DES_set_key_unchecked #define AES_set_encrypt_key private_AES_set_encrypt_key #define AES_set_decrypt_key private_AES_set_decrypt_key #define Camellia_set_key private_Camellia_set_key @@ -941,7 +939,12 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_RSA if (strcmp(*argv,"rsa") == 0) { +#ifdef OPENSSL_FIPS + if (!FIPS_mode()) +#endif + { rsa_doit[R_RSA_512]=1; + } rsa_doit[R_RSA_1024]=1; rsa_doit[R_RSA_2048]=1; rsa_doit[R_RSA_4096]=1; @@ -951,7 +954,12 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_DSA if (strcmp(*argv,"dsa") == 0) { +#ifdef OPENSSL_FIPS + if (!FIPS_mode()) +#endif + { dsa_doit[R_DSA_512]=1; + } dsa_doit[R_DSA_1024]=1; dsa_doit[R_DSA_2048]=1; } @@ -1162,12 +1170,18 @@ int MAIN(int argc, char **argv) { for (i=0; i<ALGOR_NUM; i++) { - if (i != D_EVP) + if (i != D_EVP && + (!FIPS_mode() || (i != D_WHIRLPOOL && + i != D_MD2 && i != D_MD4 && + i != D_MD5 && i != D_MDC2 && + i != D_RMD160))) doit[i]=1; } for (i=0; i<RSA_NUM; i++) + if (!FIPS_mode() || i != R_RSA_512) rsa_doit[i]=1; for (i=0; i<DSA_NUM; i++) + if (!FIPS_mode() || i != R_DSA_512) dsa_doit[i]=1; #ifndef OPENSSL_NO_ECDSA for (i=0; i<EC_NUM; i++) @@ -1226,30 +1240,54 @@ int MAIN(int argc, char **argv) AES_set_encrypt_key(key32,256,&aes_ks3); #endif #ifndef OPENSSL_NO_CAMELLIA + if (doit[D_CBC_128_CML] || doit[D_CBC_192_CML] || doit[D_CBC_256_CML]) + { Camellia_set_key(key16,128,&camellia_ks1); Camellia_set_key(ckey24,192,&camellia_ks2); Camellia_set_key(ckey32,256,&camellia_ks3); + } #endif #ifndef OPENSSL_NO_IDEA + if (doit[D_CBC_IDEA]) + { idea_set_encrypt_key(key16,&idea_ks); + } #endif #ifndef OPENSSL_NO_SEED + if (doit[D_CBC_SEED]) + { SEED_set_key(key16,&seed_ks); + } #endif #ifndef OPENSSL_NO_RC4 + if (doit[D_RC4]) + { RC4_set_key(&rc4_ks,16,key16); + } #endif #ifndef OPENSSL_NO_RC2 + if (doit[D_CBC_RC2]) + { RC2_set_key(&rc2_ks,16,key16,128); + } #endif #ifndef OPENSSL_NO_RC5 + if (doit[D_CBC_RC5]) + { RC5_32_set_key(&rc5_ks,16,key16,12); + } #endif #ifndef OPENSSL_NO_BF + if (doit[D_CBC_BF]) + { BF_set_key(&bf_ks,16,key16); + } #endif #ifndef OPENSSL_NO_CAST + if (doit[D_CBC_CAST]) + { CAST_set_key(&cast_ks,16,key16); + } #endif #ifndef OPENSSL_NO_RSA memset(rsa_c,0,sizeof(rsa_c)); @@ -1564,6 +1602,7 @@ int MAIN(int argc, char **argv) HMAC_CTX hctx; HMAC_CTX_init(&hctx); + HMAC_CTX_set_flags(&hctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...", 16,EVP_md5(), NULL); Index: openssl-1.0.1h/crypto/aes/aes_misc.c =================================================================== --- openssl-1.0.1h.orig/crypto/aes/aes_misc.c +++ openssl-1.0.1h/crypto/aes/aes_misc.c @@ -69,17 +69,11 @@ const char *AES_options(void) { int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) { -#ifdef OPENSSL_FIPS - fips_cipher_abort(AES); -#endif return private_AES_set_encrypt_key(userKey, bits, key); } int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) { -#ifdef OPENSSL_FIPS - fips_cipher_abort(AES); -#endif return private_AES_set_decrypt_key(userKey, bits, key); } Index: openssl-1.0.1h/crypto/camellia/cmll_locl.h =================================================================== --- openssl-1.0.1h.orig/crypto/camellia/cmll_locl.h +++ openssl-1.0.1h/crypto/camellia/cmll_locl.h @@ -68,7 +68,8 @@ #ifndef HEADER_CAMELLIA_LOCL_H #define HEADER_CAMELLIA_LOCL_H -#pragma GCC visibility push(hidden) +/* we comment it for FIPS compiliation */ +//#pragma GCC visibility push(hidden) typedef unsigned int u32; typedef unsigned char u8; @@ -85,5 +86,5 @@ void Camellia_DecryptBlock(int keyBitLen const KEY_TABLE_TYPE keyTable, u8 plaintext[]); int private_Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key); -#pragma GCC visibility pop +//#pragma GCC visibility pop #endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ Index: openssl-1.0.1h/crypto/cmac/cmac.c =================================================================== --- openssl-1.0.1h.orig/crypto/cmac/cmac.c +++ openssl-1.0.1h/crypto/cmac/cmac.c @@ -107,13 +107,6 @@ CMAC_CTX *CMAC_CTX_new(void) void CMAC_CTX_cleanup(CMAC_CTX *ctx) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - { - FIPS_cmac_ctx_cleanup(ctx); - return; - } -#endif EVP_CIPHER_CTX_cleanup(&ctx->cctx); OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); @@ -164,11 +157,6 @@ int CMAC_Init(CMAC_CTX *ctx, const void EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); return 0; } - /* Other algorithm blocking will be done in FIPS_cmac_init, - * via FIPS_cipherinit(). - */ - if (!impl && !ctx->cctx.engine) - return FIPS_cmac_init(ctx, key, keylen, cipher, NULL); } #endif /* All zeros means restart */ @@ -216,10 +204,6 @@ int CMAC_Update(CMAC_CTX *ctx, const voi { const unsigned char *data = in; size_t bl; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - return FIPS_cmac_update(ctx, in, dlen); -#endif if (ctx->nlast_block == -1) return 0; if (dlen == 0) @@ -261,10 +245,6 @@ int CMAC_Update(CMAC_CTX *ctx, const voi int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) { int i, bl, lb; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - return FIPS_cmac_final(ctx, out, poutlen); -#endif if (ctx->nlast_block == -1) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); Index: openssl-1.0.1h/crypto/crypto.h =================================================================== --- openssl-1.0.1h.orig/crypto/crypto.h +++ openssl-1.0.1h/crypto/crypto.h @@ -553,24 +553,29 @@ int FIPS_mode_set(int r); void OPENSSL_init(void); #define fips_md_init(alg) fips_md_init_ctx(alg, alg) +#define nonfips_md_init(alg) nonfips_md_init_ctx(alg, alg) +#define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) #ifdef OPENSSL_FIPS -#define fips_md_init_ctx(alg, cx) \ +#define nonfips_md_init_ctx(alg, cx) \ int alg##_Init(cx##_CTX *c) \ { \ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ - "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ + "Digest " #alg " forbidden in FIPS mode!"); \ return private_##alg##_Init(c); \ } \ int private_##alg##_Init(cx##_CTX *c) #define fips_cipher_abort(alg) \ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ - "Low level API call to cipher " #alg " forbidden in FIPS mode!") + "Cipher " #alg " forbidden in FIPS mode!") + +/* die if FIPS selftest failed */ +void FIPS_selftest_check(void); #else -#define fips_md_init_ctx(alg, cx) \ - int alg##_Init(cx##_CTX *c) +#define nonfips_md_init_ctx(alg, cx) fips_md_init_ctx(alg, cx) #define fips_cipher_abort(alg) while(0) #endif @@ -587,6 +592,9 @@ int CRYPTO_memcmp(const void *a, const v */ void ERR_load_CRYPTO_strings(void); +#define OPENSSL_HAVE_INIT 1 +void OPENSSL_init_library(void); + /* Error codes for the CRYPTO functions. */ /* Function codes. */ Index: openssl-1.0.1h/crypto/des/des.h =================================================================== --- openssl-1.0.1h.orig/crypto/des/des.h +++ openssl-1.0.1h/crypto/des/des.h @@ -224,9 +224,6 @@ int DES_set_key(const_DES_cblock *key,DE int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule); int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule); void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule); -#ifdef OPENSSL_FIPS -void private_DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule); -#endif void DES_string_to_key(const char *str,DES_cblock *key); void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2); void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length, Index: openssl-1.0.1h/crypto/des/set_key.c =================================================================== --- openssl-1.0.1h.orig/crypto/des/set_key.c +++ openssl-1.0.1h/crypto/des/set_key.c @@ -336,13 +336,6 @@ int DES_set_key_checked(const_DES_cblock } void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) -#ifdef OPENSSL_FIPS - { - fips_cipher_abort(DES); - private_DES_set_key_unchecked(key, schedule); - } -void private_DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) -#endif { static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; register DES_LONG c,d,t,s,t2; Index: openssl-1.0.1h/crypto/dh/dh.h =================================================================== --- openssl-1.0.1h.orig/crypto/dh/dh.h +++ openssl-1.0.1h/crypto/dh/dh.h @@ -77,6 +77,8 @@ # define OPENSSL_DH_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + #define DH_FLAG_CACHE_MONT_P 0x01 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH * implementation now uses constant time Index: openssl-1.0.1h/crypto/dh/dh_gen.c =================================================================== --- openssl-1.0.1h.orig/crypto/dh/dh_gen.c +++ openssl-1.0.1h/crypto/dh/dh_gen.c @@ -84,11 +84,6 @@ int DH_generate_parameters_ex(DH *ret, i #endif if(ret->meth->generate_params) return ret->meth->generate_params(ret, prime_len, generator, cb); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dh_generate_parameters_ex(ret, prime_len, - generator, cb); -#endif return dh_builtin_genparams(ret, prime_len, generator, cb); } @@ -123,6 +118,20 @@ static int dh_builtin_genparams(DH *ret, int g,ok= -1; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif + ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); Index: openssl-1.0.1h/crypto/dh/dh_key.c =================================================================== --- openssl-1.0.1h.orig/crypto/dh/dh_key.c +++ openssl-1.0.1h/crypto/dh/dh_key.c @@ -61,6 +61,9 @@ #include <openssl/bn.h> #include <openssl/rand.h> #include <openssl/dh.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif static int generate_key(DH *dh); static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); @@ -104,7 +107,7 @@ compute_key, dh_bn_mod_exp, dh_init, dh_finish, -0, +DH_FLAG_FIPS_METHOD, NULL, NULL }; @@ -123,6 +126,14 @@ static int generate_key(DH *dh) BN_MONT_CTX *mont=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + return 0; + } +#endif + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -213,6 +224,13 @@ static int compute_key(unsigned char *ke DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE); goto err; } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -280,6 +298,9 @@ static int dh_bn_mod_exp(const DH *dh, B static int dh_init(DH *dh) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif dh->flags |= DH_FLAG_CACHE_MONT_P; return(1); } Index: openssl-1.0.1h/crypto/dh/dh_lib.c =================================================================== --- openssl-1.0.1h.orig/crypto/dh/dh_lib.c +++ openssl-1.0.1h/crypto/dh/dh_lib.c @@ -81,14 +81,7 @@ const DH_METHOD *DH_get_default_method(v { if(!default_DH_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dh_openssl(); - else - return DH_OpenSSL(); -#else default_DH_method = DH_OpenSSL(); -#endif } return default_DH_method; } Index: openssl-1.0.1h/crypto/dsa/dsa.h =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa.h +++ openssl-1.0.1h/crypto/dsa/dsa.h @@ -88,6 +88,8 @@ # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + #define DSA_FLAG_CACHE_MONT_P 0x01 #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA * implementation now uses constant time @@ -264,6 +266,17 @@ int DSA_print_fp(FILE *bp, const DSA *x, DH *DSA_dup_DH(const DSA *r); #endif +#ifdef OPENSSL_FIPS +int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); +int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits, + const EVP_MD *evpmd, unsigned char *seed, int seed_len, + BIGNUM **p_ret, BIGNUM **q_ret, int *counter_ret, BN_GENCB *cb); +int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, + BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb); +#endif + #define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) @@ -285,10 +298,13 @@ void ERR_load_DSA_strings(void); #define DSA_F_DO_DSA_PRINT 104 #define DSA_F_DSAPARAMS_PRINT 100 #define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_BUILTIN_KEYGEN 124 +#define DSA_F_DSA_BUILTIN_PARAMGEN 123 #define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_VERIFY 113 -#define DSA_F_DSA_GENERATE_KEY 124 -#define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +#define DSA_F_DSA_GENERATE_KEY 126 +#define DSA_F_DSA_GENERATE_PARAMETERS_EX 127 +#define DSA_F_DSA_GENERATE_PARAMETERS /* unused */ 125 #define DSA_F_DSA_NEW_METHOD 103 #define DSA_F_DSA_PARAM_DECODE 119 #define DSA_F_DSA_PRINT_FP 105 @@ -314,11 +330,15 @@ void ERR_load_DSA_strings(void); #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 #define DSA_R_DECODE_ERROR 104 #define DSA_R_INVALID_DIGEST_TYPE 106 +#define DSA_R_KEY_SIZE_INVALID 113 +#define DSA_R_KEY_SIZE_TOO_SMALL 110 #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 -#define DSA_R_NEED_NEW_SETUP_VALUES 110 +#define DSA_R_NEED_NEW_SETUP_VALUES 112 #define DSA_R_NON_FIPS_DSA_METHOD 111 +#define DSA_R_NON_FIPS_METHOD 111 #define DSA_R_NO_PARAMETERS_SET 107 +#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112 #define DSA_R_PARAMETER_ENCODING_ERROR 105 #ifdef __cplusplus Index: openssl-1.0.1h/crypto/dsa/dsa_err.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_err.c +++ openssl-1.0.1h/crypto/dsa/dsa_err.c @@ -74,6 +74,8 @@ static ERR_STRING_DATA DSA_str_functs[]= {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, +{ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "dsa_builtin_keygen"}, +{ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "dsa_builtin_paramgen"}, {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, {ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"}, @@ -106,6 +108,8 @@ static ERR_STRING_DATA DSA_str_reasons[] {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, {ERR_REASON(DSA_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, +{ERR_REASON(DSA_R_KEY_SIZE_INVALID) ,"key size invalid"}, +{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"}, Index: openssl-1.0.1h/crypto/dsa/dsa_gen.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_gen.c +++ openssl-1.0.1h/crypto/dsa/dsa_gen.c @@ -85,6 +85,14 @@ #include <openssl/fips.h> #endif +#ifndef OPENSSL_FIPS +static int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits, + const EVP_MD *evpmd, unsigned char *seed, int seed_len, + BIGNUM **p_ret, BIGNUM **q_ret, int *counter_ret, BN_GENCB *cb); +static int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, + BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb); +#endif + int DSA_generate_parameters_ex(DSA *ret, int bits, const unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) @@ -100,14 +108,6 @@ int DSA_generate_parameters_ex(DSA *ret, if(ret->meth->dsa_paramgen) return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, counter_ret, h_ret, cb); -#ifdef OPENSSL_FIPS - else if (FIPS_mode()) - { - return FIPS_dsa_generate_parameters_ex(ret, bits, - seed_in, seed_len, - counter_ret, h_ret, cb); - } -#endif else { const EVP_MD *evpmd; @@ -125,27 +125,119 @@ int DSA_generate_parameters_ex(DSA *ret, } return dsa_builtin_paramgen(ret, bits, qbits, evpmd, - seed_in, seed_len, NULL, counter_ret, h_ret, cb); + seed_in, seed_len, counter_ret, h_ret, cb); } } +#ifdef OPENSSL_FIPS +int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) + { + return dsa_builtin_paramgen(ret, bits, qbits, + evpmd, seed_in, seed_len, + counter_ret, h_ret, cb); + } +#endif + int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, - unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=0; unsigned char seed[SHA256_DIGEST_LENGTH]; + BIGNUM *g=NULL,*q=NULL,*p=NULL; + size_t qsize = qbits >> 3; + BN_CTX *ctx=NULL; + +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, + FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_module_mode() && + (bits != 1024 || qbits != 160) && + (bits != 2048 || qbits != 224) && + (bits != 2048 || qbits != 256) && + (bits != 3072 || qbits != 256)) + { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_INVALID); + goto err; + } +#endif + if (seed_len && (seed_len < (size_t)qsize)) + seed_in = NULL; /* seed buffer too small -- ignore */ + if (seed_len > sizeof(seed)) + seed_len = sizeof(seed); /* App. 2.2 of FIPS PUB 186 allows larger SEED, + * but our internal buffers are restricted to 256 bits*/ + if (seed_in != NULL) + memcpy(seed, seed_in, seed_len); + else + seed_len = 0; + + if ((ctx=BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if (!FIPS_dsa_generate_pq(ctx, bits, qbits, evpmd, + seed, seed_len, &p, &q, counter_ret, cb)) + goto err; + + if (!FIPS_dsa_generate_g(ctx, p, q, &g, h_ret, cb)) + goto err; + + ok=1; +err: + if (ok) + { + if(ret->p) + { + BN_free(ret->p); + ret->p = NULL; + } + if(ret->q) + { + BN_free(ret->q); + ret->q = NULL; + } + if(ret->g) + { + BN_free(ret->g); + ret->g = NULL; + } + ret->p=BN_dup(p); + ret->q=BN_dup(q); + ret->g=BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) + ok=0; + } + if(ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; + } + +#ifndef OPENSSL_FIPS +static +#endif +int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits, + const EVP_MD *evpmd, unsigned char *seed, int seed_len, + BIGNUM **p_ret, BIGNUM **q_ret, int *counter_ret, BN_GENCB *cb) + { + int ok=0; unsigned char md[SHA256_DIGEST_LENGTH]; - unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH]; BIGNUM *r0,*W,*X,*c,*test; - BIGNUM *g=NULL,*q=NULL,*p=NULL; - BN_MONT_CTX *mont=NULL; - int i, k, n=0, m=0, qsize = qbits >> 3; + BIGNUM *q=NULL,*p=NULL; + int i, k, b, n=0, m=0, qsize = qbits >> 3; int counter=0; int r=0; - BN_CTX *ctx=NULL; - unsigned int h=2; if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) @@ -153,51 +245,43 @@ int dsa_builtin_paramgen(DSA *ret, size_ return 0; if (evpmd == NULL) - /* use SHA1 as default */ - evpmd = EVP_sha1(); + { + if (qbits <= 160) + evpmd = EVP_sha1(); + else if (qbits <= 224) + evpmd = EVP_sha224(); + else + evpmd = EVP_sha256(); + } if (bits < 512) bits = 512; bits = (bits+63)/64*64; - /* NB: seed_len == 0 is special case: copy generated seed to - * seed_in if it is not NULL. - */ - if (seed_len && (seed_len < (size_t)qsize)) - seed_in = NULL; /* seed buffer too small -- ignore */ - if (seed_len > (size_t)qsize) - seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED, - * but our internal buffers are restricted to 160 bits*/ - if (seed_in != NULL) - memcpy(seed, seed_in, seed_len); - - if ((ctx=BN_CTX_new()) == NULL) - goto err; - - if ((mont=BN_MONT_CTX_new()) == NULL) - goto err; - - BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); + *q_ret = q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); - p = BN_CTX_get(ctx); + *p_ret = p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test,BN_value_one(),bits-1)) goto err; + /* step 3 n = \lceil bits / qbits \rceil - 1 */ + n = (bits+qbits-1)/qbits - 1; + /* step 4 b = bits - 1 - n * qbits */ + b = bits - 1 - n*qbits; + for (;;) { for (;;) /* find q */ { int seed_is_random; - /* step 1 */ + /* step 5 generate seed */ if(!BN_GENCB_call(cb, 0, m++)) goto err; @@ -212,30 +296,18 @@ int dsa_builtin_paramgen(DSA *ret, size_ seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ } memcpy(buf , seed, qsize); - memcpy(buf2, seed, qsize); - /* precompute "SEED + 1" for step 7: */ - for (i = qsize-1; i >= 0; i--) - { - buf[i]++; - if (buf[i] != 0) - break; - } - /* step 2 */ + /* step 6 U = hash(seed) */ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) goto err; - if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) - goto err; - for (i = 0; i < qsize; i++) - md[i]^=buf2[i]; - /* step 3 */ + /* step 7 q = 2^(qbits-1) + U + 1 - (U mod 2) */ md[0] |= 0x80; md[qsize-1] |= 0x01; if (!BN_bin2bn(md, qsize, q)) goto err; - /* step 4 */ + /* step 8 test for prime (64 round of Rabin-Miller) */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb); if (r > 0) @@ -243,27 +315,22 @@ int dsa_builtin_paramgen(DSA *ret, size_ if (r != 0) goto err; - /* do a callback call */ - /* step 5 */ } if(!BN_GENCB_call(cb, 2, 0)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; - /* step 6 */ + /* step 11 */ counter=0; - /* "offset = 2" */ - - n=(bits-1)/160; + /* "offset = 1" */ for (;;) { if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) goto err; - /* step 7 */ + /* step 11.1, 11.2 obtain W */ BN_zero(W); - /* now 'buf' contains "SEED + offset - 1" */ for (k=0; k<=n; k++) { /* obtain "SEED + offset + k" by incrementing: */ @@ -278,28 +345,30 @@ int dsa_builtin_paramgen(DSA *ret, size_ NULL)) goto err; - /* step 8 */ if (!BN_bin2bn(md, qsize, r0)) goto err; - if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err; + if (k == n) + BN_mask_bits(r0,b); + if (!BN_lshift(r0,r0,qbits*k)) goto err; if (!BN_add(W,W,r0)) goto err; } - /* more of step 8 */ - if (!BN_mask_bits(W,bits-1)) goto err; + /* step 11.3 X = W + 2^(L-1) */ if (!BN_copy(X,W)) goto err; if (!BN_add(X,X,test)) goto err; - /* step 9 */ + /* step 11.4 c = X mod 2*q */ if (!BN_lshift1(r0,q)) goto err; if (!BN_mod(c,X,r0,ctx)) goto err; + + /* step 11.5 p = X - (c - 1) */ if (!BN_sub(r0,c,BN_value_one())) goto err; if (!BN_sub(p,X,r0)) goto err; - /* step 10 */ + /* step 11.6 */ if (BN_cmp(p,test) >= 0) { - /* step 11 */ + /* step 11.7 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) @@ -308,19 +377,45 @@ int dsa_builtin_paramgen(DSA *ret, size_ goto err; } - /* step 13 */ + /* step 11.9 */ counter++; /* "offset = offset + n + 1" */ - /* step 14 */ - if (counter >= 4096) break; + /* step 12 */ + if (counter >= 4*bits) break; } } end: if(!BN_GENCB_call(cb, 2, 1)) goto err; - /* We now need to generate g */ + ok=1; +err: + if (ok) + { + if (counter_ret != NULL) *counter_ret=counter; + } + return ok; + } + +#ifndef OPENSSL_FIPS +static +#endif +int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, + BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb) + { + int ok=0; + BIGNUM *r0, *test, *g = NULL; + BN_MONT_CTX *mont; + unsigned int h=2; + + if ((mont=BN_MONT_CTX_new()) == NULL) + goto err; + + r0 = BN_CTX_get(ctx); + *g_ret = g = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + /* Set r0=(p-1)/q */ if (!BN_sub(test,p,BN_value_one())) goto err; if (!BN_div(r0,NULL,test,q,ctx)) goto err; @@ -344,26 +439,7 @@ end: err: if (ok) { - if(ret->p) BN_free(ret->p); - if(ret->q) BN_free(ret->q); - if(ret->g) BN_free(ret->g); - ret->p=BN_dup(p); - ret->q=BN_dup(q); - ret->g=BN_dup(g); - if (ret->p == NULL || ret->q == NULL || ret->g == NULL) - { - ok=0; - goto err; - } - if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; - if (seed_out) - memcpy(seed_out, seed, qsize); - } - if(ctx) - { - BN_CTX_end(ctx); - BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; Index: openssl-1.0.1h/crypto/dsa/dsa_key.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_key.c +++ openssl-1.0.1h/crypto/dsa/dsa_key.c @@ -66,6 +66,35 @@ #ifdef OPENSSL_FIPS #include <openssl/fips.h> +#include <openssl/evp.h> + +static int fips_check_dsa(DSA *dsa) + { + EVP_PKEY *pk; + unsigned char tbs[] = "DSA Pairwise Check Data"; + int ret = 0; + + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_set1_DSA(pk, dsa); + + if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL)) + ret = 1; + + err: + if (ret == 0) + { + FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED); + fips_set_selftest_fail(); + } + + if (pk) + EVP_PKEY_free(pk); + + return ret; + } + #endif static int dsa_builtin_keygen(DSA *dsa); @@ -82,10 +111,6 @@ int DSA_generate_key(DSA *dsa) #endif if(dsa->meth->dsa_keygen) return dsa->meth->dsa_keygen(dsa); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dsa_generate_key(dsa); -#endif return dsa_builtin_keygen(dsa); } @@ -95,6 +120,15 @@ static int dsa_builtin_keygen(DSA *dsa) BN_CTX *ctx=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif + if ((ctx=BN_CTX_new()) == NULL) goto err; if (dsa->priv_key == NULL) @@ -133,6 +167,14 @@ static int dsa_builtin_keygen(DSA *dsa) dsa->priv_key=priv_key; dsa->pub_key=pub_key; +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !fips_check_dsa(dsa)) + { + dsa->pub_key = NULL; + dsa->priv_key = NULL; + goto err; + } +#endif ok=1; err: Index: openssl-1.0.1h/crypto/dsa/dsa_lib.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_lib.c +++ openssl-1.0.1h/crypto/dsa/dsa_lib.c @@ -87,14 +87,7 @@ const DSA_METHOD *DSA_get_default_method { if(!default_DSA_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dsa_openssl(); - else - return DSA_OpenSSL(); -#else default_DSA_method = DSA_OpenSSL(); -#endif } return default_DSA_method; } Index: openssl-1.0.1h/crypto/dsa/dsa_locl.h =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_locl.h +++ openssl-1.0.1h/crypto/dsa/dsa_locl.h @@ -56,5 +56,4 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, - unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) __attribute__ ((visibility ("hidden"))); Index: openssl-1.0.1h/crypto/dsa/dsa_ossl.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_ossl.c +++ openssl-1.0.1h/crypto/dsa/dsa_ossl.c @@ -65,6 +65,9 @@ #include <openssl/dsa.h> #include <openssl/rand.h> #include <openssl/asn1.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); @@ -82,7 +85,7 @@ NULL, /* dsa_mod_exp, */ NULL, /* dsa_bn_mod_exp, */ dsa_init, dsa_finish, -0, +DSA_FLAG_FIPS_METHOD, NULL, NULL, NULL @@ -138,6 +141,21 @@ static DSA_SIG *dsa_do_sign(const unsign DSA_SIG *ret=NULL; int noredo = 0; +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); + return NULL; + } + + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); + return NULL; + } +#endif + BN_init(&m); BN_init(&xr); @@ -325,6 +343,21 @@ static int dsa_do_verify(const unsigned return -1; } +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } +#endif + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); @@ -399,6 +432,9 @@ static int dsa_do_verify(const unsigned static int dsa_init(DSA *dsa) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif dsa->flags|=DSA_FLAG_CACHE_MONT_P; return(1); } Index: openssl-1.0.1h/crypto/dsa/dsa_pmeth.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsa_pmeth.c +++ openssl-1.0.1h/crypto/dsa/dsa_pmeth.c @@ -255,7 +255,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CT if (!dsa) return 0; ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, - NULL, 0, NULL, NULL, NULL, pcb); + NULL, 0, NULL, NULL, pcb); if (ret) EVP_PKEY_assign_DSA(pkey, dsa); else Index: openssl-1.0.1h/crypto/dsa/dsatest.c =================================================================== --- openssl-1.0.1h.orig/crypto/dsa/dsatest.c +++ openssl-1.0.1h/crypto/dsa/dsatest.c @@ -96,36 +96,41 @@ static int MS_CALLBACK dsa_cb(int p, int /* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */ static unsigned char seed[20]={ - 0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40, - 0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3, + 0x02,0x47,0x11,0x92,0x11,0x88,0xC8,0xFB,0xAF,0x48,0x4C,0x62, + 0xDF,0xA5,0xBE,0xA0,0xA4,0x3C,0x56,0xE3, }; static unsigned char out_p[]={ - 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa, - 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb, - 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, - 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5, - 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf, - 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac, - 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2, - 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91, + 0xAC,0xCB,0x1E,0x63,0x60,0x69,0x0C,0xFB,0x06,0x19,0x68,0x3E, + 0xA5,0x01,0x5A,0xA2,0x15,0x5C,0xE2,0x99,0x2D,0xD5,0x30,0x99, + 0x7E,0x5F,0x8D,0xE2,0xF7,0xC6,0x2E,0x8D,0xA3,0x9F,0x58,0xAD, + 0xD6,0xA9,0x7D,0x0E,0x0D,0x95,0x53,0xA6,0x71,0x3A,0xDE,0xAB, + 0xAC,0xE9,0xF4,0x36,0x55,0x9E,0xB9,0xD6,0x93,0xBF,0xF3,0x18, + 0x1C,0x14,0x7B,0xA5,0x42,0x2E,0xCD,0x00,0xEB,0x35,0x3B,0x1B, + 0xA8,0x51,0xBB,0xE1,0x58,0x42,0x85,0x84,0x22,0xA7,0x97,0x5E, + 0x99,0x6F,0x38,0x20,0xBD,0x9D,0xB6,0xD9,0x33,0x37,0x2A,0xFD, + 0xBB,0xD4,0xBC,0x0C,0x2A,0x67,0xCB,0x9F,0xBB,0xDF,0xF9,0x93, + 0xAA,0xD6,0xF0,0xD6,0x95,0x0B,0x5D,0x65,0x14,0xD0,0x18,0x9D, + 0xC6,0xAF,0xF0,0xC6,0x37,0x7C,0xF3,0x5F, }; static unsigned char out_q[]={ - 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee, - 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e, - 0xda,0xce,0x91,0x5f, + 0xE3,0x8E,0x5E,0x6D,0xBF,0x2B,0x79,0xF8,0xC5,0x4B,0x89,0x8B, + 0xBA,0x2D,0x91,0xC3,0x6C,0x80,0xAC,0x87, }; static unsigned char out_g[]={ - 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13, - 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00, - 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb, - 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e, - 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf, - 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c, - 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c, - 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02, + 0x42,0x4A,0x04,0x4E,0x79,0xB4,0x99,0x7F,0xFD,0x58,0x36,0x2C, + 0x1B,0x5F,0x18,0x7E,0x0D,0xCC,0xAB,0x81,0xC9,0x5D,0x10,0xCE, + 0x4E,0x80,0x7E,0x58,0xB4,0x34,0x3F,0xA7,0x45,0xC7,0xAA,0x36, + 0x24,0x42,0xA9,0x3B,0xE8,0x0E,0x04,0x02,0x2D,0xFB,0xA6,0x13, + 0xB9,0xB5,0x15,0xA5,0x56,0x07,0x35,0xE4,0x03,0xB6,0x79,0x7C, + 0x62,0xDD,0xDF,0x3F,0x71,0x3A,0x9D,0x8B,0xC4,0xF6,0xE7,0x1D, + 0x52,0xA8,0xA9,0x43,0x1D,0x33,0x51,0x88,0x39,0xBD,0x73,0xE9, + 0x5F,0xBE,0x82,0x49,0x27,0xE6,0xB5,0x53,0xC1,0x38,0xAC,0x2F, + 0x6D,0x97,0x6C,0xEB,0x67,0xC1,0x5F,0x67,0xF8,0x35,0x05,0x5E, + 0xD5,0x68,0x80,0xAA,0x96,0xCA,0x0B,0x8A,0xE6,0xF1,0xB1,0x41, + 0xC6,0x75,0x94,0x0A,0x0A,0x2A,0xFA,0x29, }; static const unsigned char str1[]="12345678901234567890"; @@ -157,7 +162,7 @@ int main(int argc, char **argv) BIO_printf(bio_err,"test generation of DSA parameters\n"); BN_GENCB_set(&cb, dsa_cb, bio_err); - if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512, + if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 1024, seed, 20, &counter, &h, &cb)) goto end; @@ -170,9 +175,9 @@ int main(int argc, char **argv) BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h); DSA_print(bio_err,dsa,0); - if (counter != 105) + if (counter != 239) { - BIO_printf(bio_err,"counter should be 105\n"); + BIO_printf(bio_err,"counter should be 239\n"); goto end; } if (h != 2) Index: openssl-1.0.1h/crypto/engine/eng_all.c =================================================================== --- openssl-1.0.1h.orig/crypto/engine/eng_all.c +++ openssl-1.0.1h/crypto/engine/eng_all.c @@ -58,11 +58,25 @@ #include "cryptlib.h" #include "eng_int.h" +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif void ENGINE_load_builtin_engines(void) { /* Some ENGINEs need this */ OPENSSL_cpuid_setup(); +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (FIPS_mode()) { + /* We allow loading dynamic engine as a third party + engine might be FIPS validated. + User is disallowed to load non-validated engines + by security policy. */ + ENGINE_load_dynamic(); + return; + } +#endif #if 0 /* There's no longer any need for an "openssl" ENGINE unless, one day, * it is the *only* way for standard builtin implementations to be be Index: openssl-1.0.1h/crypto/evp/Makefile =================================================================== --- openssl-1.0.1h.orig/crypto/evp/Makefile +++ openssl-1.0.1h/crypto/evp/Makefile @@ -28,7 +28,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \ evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \ - e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c evp_fips.c \ + e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \ @@ -41,7 +41,7 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_ bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \ c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \ evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \ - e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o evp_fips.o \ + e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o \ e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o SRC= $(LIBSRC) Index: openssl-1.0.1h/crypto/evp/c_allc.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/c_allc.c +++ openssl-1.0.1h/crypto/evp/c_allc.c @@ -65,6 +65,11 @@ void OpenSSL_add_all_ciphers(void) { +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if(!FIPS_mode()) + { +#endif #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cfb()); EVP_add_cipher(EVP_des_cfb1()); @@ -227,4 +232,60 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256"); EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256"); #endif +#ifdef OPENSSL_FIPS + } + else + { +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_ede_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb()); + + EVP_add_cipher(EVP_des_ede_ofb()); + EVP_add_cipher(EVP_des_ede3_ofb()); + + EVP_add_cipher(EVP_des_ede_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); + EVP_add_cipher_alias(SN_des_ede3_cbc,"DES3"); + EVP_add_cipher_alias(SN_des_ede3_cbc,"des3"); + + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); +#endif + +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_ecb()); + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_128_cfb()); + EVP_add_cipher(EVP_aes_128_cfb1()); + EVP_add_cipher(EVP_aes_128_cfb8()); + EVP_add_cipher(EVP_aes_128_ofb()); + EVP_add_cipher(EVP_aes_128_ctr()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher_alias(SN_aes_128_cbc,"AES128"); + EVP_add_cipher_alias(SN_aes_128_cbc,"aes128"); + EVP_add_cipher(EVP_aes_192_ecb()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_192_cfb()); + EVP_add_cipher(EVP_aes_192_cfb1()); + EVP_add_cipher(EVP_aes_192_cfb8()); + EVP_add_cipher(EVP_aes_192_ofb()); + EVP_add_cipher(EVP_aes_192_ctr()); + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher_alias(SN_aes_192_cbc,"AES192"); + EVP_add_cipher_alias(SN_aes_192_cbc,"aes192"); + EVP_add_cipher(EVP_aes_256_ecb()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_256_cfb()); + EVP_add_cipher(EVP_aes_256_cfb1()); + EVP_add_cipher(EVP_aes_256_cfb8()); + EVP_add_cipher(EVP_aes_256_ofb()); + EVP_add_cipher(EVP_aes_256_ctr()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher_alias(SN_aes_256_cbc,"AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc,"aes256"); +#endif + } +#endif } Index: openssl-1.0.1h/crypto/evp/c_alld.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/c_alld.c +++ openssl-1.0.1h/crypto/evp/c_alld.c @@ -64,6 +64,11 @@ void OpenSSL_add_all_digests(void) { +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (!FIPS_mode()) + { +#endif #ifndef OPENSSL_NO_MD4 EVP_add_digest(EVP_md4()); #endif @@ -111,4 +116,32 @@ void OpenSSL_add_all_digests(void) #ifndef OPENSSL_NO_WHIRLPOOL EVP_add_digest(EVP_whirlpool()); #endif +#ifdef OPENSSL_FIPS + } + else + { +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_digest(EVP_sha1()); + EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); +#ifndef OPENSSL_NO_DSA + EVP_add_digest(EVP_dss1()); + EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1,"dss1"); +#endif +#ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +#endif +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif + } +#endif } Index: openssl-1.0.1h/crypto/evp/digest.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/digest.c +++ openssl-1.0.1h/crypto/evp/digest.c @@ -142,9 +142,50 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, cons return EVP_DigestInit_ex(ctx, type, NULL); } +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_MD_CTX *ctx) + { FIPS_ERROR_IGNORED("Digest init"); return 0;} + +static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count) + { FIPS_ERROR_IGNORED("Digest update"); return 0;} + +static int bad_final(EVP_MD_CTX *ctx,unsigned char *md) + { FIPS_ERROR_IGNORED("Digest Final"); return 0;} + +static const EVP_MD bad_md = + { + 0, + 0, + 0, + 0, + bad_init, + bad_update, + bad_final, + NULL, + NULL, + NULL, + 0, + {0,0,0,0}, + }; + +#endif + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); + ctx->digest = &bad_md; + return 0; + } +#endif #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing @@ -201,6 +242,18 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c #endif if (ctx->digest != type) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if (!(type->flags & EVP_MD_FLAG_FIPS) + && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->digest = &bad_md; + return 0; + } + } +#endif if (ctx->digest && ctx->digest->ctx_size) OPENSSL_free(ctx->md_data); ctx->digest=type; @@ -229,26 +282,15 @@ skip_to_init: } if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) return 1; -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - { - if (FIPS_digestinit(ctx, type)) - return 1; - OPENSSL_free(ctx->md_data); - ctx->md_data = NULL; - return 0; - } -#endif return ctx->digest->init(ctx); } int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { #ifdef OPENSSL_FIPS - return FIPS_digestupdate(ctx, data, count); -#else - return ctx->update(ctx,data,count); + FIPS_selftest_check(); #endif + return ctx->update(ctx,data,count); } /* The caller can assume that this removes any secret data from the context */ @@ -263,11 +305,11 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, uns /* The caller can assume that this removes any secret data from the context */ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { -#ifdef OPENSSL_FIPS - return FIPS_digestfinal(ctx, md, size); -#else int ret; +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret=ctx->digest->final(ctx,md); if (size != NULL) @@ -279,7 +321,6 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, } memset(ctx->md_data,0,ctx->digest->ctx_size); return ret; -#endif } int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) @@ -376,7 +417,6 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) /* This call frees resources associated with the context */ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { -#ifndef OPENSSL_FIPS /* Don't assume ctx->md_data was cleaned in EVP_Digest_Final, * because sometimes only copies of the context are ever finalised. */ @@ -389,7 +429,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); OPENSSL_free(ctx->md_data); } -#endif if (ctx->pctx) EVP_PKEY_CTX_free(ctx->pctx); #ifndef OPENSSL_NO_ENGINE @@ -398,9 +437,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) * functional reference we held for this reason. */ ENGINE_finish(ctx->engine); #endif -#ifdef OPENSSL_FIPS - FIPS_md_ctx_cleanup(ctx); -#endif memset(ctx,'\0',sizeof *ctx); return 1; Index: openssl-1.0.1h/crypto/evp/e_aes.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/e_aes.c +++ openssl-1.0.1h/crypto/evp/e_aes.c @@ -56,7 +56,6 @@ #include <assert.h> #include <openssl/aes.h> #include "evp_locl.h" -#ifndef OPENSSL_FIPS #include "modes_lcl.h" #include <openssl/rand.h> @@ -726,7 +725,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX * if (arg <= 0) return 0; #ifdef OPENSSL_FIPS - if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) + if (FIPS_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && arg < 12) return 0; #endif @@ -1144,7 +1143,7 @@ static int aes_xts_cipher(EVP_CIPHER_CTX return 0; #ifdef OPENSSL_FIPS /* Requirement of SP800-38E */ - if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && + if (FIPS_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && (len > (1UL<<20)*16)) { EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); @@ -1327,4 +1326,3 @@ BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) #endif -#endif Index: openssl-1.0.1h/crypto/evp/e_des3.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/e_des3.c +++ openssl-1.0.1h/crypto/evp/e_des3.c @@ -65,8 +65,6 @@ #include <openssl/des.h> #include <openssl/rand.h> -#ifndef OPENSSL_FIPS - static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); @@ -208,9 +206,9 @@ static int des_ede3_cfb8_cipher(EVP_CIPH } BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, - EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede_init_key, + NULL, NULL, NULL, des3_ctrl) #define des_ede3_cfb64_cipher des_ede_cfb64_cipher @@ -219,21 +217,21 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, #define des_ede3_ecb_cipher des_ede_ecb_cipher BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, - EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -313,4 +311,3 @@ const EVP_CIPHER *EVP_des_ede3(void) return &des_ede3_ecb; } #endif -#endif Index: openssl-1.0.1h/crypto/evp/e_null.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/e_null.c +++ openssl-1.0.1h/crypto/evp/e_null.c @@ -61,8 +61,6 @@ #include <openssl/evp.h> #include <openssl/objects.h> -#ifndef OPENSSL_FIPS - static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, @@ -71,7 +69,7 @@ static const EVP_CIPHER n_cipher= { NID_undef, 1,0,0, - 0, + EVP_CIPH_FLAG_FIPS, null_init_key, null_cipher, NULL, @@ -101,4 +99,3 @@ static int null_cipher(EVP_CIPHER_CTX *c memcpy((char *)out,(const char *)in,inl); return 1; } -#endif Index: openssl-1.0.1h/crypto/evp/evp.h =================================================================== --- openssl-1.0.1h.orig/crypto/evp/evp.h +++ openssl-1.0.1h/crypto/evp/evp.h @@ -75,6 +75,10 @@ #include <openssl/bio.h> #endif +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + /* #define EVP_RC2_KEY_SIZE 16 #define EVP_RC4_KEY_SIZE 16 @@ -282,10 +286,6 @@ struct env_md_ctx_st * cleaned */ #define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data * in EVP_MD_CTX_cleanup */ -/* FIPS and pad options are ignored in 1.0.0, definitions are here - * so we don't accidentally reuse the values for other purposes. - */ - #define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest * in FIPS mode */ @@ -297,6 +297,10 @@ struct env_md_ctx_st #define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ #define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ #define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ +#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \ + ((ctx->flags>>16) &0xFFFF) /* seed length */ +#define EVP_MD_CTX_FLAG_PSS_MDLEN 0xFFFF /* salt len same as digest */ +#define EVP_MD_CTX_FLAG_PSS_MREC 0xFFFE /* salt max or auto recovered */ #define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */ @@ -348,15 +352,15 @@ struct evp_cipher_st /* cipher handles random key generation */ #define EVP_CIPH_RAND_KEY 0x200 /* cipher has its own additional copying logic */ -#define EVP_CIPH_CUSTOM_COPY 0x400 +#define EVP_CIPH_CUSTOM_COPY 0x4000 /* Allow use default ASN1 get/set iv */ #define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 /* Buffer length in bits not bytes: CFB1 mode only */ #define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 /* Note if suitable for use in FIPS mode */ -#define EVP_CIPH_FLAG_FIPS 0x4000 +#define EVP_CIPH_FLAG_FIPS 0x400 /* Allow non FIPS cipher in FIPS mode */ -#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 /* Cipher handles any and all padding logic as well * as finalisation. */ Index: openssl-1.0.1h/crypto/evp/evp_enc.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/evp_enc.c +++ openssl-1.0.1h/crypto/evp/evp_enc.c @@ -69,17 +69,58 @@ #endif #include "evp_locl.h" -#ifdef OPENSSL_FIPS -#define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl) -#else #define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) -#endif const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { FIPS_ERROR_IGNORED("Cipher init"); return 0;} + +static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { FIPS_ERROR_IGNORED("Cipher update"); return 0;} + +/* NB: no cleanup because it is allowed after failed init */ + +static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) + { FIPS_ERROR_IGNORED("Cipher set_asn1"); return 0;} +static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) + { FIPS_ERROR_IGNORED("Cipher get_asn1"); return 0;} +static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) + { FIPS_ERROR_IGNORED("Cipher ctrl"); return 0;} + +static const EVP_CIPHER bad_cipher = + { + 0, + 0, + 0, + 0, + 0, + bad_init, + bad_do_cipher, + NULL, + 0, + bad_set_asn1, + bad_get_asn1, + bad_ctrl, + NULL + }; + +#endif + void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset(ctx,0,sizeof(EVP_CIPHER_CTX)); /* ctx->cipher=NULL; */ } @@ -111,6 +152,14 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct enc = 1; ctx->encrypt = enc; } +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_EVP_CIPHERINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); + ctx->cipher = &bad_cipher; + return 0; + } +#endif #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing @@ -169,10 +218,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct ctx->engine = NULL; #endif -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_cipherinit(ctx, cipher, key, iv, enc); -#endif ctx->cipher=cipher; if (ctx->cipher->ctx_size) { @@ -206,10 +251,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct #ifndef OPENSSL_NO_ENGINE skip_to_init: #endif -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_cipherinit(ctx, cipher, key, iv, enc); -#endif /* we assume block size is a power of 2 in *cryptUpdate */ OPENSSL_assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 @@ -249,6 +290,22 @@ skip_to_init: } } +#ifdef OPENSSL_FIPS + /* After 'key' is set no further parameters changes are permissible. + * So only check for non FIPS enabling at this point. + */ + if (key && FIPS_mode()) + { + if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS) + & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->cipher = &bad_cipher; + return 0; + } + } +#endif + if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; } @@ -568,7 +625,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { -#ifndef OPENSSL_FIPS if (c->cipher != NULL) { if(c->cipher->cleanup && !c->cipher->cleanup(c)) @@ -579,16 +635,12 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CT } if (c->cipher_data) OPENSSL_free(c->cipher_data); -#endif #ifndef OPENSSL_NO_ENGINE if (c->engine) /* The EVP_CIPHER we used belongs to an ENGINE, release the * functional reference we held for this reason. */ ENGINE_finish(c->engine); #endif -#ifdef OPENSSL_FIPS - FIPS_cipher_ctx_cleanup(c); -#endif memset(c,0,sizeof(EVP_CIPHER_CTX)); return 1; } Index: openssl-1.0.1h/crypto/evp/evp_lib.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/evp_lib.c +++ openssl-1.0.1h/crypto/evp/evp_lib.c @@ -190,6 +190,9 @@ int EVP_CIPHER_CTX_block_size(const EVP_ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif return ctx->cipher->do_cipher(ctx,out,in,inl); } Index: openssl-1.0.1h/crypto/evp/evp_locl.h =================================================================== --- openssl-1.0.1h.orig/crypto/evp/evp_locl.h +++ openssl-1.0.1h/crypto/evp/evp_locl.h @@ -371,11 +371,6 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_ #define MD2_Init private_MD2_Init #define MDC2_Init private_MDC2_Init #define SHA_Init private_SHA_Init -#define SHA1_Init private_SHA1_Init -#define SHA224_Init private_SHA224_Init -#define SHA256_Init private_SHA256_Init -#define SHA384_Init private_SHA384_Init -#define SHA512_Init private_SHA512_Init #define BF_set_key private_BF_set_key #define CAST_set_key private_CAST_set_key @@ -383,7 +378,6 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_ #define SEED_set_key private_SEED_set_key #define RC2_set_key private_RC2_set_key #define RC4_set_key private_RC4_set_key -#define DES_set_key_unchecked private_DES_set_key_unchecked #define Camellia_set_key private_Camellia_set_key #endif Index: openssl-1.0.1h/crypto/evp/m_dss.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/m_dss.c +++ openssl-1.0.1h/crypto/evp/m_dss.c @@ -66,7 +66,6 @@ #endif #ifndef OPENSSL_NO_SHA -#ifndef OPENSSL_FIPS static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -82,7 +81,7 @@ static const EVP_MD dsa_md= NID_dsaWithSHA, NID_dsaWithSHA, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, + EVP_MD_FLAG_PKEY_DIGEST|EVP_MD_FLAG_FIPS, init, update, final, @@ -98,4 +97,3 @@ const EVP_MD *EVP_dss(void) return(&dsa_md); } #endif -#endif Index: openssl-1.0.1h/crypto/evp/m_dss1.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/m_dss1.c +++ openssl-1.0.1h/crypto/evp/m_dss1.c @@ -68,8 +68,6 @@ #include <openssl/dsa.h> #endif -#ifndef OPENSSL_FIPS - static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -84,7 +82,7 @@ static const EVP_MD dss1_md= NID_dsa, NID_dsaWithSHA1, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, + EVP_MD_FLAG_PKEY_DIGEST|EVP_MD_FLAG_FIPS, init, update, final, @@ -100,4 +98,3 @@ const EVP_MD *EVP_dss1(void) return(&dss1_md); } #endif -#endif Index: openssl-1.0.1h/crypto/evp/m_md2.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/m_md2.c +++ openssl-1.0.1h/crypto/evp/m_md2.c @@ -68,6 +68,7 @@ #ifndef OPENSSL_NO_RSA #include <openssl/rsa.h> #endif +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return MD2_Init(ctx->md_data); } Index: openssl-1.0.1h/crypto/evp/m_sha1.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/m_sha1.c +++ openssl-1.0.1h/crypto/evp/m_sha1.c @@ -59,8 +59,6 @@ #include <stdio.h> #include "cryptlib.h" -#ifndef OPENSSL_FIPS - #ifndef OPENSSL_NO_SHA #include <openssl/evp.h> @@ -85,7 +83,8 @@ static const EVP_MD sha1_md= NID_sha1, NID_sha1WithRSAEncryption, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init, update, final, @@ -122,7 +121,8 @@ static const EVP_MD sha224_md= NID_sha224, NID_sha224WithRSAEncryption, SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init224, update256, final256, @@ -141,7 +141,8 @@ static const EVP_MD sha256_md= NID_sha256, NID_sha256WithRSAEncryption, SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init256, update256, final256, @@ -172,7 +173,8 @@ static const EVP_MD sha384_md= NID_sha384, NID_sha384WithRSAEncryption, SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init384, update512, final512, @@ -191,7 +193,8 @@ static const EVP_MD sha512_md= NID_sha512, NID_sha512WithRSAEncryption, SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init512, update512, final512, @@ -206,4 +209,3 @@ const EVP_MD *EVP_sha512(void) { return(&sha512_md); } #endif /* ifndef OPENSSL_NO_SHA512 */ -#endif Index: openssl-1.0.1h/crypto/evp/p_sign.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/p_sign.c +++ openssl-1.0.1h/crypto/evp/p_sign.c @@ -61,6 +61,7 @@ #include <openssl/evp.h> #include <openssl/objects.h> #include <openssl/x509.h> +#include <openssl/rsa.h> #ifdef undef void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) @@ -103,6 +104,22 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsig goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931) + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0) + goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) + { + int saltlen; + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + } if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) goto err; *siglen = sltmp; Index: openssl-1.0.1h/crypto/evp/p_verify.c =================================================================== --- openssl-1.0.1h.orig/crypto/evp/p_verify.c +++ openssl-1.0.1h/crypto/evp/p_verify.c @@ -61,6 +61,7 @@ #include <openssl/evp.h> #include <openssl/objects.h> #include <openssl/x509.h> +#include <openssl/rsa.h> int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey) @@ -88,6 +89,22 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, con goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931) + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0) + goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) + { + int saltlen; + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + } i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); err: EVP_PKEY_CTX_free(pkctx); Index: openssl-1.0.1h/crypto/fips/Makefile =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/Makefile @@ -0,0 +1,340 @@ +# +# OpenSSL/crypto/fips/Makefile +# + +DIR= fips +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=fips_test_suite.c fips_randtest.c +APPS= + +PROGRAM= fips_standalone_hmac +EXE= $(PROGRAM)$(EXE_EXT) + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_aes_selftest.c fips_des_selftest.c fips_hmac_selftest.c fips_rand_selftest.c \ + fips_rsa_selftest.c fips_sha_selftest.c fips.c fips_dsa_selftest.c fips_rand.c \ + fips_rsa_x931g.c fips_post.c fips_drbg_ctr.c fips_drbg_hash.c fips_drbg_hmac.c \ + fips_drbg_lib.c fips_drbg_rand.c fips_drbg_selftest.c fips_rand_lib.c \ + fips_cmac_selftest.c fips_enc.c fips_md.c + +LIBOBJ=fips_aes_selftest.o fips_des_selftest.o fips_hmac_selftest.o fips_rand_selftest.o \ + fips_rsa_selftest.o fips_sha_selftest.o fips.o fips_dsa_selftest.o fips_rand.o \ + fips_rsa_x931g.o fips_post.o fips_drbg_ctr.o fips_drbg_hash.o fips_drbg_hmac.o \ + fips_drbg_lib.o fips_drbg_rand.o fips_drbg_selftest.o fips_rand_lib.o \ + fips_cmac_selftest.o fips_enc.o fips_md.o + +LIBCRYPTO=-L.. -lcrypto + +SRC= $(LIBSRC) fips_standalone_hmac.c + +EXHEADER= fips.h fips_rand.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib exe + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +exe: $(EXE) + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +$(EXE): $(PROGRAM).o + FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha256.o; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../sha/$$i" ; done; \ + $(CC) -o $@ $(CFLAGS) $(PROGRAM).o $$FIPS_SHA_ASM + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h +fips.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +fips.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +fips.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips.o: ../../include/openssl/symhacks.h fips.c fips_locl.h +fips_aes_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_aes_selftest.o: ../../include/openssl/crypto.h +fips_aes_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_aes_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_aes_selftest.o: ../../include/openssl/lhash.h +fips_aes_selftest.o: ../../include/openssl/obj_mac.h +fips_aes_selftest.o: ../../include/openssl/objects.h +fips_aes_selftest.o: ../../include/openssl/opensslconf.h +fips_aes_selftest.o: ../../include/openssl/opensslv.h +fips_aes_selftest.o: ../../include/openssl/ossl_typ.h +fips_aes_selftest.o: ../../include/openssl/safestack.h +fips_aes_selftest.o: ../../include/openssl/stack.h +fips_aes_selftest.o: ../../include/openssl/symhacks.h fips_aes_selftest.c +fips_des_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_des_selftest.o: ../../include/openssl/crypto.h +fips_des_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_des_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_des_selftest.o: ../../include/openssl/lhash.h +fips_des_selftest.o: ../../include/openssl/obj_mac.h +fips_des_selftest.o: ../../include/openssl/objects.h +fips_des_selftest.o: ../../include/openssl/opensslconf.h +fips_des_selftest.o: ../../include/openssl/opensslv.h +fips_des_selftest.o: ../../include/openssl/ossl_typ.h +fips_des_selftest.o: ../../include/openssl/safestack.h +fips_des_selftest.o: ../../include/openssl/stack.h +fips_des_selftest.o: ../../include/openssl/symhacks.h fips_des_selftest.c +fips_drbg_ctr.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_ctr.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_ctr.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +fips_drbg_ctr.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_drbg_ctr.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_drbg_ctr.o: ../../include/openssl/objects.h +fips_drbg_ctr.o: ../../include/openssl/opensslconf.h +fips_drbg_ctr.o: ../../include/openssl/opensslv.h +fips_drbg_ctr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_ctr.o: ../../include/openssl/safestack.h +fips_drbg_ctr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_drbg_ctr.o: fips_drbg_ctr.c fips_rand_lcl.h +fips_drbg_hash.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_hash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_hash.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +fips_drbg_hash.o: ../../include/openssl/fips.h +fips_drbg_hash.o: ../../include/openssl/fips_rand.h +fips_drbg_hash.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_drbg_hash.o: ../../include/openssl/objects.h +fips_drbg_hash.o: ../../include/openssl/opensslconf.h +fips_drbg_hash.o: ../../include/openssl/opensslv.h +fips_drbg_hash.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_hash.o: ../../include/openssl/safestack.h +fips_drbg_hash.o: ../../include/openssl/stack.h +fips_drbg_hash.o: ../../include/openssl/symhacks.h fips_drbg_hash.c +fips_drbg_hash.o: fips_rand_lcl.h +fips_drbg_hmac.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_hmac.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +fips_drbg_hmac.o: ../../include/openssl/fips.h +fips_drbg_hmac.o: ../../include/openssl/fips_rand.h +fips_drbg_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_drbg_hmac.o: ../../include/openssl/objects.h +fips_drbg_hmac.o: ../../include/openssl/opensslconf.h +fips_drbg_hmac.o: ../../include/openssl/opensslv.h +fips_drbg_hmac.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_hmac.o: ../../include/openssl/safestack.h +fips_drbg_hmac.o: ../../include/openssl/stack.h +fips_drbg_hmac.o: ../../include/openssl/symhacks.h fips_drbg_hmac.c +fips_drbg_hmac.o: fips_rand_lcl.h +fips_drbg_lib.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_drbg_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_drbg_lib.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h +fips_drbg_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_drbg_lib.o: ../../include/openssl/objects.h +fips_drbg_lib.o: ../../include/openssl/opensslconf.h +fips_drbg_lib.o: ../../include/openssl/opensslv.h +fips_drbg_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_lib.o: ../../include/openssl/safestack.h +fips_drbg_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_drbg_lib.o: fips_drbg_lib.c fips_locl.h fips_rand_lcl.h +fips_drbg_rand.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_drbg_rand.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_drbg_rand.o: ../../include/openssl/fips_rand.h +fips_drbg_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_drbg_rand.o: ../../include/openssl/obj_mac.h +fips_drbg_rand.o: ../../include/openssl/objects.h +fips_drbg_rand.o: ../../include/openssl/opensslconf.h +fips_drbg_rand.o: ../../include/openssl/opensslv.h +fips_drbg_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_rand.o: ../../include/openssl/safestack.h +fips_drbg_rand.o: ../../include/openssl/stack.h +fips_drbg_rand.o: ../../include/openssl/symhacks.h fips_drbg_rand.c +fips_drbg_rand.o: fips_rand_lcl.h +fips_drbg_selftest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_selftest.o: ../../include/openssl/bio.h +fips_drbg_selftest.o: ../../include/openssl/crypto.h +fips_drbg_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_drbg_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_drbg_selftest.o: ../../include/openssl/fips_rand.h +fips_drbg_selftest.o: ../../include/openssl/hmac.h +fips_drbg_selftest.o: ../../include/openssl/lhash.h +fips_drbg_selftest.o: ../../include/openssl/obj_mac.h +fips_drbg_selftest.o: ../../include/openssl/objects.h +fips_drbg_selftest.o: ../../include/openssl/opensslconf.h +fips_drbg_selftest.o: ../../include/openssl/opensslv.h +fips_drbg_selftest.o: ../../include/openssl/ossl_typ.h +fips_drbg_selftest.o: ../../include/openssl/rand.h +fips_drbg_selftest.o: ../../include/openssl/safestack.h +fips_drbg_selftest.o: ../../include/openssl/stack.h +fips_drbg_selftest.o: ../../include/openssl/symhacks.h fips_drbg_selftest.c +fips_drbg_selftest.o: fips_drbg_selftest.h fips_locl.h fips_rand_lcl.h +fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_dsa_selftest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_dsa_selftest.o: ../../include/openssl/obj_mac.h +fips_dsa_selftest.o: ../../include/openssl/objects.h +fips_dsa_selftest.o: ../../include/openssl/opensslconf.h +fips_dsa_selftest.o: ../../include/openssl/opensslv.h +fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h +fips_dsa_selftest.o: ../../include/openssl/safestack.h +fips_dsa_selftest.o: ../../include/openssl/stack.h +fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c +fips_dsa_selftest.o: fips_locl.h +fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_hmac_selftest.o: ../../include/openssl/crypto.h +fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_hmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_hmac_selftest.o: ../../include/openssl/hmac.h +fips_hmac_selftest.o: ../../include/openssl/lhash.h +fips_hmac_selftest.o: ../../include/openssl/obj_mac.h +fips_hmac_selftest.o: ../../include/openssl/objects.h +fips_hmac_selftest.o: ../../include/openssl/opensslconf.h +fips_hmac_selftest.o: ../../include/openssl/opensslv.h +fips_hmac_selftest.o: ../../include/openssl/ossl_typ.h +fips_hmac_selftest.o: ../../include/openssl/safestack.h +fips_hmac_selftest.o: ../../include/openssl/stack.h +fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c +fips_post.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_post.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_post.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_post.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_post.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_post.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_post.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +fips_post.o: ../../include/openssl/opensslconf.h +fips_post.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips_post.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +fips_post.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_post.o: ../../include/openssl/symhacks.h fips_locl.h fips_post.c +fips_rand.o: ../../e_os.h ../../include/openssl/aes.h +fips_rand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +fips_rand.o: ../../include/openssl/opensslconf.h +fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h +fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rand.o: fips_locl.h fips_rand.c +fips_rand_lib.o: ../../e_os.h ../../include/openssl/aes.h +fips_rand_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_rand_lib.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rand_lib.o: ../../include/openssl/obj_mac.h +fips_rand_lib.o: ../../include/openssl/objects.h +fips_rand_lib.o: ../../include/openssl/opensslconf.h +fips_rand_lib.o: ../../include/openssl/opensslv.h +fips_rand_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_rand_lib.o: ../../include/openssl/safestack.h +fips_rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rand_lib.o: fips_rand_lib.c +fips_rand_selftest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_rand_selftest.o: ../../include/openssl/bio.h +fips_rand_selftest.o: ../../include/openssl/crypto.h +fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rand_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rand_selftest.o: ../../include/openssl/fips_rand.h +fips_rand_selftest.o: ../../include/openssl/hmac.h +fips_rand_selftest.o: ../../include/openssl/lhash.h +fips_rand_selftest.o: ../../include/openssl/obj_mac.h +fips_rand_selftest.o: ../../include/openssl/objects.h +fips_rand_selftest.o: ../../include/openssl/opensslconf.h +fips_rand_selftest.o: ../../include/openssl/opensslv.h +fips_rand_selftest.o: ../../include/openssl/ossl_typ.h +fips_rand_selftest.o: ../../include/openssl/rand.h +fips_rand_selftest.o: ../../include/openssl/safestack.h +fips_rand_selftest.o: ../../include/openssl/stack.h +fips_rand_selftest.o: ../../include/openssl/symhacks.h fips_locl.h +fips_rand_selftest.o: fips_rand_selftest.c +fips_rsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsa_selftest.o: ../../include/openssl/lhash.h +fips_rsa_selftest.o: ../../include/openssl/obj_mac.h +fips_rsa_selftest.o: ../../include/openssl/objects.h +fips_rsa_selftest.o: ../../include/openssl/opensslconf.h +fips_rsa_selftest.o: ../../include/openssl/opensslv.h +fips_rsa_selftest.o: ../../include/openssl/ossl_typ.h +fips_rsa_selftest.o: ../../include/openssl/rsa.h +fips_rsa_selftest.o: ../../include/openssl/safestack.h +fips_rsa_selftest.o: ../../include/openssl/stack.h +fips_rsa_selftest.o: ../../include/openssl/symhacks.h fips_rsa_selftest.c +fips_rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_x931g.o: ../../include/openssl/opensslconf.h +fips_rsa_x931g.o: ../../include/openssl/opensslv.h +fips_rsa_x931g.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_x931g.o: ../../include/openssl/safestack.h +fips_rsa_x931g.o: ../../include/openssl/stack.h +fips_rsa_x931g.o: ../../include/openssl/symhacks.h fips_rsa_x931g.c +fips_sha_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_sha_selftest.o: ../../include/openssl/crypto.h +fips_sha_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_sha_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_sha_selftest.o: ../../include/openssl/lhash.h +fips_sha_selftest.o: ../../include/openssl/obj_mac.h +fips_sha_selftest.o: ../../include/openssl/objects.h +fips_sha_selftest.o: ../../include/openssl/opensslconf.h +fips_sha_selftest.o: ../../include/openssl/opensslv.h +fips_sha_selftest.o: ../../include/openssl/ossl_typ.h +fips_sha_selftest.o: ../../include/openssl/safestack.h +fips_sha_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +fips_sha_selftest.o: ../../include/openssl/symhacks.h fips_sha_selftest.c Index: openssl-1.0.1h/crypto/fips/cavs/fips_aesavs.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_aesavs.c @@ -0,0 +1,939 @@ +/* ==================================================================== + * Copyright (c) 2004 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. + * + */ +/*--------------------------------------------- + NIST AES Algorithm Validation Suite + Test Program + + Donated to OpenSSL by: + V-ONE Corporation + 20250 Century Blvd, Suite 300 + Germantown, MD 20874 + U.S.A. + ----------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <ctype.h> +#include <openssl/aes.h> +#include <openssl/evp.h> +#include <openssl/bn.h> + +#include <openssl/err.h> +#include "e_os.h" + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS AES support\n"); + return(0); +} + +#else + +#include <openssl/fips.h> +#include "fips_utl.h" + +#define AES_BLOCK_SIZE 16 + +#define VERBOSE 0 + +/*-----------------------------------------------*/ + +int AESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *plaintext, unsigned char *ciphertext, int len) + { + const EVP_CIPHER *cipher = NULL; + + if (strcasecmp(amode, "CBC") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cbc(); + break; + + case 192: + cipher = EVP_aes_192_cbc(); + break; + + case 256: + cipher = EVP_aes_256_cbc(); + break; + } + + } + else if (strcasecmp(amode, "ECB") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ecb(); + break; + + case 192: + cipher = EVP_aes_192_ecb(); + break; + + case 256: + cipher = EVP_aes_256_ecb(); + break; + } + } + else if (strcasecmp(amode, "CFB128") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb128(); + break; + + case 192: + cipher = EVP_aes_192_cfb128(); + break; + + case 256: + cipher = EVP_aes_256_cfb128(); + break; + } + + } + else if (strncasecmp(amode, "OFB", 3) == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ofb(); + break; + + case 192: + cipher = EVP_aes_192_ofb(); + break; + + case 256: + cipher = EVP_aes_256_ofb(); + break; + } + } + else if(!strcasecmp(amode,"CFB1")) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb1(); + break; + + case 192: + cipher = EVP_aes_192_cfb1(); + break; + + case 256: + cipher = EVP_aes_256_cfb1(); + break; + } + } + else if(!strcasecmp(amode,"CFB8")) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb8(); + break; + + case 192: + cipher = EVP_aes_192_cfb8(); + break; + + case 256: + cipher = EVP_aes_256_cfb8(); + break; + } + } + else + { + printf("Unknown mode: %s\n", amode); + return 0; + } + if (!cipher) + { + printf("Invalid key size: %d\n", akeysz); + return 0; + } + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; + if(!strcasecmp(amode,"CFB1")) + M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + if (dir) + EVP_Cipher(ctx, ciphertext, plaintext, len); + else + EVP_Cipher(ctx, plaintext, ciphertext, len); + return 1; + } + +/*-----------------------------------------------*/ +char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; +char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"}; +enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128}; +enum XCrypt {XDECRYPT, XENCRYPT}; + +/*=============================*/ +/* Monte Carlo Tests */ +/*-----------------------------*/ + +/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/ +/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/ + +#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1) +#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8))) + +int do_mct(char *amode, + int akeysz, unsigned char *aKey,unsigned char *iVec, + int dir, unsigned char *text, int len, + FILE *rfp) + { + int ret = 0; + unsigned char key[101][32]; + unsigned char iv[101][AES_BLOCK_SIZE]; + unsigned char ptext[1001][32]; + unsigned char ctext[1001][32]; + unsigned char ciphertext[64+4]; + int i, j, n, n1, n2; + int imode = 0, nkeysz = akeysz/8; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (len > 32) + { + printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n", + amode, akeysz); + return -1; + } + for (imode = 0; imode < 6; ++imode) + if (strcmp(amode, t_mode[imode]) == 0) + break; + if (imode == 6) + { + printf("Unrecognized mode: %s\n", amode); + return -1; + } + + memcpy(key[0], aKey, nkeysz); + if (iVec) + memcpy(iv[0], iVec, AES_BLOCK_SIZE); + if (dir == XENCRYPT) + memcpy(ptext[0], text, len); + else + memcpy(ctext[0], text, len); + for (i = 0; i < 100; ++i) + { + /* printf("Iteration %d\n", i); */ + if (i > 0) + { + fprintf(rfp,"COUNT = %d\n",i); + OutputValue("KEY",key[i],nkeysz,rfp,0); + if (imode != ECB) /* ECB */ + OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0); + /* Output Ciphertext | Plaintext */ + OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp, + imode == CFB1); + } + for (j = 0; j < 1000; ++j) + { + switch (imode) + { + case ECB: + if (j == 0) + { /* set up encryption */ + ret = AESTest(&ctx, amode, akeysz, key[i], NULL, + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + if (dir == XENCRYPT) + memcpy(ptext[j+1], ctext[j], len); + else + memcpy(ctext[j+1], ptext[j], len); + } + else + { + if (dir == XENCRYPT) + { + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + memcpy(ptext[j+1], ctext[j], len); + } + else + { + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + memcpy(ctext[j+1], ptext[j], len); + } + } + break; + + case CBC: + case OFB: + case CFB128: + if (j == 0) + { + ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + if (dir == XENCRYPT) + memcpy(ptext[j+1], iv[i], len); + else + memcpy(ctext[j+1], iv[i], len); + } + else + { + if (dir == XENCRYPT) + { + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + memcpy(ptext[j+1], ctext[j-1], len); + } + else + { + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + memcpy(ctext[j+1], ptext[j-1], len); + } + } + break; + + case CFB8: + if (j == 0) + { + ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + } + else + { + if (dir == XENCRYPT) + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + else + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + } + if (dir == XENCRYPT) + { + if (j < 16) + memcpy(ptext[j+1], &iv[i][j], len); + else + memcpy(ptext[j+1], ctext[j-16], len); + } + else + { + if (j < 16) + memcpy(ctext[j+1], &iv[i][j], len); + else + memcpy(ctext[j+1], ptext[j-16], len); + } + break; + + case CFB1: + if(j == 0) + { +#if 0 + /* compensate for wrong endianness of input file */ + if(i == 0) + ptext[0][0]<<=7; +#endif + ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, + ptext[j], ctext[j], len); + } + else + { + if (dir == XENCRYPT) + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + else + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + + } + if(dir == XENCRYPT) + { + if(j < 128) + sb(ptext[j+1],0,gb(iv[i],j)); + else + sb(ptext[j+1],0,gb(ctext[j-128],0)); + } + else + { + if(j < 128) + sb(ctext[j+1],0,gb(iv[i],j)); + else + sb(ctext[j+1],0,gb(ptext[j-128],0)); + } + break; + } + } + --j; /* reset to last of range */ + /* Output Ciphertext | Plaintext */ + OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp, + imode == CFB1); + fprintf(rfp, "\n"); /* add separator */ + + /* Compute next KEY */ + if (dir == XENCRYPT) + { + if (imode == CFB8) + { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ + for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) + ciphertext[n1] = ctext[j-n2][0]; + } + else if(imode == CFB1) + { + for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) + sb(ciphertext,n1,gb(ctext[j-n2],0)); + } + else + switch (akeysz) + { + case 128: + memcpy(ciphertext, ctext[j], 16); + break; + case 192: + memcpy(ciphertext, ctext[j-1]+8, 8); + memcpy(ciphertext+8, ctext[j], 16); + break; + case 256: + memcpy(ciphertext, ctext[j-1], 16); + memcpy(ciphertext+16, ctext[j], 16); + break; + } + } + else + { + if (imode == CFB8) + { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ + for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) + ciphertext[n1] = ptext[j-n2][0]; + } + else if(imode == CFB1) + { + for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) + sb(ciphertext,n1,gb(ptext[j-n2],0)); + } + else + switch (akeysz) + { + case 128: + memcpy(ciphertext, ptext[j], 16); + break; + case 192: + memcpy(ciphertext, ptext[j-1]+8, 8); + memcpy(ciphertext+8, ptext[j], 16); + break; + case 256: + memcpy(ciphertext, ptext[j-1], 16); + memcpy(ciphertext+16, ptext[j], 16); + break; + } + } + /* Compute next key: Key[i+1] = Key[i] xor ct */ + for (n = 0; n < nkeysz; ++n) + key[i+1][n] = key[i][n] ^ ciphertext[n]; + + /* Compute next IV and text */ + if (dir == XENCRYPT) + { + switch (imode) + { + case ECB: + memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE); + break; + case CBC: + case OFB: + case CFB128: + memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE); + memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE); + break; + case CFB8: + /* IV[i+1] = ct */ + for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) + iv[i+1][n1] = ctext[j-n2][0]; + ptext[0][0] = ctext[j-16][0]; + break; + case CFB1: + for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) + sb(iv[i+1],n1,gb(ctext[j-n2],0)); + ptext[0][0]=ctext[j-128][0]&0x80; + break; + } + } + else + { + switch (imode) + { + case ECB: + memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE); + break; + case CBC: + case OFB: + case CFB128: + memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE); + memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE); + break; + case CFB8: + for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) + iv[i+1][n1] = ptext[j-n2][0]; + ctext[0][0] = ptext[j-16][0]; + break; + case CFB1: + for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) + sb(iv[i+1],n1,gb(ptext[j-n2],0)); + ctext[0][0]=ptext[j-128][0]&0x80; + break; + } + } + } + + return ret; + } + +/*================================================*/ +/*---------------------------- + # Config info for v-one + # AESVS MMT test data for ECB + # State : Encrypt and Decrypt + # Key Length : 256 + # Fri Aug 30 04:07:22 PM + ----------------------------*/ + +int proc_file(char *rqfile, char *rspfile) + { + char afn[256], rfn[256]; + FILE *afp = NULL, *rfp = NULL; + char ibuf[2048]; + char tbuf[2048]; + int ilen, len, ret = 0; + char algo[8] = ""; + char amode[8] = ""; + char atest[8] = ""; + int akeysz = 0; + unsigned char iVec[20], aKey[40]; + int dir = -1, err = 0, step = 0; + unsigned char plaintext[2048]; + unsigned char ciphertext[2048]; + char *rp; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (!rqfile || !(*rqfile)) + { + printf("No req file\n"); + return -1; + } + strcpy(afn, rqfile); + + if ((afp = fopen(afn, "r")) == NULL) + { + printf("Cannot open file: %s, %s\n", + afn, strerror(errno)); + return -1; + } + if (!rspfile) + { + strcpy(rfn,afn); + rp=strstr(rfn,"req/"); +#ifdef OPENSSL_SYS_WIN32 + if (!rp) + rp=strstr(rfn,"req\\"); +#endif + assert(rp); + memcpy(rp,"rsp",3); + rp = strstr(rfn, ".req"); + memcpy(rp, ".rsp", 4); + rspfile = rfn; + } + if ((rfp = fopen(rspfile, "w")) == NULL) + { + printf("Cannot open file: %s, %s\n", + rfn, strerror(errno)); + fclose(afp); + afp = NULL; + return -1; + } + while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) + { + tidy_line(tbuf, ibuf); + ilen = strlen(ibuf); + /* printf("step=%d ibuf=%s",step,ibuf); */ + switch (step) + { + case 0: /* read preamble */ + if (ibuf[0] == '\n') + { /* end of preamble */ + if ((*algo == '\0') || + (*amode == '\0') || + (akeysz == 0)) + { + printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n", + algo,amode,akeysz); + err = 1; + } + else + { + fputs(ibuf, rfp); + ++ step; + } + } + else if (ibuf[0] != '#') + { + printf("Invalid preamble item: %s\n", ibuf); + err = 1; + } + else + { /* process preamble */ + char *xp, *pp = ibuf+2; + int n; + if (akeysz) + { /* insert current time & date */ + time_t rtim = time(0); + fprintf(rfp, "# %s", ctime(&rtim)); + } + else + { + fputs(ibuf, rfp); + if (strncmp(pp, "AESVS ", 6) == 0) + { + strcpy(algo, "AES"); + /* get test type */ + pp += 6; + xp = strchr(pp, ' '); + n = xp-pp; + strncpy(atest, pp, n); + atest[n] = '\0'; + /* get mode */ + xp = strrchr(pp, ' '); /* get mode" */ + n = strlen(xp+1)-1; + strncpy(amode, xp+1, n); + amode[n] = '\0'; + /* amode[3] = '\0'; */ + if (VERBOSE) + printf("Test = %s, Mode = %s\n", atest, amode); + } + else if (strncasecmp(pp, "Key Length : ", 13) == 0) + { + akeysz = atoi(pp+13); + if (VERBOSE) + printf("Key size = %d\n", akeysz); + } + } + } + break; + + case 1: /* [ENCRYPT] | [DECRYPT] */ + if (ibuf[0] == '[') + { + fputs(ibuf, rfp); + ++step; + if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) + dir = 1; + else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) + dir = 0; + else + { + printf("Invalid keyword: %s\n", ibuf); + err = 1; + } + break; + } + else if (dir == -1) + { + err = 1; + printf("Missing ENCRYPT/DECRYPT keyword\n"); + break; + } + else + step = 2; + + case 2: /* KEY = xxxx */ + fputs(ibuf, rfp); + if(*ibuf == '\n') + break; + if(!strncasecmp(ibuf,"COUNT = ",8)) + break; + + if (strncasecmp(ibuf, "KEY = ", 6) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+6, aKey); + if (len < 0) + { + printf("Invalid KEY\n"); + err =1; + break; + } + PrintValue("KEY", aKey, len); + if (strcmp(amode, "ECB") == 0) + { + memset(iVec, 0, sizeof(iVec)); + step = (dir)? 4: 5; /* no ivec for ECB */ + } + else + ++step; + } + break; + + case 3: /* IV = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "IV = ", 5) != 0) + { + printf("Missing IV\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+5, iVec); + if (len < 0) + { + printf("Invalid IV\n"); + err =1; + break; + } + PrintValue("IV", iVec, len); + step = (dir)? 4: 5; + } + break; + + case 4: /* PLAINTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) + { + printf("Missing PLAINTEXT\n"); + err = 1; + } + else + { + int nn = strlen(ibuf+12); + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+12,nn-1,plaintext); + else + len=hex2bin(ibuf+12, plaintext); + if (len < 0) + { + printf("Invalid PLAINTEXT: %s", ibuf+12); + err =1; + break; + } + if (len >= sizeof(plaintext)) + { + printf("Buffer overflow\n"); + } + PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); + if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ + { + if(do_mct(amode, akeysz, aKey, iVec, + dir, (unsigned char*)plaintext, len, + rfp) < 0) + EXIT(1); + } + else + { + ret = AESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("CIPHERTEXT",ciphertext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 5: /* CIPHERTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); + else + len = hex2bin(ibuf+13,ciphertext); + if (len < 0) + { + printf("Invalid CIPHERTEXT\n"); + err =1; + break; + } + + PrintValue("CIPHERTEXT", ciphertext, len); + if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ + { + do_mct(amode, akeysz, aKey, iVec, + dir, ciphertext, len, rfp); + } + else + { + ret = AESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 6: + if (ibuf[0] != '\n') + { + err = 1; + printf("Missing terminator\n"); + } + else if (strcmp(atest, "MCT") != 0) + { /* MCT already added terminating nl */ + fputs(ibuf, rfp); + } + step = 1; + break; + } + } + if (rfp) + fclose(rfp); + if (afp) + fclose(afp); + return err; + } + +/*-------------------------------------------------- + Processes either a single file or + a set of files whose names are passed in a file. + A single file is specified as: + aes_test -f xxx.req + A set of files is specified as: + aes_test -d xxxxx.xxx + The default is: -d req.txt +--------------------------------------------------*/ +int main(int argc, char **argv) + { + char *rqlist = "req.txt", *rspfile = NULL; + FILE *fp = NULL; + char fn[250] = "", rfn[256] = ""; + int f_opt = 0, d_opt = 1; + +#ifdef OPENSSL_FIPS + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } +#endif + if (argc > 1) + { + if (strcasecmp(argv[1], "-d") == 0) + { + d_opt = 1; + } + else if (strcasecmp(argv[1], "-f") == 0) + { + f_opt = 1; + d_opt = 0; + } + else + { + printf("Invalid parameter: %s\n", argv[1]); + return 0; + } + if (argc < 3) + { + printf("Missing parameter\n"); + return 0; + } + if (d_opt) + rqlist = argv[2]; + else + { + strcpy(fn, argv[2]); + rspfile = argv[3]; + } + } + if (d_opt) + { /* list of files (directory) */ + if (!(fp = fopen(rqlist, "r"))) + { + printf("Cannot open req list file\n"); + return -1; + } + while (fgets(fn, sizeof(fn), fp)) + { + strtok(fn, "\r\n"); + strcpy(rfn, fn); + if (VERBOSE) + printf("Processing: %s\n", rfn); + if (proc_file(rfn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", rfn); + EXIT(1); + } + } + fclose(fp); + } + else /* single file */ + { + if (VERBOSE) + printf("Processing: %s\n", fn); + if (proc_file(fn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", fn); + } + } + EXIT(0); + return 0; + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_cmactest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_cmactest.c @@ -0,0 +1,517 @@ +/* fips_cmactest.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_FIPSAPI + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/cmac.h> +#include <openssl/err.h> +#include <openssl/bn.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS CMAC support\n"); + return(0); +} + +#else + +#include <openssl/fips.h> +#include "fips_utl.h" + +static int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in, + int mode, int Klen_counts_keys, int known_keylen); +static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out, + unsigned char *Key, int Klen, + unsigned char *Msg, int Msglen, + int Tlen); +static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out, + unsigned char *Key, int Klen, + unsigned char *Msg, int Msglen, + unsigned char *Mac, int Maclen, + int Tlen); + +#ifdef FIPS_ALGVS +int fips_cmactest_main(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif + { + FILE *in = NULL, *out = NULL; + int mode = 0; /* 0 => Generate, 1 => Verify */ + int Klen_counts_keys = 0; /* 0 => Klen is size of one key + 1 => Klen is amount of keys + */ + int known_keylen = 0; /* Only set when Klen_counts_keys = 1 */ + const EVP_CIPHER *cipher = 0; + int ret = 1; + fips_algtest_init(); + + while (argc > 1 && argv[1][0] == '-') + { + switch (argv[1][1]) + { + case 'a': + { + char *p = &argv[1][2]; + if (*p == '\0') + { + if (argc <= 2) + { + fprintf(stderr, "Option %s needs a value\n", argv[1]); + goto end; + } + argv++; + argc--; + p = &argv[1][0]; + } + if (!strcmp(p, "aes128")) + cipher = EVP_aes_128_cbc(); + else if (!strcmp(p, "aes192")) + cipher = EVP_aes_192_cbc(); + else if (!strcmp(p, "aes256")) + cipher = EVP_aes_256_cbc(); + else if (!strcmp(p, "tdea3") || !strcmp(p, "tdes3")) + { + cipher = EVP_des_ede3_cbc(); + Klen_counts_keys = 1; + known_keylen = 8; + } + else + { + fprintf(stderr, "Unknown algorithm %s\n", p); + goto end; + } + } + break; + case 'g': + mode = 0; + break; + case 'v': + mode = 1; + break; + default: + fprintf(stderr, "Unknown option %s\n", argv[1]); + goto end; + } + argv++; + argc--; + } + 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 (!cmac_test(cipher, out, in, mode, + Klen_counts_keys, known_keylen)) + { + fprintf(stderr, "FATAL cmac 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 CMAC_TEST_MAXLINELEN 150000 + +int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in, + int mode, int Klen_counts_keys, int known_keylen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + unsigned char **Keys = NULL, *Msg = NULL, *Mac = NULL; + unsigned char *Key = NULL; + int Count, Klen, Mlen, Tlen; + long Keylen, Msglen, Maclen; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + Count = -1; + Klen = -1; + Mlen = -1; + Tlen = -1; + + while (fgets(olinebuf, CMAC_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Skip comments */ + if (keyword[0] == '#') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [L=20] line) 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; + + if (!strcmp(keyword, "Count")) + { + if (Count != -1) + goto parse_error; + Count = atoi(value); + if (Count < 0) + goto parse_error; + } + else if (!strcmp(keyword, "Klen")) + { + if (Klen != -1) + goto parse_error; + Klen = atoi(value); + if (Klen < 0) + goto parse_error; + if (Klen_counts_keys) + { + Keys = OPENSSL_malloc(sizeof(*Keys) * Klen); + memset(Keys, '\0', sizeof(*Keys) * Klen); + } + else + { + Keys = OPENSSL_malloc(sizeof(*Keys)); + memset(Keys, '\0', sizeof(*Keys)); + } + } + else if (!strcmp(keyword, "Mlen")) + { + if (Mlen != -1) + goto parse_error; + Mlen = atoi(value); + if (Mlen < 0) + goto parse_error; + } + else if (!strcmp(keyword, "Tlen")) + { + if (Tlen != -1) + goto parse_error; + Tlen = atoi(value); + if (Tlen < 0) + goto parse_error; + } + else if (!strcmp(keyword, "Key") && !Klen_counts_keys) + { + if (Keys[0]) + goto parse_error; + Keys[0] = hex2bin_m(value, &Keylen); + if (!Keys[0]) + goto parse_error; + } + else if (!strncmp(keyword, "Key", 3) && Klen_counts_keys) + { + int keynum = atoi(keyword + 3); + if (!keynum || keynum > Klen || Keys[keynum-1]) + goto parse_error; + Keys[keynum-1] = hex2bin_m(value, &Keylen); + if (!Keys[keynum-1]) + goto parse_error; + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "Mac")) + { + if (mode == 0) + continue; + if (Mac) + goto parse_error; + Mac = hex2bin_m(value, &Maclen); + if (!Mac) + goto parse_error; + } + else if (!strcmp(keyword, "Result")) + { + if (mode == 1) + continue; + goto parse_error; + } + else + goto parse_error; + + fputs(olinebuf, out); + + if (Keys && Msg && (!mode || Mac) && (Tlen > 0) && (Klen > 0)) + { + if (Klen_counts_keys) + { + int x; + Key = OPENSSL_malloc(Klen * known_keylen); + for (x = 0; x < Klen; x++) + { + memcpy(Key + x * known_keylen, + Keys[x], known_keylen); + OPENSSL_free(Keys[x]); + } + Klen *= known_keylen; + } + else + { + Key = OPENSSL_malloc(Klen); + memcpy(Key, Keys[0], Klen); + OPENSSL_free(Keys[0]); + } + OPENSSL_free(Keys); + + switch(mode) + { + case 0: + if (!print_cmac_gen(cipher, out, + Key, Klen, + Msg, Mlen, + Tlen)) + goto error; + break; + case 1: + if (!print_cmac_ver(cipher, out, + Key, Klen, + Msg, Mlen, + Mac, Maclen, + Tlen)) + goto error; + break; + } + + OPENSSL_free(Key); + Key = NULL; + OPENSSL_free(Msg); + Msg = NULL; + OPENSSL_free(Mac); + Mac = NULL; + Klen = -1; + Mlen = -1; + Tlen = -1; + Count = -1; + } + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (Key) + OPENSSL_free(Key); + if (Msg) + OPENSSL_free(Msg); + if (Mac) + OPENSSL_free(Mac); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out, + unsigned char *Key, int Klen, + unsigned char *Msg, int Mlen, + int Tlen) + { + int rc, i; + size_t reslen; + unsigned char res[128]; + CMAC_CTX *cmac_ctx = CMAC_CTX_new(); + + CMAC_Init(cmac_ctx, Key, Klen, cipher, 0); + CMAC_Update(cmac_ctx, Msg, Mlen); + if (!CMAC_Final(cmac_ctx, res, &reslen)) + { + fputs("Error calculating CMAC\n", stderr); + rc = 0; + } + else if (Tlen > (int)reslen) + { + fputs("Parameter error, Tlen > CMAC length\n", stderr); + rc = 0; + } + else + { + fputs("Mac = ", out); + for (i = 0; i < Tlen; i++) + fprintf(out, "%02x", res[i]); + fputs(RESP_EOL, out); + rc = 1; + } + CMAC_CTX_free(cmac_ctx); + return rc; + } + +static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out, + unsigned char *Key, int Klen, + unsigned char *Msg, int Mlen, + unsigned char *Mac, int Maclen, + int Tlen) + { + int rc = 1; + size_t reslen; + unsigned char res[128]; + CMAC_CTX *cmac_ctx = CMAC_CTX_new(); + + CMAC_Init(cmac_ctx, Key, Klen, cipher, 0); + CMAC_Update(cmac_ctx, Msg, Mlen); + if (!CMAC_Final(cmac_ctx, res, &reslen)) + { + fputs("Error calculating CMAC\n", stderr); + rc = 0; + } + else if (Tlen > (int)reslen) + { + fputs("Parameter error, Tlen > CMAC length\n", stderr); + rc = 0; + } + else if (Tlen != Maclen) + { + fputs("Parameter error, Tlen != resulting Mac length\n", stderr); + rc = 0; + } + else + { + if (!memcmp(Mac, res, Maclen)) + fputs("Result = P" RESP_EOL, out); + else + fputs("Result = F" RESP_EOL, out); + } + CMAC_CTX_free(cmac_ctx); + return rc; + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_desmovs.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_desmovs.c @@ -0,0 +1,702 @@ +/* ==================================================================== + * Copyright (c) 2004 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. + * + */ +/*--------------------------------------------- + NIST DES Modes of Operation Validation System + Test Program + + Based on the AES Validation Suite, which was: + Donated to OpenSSL by: + V-ONE Corporation + 20250 Century Blvd, Suite 300 + Germantown, MD 20874 + U.S.A. + ----------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <ctype.h> +#include <openssl/des.h> +#include <openssl/evp.h> +#include <openssl/bn.h> + +#include <openssl/err.h> +#include "e_os.h" + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS DES support\n"); + return(0); +} + +#else + +#include <openssl/fips.h> +#include "fips_utl.h" + +#define DES_BLOCK_SIZE 8 + +#define VERBOSE 0 + +int DESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *out, unsigned char *in, int len) + { + const EVP_CIPHER *cipher = NULL; + + if (akeysz != 192) + { + printf("Invalid key size: %d\n", akeysz); + EXIT(1); + } + + if (strcasecmp(amode, "CBC") == 0) + cipher = EVP_des_ede3_cbc(); + else if (strcasecmp(amode, "ECB") == 0) + cipher = EVP_des_ede3_ecb(); + else if (strcasecmp(amode, "CFB64") == 0) + cipher = EVP_des_ede3_cfb64(); + else if (strncasecmp(amode, "OFB", 3) == 0) + cipher = EVP_des_ede3_ofb(); + else if(!strcasecmp(amode,"CFB8")) + cipher = EVP_des_ede3_cfb8(); + else if(!strcasecmp(amode,"CFB1")) + cipher = EVP_des_ede3_cfb1(); + else + { + printf("Unknown mode: %s\n", amode); + EXIT(1); + } + + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; + if(!strcasecmp(amode,"CFB1")) + M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + EVP_Cipher(ctx, out, in, len); + + return 1; + } + +void DebugValue(char *tag, unsigned char *val, int len) + { + char obuf[2048]; + int olen; + olen = bin2hex(val, len, obuf); + printf("%s = %.*s\n", tag, olen, obuf); + } + +void shiftin(unsigned char *dst,unsigned char *src,int nbits) + { + int n; + + /* move the bytes... */ + memmove(dst,dst+nbits/8,3*8-nbits/8); + /* append new data */ + memcpy(dst+3*8-nbits/8,src,(nbits+7)/8); + /* left shift the bits */ + if(nbits%8) + for(n=0 ; n < 3*8 ; ++n) + dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8)); + } + +/*-----------------------------------------------*/ +char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; +char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"}; +enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64}; +int Sizes[6]={64,64,64,1,8,64}; + +void do_mct(char *amode, + int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec, + int dir, unsigned char *text, int len, + FILE *rfp) + { + int i,imode; + unsigned char nk[4*8]; /* longest key+8 */ + unsigned char text0[8]; + + for (imode=0 ; imode < 6 ; ++imode) + if(!strcmp(amode,t_mode[imode])) + break; + if (imode == 6) + { + printf("Unrecognized mode: %s\n", amode); + EXIT(1); + } + + for(i=0 ; i < 400 ; ++i) + { + int j; + int n; + int kp=akeysz/64; + unsigned char old_iv[8]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + fprintf(rfp,"\nCOUNT = %d\n",i); + if(kp == 1) + OutputValue("KEY",akey,8,rfp,0); + else + for(n=0 ; n < kp ; ++n) + { + fprintf(rfp,"KEY%d",n+1); + OutputValue("",akey+n*8,8,rfp,0); + } + + if(imode != ECB) + OutputValue("IV",ivec,8,rfp,0); + OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1); +#if 0 + /* compensate for endianness */ + if(imode == CFB1) + text[0]<<=7; +#endif + memcpy(text0,text,8); + + for(j=0 ; j < 10000 ; ++j) + { + unsigned char old_text[8]; + + memcpy(old_text,text,8); + if(j == 0) + { + memcpy(old_iv,ivec,8); + DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len); + } + else + { + memcpy(old_iv,ctx.iv,8); + EVP_Cipher(&ctx,text,text,len); + } + if(j == 9999) + { + OutputValue(t_tag[dir],text,len,rfp,imode == CFB1); + /* memcpy(ivec,text,8); */ + } + /* DebugValue("iv",ctx.iv,8); */ + /* accumulate material for the next key */ + shiftin(nk,text,Sizes[imode]); + /* DebugValue("nk",nk,24);*/ + if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64 + || imode == CBC)) || imode == OFB) + memcpy(text,old_iv,8); + + if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64)) + { + /* the test specifies using the output of the raw DES operation + which we don't have, so reconstruct it... */ + for(n=0 ; n < 8 ; ++n) + text[n]^=old_text[n]; + } + } + for(n=0 ; n < 8 ; ++n) + akey[n]^=nk[16+n]; + for(n=0 ; n < 8 ; ++n) + akey[8+n]^=nk[8+n]; + for(n=0 ; n < 8 ; ++n) + akey[16+n]^=nk[n]; + if(numkeys < 3) + memcpy(&akey[2*8],akey,8); + if(numkeys < 2) + memcpy(&akey[8],akey,8); + DES_set_odd_parity((DES_cblock *)akey); + DES_set_odd_parity((DES_cblock *)(akey+8)); + DES_set_odd_parity((DES_cblock *)(akey+16)); + memcpy(ivec,ctx.iv,8); + + /* pointless exercise - the final text doesn't depend on the + initial text in OFB mode, so who cares what it is? (Who + designed these tests?) */ + if(imode == OFB) + for(n=0 ; n < 8 ; ++n) + text[n]=text0[n]^old_iv[n]; + } + } + +int proc_file(char *rqfile, char *rspfile) + { + char afn[256], rfn[256]; + FILE *afp = NULL, *rfp = NULL; + char ibuf[2048], tbuf[2048]; + int ilen, len, ret = 0; + char amode[8] = ""; + char atest[100] = ""; + int akeysz=0; + unsigned char iVec[20], aKey[40]; + int dir = -1, err = 0, step = 0; + unsigned char plaintext[2048]; + unsigned char ciphertext[2048]; + char *rp; + EVP_CIPHER_CTX ctx; + int numkeys=1; + EVP_CIPHER_CTX_init(&ctx); + + if (!rqfile || !(*rqfile)) + { + printf("No req file\n"); + return -1; + } + strcpy(afn, rqfile); + + if ((afp = fopen(afn, "r")) == NULL) + { + printf("Cannot open file: %s, %s\n", + afn, strerror(errno)); + return -1; + } + if (!rspfile) + { + strcpy(rfn,afn); + rp=strstr(rfn,"req/"); +#ifdef OPENSSL_SYS_WIN32 + if (!rp) + rp=strstr(rfn,"req\\"); +#endif + assert(rp); + memcpy(rp,"rsp",3); + rp = strstr(rfn, ".req"); + memcpy(rp, ".rsp", 4); + rspfile = rfn; + } + if ((rfp = fopen(rspfile, "w")) == NULL) + { + printf("Cannot open file: %s, %s\n", + rfn, strerror(errno)); + fclose(afp); + afp = NULL; + return -1; + } + while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) + { + tidy_line(tbuf, ibuf); + ilen = strlen(ibuf); + /* printf("step=%d ibuf=%s",step,ibuf);*/ + if(step == 3 && !strcmp(amode,"ECB")) + { + memset(iVec, 0, sizeof(iVec)); + step = (dir)? 4: 5; /* no ivec for ECB */ + } + switch (step) + { + case 0: /* read preamble */ + if (ibuf[0] == '\n') + { /* end of preamble */ + if (*amode == '\0') + { + printf("Missing Mode\n"); + err = 1; + } + else + { + fputs(ibuf, rfp); + ++ step; + } + } + else if (ibuf[0] != '#') + { + printf("Invalid preamble item: %s\n", ibuf); + err = 1; + } + else + { /* process preamble */ + char *xp, *pp = ibuf+2; + int n; + if(*amode) + { /* insert current time & date */ + time_t rtim = time(0); + fprintf(rfp, "# %s", ctime(&rtim)); + } + else + { + fputs(ibuf, rfp); + if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4) + || !strncmp(pp,"TDES ",5) + || !strncmp(pp,"PERMUTATION ",12) + || !strncmp(pp,"SUBSTITUTION ",13) + || !strncmp(pp,"VARIABLE ",9)) + { + /* get test type */ + if(!strncmp(pp,"DES ",4)) + pp+=4; + else if(!strncmp(pp,"TDES ",5)) + pp+=5; + xp = strchr(pp, ' '); + n = xp-pp; + strncpy(atest, pp, n); + atest[n] = '\0'; + /* get mode */ + xp = strrchr(pp, ' '); /* get mode" */ + n = strlen(xp+1)-1; + strncpy(amode, xp+1, n); + amode[n] = '\0'; + /* amode[3] = '\0'; */ + if (VERBOSE) + printf("Test=%s, Mode=%s\n",atest,amode); + } + } + } + break; + + case 1: /* [ENCRYPT] | [DECRYPT] */ + if(ibuf[0] == '\n') + break; + if (ibuf[0] == '[') + { + fputs(ibuf, rfp); + ++step; + if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) + dir = 1; + else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) + dir = 0; + else + { + printf("Invalid keyword: %s\n", ibuf); + err = 1; + } + break; + } + else if (dir == -1) + { + err = 1; + printf("Missing ENCRYPT/DECRYPT keyword\n"); + break; + } + else + step = 2; + + case 2: /* KEY = xxxx */ + if(*ibuf == '\n') + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"COUNT = ",8)) + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"COUNT=",6)) + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"NumKeys = ",10)) + { + numkeys=atoi(ibuf+10); + break; + } + + fputs(ibuf, rfp); + if(!strncasecmp(ibuf,"KEY = ",6)) + { + akeysz=64; + len = hex2bin((char*)ibuf+6, aKey); + if (len < 0) + { + printf("Invalid KEY\n"); + err=1; + break; + } + PrintValue("KEY", aKey, len); + ++step; + } + else if(!strncasecmp(ibuf,"KEYs = ",7)) + { + akeysz=64*3; + len=hex2bin(ibuf+7,aKey); + if(len != 8) + { + printf("Invalid KEY\n"); + err=1; + break; + } + memcpy(aKey+8,aKey,8); + memcpy(aKey+16,aKey,8); + ibuf[4]='\0'; + PrintValue("KEYs",aKey,len); + ++step; + } + else if(!strncasecmp(ibuf,"KEY",3)) + { + int n=ibuf[3]-'1'; + + akeysz=64*3; + len=hex2bin(ibuf+7,aKey+n*8); + if(len != 8) + { + printf("Invalid KEY\n"); + err=1; + break; + } + ibuf[4]='\0'; + PrintValue(ibuf,aKey,len); + if(n == 2) + ++step; + } + else + { + printf("Missing KEY\n"); + err = 1; + } + break; + + case 3: /* IV = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "IV = ", 5) != 0) + { + printf("Missing IV\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+5, iVec); + if (len < 0) + { + printf("Invalid IV\n"); + err =1; + break; + } + PrintValue("IV", iVec, len); + step = (dir)? 4: 5; + } + break; + + case 4: /* PLAINTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) + { + printf("Missing PLAINTEXT\n"); + err = 1; + } + else + { + int nn = strlen(ibuf+12); + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+12,nn-1,plaintext); + else + len=hex2bin(ibuf+12, plaintext); + if (len < 0) + { + printf("Invalid PLAINTEXT: %s", ibuf+12); + err =1; + break; + } + if (len >= sizeof(plaintext)) + { + printf("Buffer overflow\n"); + } + PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); + if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ + { + do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp); + } + else + { + assert(dir == 1); + ret = DESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + ciphertext, plaintext, len); + OutputValue("CIPHERTEXT",ciphertext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 5: /* CIPHERTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); + else + len = hex2bin(ibuf+13,ciphertext); + if (len < 0) + { + printf("Invalid CIPHERTEXT\n"); + err =1; + break; + } + + PrintValue("CIPHERTEXT", ciphertext, len); + if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ + { + do_mct(amode, akeysz, numkeys, aKey, iVec, + dir, ciphertext, len, rfp); + } + else + { + assert(dir == 0); + ret = DESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 6: + if (ibuf[0] != '\n') + { + err = 1; + printf("Missing terminator\n"); + } + else if (strcmp(atest, "MCT") != 0) + { /* MCT already added terminating nl */ + fputs(ibuf, rfp); + } + step = 1; + break; + } + } + if (rfp) + fclose(rfp); + if (afp) + fclose(afp); + return err; + } + +/*-------------------------------------------------- + Processes either a single file or + a set of files whose names are passed in a file. + A single file is specified as: + aes_test -f xxx.req + A set of files is specified as: + aes_test -d xxxxx.xxx + The default is: -d req.txt +--------------------------------------------------*/ +int main(int argc, char **argv) + { + char *rqlist = "req.txt", *rspfile = NULL; + FILE *fp = NULL; + char fn[250] = "", rfn[256] = ""; + int f_opt = 0, d_opt = 1; + +#ifdef OPENSSL_FIPS + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } +#endif + if (argc > 1) + { + if (strcasecmp(argv[1], "-d") == 0) + { + d_opt = 1; + } + else if (strcasecmp(argv[1], "-f") == 0) + { + f_opt = 1; + d_opt = 0; + } + else + { + printf("Invalid parameter: %s\n", argv[1]); + return 0; + } + if (argc < 3) + { + printf("Missing parameter\n"); + return 0; + } + if (d_opt) + rqlist = argv[2]; + else + { + strcpy(fn, argv[2]); + rspfile = argv[3]; + } + } + if (d_opt) + { /* list of files (directory) */ + if (!(fp = fopen(rqlist, "r"))) + { + printf("Cannot open req list file\n"); + return -1; + } + while (fgets(fn, sizeof(fn), fp)) + { + strtok(fn, "\r\n"); + strcpy(rfn, fn); + printf("Processing: %s\n", rfn); + if (proc_file(rfn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", rfn); + EXIT(1); + } + } + fclose(fp); + } + else /* single file */ + { + if (VERBOSE) + printf("Processing: %s\n", fn); + if (proc_file(fn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", fn); + } + } + EXIT(0); + return 0; + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_dhvs.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_dhvs.c @@ -0,0 +1,292 @@ +/* fips/dh/fips_dhvs.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + + +#define OPENSSL_FIPSAPI +#include <openssl/opensslconf.h> + +#ifndef OPENSSL_FIPS +#include <stdio.h> + +int main(int argc, char **argv) +{ + printf("No FIPS DH support\n"); + return(0); +} +#else + +#include <openssl/crypto.h> +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <string.h> +#include <ctype.h> + +#include "fips_utl.h" + +static const EVP_MD *parse_md(char *line) + { + char *p; + if (line[0] != '[' || line[1] != 'F') + return NULL; + p = strchr(line, '-'); + if (!p) + return NULL; + line = p + 1; + p = strchr(line, ']'); + if (!p) + return NULL; + *p = 0; + p = line; + while(isspace(*p)) + p++; + if (!strcmp(p, "SHA1")) + return EVP_sha1(); + else if (!strcmp(p, "SHA224")) + return EVP_sha224(); + else if (!strcmp(p, "SHA256")) + return EVP_sha256(); + else if (!strcmp(p, "SHA384")) + return EVP_sha384(); + else if (!strcmp(p, "SHA512")) + return EVP_sha512(); + else + return NULL; + } + +static void output_Zhash(FILE *out, int exout, + DH *dh, BIGNUM *peerkey, const EVP_MD *md, + unsigned char *rhash, size_t rhashlen) + { + unsigned char *Z; + unsigned char chash[EVP_MAX_MD_SIZE]; + int Zlen; + if (rhash == NULL) + { + rhashlen = M_EVP_MD_size(md); + if (!DH_generate_key(dh)) + exit (1); + do_bn_print_name(out, "YephemIUT", dh->pub_key); + if (exout) + do_bn_print_name(out, "XephemIUT", dh->priv_key); + } + Z = OPENSSL_malloc(BN_num_bytes(dh->p)); + if (!Z) + exit(1); + Zlen = DH_compute_key_padded(Z, peerkey, dh); + if (exout) + OutputValue("Z", Z, Zlen, out, 0); + FIPS_digest(Z, Zlen, chash, NULL, md); + OutputValue(rhash ? "IUTHashZZ" : "HashZZ", chash, rhashlen, out, 0); + if (rhash) + { + fprintf(out, "Result = %s\n", + memcmp(chash, rhash, rhashlen) ? "F" : "P"); + } + else + { + BN_clear_free(dh->priv_key); + BN_clear_free(dh->pub_key); + dh->priv_key = NULL; + dh->pub_key = NULL; + } + OPENSSL_cleanse(Z, Zlen); + OPENSSL_free(Z); + } + +#ifdef FIPS_ALGVS +int fips_dhvs_main(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif + { + char **args = argv + 1; + int argn = argc - 1; + FILE *in, *out; + char buf[2048], lbuf[2048]; + unsigned char *rhash; + long rhashlen; + DH *dh = NULL; + const EVP_MD *md = NULL; + BIGNUM *peerkey = NULL; + char *keyword = NULL, *value = NULL; + int do_verify = -1, exout = 0; + + fips_algtest_init(); + + if (argn && !strcmp(*args, "dhver")) + { + do_verify = 1; + args++; + argn--; + } + else if (argn && !strcmp(*args, "dhgen")) + { + do_verify = 0; + args++; + argn--; + } + + if (argn && !strcmp(*args, "-exout")) + { + exout = 1; + args++; + argn--; + } + + if (do_verify == -1) + { + fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]); + exit(1); + } + + if (argn == 2) + { + in = fopen(*args, "r"); + if (!in) + { + fprintf(stderr, "Error opening input file\n"); + exit(1); + } + out = fopen(args[1], "w"); + if (!out) + { + fprintf(stderr, "Error opening output file\n"); + exit(1); + } + } + else if (argn == 0) + { + in = stdin; + out = stdout; + } + else + { + fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]); + exit(1); + } + + dh = FIPS_dh_new(); + + while (fgets(buf, sizeof(buf), in) != NULL) + { + fputs(buf, out); + if (strlen(buf) > 6 && !strncmp(buf, "[F", 2)) + { + md = parse_md(buf); + if (md == NULL) + goto parse_error; + if (dh) + FIPS_dh_free(dh); + dh = FIPS_dh_new(); + continue; + } + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if (!strcmp(keyword, "P")) + { + if (!do_hex2bn(&dh->p, value)) + goto parse_error; + } + else if (!strcmp(keyword, "Q")) + { + if (!do_hex2bn(&dh->q, value)) + goto parse_error; + } + else if (!strcmp(keyword, "G")) + { + if (!do_hex2bn(&dh->g, value)) + goto parse_error; + } + else if (!strcmp(keyword, "XephemIUT")) + { + if (!do_hex2bn(&dh->priv_key, value)) + goto parse_error; + } + else if (!strcmp(keyword, "YephemIUT")) + { + if (!do_hex2bn(&dh->pub_key, value)) + goto parse_error; + } + else if (!strcmp(keyword, "YephemCAVS")) + { + if (!do_hex2bn(&peerkey, value)) + goto parse_error; + if (do_verify == 0) + output_Zhash(out, exout, dh, peerkey, md, + NULL, 0); + } + else if (!strcmp(keyword, "CAVSHashZZ")) + { + if (!md) + goto parse_error; + rhash = hex2bin_m(value, &rhashlen); + if (!rhash || rhashlen != M_EVP_MD_size(md)) + goto parse_error; + output_Zhash(out, exout, dh, peerkey, md, + rhash, rhashlen); + } + } + if (in && in != stdin) + fclose(in); + if (out && out != stdout) + fclose(out); + return 0; + parse_error: + fprintf(stderr, "Error Parsing request file\n"); + exit(1); + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_drbgvs.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_drbgvs.c @@ -0,0 +1,416 @@ +/* fips/rand/fips_drbgvs.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + + +#define OPENSSL_FIPSAPI +#include <openssl/opensslconf.h> + +#ifndef OPENSSL_FIPS +#include <stdio.h> + +int main(int argc, char **argv) +{ + printf("No FIPS DRBG support\n"); + return(0); +} +#else + +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <string.h> +#include <ctype.h> + +#include "fips_utl.h" + +static int dparse_md(char *str) + { + switch(atoi(str + 5)) + { + case 1: + return NID_sha1; + + case 224: + return NID_sha224; + + case 256: + return NID_sha256; + + case 384: + return NID_sha384; + + case 512: + return NID_sha512; + + } + + return NID_undef; + } + +static int parse_ec(char *str) + { + int curve_nid, md_nid; + char *md; + md = strchr(str, ' '); + if (!md) + return NID_undef; + if (!strncmp(str, "[P-256", 6)) + curve_nid = NID_X9_62_prime256v1; + else if (!strncmp(str, "[P-384", 6)) + curve_nid = NID_secp384r1; + else if (!strncmp(str, "[P-521", 6)) + curve_nid = NID_secp521r1; + else + return NID_undef; + md_nid = dparse_md(md); + if (md_nid == NID_undef) + return NID_undef; + return (curve_nid << 16) | md_nid; + } + +static int parse_aes(char *str, int *pdf) + { + + if (!strncmp(str + 9, "no", 2)) + *pdf = 0; + else + *pdf = DRBG_FLAG_CTR_USE_DF; + + switch(atoi(str + 5)) + { + case 128: + return NID_aes_128_ctr; + + case 192: + return NID_aes_192_ctr; + + case 256: + return NID_aes_256_ctr; + + default: + return NID_undef; + + } + } + +typedef struct + { + unsigned char *ent; + size_t entlen; + unsigned char *nonce; + size_t noncelen; + } TEST_ENT; + +static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) + { + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + *pout = (unsigned char *)t->ent; + return t->entlen; + } + +static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) + { + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + *pout = (unsigned char *)t->nonce; + return t->noncelen; + } + +#ifdef FIPS_ALGVS +int fips_drbgvs_main(int argc,char **argv) +#else +int main(int argc,char **argv) +#endif + { + FILE *in = NULL, *out = NULL; + DRBG_CTX *dctx = NULL; + TEST_ENT t; + int r, nid = 0; + int pr = 0; + char buf[2048], lbuf[2048]; + unsigned char randout[2048]; + char *keyword = NULL, *value = NULL; + + unsigned char *ent = NULL, *nonce = NULL, *pers = NULL, *adin = NULL; + long entlen, noncelen, perslen, adinlen; + int df = 0; + + enum dtype { DRBG_NONE, DRBG_CTR, DRBG_HASH, DRBG_HMAC, DRBG_DUAL_EC } + drbg_type = DRBG_NONE; + + int randoutlen = 0; + + int gen = 0; + + fips_algtest_init(); + + if (argc == 3) + { + in = fopen(argv[1], "r"); + if (!in) + { + fprintf(stderr, "Error opening input file\n"); + exit(1); + } + out = fopen(argv[2], "w"); + if (!out) + { + fprintf(stderr, "Error opening output file\n"); + exit(1); + } + } + else if (argc == 1) + { + in = stdin; + out = stdout; + } + else + { + fprintf(stderr,"%s (infile outfile)\n",argv[0]); + exit(1); + } + + while (fgets(buf, sizeof(buf), in) != NULL) + { + fputs(buf, out); + if (drbg_type == DRBG_NONE) + { + if (strstr(buf, "CTR_DRBG")) + drbg_type = DRBG_CTR; + else if (strstr(buf, "Hash_DRBG")) + drbg_type = DRBG_HASH; + else if (strstr(buf, "HMAC_DRBG")) + drbg_type = DRBG_HMAC; + else if (strstr(buf, "Dual_EC_DRBG")) + drbg_type = DRBG_DUAL_EC; + else + continue; + } + if (strlen(buf) > 4 && !strncmp(buf, "[SHA-", 5)) + { + nid = dparse_md(buf); + if (nid == NID_undef) + exit(1); + if (drbg_type == DRBG_HMAC) + { + switch (nid) + { + case NID_sha1: + nid = NID_hmacWithSHA1; + break; + + case NID_sha224: + nid = NID_hmacWithSHA224; + break; + + case NID_sha256: + nid = NID_hmacWithSHA256; + break; + + case NID_sha384: + nid = NID_hmacWithSHA384; + break; + + case NID_sha512: + nid = NID_hmacWithSHA512; + break; + + default: + exit(1); + } + } + } + if (strlen(buf) > 12 && !strncmp(buf, "[AES-", 5)) + { + nid = parse_aes(buf, &df); + if (nid == NID_undef) + exit(1); + } + if (strlen(buf) > 12 && !strncmp(buf, "[P-", 3)) + { + nid = parse_ec(buf); + if (nid == NID_undef) + exit(1); + } + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + + if (!strcmp(keyword, "[PredictionResistance")) + { + if (!strcmp(value, "True]")) + pr = 1; + else if (!strcmp(value, "False]")) + pr = 0; + else + exit(1); + } + + if (!strcmp(keyword, "EntropyInput")) + { + ent = hex2bin_m(value, &entlen); + t.ent = ent; + t.entlen = entlen; + } + + if (!strcmp(keyword, "Nonce")) + { + nonce = hex2bin_m(value, &noncelen); + t.nonce = nonce; + t.noncelen = noncelen; + } + + if (!strcmp(keyword, "PersonalizationString")) + { + pers = hex2bin_m(value, &perslen); + if (nid == 0) + { + fprintf(stderr, "DRBG type not recognised!\n"); + exit (1); + } + dctx = FIPS_drbg_new(nid, df | DRBG_FLAG_TEST); + if (!dctx) + exit (1); + FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, + test_nonce, 0); + FIPS_drbg_set_app_data(dctx, &t); + randoutlen = (int)FIPS_drbg_get_blocklength(dctx); + r = FIPS_drbg_instantiate(dctx, pers, perslen); + if (!r) + { + fprintf(stderr, "Error instantiating DRBG\n"); + exit(1); + } + OPENSSL_free(pers); + OPENSSL_free(ent); + OPENSSL_free(nonce); + ent = nonce = pers = NULL; + gen = 0; + } + + if (!strcmp(keyword, "AdditionalInput")) + { + adin = hex2bin_m(value, &adinlen); + if (pr) + continue; + r = FIPS_drbg_generate(dctx, randout, randoutlen, 0, + adin, adinlen); + if (!r) + { + fprintf(stderr, "Error generating DRBG bits\n"); + exit(1); + } + if (!r) + exit(1); + OPENSSL_free(adin); + adin = NULL; + gen++; + } + + if (pr) + { + if (!strcmp(keyword, "EntropyInputPR")) + { + ent = hex2bin_m(value, &entlen); + t.ent = ent; + t.entlen = entlen; + r = FIPS_drbg_generate(dctx, + randout, randoutlen, + 1, adin, adinlen); + if (!r) + { + fprintf(stderr, + "Error generating DRBG bits\n"); + exit(1); + } + OPENSSL_free(adin); + OPENSSL_free(ent); + adin = ent = NULL; + gen++; + } + } + if (!strcmp(keyword, "EntropyInputReseed")) + { + ent = hex2bin_m(value, &entlen); + t.ent = ent; + t.entlen = entlen; + } + if (!strcmp(keyword, "AdditionalInputReseed")) + { + adin = hex2bin_m(value, &adinlen); + FIPS_drbg_reseed(dctx, adin, adinlen); + OPENSSL_free(ent); + OPENSSL_free(adin); + ent = adin = NULL; + } + if (gen == 2) + { + OutputValue("ReturnedBits", randout, randoutlen, + out, 0); + FIPS_drbg_free(dctx); + dctx = NULL; + gen = 0; + } + + } + if (in && in != stdin) + fclose(in); + if (out && out != stdout) + fclose(out); + return 0; + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_dssvs.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_dssvs.c @@ -0,0 +1,537 @@ +#include <openssl/opensslconf.h> + +#ifndef OPENSSL_FIPS +#include <stdio.h> + +int main(int argc, char **argv) +{ + printf("No FIPS DSA support\n"); + return(0); +} +#else + +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <string.h> +#include <ctype.h> + +#include "fips_utl.h" + +static void pbn(const char *name, BIGNUM *bn) + { + int len, i; + unsigned char *tmp; + len = BN_num_bytes(bn); + tmp = OPENSSL_malloc(len); + if (!tmp) + { + fprintf(stderr, "Memory allocation error\n"); + return; + } + BN_bn2bin(bn, tmp); + printf("%s = ", name); + for (i = 0; i < len; i++) + printf("%02X", tmp[i]); + fputs("\n", stdout); + OPENSSL_free(tmp); + return; + } + +void primes() + { + char buf[10240]; + char lbuf[10240]; + char *keyword, *value; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Prime")) + { + BIGNUM *pp; + + pp=BN_new(); + do_hex2bn(&pp,value); + printf("result= %c\n", + BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F'); + } + } + } + +void pqg() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"N")) + { + int n=atoi(value); + + printf("[mod = %d]\n\n",nmod); + + while(n--) + { + unsigned char seed[20]; + DSA *dsa; + int counter; + unsigned long h; + dsa = FIPS_dsa_new(); + + if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + pv("Seed",seed,20); + printf("c = %d\n",counter); + printf("H = %lx\n",h); + putc('\n',stdout); + } + } + else + fputs(buf,stdout); + } + } + +void pqgver() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + BIGNUM *p = NULL, *q = NULL, *g = NULL; + int counter, counter2; + unsigned long h, h2; + DSA *dsa=NULL; + int nmod=0; + unsigned char seed[1024]; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + fputs(buf, stdout); + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"P")) + p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + q=hex2bn(value); + else if(!strcmp(keyword,"G")) + g=hex2bn(value); + else if(!strcmp(keyword,"Seed")) + { + int slen = hex2bin(value, seed); + if (slen != 20) + { + fprintf(stderr, "Seed parse length error\n"); + exit (1); + } + } + else if(!strcmp(keyword,"c")) + counter =atoi(buf+4); + else if(!strcmp(keyword,"H")) + { + h = atoi(value); + if (!p || !q || !g) + { + fprintf(stderr, "Parse Error\n"); + exit (1); + } + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL)) + { + do_print_errors(); + exit(1); + } + if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g) + || (counter != counter2) || (h != h2)) + printf("Result = F\n"); + else + printf("Result = P\n"); + BN_free(p); + BN_free(q); + BN_free(g); + p = NULL; + q = NULL; + g = NULL; + FIPS_dsa_free(dsa); + dsa = NULL; + } + } + } + +/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2 + * algorithm tests. It is an additional test to perform sanity checks on the + * output of the KeyPair test. + */ + +static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g, + BN_CTX *ctx) + { + BIGNUM *rem = NULL; + if (BN_num_bits(p) != nmod) + return 0; + if (BN_num_bits(q) != 160) + return 0; + if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1) + return 0; + if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1) + return 0; + rem = BN_new(); + if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem) + || (BN_cmp(g, BN_value_one()) <= 0) + || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) + { + BN_free(rem); + return 0; + } + /* Todo: check g */ + BN_free(rem); + return 1; + } + +void keyver() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL; + BIGNUM *Y2; + BN_CTX *ctx = NULL; + int nmod=0, paramcheck = 0; + + ctx = BN_CTX_new(); + Y2 = BN_new(); + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + if (p) + BN_free(p); + p = NULL; + if (q) + BN_free(q); + q = NULL; + if (g) + BN_free(g); + g = NULL; + paramcheck = 0; + nmod=atoi(value); + } + else if(!strcmp(keyword,"P")) + p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + q=hex2bn(value); + else if(!strcmp(keyword,"G")) + g=hex2bn(value); + else if(!strcmp(keyword,"X")) + X=hex2bn(value); + else if(!strcmp(keyword,"Y")) + { + Y=hex2bn(value); + if (!p || !q || !g || !X || !Y) + { + fprintf(stderr, "Parse Error\n"); + exit (1); + } + pbn("P",p); + pbn("Q",q); + pbn("G",g); + pbn("X",X); + pbn("Y",Y); + if (!paramcheck) + { + if (dss_paramcheck(nmod, p, q, g, ctx)) + paramcheck = 1; + else + paramcheck = -1; + } + if (paramcheck != 1) + printf("Result = F\n"); + else + { + if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y)) + printf("Result = F\n"); + else + printf("Result = P\n"); + } + BN_free(X); + BN_free(Y); + X = NULL; + Y = NULL; + } + } + if (p) + BN_free(p); + if (q) + BN_free(q); + if (g) + BN_free(g); + if (Y2) + BN_free(Y2); + } + +void keypair() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"N")) + { + DSA *dsa; + int n=atoi(value); + + printf("[mod = %d]\n\n",nmod); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + + while(n--) + { + if (!DSA_generate_key(dsa)) + { + do_print_errors(); + exit(1); + } + + pbn("X",dsa->priv_key); + pbn("Y",dsa->pub_key); + putc('\n',stdout); + } + } + } + } + +void siggen() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + DSA *dsa=NULL; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + nmod=atoi(value); + printf("[mod = %d]\n\n",nmod); + if (dsa) + FIPS_dsa_free(dsa); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + } + else if(!strcmp(keyword,"Msg")) + { + unsigned char msg[1024]; + unsigned char sbuf[60]; + unsigned int slen; + int n; + EVP_PKEY pk; + EVP_MD_CTX mctx; + DSA_SIG *sig; + EVP_MD_CTX_init(&mctx); + + n=hex2bin(value,msg); + pv("Msg",msg,n); + + if (!DSA_generate_key(dsa)) + { + do_print_errors(); + exit(1); + } + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + pbn("Y",dsa->pub_key); + + EVP_SignInit_ex(&mctx, EVP_dss1(), NULL); + EVP_SignUpdate(&mctx, msg, n); + EVP_SignFinal(&mctx, sbuf, &slen, &pk); + + sig = DSA_SIG_new(); + FIPS_dsa_sig_decode(sig, sbuf, slen); + + pbn("R",sig->r); + pbn("S",sig->s); + putc('\n',stdout); + DSA_SIG_free(sig); + EVP_MD_CTX_cleanup(&mctx); + } + } + if (dsa) + FIPS_dsa_free(dsa); + } + +void sigver() + { + DSA *dsa=NULL; + char buf[1024]; + char lbuf[1024]; + unsigned char msg[1024]; + char *keyword, *value; + int nmod=0, n=0; + DSA_SIG sg, *sig = &sg; + + sig->r = NULL; + sig->s = NULL; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + nmod=atoi(value); + if(dsa) + FIPS_dsa_free(dsa); + dsa=FIPS_dsa_new(); + } + else if(!strcmp(keyword,"P")) + dsa->p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + dsa->q=hex2bn(value); + else if(!strcmp(keyword,"G")) + { + dsa->g=hex2bn(value); + + printf("[mod = %d]\n\n",nmod); + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + } + else if(!strcmp(keyword,"Msg")) + { + n=hex2bin(value,msg); + pv("Msg",msg,n); + } + else if(!strcmp(keyword,"Y")) + dsa->pub_key=hex2bn(value); + else if(!strcmp(keyword,"R")) + sig->r=hex2bn(value); + else if(!strcmp(keyword,"S")) + { + EVP_MD_CTX mctx; + EVP_PKEY pk; + unsigned char sigbuf[60]; + unsigned int slen; + int r; + EVP_MD_CTX_init(&mctx); + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + sig->s=hex2bn(value); + + pbn("Y",dsa->pub_key); + pbn("R",sig->r); + pbn("S",sig->s); + + slen = FIPS_dsa_sig_encode(sigbuf, sig); + EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL); + EVP_VerifyUpdate(&mctx, msg, n); + r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk); + EVP_MD_CTX_cleanup(&mctx); + + printf("Result = %c\n", r == 1 ? 'P' : 'F'); + putc('\n',stdout); + } + } + } + +int main(int argc,char **argv) + { + if(argc != 2) + { + fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]); + exit(1); + } + if(!FIPS_mode_set(1)) + { + do_print_errors(); + exit(1); + } + if(!strcmp(argv[1],"prime")) + primes(); + else if(!strcmp(argv[1],"pqg")) + pqg(); + else if(!strcmp(argv[1],"pqgver")) + pqgver(); + else if(!strcmp(argv[1],"keypair")) + keypair(); + else if(!strcmp(argv[1],"keyver")) + keyver(); + else if(!strcmp(argv[1],"siggen")) + siggen(); + else if(!strcmp(argv[1],"sigver")) + sigver(); + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + return 0; + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_gcmtest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_gcmtest.c @@ -0,0 +1,571 @@ +/* fips/aes/fips_gcmtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + + +#define OPENSSL_FIPSAPI +#include <openssl/opensslconf.h> + +#ifndef OPENSSL_FIPS +#include <stdio.h> + +int main(int argc, char **argv) +{ + printf("No FIPS GCM support\n"); + return(0); +} +#else + +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <string.h> +#include <ctype.h> + +#include "fips_utl.h" + +static void gcmtest(FILE *in, FILE *out, int encrypt) + { + char buf[2048]; + char lbuf[2048]; + char *keyword, *value; + int keylen = -1, ivlen = -1, aadlen = -1, taglen = -1, ptlen = -1; + int rv; + long l; + unsigned char *key = NULL, *iv = NULL, *aad = NULL, *tag = NULL; + unsigned char *ct = NULL, *pt = NULL; + EVP_CIPHER_CTX ctx; + const EVP_CIPHER *gcm = NULL; + FIPS_cipher_ctx_init(&ctx); + + while(fgets(buf,sizeof buf,in) != NULL) + { + fputs(buf,out); + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"[Keylen")) + { + keylen = atoi(value); + if (keylen == 128) + gcm = EVP_aes_128_gcm(); + else if (keylen == 192) + gcm = EVP_aes_192_gcm(); + else if (keylen == 256) + gcm = EVP_aes_256_gcm(); + else + { + fprintf(stderr, "Unsupported keylen %d\n", + keylen); + } + keylen >>= 3; + } + else if (!strcmp(keyword, "[IVlen")) + ivlen = atoi(value) >> 3; + else if (!strcmp(keyword, "[AADlen")) + aadlen = atoi(value) >> 3; + else if (!strcmp(keyword, "[Taglen")) + taglen = atoi(value) >> 3; + else if (!strcmp(keyword, "[PTlen")) + ptlen = atoi(value) >> 3; + else if(!strcmp(keyword,"Key")) + { + key = hex2bin_m(value, &l); + if (l != keylen) + { + fprintf(stderr, "Inconsistent Key length\n"); + exit(1); + } + } + else if(!strcmp(keyword,"IV")) + { + iv = hex2bin_m(value, &l); + if (l != ivlen) + { + fprintf(stderr, "Inconsistent IV length\n"); + exit(1); + } + } + else if(!strcmp(keyword,"PT")) + { + pt = hex2bin_m(value, &l); + if (l != ptlen) + { + fprintf(stderr, "Inconsistent PT length\n"); + exit(1); + } + } + else if(!strcmp(keyword,"CT")) + { + ct = hex2bin_m(value, &l); + if (l != ptlen) + { + fprintf(stderr, "Inconsistent CT length\n"); + exit(1); + } + } + else if(!strcmp(keyword,"AAD")) + { + aad = hex2bin_m(value, &l); + if (l != aadlen) + { + fprintf(stderr, "Inconsistent AAD length\n"); + exit(1); + } + } + else if(!strcmp(keyword,"Tag")) + { + tag = hex2bin_m(value, &l); + if (l != taglen) + { + fprintf(stderr, "Inconsistent Tag length\n"); + exit(1); + } + } + if (encrypt && pt && aad && (iv || encrypt==1)) + { + tag = OPENSSL_malloc(taglen); + FIPS_cipherinit(&ctx, gcm, NULL, NULL, 1); + /* Relax FIPS constraints for testing */ + M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0); + if (encrypt == 1) + { + static unsigned char iv_fixed[4] = {1,2,3,4}; + if (!iv) + iv = OPENSSL_malloc(ivlen); + FIPS_cipherinit(&ctx, NULL, key, NULL, 1); + FIPS_cipher_ctx_ctrl(&ctx, + EVP_CTRL_GCM_SET_IV_FIXED, + 4, iv_fixed); + if (!FIPS_cipher_ctx_ctrl(&ctx, + EVP_CTRL_GCM_IV_GEN, 0, iv)) + { + fprintf(stderr, "IV gen error\n"); + exit(1); + } + OutputValue("IV", iv, ivlen, out, 0); + } + else + FIPS_cipherinit(&ctx, NULL, key, iv, 1); + + + if (aadlen) + FIPS_cipher(&ctx, NULL, aad, aadlen); + if (ptlen) + { + ct = OPENSSL_malloc(ptlen); + rv = FIPS_cipher(&ctx, ct, pt, ptlen); + } + FIPS_cipher(&ctx, NULL, NULL, 0); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, + taglen, tag); + OutputValue("CT", ct, ptlen, out, 0); + OutputValue("Tag", tag, taglen, out, 0); + if (iv) + OPENSSL_free(iv); + if (aad) + OPENSSL_free(aad); + if (ct) + OPENSSL_free(ct); + if (pt) + OPENSSL_free(pt); + if (key) + OPENSSL_free(key); + if (tag) + OPENSSL_free(tag); + iv = aad = ct = pt = key = tag = NULL; + } + if (!encrypt && tag) + { + FIPS_cipherinit(&ctx, gcm, NULL, NULL, 0); + /* Relax FIPS constraints for testing */ + M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0); + FIPS_cipherinit(&ctx, NULL, key, iv, 0); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag); + if (aadlen) + FIPS_cipher(&ctx, NULL, aad, aadlen); + if (ptlen) + { + pt = OPENSSL_malloc(ptlen); + rv = FIPS_cipher(&ctx, pt, ct, ptlen); + } + rv = FIPS_cipher(&ctx, NULL, NULL, 0); + if (rv < 0) + fprintf(out, "FAIL" RESP_EOL); + else + OutputValue("PT", pt, ptlen, out, 0); + if (iv) + OPENSSL_free(iv); + if (aad) + OPENSSL_free(aad); + if (ct) + OPENSSL_free(ct); + if (pt) + OPENSSL_free(pt); + if (key) + OPENSSL_free(key); + if (tag) + OPENSSL_free(tag); + iv = aad = ct = pt = key = tag = NULL; + } + } + FIPS_cipher_ctx_cleanup(&ctx); + } + +static void xtstest(FILE *in, FILE *out) + { + char buf[204800]; + char lbuf[204800]; + char *keyword, *value; + int inlen = 0; + int encrypt = 0; + long l; + unsigned char *key = NULL, *iv = NULL; + unsigned char *inbuf = NULL, *outbuf = NULL; + EVP_CIPHER_CTX ctx; + const EVP_CIPHER *xts = NULL; + FIPS_cipher_ctx_init(&ctx); + + while(fgets(buf,sizeof buf,in) != NULL) + { + fputs(buf,out); + if (buf[0] == '[' && strlen(buf) >= 9) + { + if(!strncmp(buf,"[ENCRYPT]", 9)) + encrypt = 1; + else if(!strncmp(buf,"[DECRYPT]", 9)) + encrypt = 0; + } + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + else if(!strcmp(keyword,"Key")) + { + key = hex2bin_m(value, &l); + if (l == 32) + xts = EVP_aes_128_xts(); + else if (l == 64) + xts = EVP_aes_256_xts(); + else + { + fprintf(stderr, "Inconsistent Key length\n"); + exit(1); + } + } + else if(!strcmp(keyword,"i")) + { + iv = hex2bin_m(value, &l); + if (l != 16) + { + fprintf(stderr, "Inconsistent i length\n"); + exit(1); + } + } + else if(encrypt && !strcmp(keyword,"PT")) + { + inbuf = hex2bin_m(value, &l); + inlen = l; + } + else if(!encrypt && !strcmp(keyword,"CT")) + { + inbuf = hex2bin_m(value, &l); + inlen = l; + } + if (inbuf) + { + FIPS_cipherinit(&ctx, xts, key, iv, encrypt); + outbuf = OPENSSL_malloc(inlen); + FIPS_cipher(&ctx, outbuf, inbuf, inlen); + OutputValue(encrypt ? "CT":"PT", outbuf, inlen, out, 0); + OPENSSL_free(inbuf); + OPENSSL_free(outbuf); + OPENSSL_free(key); + OPENSSL_free(iv); + iv = key = inbuf = outbuf = NULL; + } + } + FIPS_cipher_ctx_cleanup(&ctx); + } + +static void ccmtest(FILE *in, FILE *out) + { + char buf[200048]; + char lbuf[200048]; + char *keyword, *value; + long l; + unsigned char *Key = NULL, *Nonce = NULL; + unsigned char *Adata = NULL, *Payload = NULL; + unsigned char *CT = NULL; + int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1; + int decr = 0; + EVP_CIPHER_CTX ctx; + const EVP_CIPHER *ccm = NULL; + FIPS_cipher_ctx_init(&ctx); + + while(fgets(buf,sizeof buf,in) != NULL) + { + char *p; + fputs(buf,out); + redo: + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + + /* If surrounded by square brackets zap them */ + if (keyword[0] == '[') + { + keyword++; + p = strchr(value, ']'); + if (p) + *p = 0; + } + /* See if we have a comma separated list of parameters + * if so copy rest of line back to buffer and redo later. + */ + p = strchr(value, ','); + if (p) + { + *p = 0; + strcpy(buf, p + 1); + strcat(buf, "\n"); + decr = 1; + } + if (!strcmp(keyword,"Plen")) + Plen = atoi(value); + else if (!strcmp(keyword,"Nlen")) + Nlen = atoi(value); + else if (!strcmp(keyword,"Tlen")) + Tlen = atoi(value); + else if (!strcmp(keyword,"Alen")) + Alen = atoi(value); + if (p) + goto redo; + if (!strcmp(keyword,"Key")) + { + if (Key) + OPENSSL_free(Key); + Key = hex2bin_m(value, &l); + if (l == 16) + ccm = EVP_aes_128_ccm(); + else if (l == 24) + ccm = EVP_aes_192_ccm(); + else if (l == 32) + ccm = EVP_aes_256_ccm(); + else + { + fprintf(stderr, "Inconsistent Key length\n"); + exit(1); + } + } + else if (!strcmp(keyword,"Nonce")) + { + if (Nonce) + OPENSSL_free(Nonce); + Nonce = hex2bin_m(value, &l); + if (l != Nlen) + { + fprintf(stderr, "Inconsistent nonce length\n"); + exit(1); + } + } + else if (!strcmp(keyword,"Payload") && !decr) + { + Payload = hex2bin_m(value, &l); + if (Plen && l != Plen) + { + fprintf(stderr, "Inconsistent Payload length\n"); + exit(1); + } + } + else if (!strcmp(keyword,"Adata")) + { + if (Adata) + OPENSSL_free(Adata); + Adata = hex2bin_m(value, &l); + if (Alen && l != Alen) + { + fprintf(stderr, "Inconsistent Payload length\n"); + exit(1); + } + } + else if (!strcmp(keyword,"CT") && decr) + { + CT = hex2bin_m(value, &l); + if (l != (Plen + Tlen)) + { + fprintf(stderr, "Inconsistent CT length\n"); + exit(1); + } + } + if (Payload) + { + FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, Tlen, 0); + FIPS_cipherinit(&ctx, NULL, Key, Nonce, 1); + + FIPS_cipher(&ctx, NULL, NULL, Plen); + FIPS_cipher(&ctx, NULL, Adata, Alen); + CT = OPENSSL_malloc(Plen + Tlen); + FIPS_cipher(&ctx, CT, Payload, Plen); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, Tlen, + CT + Plen); + OutputValue("CT", CT, Plen + Tlen, out, 0); + OPENSSL_free(CT); + OPENSSL_free(Payload); + CT = Payload = NULL; + } + if (CT) + { + int rv; + int len = Plen == 0 ? 1: Plen; + FIPS_cipherinit(&ctx, ccm, NULL, NULL, 0); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0); + FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, + Tlen, CT + Plen); + FIPS_cipherinit(&ctx, NULL, Key, Nonce, 0); + FIPS_cipher(&ctx, NULL, NULL, Plen); + FIPS_cipher(&ctx, NULL, Adata, Alen); + Payload = OPENSSL_malloc(len); + rv = FIPS_cipher(&ctx, Payload, CT, Plen); + if (rv >= 0) + { + if (rv == 0) + Payload[0] = 0; + fputs("Result = Pass" RESP_EOL, out); + OutputValue("Payload", Payload, len, out, 0); + } + else + fputs("Result = Fail" RESP_EOL, out); + OPENSSL_free(CT); + OPENSSL_free(Payload); + CT = Payload = NULL; + } + } + if (Key) + OPENSSL_free(Key); + if (Nonce) + OPENSSL_free(Nonce); + if (Adata) + OPENSSL_free(Adata); + FIPS_cipher_ctx_cleanup(&ctx); + } + +#ifdef FIPS_ALGVS +int fips_gcmtest_main(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif + { + int encrypt; + int xts = 0, ccm = 0; + FILE *in, *out; + if (argc == 4) + { + in = fopen(argv[2], "r"); + if (!in) + { + fprintf(stderr, "Error opening input file\n"); + exit(1); + } + out = fopen(argv[3], "w"); + if (!out) + { + fprintf(stderr, "Error opening output file\n"); + exit(1); + } + } + else if (argc == 2) + { + in = stdin; + out = stdout; + } + else + { + fprintf(stderr,"%s [-encrypt|-decrypt]\n",argv[0]); + exit(1); + } + fips_algtest_init(); + if(!strcmp(argv[1],"-encrypt")) + encrypt = 1; + else if(!strcmp(argv[1],"-encryptIVext")) + encrypt = 2; + else if(!strcmp(argv[1],"-decrypt")) + encrypt = 0; + else if(!strcmp(argv[1],"-ccm")) + ccm = 1; + else if(!strcmp(argv[1],"-xts")) + xts = 1; + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + if (ccm) + ccmtest(in, out); + else if (xts) + xtstest(in, out); + else + gcmtest(in, out, encrypt); + + if (argc == 4) + { + fclose(in); + fclose(out); + } + + return 0; +} + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_rngvs.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_rngvs.c @@ -0,0 +1,230 @@ +/* + * Crude test driver for processing the VST and MCT testvector files + * generated by the CMVP RNGVS product. + * + * Note the input files are assumed to have a _very_ specific format + * as described in the NIST document "The Random Number Generator + * Validation System (RNGVS)", May 25, 2004. + * + */ +#include <openssl/opensslconf.h> + +#ifndef OPENSSL_FIPS +#include <stdio.h> + +int main(int argc, char **argv) +{ + printf("No FIPS RNG support\n"); + return 0; +} +#else + +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/x509v3.h> +#include <string.h> +#include <ctype.h> + +#include "fips_utl.h" + +void vst() + { + unsigned char *key = NULL; + unsigned char *v = NULL; + unsigned char *dt = NULL; + unsigned char ret[16]; + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + long i, keylen; + + keylen = 0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if(!strncmp(buf,"[AES 128-Key]", 13)) + keylen = 16; + else if(!strncmp(buf,"[AES 192-Key]", 13)) + keylen = 24; + else if(!strncmp(buf,"[AES 256-Key]", 13)) + keylen = 32; + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Key")) + { + key=hex2bin_m(value,&i); + if (i != keylen) + { + fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); + return; + } + } + else if(!strcmp(keyword,"DT")) + { + dt=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid DT length\n"); + return; + } + } + else if(!strcmp(keyword,"V")) + { + v=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid V length\n"); + return; + } + + if (!key || !dt) + { + fprintf(stderr, "Missing key or DT\n"); + return; + } + + FIPS_x931_set_key(key, keylen); + FIPS_x931_seed(v,16); + FIPS_x931_set_dt(dt); + if (FIPS_x931_bytes(ret,16) <= 0) + { + fprintf(stderr, "Error getting PRNG value\n"); + return; + } + + pv("R",ret,16); + OPENSSL_free(key); + key = NULL; + OPENSSL_free(dt); + dt = NULL; + OPENSSL_free(v); + v = NULL; + } + } + } + +void mct() + { + unsigned char *key = NULL; + unsigned char *v = NULL; + unsigned char *dt = NULL; + unsigned char ret[16]; + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + long i, keylen; + int j; + + keylen = 0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if(!strncmp(buf,"[AES 128-Key]", 13)) + keylen = 16; + else if(!strncmp(buf,"[AES 192-Key]", 13)) + keylen = 24; + else if(!strncmp(buf,"[AES 256-Key]", 13)) + keylen = 32; + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Key")) + { + key=hex2bin_m(value,&i); + if (i != keylen) + { + fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); + return; + } + } + else if(!strcmp(keyword,"DT")) + { + dt=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid DT length\n"); + return; + } + } + else if(!strcmp(keyword,"V")) + { + v=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid V length\n"); + return; + } + + if (!key || !dt) + { + fprintf(stderr, "Missing key or DT\n"); + return; + } + + FIPS_x931_set_key(key, keylen); + FIPS_x931_seed(v,16); + for (i = 0; i < 10000; i++) + { + FIPS_x931_set_dt(dt); + if (FIPS_x931_bytes(ret,16) <= 0) + { + fprintf(stderr, "Error getting PRNG value\n"); + return; + } + /* Increment DT */ + for (j = 15; j >= 0; j--) + { + dt[j]++; + if (dt[j]) + break; + } + } + + pv("R",ret,16); + OPENSSL_free(key); + key = NULL; + OPENSSL_free(dt); + dt = NULL; + OPENSSL_free(v); + v = NULL; + } + } + } + +int main(int argc,char **argv) + { + if(argc != 2) + { + fprintf(stderr,"%s [mct|vst]\n",argv[0]); + exit(1); + } + if(!FIPS_mode_set(1)) + { + do_print_errors(); + exit(1); + } + FIPS_x931_reset(); + if (!FIPS_x931_test_mode()) + { + fprintf(stderr, "Error setting PRNG test mode\n"); + do_print_errors(); + exit(1); + } + if(!strcmp(argv[1],"mct")) + mct(); + else if(!strcmp(argv[1],"vst")) + vst(); + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + return 0; + } +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_rsagtest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_rsagtest.c @@ -0,0 +1,390 @@ +/* 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). + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/x509v3.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#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; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + 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 (ret) + do_print_errors(); + + 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 Index: openssl-1.0.1h/crypto/fips/cavs/fips_rsastest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_rsastest.c @@ -0,0 +1,370 @@ +/* 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). + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/x509v3.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#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; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + 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 (ret) + do_print_errors(); + + 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; + /* EVP_PKEY structure */ + EVP_PKEY pk; + EVP_MD_CTX ctx; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + siglen = RSA_size(rsa); + sigbuf = OPENSSL_malloc(siglen); + if (!sigbuf) + goto error; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_SignInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_SignUpdate(&ctx, Msg, Msglen)) + goto error; + if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) + 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 Index: openssl-1.0.1h/crypto/fips/cavs/fips_rsavtest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_rsavtest.c @@ -0,0 +1,377 @@ +/* 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 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 <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/x509v3.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in, int saltlen); +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + int Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + 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_test(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSAVTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + 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, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + const EVP_MD *dgst = NULL; + BIGNUM *n = NULL, *e = NULL; + unsigned char *Msg = NULL, *S = NULL; + long Msglen, Slen; + 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, "n")) + { + if (!do_hex2bn(&n,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (!do_hex2bn(&e,value)) + 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; + } + else if (!strcmp(keyword, "S")) + { + if (S) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + S = hex2bin_m(value, &Slen); + if (!S) + goto parse_error; + } + else if (!strcmp(keyword, "Result")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (n && e && Msg && S && dgst) + { + if (!rsa_printver(out, n, e, dgst, + Msg, Msglen, S, Slen, Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + OPENSSL_free(S); + S = NULL; + } + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (n) + BN_free(n); + if (e) + BN_free(e); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen) + { + int ret = 0, r; + /* Setup RSA and EVP_PKEY structures */ + RSA *rsa_pubkey = NULL; + EVP_PKEY pk; + EVP_MD_CTX ctx; + unsigned char *buf = NULL; + rsa_pubkey = FIPS_rsa_new(); + if (!rsa_pubkey) + goto error; + rsa_pubkey->n = BN_dup(n); + rsa_pubkey->e = BN_dup(e); + if (!rsa_pubkey->n || !rsa_pubkey->e) + goto error; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa_pubkey; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) + goto error; + + r = EVP_VerifyFinal(&ctx, S, Slen, &pk); + + + EVP_MD_CTX_cleanup(&ctx); + + if (r < 0) + goto error; + ERR_clear_error(); + + if (r == 0) + fputs("Result = F\n", out); + else + fputs("Result = P\n", out); + + ret = 1; + + error: + if (rsa_pubkey) + FIPS_rsa_free(rsa_pubkey); + if (buf) + OPENSSL_free(buf); + + return ret; + } +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_shatest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_shatest.c @@ -0,0 +1,388 @@ +/* fips_shatest.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). + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/x509v3.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS SHAXXX support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +static int dgst_test(FILE *out, FILE *in); +static int print_dgst(const EVP_MD *md, FILE *out, + unsigned char *Msg, int Msglen); +static int print_monte(const EVP_MD *md, FILE *out, + unsigned char *Seed, int SeedLen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + 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 (!dgst_test(out, in)) + { + fprintf(stderr, "FATAL digest file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define SHA_TEST_MAX_BITS 102400 +#define SHA_TEST_MAXLINELEN (((SHA_TEST_MAX_BITS >> 3) * 2) + 100) + +int dgst_test(FILE *out, FILE *in) + { + const EVP_MD *md = NULL; + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + unsigned char *Msg = NULL, *Seed = NULL; + long MsgLen = -1, Len = -1, SeedLen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + + while (fgets(olinebuf, SHA_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 [L=20] line) just copy */ + if (!p) + { + fputs(olinebuf, out); + 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,"[L") && *p==']') + { + switch (atoi(value)) + { + case 20: md=EVP_sha1(); break; + case 28: md=EVP_sha224(); break; + case 32: md=EVP_sha256(); break; + case 48: md=EVP_sha384(); break; + case 64: md=EVP_sha512(); break; + default: goto parse_error; + } + } + else if (!strcmp(keyword, "Len")) + { + if (Len != -1) + goto parse_error; + Len = atoi(value); + if (Len < 0) + goto parse_error; + /* Only handle multiples of 8 bits */ + if (Len & 0x7) + goto parse_error; + if (Len > SHA_TEST_MAX_BITS) + goto parse_error; + MsgLen = Len >> 3; + } + + else if (!strcmp(keyword, "Msg")) + { + long tmplen; + if (strlen(value) & 1) + *(--value) = '0'; + if (Msg) + goto parse_error; + Msg = hex2bin_m(value, &tmplen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "Seed")) + { + if (strlen(value) & 1) + *(--value) = '0'; + if (Seed) + goto parse_error; + Seed = hex2bin_m(value, &SeedLen); + if (!Seed) + goto parse_error; + } + else if (!strcmp(keyword, "MD")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (md && Msg && (MsgLen >= 0)) + { + if (!print_dgst(md, out, Msg, MsgLen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + MsgLen = -1; + Len = -1; + } + else if (md && Seed && (SeedLen > 0)) + { + if (!print_monte(md, out, Seed, SeedLen)) + goto error; + OPENSSL_free(Seed); + Seed = NULL; + SeedLen = -1; + } + + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (Msg) + OPENSSL_free(Msg); + if (Seed) + OPENSSL_free(Seed); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int print_dgst(const EVP_MD *emd, FILE *out, + unsigned char *Msg, int Msglen) + { + int i, mdlen; + unsigned char md[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL)) + { + fputs("Error calculating HASH\n", stderr); + return 0; + } + fputs("MD = ", out); + for (i = 0; i < mdlen; i++) + fprintf(out, "%02x", md[i]); + fputs("\n", out); + return 1; + } + +static int print_monte(const EVP_MD *md, FILE *out, + unsigned char *Seed, int SeedLen) + { + unsigned int i, j, k; + int ret = 0; + EVP_MD_CTX ctx; + unsigned char *m1, *m2, *m3, *p; + unsigned int mlen, m1len, m2len, m3len; + + EVP_MD_CTX_init(&ctx); + + if (SeedLen > EVP_MAX_MD_SIZE) + mlen = SeedLen; + else + mlen = EVP_MAX_MD_SIZE; + + m1 = OPENSSL_malloc(mlen); + m2 = OPENSSL_malloc(mlen); + m3 = OPENSSL_malloc(mlen); + + if (!m1 || !m2 || !m3) + goto mc_error; + + m1len = m2len = m3len = SeedLen; + memcpy(m1, Seed, SeedLen); + memcpy(m2, Seed, SeedLen); + memcpy(m3, Seed, SeedLen); + + fputs("\n", out); + + for (j = 0; j < 100; j++) + { + for (i = 0; i < 1000; i++) + { + EVP_DigestInit_ex(&ctx, md, NULL); + EVP_DigestUpdate(&ctx, m1, m1len); + EVP_DigestUpdate(&ctx, m2, m2len); + EVP_DigestUpdate(&ctx, m3, m3len); + p = m1; + m1 = m2; + m1len = m2len; + m2 = m3; + m2len = m3len; + m3 = p; + EVP_DigestFinal_ex(&ctx, m3, &m3len); + } + fprintf(out, "COUNT = %d\n", j); + fputs("MD = ", out); + for (k = 0; k < m3len; k++) + fprintf(out, "%02x", m3[k]); + fputs("\n\n", out); + memcpy(m1, m3, m3len); + memcpy(m2, m3, m3len); + m1len = m2len = m3len; + } + + ret = 1; + + mc_error: + if (m1) + OPENSSL_free(m1); + if (m2) + OPENSSL_free(m2); + if (m3) + OPENSSL_free(m3); + + EVP_MD_CTX_cleanup(&ctx); + + return ret; + } + +#endif Index: openssl-1.0.1h/crypto/fips/cavs/fips_utl.h =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/cavs/fips_utl.h @@ -0,0 +1,343 @@ +/* ==================================================================== + * 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 + * 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. + * + */ + +void do_print_errors(void) + { + const char *file, *data; + int line, flags; + unsigned long l; + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags))) + { + fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d" + ":file=%s:line=%d:%s\n", + l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l), + file, line, flags & ERR_TXT_STRING ? data : ""); + } + } + +int hex2bin(const char *in, unsigned char *out) + { + int n1, n2; + unsigned char ch; + + for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; ) + { /* first byte */ + if ((in[n1] >= '0') && (in[n1] <= '9')) + ch = in[n1++] - '0'; + else if ((in[n1] >= 'A') && (in[n1] <= 'F')) + ch = in[n1++] - 'A' + 10; + else if ((in[n1] >= 'a') && (in[n1] <= 'f')) + ch = in[n1++] - 'a' + 10; + else + return -1; + if(!in[n1]) + { + out[n2++]=ch; + break; + } + out[n2] = ch << 4; + /* second byte */ + if ((in[n1] >= '0') && (in[n1] <= '9')) + ch = in[n1++] - '0'; + else if ((in[n1] >= 'A') && (in[n1] <= 'F')) + ch = in[n1++] - 'A' + 10; + else if ((in[n1] >= 'a') && (in[n1] <= 'f')) + ch = in[n1++] - 'a' + 10; + else + return -1; + out[n2++] |= ch; + } + return n2; + } + +unsigned char *hex2bin_m(const char *in, long *plen) + { + unsigned char *p; + p = OPENSSL_malloc((strlen(in) + 1)/2); + *plen = hex2bin(in, p); + return p; + } + +int do_hex2bn(BIGNUM **pr, const char *in) + { + unsigned char *p; + long plen; + int r = 0; + p = hex2bin_m(in, &plen); + if (!p) + return 0; + if (!*pr) + *pr = BN_new(); + if (!*pr) + return 0; + if (BN_bin2bn(p, plen, *pr)) + r = 1; + OPENSSL_free(p); + return r; + } + +int do_bn_print(FILE *out, BIGNUM *bn) + { + int len, i; + unsigned char *tmp; + len = BN_num_bytes(bn); + if (len == 0) + { + fputs("00", out); + return 1; + } + + tmp = OPENSSL_malloc(len); + if (!tmp) + { + fprintf(stderr, "Memory allocation error\n"); + return 0; + } + BN_bn2bin(bn, tmp); + for (i = 0; i < len; i++) + fprintf(out, "%02x", tmp[i]); + OPENSSL_free(tmp); + return 1; + } + +int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn) + { + int r; + fprintf(out, "%s = ", name); + r = do_bn_print(out, bn); + if (!r) + return 0; + fputs("\n", out); + return 1; + } + +int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf) + { + char *keyword, *value, *p, *q; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no '=' exit */ + if (!p) + return 0; + + 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; + + *pkw = keyword; + *pval = value; + return 1; + } + +BIGNUM *hex2bn(const char *in) + { + BIGNUM *p=NULL; + + if (!do_hex2bn(&p, in)) + return NULL; + + return p; + } + +int bin2hex(const unsigned char *in,int len,char *out) + { + int n1, n2; + unsigned char ch; + + for (n1=0,n2=0 ; n1 < len ; ++n1) + { + ch=in[n1] >> 4; + if (ch <= 0x09) + out[n2++]=ch+'0'; + else + out[n2++]=ch-10+'a'; + ch=in[n1] & 0x0f; + if(ch <= 0x09) + out[n2++]=ch+'0'; + else + out[n2++]=ch-10+'a'; + } + out[n2]='\0'; + return n2; + } + +void pv(const char *tag,const unsigned char *val,int len) + { + char obuf[2048]; + + bin2hex(val,len,obuf); + printf("%s = %s\n",tag,obuf); + } + +/* To avoid extensive changes to test program at this stage just convert + * the input line into an acceptable form. Keyword lines converted to form + * "keyword = value\n" no matter what white space present, all other lines + * just have leading and trailing space removed. + */ + +int tidy_line(char *linebuf, char *olinebuf) + { + char *keyword, *value, *p, *q; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no '=' just chop leading, trailing ws */ + if (!p) + { + p = keyword + strlen(keyword) - 1; + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + strcpy(olinebuf, keyword); + strcat(olinebuf, "\n"); + return 1; + } + + 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; + + strcpy(olinebuf, keyword); + strcat(olinebuf, " = "); + strcat(olinebuf, value); + strcat(olinebuf, "\n"); + + return 1; + } + +/* NB: this return the number of _bits_ read */ +int bint2bin(const char *in, int len, unsigned char *out) + { + int n; + + memset(out,0,len); + for(n=0 ; n < len ; ++n) + if(in[n] == '1') + out[n/8]|=(0x80 >> (n%8)); + return len; + } + +int bin2bint(const unsigned char *in,int len,char *out) + { + int n; + + for(n=0 ; n < len ; ++n) + out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; + return n; + } + +/*-----------------------------------------------*/ + +void PrintValue(char *tag, unsigned char *val, int len) +{ +#if VERBOSE + char obuf[2048]; + int olen; + olen = bin2hex(val, len, obuf); + printf("%s = %.*s\n", tag, olen, obuf); +#endif +} + +void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) + { + char obuf[2048]; + int olen; + + if(bitmode) + olen=bin2bint(val,len,obuf); + else + olen=bin2hex(val,len,obuf); + + fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); +#if VERBOSE + printf("%s = %.*s\n", tag, olen, obuf); +#endif + } + Index: openssl-1.0.1h/crypto/fips/fips.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips.c @@ -0,0 +1,489 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +// tmp comment: #define _GNU_SOURCE + +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bio.h> +#include <openssl/hmac.h> +#include <openssl/rsa.h> +#include <string.h> +#include <limits.h> +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +#include <openssl/fips.h> + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +static int fips_selftest_fail = 0; +static int fips_mode = 0; +static int fips_started = 0; + +static int fips_is_owning_thread(void); +static int fips_set_owning_thread(void); +static int fips_clear_owning_thread(void); + +#define fips_w_lock() CRYPTO_w_lock(CRYPTO_LOCK_FIPS) +#define fips_w_unlock() CRYPTO_w_unlock(CRYPTO_LOCK_FIPS) +#define fips_r_lock() CRYPTO_r_lock(CRYPTO_LOCK_FIPS) +#define fips_r_unlock() CRYPTO_r_unlock(CRYPTO_LOCK_FIPS) + +static void fips_set_mode(int onoff) + { + int owning_thread = fips_is_owning_thread(); + + if (fips_started) + { + if (!owning_thread) fips_w_lock(); + fips_mode = onoff; + if (!owning_thread) fips_w_unlock(); + } + } + +int FIPS_module_mode(void) + { + int ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_started) + { + if (!owning_thread) fips_r_lock(); + ret = fips_mode; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +int FIPS_selftest_failed(void) + { + int ret = 0; + if (fips_started) + { + int owning_thread = fips_is_owning_thread(); + + if (!owning_thread) fips_r_lock(); + ret = fips_selftest_fail; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +/* Selftest failure fatal exit routine. This will be called + * during *any* cryptographic operation. It has the minimum + * overhead possible to avoid too big a performance hit. + */ + +void FIPS_selftest_check(void) + { + if (fips_selftest_fail) + { + OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE"); + } + } + +void fips_set_selftest_fail(void) + { + fips_selftest_fail = 1; + } + +/* we implement what libfipscheck does ourselves */ + +static int +get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) +{ + Dl_info info; + void *dl, *sym; + int rv = -1; + + dl = dlopen(libname, RTLD_LAZY); + if (dl == NULL) { + return -1; + } + + sym = dlsym(dl, symbolname); + + if (sym != NULL && dladdr(sym, &info)) { + strncpy(path, info.dli_fname, pathlen-1); + path[pathlen-1] = '\0'; + rv = 0; + } + + dlclose(dl); + + return rv; +} + +static const char conv[] = "0123456789abcdef"; + +static char * +bin2hex(void *buf, size_t len) +{ + char *hex, *p; + unsigned char *src = buf; + + hex = malloc(len * 2 + 1); + if (hex == NULL) + return NULL; + + p = hex; + + while (len > 0) { + unsigned c; + + c = *src; + src++; + + *p = conv[c >> 4]; + ++p; + *p = conv[c & 0x0f]; + ++p; + --len; + } + *p = '\0'; + return hex; +} + +#define HMAC_PREFIX "." +#define HMAC_SUFFIX ".hmac" +#define READ_BUFFER_LENGTH 16384 + +static char * +make_hmac_path(const char *origpath) +{ + char *path, *p; + const char *fn; + + path = malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath)); + if(path == NULL) { + return NULL; + } + + fn = strrchr(origpath, '/'); + if (fn == NULL) { + fn = origpath; + } else { + ++fn; + } + + strncpy(path, origpath, fn-origpath); + p = path + (fn - origpath); + p = stpcpy(p, HMAC_PREFIX); + p = stpcpy(p, fn); + p = stpcpy(p, HMAC_SUFFIX); + + return path; +} + +static const char hmackey[] = "orboDeJITITejsirpADONivirpUkvarP"; + +static int +compute_file_hmac(const char *path, void **buf, size_t *hmaclen) +{ + FILE *f = NULL; + int rv = -1; + unsigned char rbuf[READ_BUFFER_LENGTH]; + size_t len; + unsigned int hlen; + HMAC_CTX c; + + HMAC_CTX_init(&c); + + f = fopen(path, "r"); + + if (f == NULL) { + goto end; + } + + HMAC_Init(&c, hmackey, sizeof(hmackey)-1, EVP_sha256()); + + while ((len=fread(rbuf, 1, sizeof(rbuf), f)) != 0) { + HMAC_Update(&c, rbuf, len); + } + + len = sizeof(rbuf); + /* reuse rbuf for hmac */ + HMAC_Final(&c, rbuf, &hlen); + + *buf = malloc(hlen); + if (*buf == NULL) { + goto end; + } + + *hmaclen = hlen; + + memcpy(*buf, rbuf, hlen); + + rv = 0; +end: + HMAC_CTX_cleanup(&c); + + if (f) + fclose(f); + + return rv; +} + +static int +FIPSCHECK_verify(const char *libname, const char *symbolname) +{ + char path[PATH_MAX+1]; + int rv; + FILE *hf; + char *hmacpath, *p; + char *hmac = NULL; + size_t n; + + rv = get_library_path(libname, symbolname, path, sizeof(path)); + + if (rv < 0) + return 0; + + hmacpath = make_hmac_path(path); + if (hmacpath == NULL) + return 0; + + hf = fopen(hmacpath, "r"); + if (hf == NULL) { + free(hmacpath); + return 0; + } + + if (getline(&hmac, &n, hf) > 0) { + void *buf; + size_t hmaclen; + char *hex; + + if ((p=strchr(hmac, '\n')) != NULL) + *p = '\0'; + + if (compute_file_hmac(path, &buf, &hmaclen) < 0) { + rv = -4; + goto end; + } + + if ((hex=bin2hex(buf, hmaclen)) == NULL) { + free(buf); + rv = -5; + goto end; + } + + if (strcmp(hex, hmac) != 0) { + rv = -1; + } + free(buf); + free(hex); + } + +end: + free(hmac); + free(hmacpath); + fclose(hf); + + if (rv < 0) + return 0; + + /* check successful */ + return 1; +} + +int FIPS_module_mode_set(int onoff, const char *auth) + { + int ret = 0; + + fips_w_lock(); + fips_started = 1; + fips_set_owning_thread(); + + if(onoff) + { + + fips_selftest_fail = 0; + + /* Don't go into FIPS mode twice, just so we can do automagic + seeding */ + if(FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + +#ifdef OPENSSL_IA32_SSE2 + { + extern unsigned int OPENSSL_ia32cap_P[2]; + if ((OPENSSL_ia32cap_P[0] & (1<<25|1<<26)) != (1<<25|1<<26)) + { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + OPENSSL_ia32cap_P[0] |= (1<<28); /* set "shared cache" */ + OPENSSL_ia32cap_P[1] &= ~(1<<(60-32)); /* clear AVX */ + } +#endif + + if(!FIPSCHECK_verify("libcrypto.so." SHLIB_VERSION_NUMBER,"FIPS_mode_set")) + { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + if(!FIPSCHECK_verify("libssl.so." SHLIB_VERSION_NUMBER,"SSL_CTX_new")) + { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + if(FIPS_selftest()) + fips_set_mode(onoff); + else + { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + ret = 1; + goto end; + } + fips_set_mode(0); + fips_selftest_fail = 0; + ret = 1; +end: + fips_clear_owning_thread(); + fips_w_unlock(); + return ret; + } + +static CRYPTO_THREADID fips_thread; +static int fips_thread_set = 0; + +static int fips_is_owning_thread(void) + { + int ret = 0; + + if (fips_started) + { + CRYPTO_r_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread_set) + { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, &fips_thread)) + ret = 1; + } + CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; + } + +int fips_set_owning_thread(void) + { + int ret = 0; + + if (fips_started) + { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (!fips_thread_set) + { + CRYPTO_THREADID_current(&fips_thread); + ret = 1; + fips_thread_set = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; + } + +int fips_clear_owning_thread(void) + { + int ret = 0; + + if (fips_started) + { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread_set) + { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, &fips_thread)) + fips_thread_set = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; + } + + +#if 0 +/* The purpose of this is to ensure the error code exists and the function + * name is to keep the error checking script quiet + */ +void hash_final(void) + { + FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); + } +#endif + + +#endif Index: openssl-1.0.1h/crypto/fips/fips.h =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips.h @@ -0,0 +1,279 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <openssl/opensslconf.h> +#include <openssl/crypto.h> +#include <stdarg.h> + +#ifndef OPENSSL_FIPS +#error FIPS is disabled. +#endif + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +struct dsa_st; +struct rsa_st; +struct evp_pkey_st; +struct env_md_st; +struct env_md_ctx_st; +struct evp_cipher_st; +struct evp_cipher_ctx_st; +struct dh_method; +struct CMAC_CTX_st; +struct hmac_ctx_st; + +int FIPS_module_mode_set(int onoff, const char *auth); +int FIPS_module_mode(void); +const void *FIPS_rand_check(void); +int FIPS_selftest(void); +int FIPS_selftest_failed(void); +void FIPS_corrupt_sha1(void); +int FIPS_selftest_sha1(void); +int FIPS_selftest_sha2(void); +void FIPS_corrupt_aes(void); +int FIPS_selftest_aes_ccm(void); +int FIPS_selftest_aes_gcm(void); +int FIPS_selftest_aes_xts(void); +int FIPS_selftest_aes(void); +void FIPS_corrupt_des(void); +int FIPS_selftest_des(void); +void FIPS_corrupt_rsa(void); +void FIPS_corrupt_rsa_keygen(void); +int FIPS_selftest_rsa(void); +void FIPS_corrupt_dsa(void); +void FIPS_corrupt_dsa_keygen(void); +int FIPS_selftest_dsa(void); +void FIPS_corrupt_rng(void); +void FIPS_rng_stick(void); +void FIPS_x931_stick(int onoff); +void FIPS_drbg_stick(int onoff); +int FIPS_selftest_rng(void); +int FIPS_selftest_x931(void); +int FIPS_selftest_hmac(void); +int FIPS_selftest_drbg(void); +int FIPS_selftest_drbg_all(void); +int FIPS_selftest_cmac(void); + +void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr); + +#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \ + alg " previous FIPS forbidden algorithm error ignored"); + +int fips_pkey_signature_test(struct evp_pkey_st *pkey, + const unsigned char *tbs, int tbslen, + const unsigned char *kat, unsigned int katlen, + const struct env_md_st *digest, unsigned int md_flags, + const char *fail_str); + +int fips_cipher_test(struct evp_cipher_ctx_st *ctx, + const struct evp_cipher_st *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len); + +void fips_set_selftest_fail(void); + +const struct env_md_st *FIPS_get_digestbynid(int nid); + +const struct evp_cipher_st *FIPS_get_cipherbynid(int nid); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_FIPS_strings(void); + +/* Error codes for the FIPS functions. */ + +/* Function codes. */ +#define FIPS_F_DH_BUILTIN_GENPARAMS 100 +#define FIPS_F_DH_INIT 148 +#define FIPS_F_DRBG_RESEED 162 +#define FIPS_F_DSA_BUILTIN_PARAMGEN 101 +#define FIPS_F_DSA_BUILTIN_PARAMGEN2 107 +#define FIPS_F_DSA_DO_SIGN 102 +#define FIPS_F_DSA_DO_VERIFY 103 +#define FIPS_F_ECDH_COMPUTE_KEY 163 +#define FIPS_F_ECDSA_DO_SIGN 164 +#define FIPS_F_ECDSA_DO_VERIFY 165 +#define FIPS_F_EC_KEY_GENERATE_KEY 166 +#define FIPS_F_EVP_CIPHERINIT_EX 124 +#define FIPS_F_EVP_DIGESTINIT_EX 125 +#define FIPS_F_FIPS_CHECK_DSA 104 +#define FIPS_F_FIPS_CHECK_DSA_PRNG 151 +#define FIPS_F_FIPS_CHECK_EC 142 +#define FIPS_F_FIPS_CHECK_EC_PRNG 152 +#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105 +#define FIPS_F_FIPS_CHECK_RSA 106 +#define FIPS_F_FIPS_CHECK_RSA_PRNG 150 +#define FIPS_F_FIPS_CIPHER 160 +#define FIPS_F_FIPS_CIPHERINIT 143 +#define FIPS_F_FIPS_CIPHER_CTX_CTRL 161 +#define FIPS_F_FIPS_DIGESTFINAL 158 +#define FIPS_F_FIPS_DIGESTINIT 128 +#define FIPS_F_FIPS_DIGESTUPDATE 159 +#define FIPS_F_FIPS_DRBG_BYTES 131 +#define FIPS_F_FIPS_DRBG_CHECK 146 +#define FIPS_F_FIPS_DRBG_CPRNG_TEST 132 +#define FIPS_F_FIPS_DRBG_ERROR_CHECK 136 +#define FIPS_F_FIPS_DRBG_GENERATE 134 +#define FIPS_F_FIPS_DRBG_INIT 135 +#define FIPS_F_FIPS_DRBG_INSTANTIATE 138 +#define FIPS_F_FIPS_DRBG_NEW 139 +#define FIPS_F_FIPS_DRBG_RESEED 140 +#define FIPS_F_FIPS_DRBG_SINGLE_KAT 141 +#define FIPS_F_FIPS_DSA_CHECK /* unused */ 107 +#define FIPS_F_FIPS_DSA_SIGN_DIGEST 154 +#define FIPS_F_FIPS_DSA_VERIFY_DIGEST 155 +#define FIPS_F_FIPS_GET_ENTROPY 147 +#define FIPS_F_FIPS_MODE_SET /* unused */ 108 +#define FIPS_F_FIPS_MODULE_MODE_SET 108 +#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109 +#define FIPS_F_FIPS_RAND_ADD 137 +#define FIPS_F_FIPS_RAND_BYTES 122 +#define FIPS_F_FIPS_RAND_PSEUDO_BYTES 167 +#define FIPS_F_FIPS_RAND_SEED 168 +#define FIPS_F_FIPS_RAND_SET_METHOD 126 +#define FIPS_F_FIPS_RAND_STATUS 127 +#define FIPS_F_FIPS_RSA_SIGN_DIGEST 156 +#define FIPS_F_FIPS_RSA_VERIFY_DIGEST 157 +#define FIPS_F_FIPS_SELFTEST_AES 110 +#define FIPS_F_FIPS_SELFTEST_AES_CCM 145 +#define FIPS_F_FIPS_SELFTEST_AES_GCM 129 +#define FIPS_F_FIPS_SELFTEST_AES_XTS 144 +#define FIPS_F_FIPS_SELFTEST_CMAC 130 +#define FIPS_F_FIPS_SELFTEST_DES 111 +#define FIPS_F_FIPS_SELFTEST_DSA 112 +#define FIPS_F_FIPS_SELFTEST_ECDSA 133 +#define FIPS_F_FIPS_SELFTEST_HMAC 113 +#define FIPS_F_FIPS_SELFTEST_RNG /* unused */ 114 +#define FIPS_F_FIPS_SELFTEST_SHA1 115 +#define FIPS_F_FIPS_SELFTEST_X931 114 +#define FIPS_F_FIPS_SET_PRNG_KEY 153 +#define FIPS_F_HASH_FINAL 123 +#define FIPS_F_RSA_BUILTIN_KEYGEN 116 +#define FIPS_F_RSA_EAY_INIT 149 +#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT 117 +#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT 118 +#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT 119 +#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 120 +#define FIPS_F_RSA_X931_GENERATE_KEY_EX 121 +#define FIPS_F_SSLEAY_RAND_BYTES /* unused */ 122 + +/* Reason codes. */ +#define FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED 150 +#define FIPS_R_ADDITIONAL_INPUT_TOO_LONG 125 +#define FIPS_R_ALREADY_INSTANTIATED 134 +#define FIPS_R_AUTHENTICATION_FAILURE 151 +#define FIPS_R_CANNOT_READ_EXE /* unused */ 103 +#define FIPS_R_CANNOT_READ_EXE_DIGEST /* unused */ 104 +#define FIPS_R_CONTRADICTING_EVIDENCE 114 +#define FIPS_R_DRBG_NOT_INITIALISED 152 +#define FIPS_R_DRBG_STUCK 103 +#define FIPS_R_ENTROPY_ERROR_UNDETECTED 104 +#define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED 105 +#define FIPS_R_ENTROPY_SOURCE_STUCK 142 +#define FIPS_R_ERROR_INITIALISING_DRBG 115 +#define FIPS_R_ERROR_INSTANTIATING_DRBG 127 +#define FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 124 +#define FIPS_R_ERROR_RETRIEVING_ENTROPY 122 +#define FIPS_R_ERROR_RETRIEVING_NONCE 140 +#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH /* unused */ 105 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112 +#define FIPS_R_FIPS_MODE_ALREADY_SET 102 +#define FIPS_R_FIPS_SELFTEST_FAILED 106 +#define FIPS_R_FUNCTION_ERROR 116 +#define FIPS_R_GENERATE_ERROR 137 +#define FIPS_R_GENERATE_ERROR_UNDETECTED 118 +#define FIPS_R_INSTANTIATE_ERROR 119 +#define FIPS_R_INSUFFICIENT_SECURITY_STRENGTH 120 +#define FIPS_R_INTERNAL_ERROR 121 +#define FIPS_R_INVALID_KEY_LENGTH 109 +#define FIPS_R_INVALID_PARAMETERS 144 +#define FIPS_R_IN_ERROR_STATE 123 +#define FIPS_R_KEY_TOO_SHORT 108 +#define FIPS_R_NONCE_ERROR_UNDETECTED 149 +#define FIPS_R_NON_FIPS_METHOD 100 +#define FIPS_R_NOPR_TEST1_FAILURE 145 +#define FIPS_R_NOPR_TEST2_FAILURE 146 +#define FIPS_R_NOT_INSTANTIATED 126 +#define FIPS_R_PAIRWISE_TEST_FAILED 107 +#define FIPS_R_PERSONALISATION_ERROR_UNDETECTED 128 +#define FIPS_R_PERSONALISATION_STRING_TOO_LONG 129 +#define FIPS_R_PRNG_STRENGTH_TOO_LOW 143 +#define FIPS_R_PR_TEST1_FAILURE 147 +#define FIPS_R_PR_TEST2_FAILURE 148 +#define FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED 130 +#define FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG 131 +#define FIPS_R_RESEED_COUNTER_ERROR 132 +#define FIPS_R_RESEED_ERROR 133 +#define FIPS_R_RSA_DECRYPT_ERROR /* unused */ 115 +#define FIPS_R_RSA_ENCRYPT_ERROR /* unused */ 116 +#define FIPS_R_SELFTEST_FAILED 101 +#define FIPS_R_SELFTEST_FAILURE 135 +#define FIPS_R_STRENGTH_ERROR_UNDETECTED 136 +#define FIPS_R_TEST_FAILURE 117 +#define FIPS_R_UNINSTANTIATE_ERROR 141 +#define FIPS_R_UNINSTANTIATE_ZEROISE_ERROR 138 +#define FIPS_R_UNSUPPORTED_DRBG_TYPE 139 +#define FIPS_R_UNSUPPORTED_PLATFORM 113 + +#ifdef __cplusplus +} +#endif +#endif Index: openssl-1.0.1h/crypto/fips/fips_aes_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_aes_selftest.c @@ -0,0 +1,359 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +#include <openssl/evp.h> + +#ifdef OPENSSL_FIPS +static const struct + { + const unsigned char key[16]; + const unsigned char plaintext[16]; + const unsigned char ciphertext[16]; + } tests[]= + { + { + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, + { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, + 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }, + { 0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30, + 0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A }, + }, + }; + +static int corrupt_aes; + +void FIPS_corrupt_aes() + { + corrupt_aes = 1; + } + +int FIPS_selftest_aes() + { + int n; + int ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + for(n=0 ; n < 1 ; ++n) + { + unsigned char key[16]; + + memcpy(key, tests[n].key, sizeof(key)); + if (corrupt_aes) + key[0]++; + if (fips_cipher_test(&ctx, EVP_aes_128_ecb(), + key, NULL, + tests[n].plaintext, + tests[n].ciphertext, + 16) <= 0) + goto err; + } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED); + return ret; + } + +/* AES-CCM test data from NIST public test vectors */ + +static const unsigned char ccm_key[] = { + 0xce,0xb0,0x09,0xae,0xa4,0x45,0x44,0x51,0xfe,0xad,0xf0,0xe6, + 0xb3,0x6f,0x45,0x55,0x5d,0xd0,0x47,0x23,0xba,0xa4,0x48,0xe8 +}; +static const unsigned char ccm_nonce[] = { + 0x76,0x40,0x43,0xc4,0x94,0x60,0xb7 +}; +static const unsigned char ccm_adata[] = { + 0x6e,0x80,0xdd,0x7f,0x1b,0xad,0xf3,0xa1,0xc9,0xab,0x25,0xc7, + 0x5f,0x10,0xbd,0xe7,0x8c,0x23,0xfa,0x0e,0xb8,0xf9,0xaa,0xa5, + 0x3a,0xde,0xfb,0xf4,0xcb,0xf7,0x8f,0xe4 +}; +static const unsigned char ccm_pt[] = { + 0xc8,0xd2,0x75,0xf9,0x19,0xe1,0x7d,0x7f,0xe6,0x9c,0x2a,0x1f, + 0x58,0x93,0x9d,0xfe,0x4d,0x40,0x37,0x91,0xb5,0xdf,0x13,0x10 +}; +static const unsigned char ccm_ct[] = { + 0x8a,0x0f,0x3d,0x82,0x29,0xe4,0x8e,0x74,0x87,0xfd,0x95,0xa2, + 0x8a,0xd3,0x92,0xc8,0x0b,0x36,0x81,0xd4,0xfb,0xc7,0xbb,0xfd +}; +static const unsigned char ccm_tag[] = { + 0x2d,0xd6,0xef,0x1c,0x45,0xd4,0xcc,0xb7,0x23,0xdc,0x07,0x44, + 0x14,0xdb,0x50,0x6d +}; + +int FIPS_selftest_aes_ccm(void) + { + int ret = 0; + unsigned char out[128], tag[16]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + memset(out, 0, sizeof(out)); + if (!EVP_CipherInit_ex(&ctx, EVP_aes_192_ccm(),NULL, NULL, NULL, 1)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, + sizeof(ccm_nonce), NULL)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, + sizeof(ccm_tag), NULL)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, ccm_key, ccm_nonce, 1)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, sizeof(ccm_pt)) != sizeof(ccm_pt)) + goto err; + if (EVP_Cipher(&ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, ccm_pt, sizeof(ccm_pt)) != sizeof(ccm_ct)) + goto err; + + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, 16, tag)) + goto err; + if (memcmp(tag, ccm_tag, sizeof(ccm_tag)) + || memcmp(out, ccm_ct, sizeof(ccm_ct))) + goto err; + + memset(out, 0, sizeof(out)); + + if (!EVP_CipherInit_ex(&ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 0)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, + sizeof(ccm_nonce), NULL)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, 16, tag)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, ccm_key, ccm_nonce, 0)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, sizeof(ccm_ct)) != sizeof(ccm_ct)) + goto err; + if (EVP_Cipher(&ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, ccm_ct, sizeof(ccm_ct)) != sizeof(ccm_pt)) + goto err; + + if (memcmp(out, ccm_pt, sizeof(ccm_pt))) + goto err; + + ret = 1; + + err: + EVP_CIPHER_CTX_cleanup(&ctx); + + if (ret == 0) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_AES_CCM,FIPS_R_SELFTEST_FAILED); + return 0; + } + else + return ret; + + } + +/* AES-GCM test data from NIST public test vectors */ + +static const unsigned char gcm_key[] = { + 0xee,0xbc,0x1f,0x57,0x48,0x7f,0x51,0x92,0x1c,0x04,0x65,0x66, + 0x5f,0x8a,0xe6,0xd1,0x65,0x8b,0xb2,0x6d,0xe6,0xf8,0xa0,0x69, + 0xa3,0x52,0x02,0x93,0xa5,0x72,0x07,0x8f +}; +static const unsigned char gcm_iv[] = { + 0x99,0xaa,0x3e,0x68,0xed,0x81,0x73,0xa0,0xee,0xd0,0x66,0x84 +}; +static const unsigned char gcm_pt[] = { + 0xf5,0x6e,0x87,0x05,0x5b,0xc3,0x2d,0x0e,0xeb,0x31,0xb2,0xea, + 0xcc,0x2b,0xf2,0xa5 +}; +static const unsigned char gcm_aad[] = { + 0x4d,0x23,0xc3,0xce,0xc3,0x34,0xb4,0x9b,0xdb,0x37,0x0c,0x43, + 0x7f,0xec,0x78,0xde +}; +static const unsigned char gcm_ct[] = { + 0xf7,0x26,0x44,0x13,0xa8,0x4c,0x0e,0x7c,0xd5,0x36,0x86,0x7e, + 0xb9,0xf2,0x17,0x36 +}; +static const unsigned char gcm_tag[] = { + 0x67,0xba,0x05,0x10,0x26,0x2a,0xe4,0x87,0xd7,0x37,0xee,0x62, + 0x98,0xf7,0x7e,0x0c +}; + +int FIPS_selftest_aes_gcm(void) + { + int ret = 0; + unsigned char out[128], tag[16]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + memset(out, 0, sizeof(out)); + memset(tag, 0, sizeof(tag)); + if (!EVP_CipherInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 1)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, + sizeof(gcm_iv), NULL)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, gcm_key, gcm_iv, 1)) + goto err; + if (EVP_Cipher(&ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, gcm_pt, sizeof(gcm_pt)) != sizeof(gcm_ct)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, 0) < 0) + goto err; + + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + goto err; + + if (memcmp(tag, gcm_tag, 16) || memcmp(out, gcm_ct, 16)) + goto err; + + memset(out, 0, sizeof(out)); + + if (!EVP_CipherInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 0)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, + sizeof(gcm_iv), NULL)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, gcm_key, gcm_iv, 0)) + goto err; + if (EVP_Cipher(&ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, gcm_ct, sizeof(gcm_ct)) != sizeof(gcm_pt)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, 0) < 0) + goto err; + + if (memcmp(out, gcm_pt, 16)) + goto err; + + ret = 1; + + err: + EVP_CIPHER_CTX_cleanup(&ctx); + + if (ret == 0) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_AES_GCM,FIPS_R_SELFTEST_FAILED); + return 0; + } + else + return ret; + + } + + +static const unsigned char XTS_128_key[] = { + 0xa1,0xb9,0x0c,0xba,0x3f,0x06,0xac,0x35,0x3b,0x2c,0x34,0x38, + 0x76,0x08,0x17,0x62,0x09,0x09,0x23,0x02,0x6e,0x91,0x77,0x18, + 0x15,0xf2,0x9d,0xab,0x01,0x93,0x2f,0x2f +}; +static const unsigned char XTS_128_i[] = { + 0x4f,0xae,0xf7,0x11,0x7c,0xda,0x59,0xc6,0x6e,0x4b,0x92,0x01, + 0x3e,0x76,0x8a,0xd5 +}; +static const unsigned char XTS_128_pt[] = { + 0xeb,0xab,0xce,0x95,0xb1,0x4d,0x3c,0x8d,0x6f,0xb3,0x50,0x39, + 0x07,0x90,0x31,0x1c +}; +static const unsigned char XTS_128_ct[] = { + 0x77,0x8a,0xe8,0xb4,0x3c,0xb9,0x8d,0x5a,0x82,0x50,0x81,0xd5, + 0xbe,0x47,0x1c,0x63 +}; + +static const unsigned char XTS_256_key[] = { + 0x1e,0xa6,0x61,0xc5,0x8d,0x94,0x3a,0x0e,0x48,0x01,0xe4,0x2f, + 0x4b,0x09,0x47,0x14,0x9e,0x7f,0x9f,0x8e,0x3e,0x68,0xd0,0xc7, + 0x50,0x52,0x10,0xbd,0x31,0x1a,0x0e,0x7c,0xd6,0xe1,0x3f,0xfd, + 0xf2,0x41,0x8d,0x8d,0x19,0x11,0xc0,0x04,0xcd,0xa5,0x8d,0xa3, + 0xd6,0x19,0xb7,0xe2,0xb9,0x14,0x1e,0x58,0x31,0x8e,0xea,0x39, + 0x2c,0xf4,0x1b,0x08 +}; +static const unsigned char XTS_256_i[] = { + 0xad,0xf8,0xd9,0x26,0x27,0x46,0x4a,0xd2,0xf0,0x42,0x8e,0x84, + 0xa9,0xf8,0x75,0x64 +}; +static const unsigned char XTS_256_pt[] = { + 0x2e,0xed,0xea,0x52,0xcd,0x82,0x15,0xe1,0xac,0xc6,0x47,0xe8, + 0x10,0xbb,0xc3,0x64,0x2e,0x87,0x28,0x7f,0x8d,0x2e,0x57,0xe3, + 0x6c,0x0a,0x24,0xfb,0xc1,0x2a,0x20,0x2e +}; +static const unsigned char XTS_256_ct[] = { + 0xcb,0xaa,0xd0,0xe2,0xf6,0xce,0xa3,0xf5,0x0b,0x37,0xf9,0x34, + 0xd4,0x6a,0x9b,0x13,0x0b,0x9d,0x54,0xf0,0x7e,0x34,0xf3,0x6a, + 0xf7,0x93,0xe8,0x6f,0x73,0xc6,0xd7,0xdb +}; + +int FIPS_selftest_aes_xts() + { + int ret = 1; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (fips_cipher_test(&ctx, EVP_aes_128_xts(), + XTS_128_key, XTS_128_i, XTS_128_pt, XTS_128_ct, + sizeof(XTS_128_pt)) <= 0) + ret = 0; + + if (fips_cipher_test(&ctx, EVP_aes_256_xts(), + XTS_256_key, XTS_256_i, XTS_256_pt, XTS_256_ct, + sizeof(XTS_256_pt)) <= 0) + ret = 0; + + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_AES_XTS,FIPS_R_SELFTEST_FAILED); + return ret; + } + +#endif Index: openssl-1.0.1h/crypto/fips/fips_cmac_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_cmac_selftest.c @@ -0,0 +1,161 @@ +/* ==================================================================== + * Copyright (c) 2011 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/cmac.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS +typedef struct { + int nid; + const unsigned char key[EVP_MAX_KEY_LENGTH]; size_t keysize; + const unsigned char msg[64]; size_t msgsize; + const unsigned char mac[32]; size_t macsize; +} CMAC_KAT; + +/* from http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf */ +static const CMAC_KAT vector[] = { + { NID_aes_128_cbc, /* Count = 32 from CMACGenAES128.txt */ + { 0x77,0xa7,0x7f,0xaf, 0x29,0x0c,0x1f,0xa3, + 0x0c,0x68,0x3d,0xf1, 0x6b,0xa7,0xa7,0x7b, }, 128, + { 0x02,0x06,0x83,0xe1, 0xf0,0x39,0x2f,0x4c, + 0xac,0x54,0x31,0x8b, 0x60,0x29,0x25,0x9e, + 0x9c,0x55,0x3d,0xbc, 0x4b,0x6a,0xd9,0x98, + 0xe6,0x4d,0x58,0xe4, 0xe7,0xdc,0x2e,0x13, }, 256, + { 0xfb,0xfe,0xa4,0x1b, }, 32 + }, + { NID_aes_192_cbc, /* Count = 23 from CMACGenAES192.txt */ + { 0x7b,0x32,0x39,0x13, 0x69,0xaa,0x4c,0xa9, + 0x75,0x58,0x09,0x5b, 0xe3,0xc3,0xec,0x86, + 0x2b,0xd0,0x57,0xce, 0xf1,0xe3,0x2d,0x62, }, 192, + { 0x0 }, 0, + { 0xe4,0xd9,0x34,0x0b, 0x03,0xe6,0x7d,0xef, + 0xd4,0x96,0x9c,0xc1, 0xed,0x37,0x35,0xe6, }, 128, + }, + { NID_aes_256_cbc, /* Count = 33 from CMACGenAES256.txt */ + { 0x0b,0x12,0x2a,0xc8, 0xf3,0x4e,0xd1,0xfe, + 0x08,0x2a,0x36,0x25, 0xd1,0x57,0x56,0x14, + 0x54,0x16,0x7a,0xc1, 0x45,0xa1,0x0b,0xbf, + 0x77,0xc6,0xa7,0x05, 0x96,0xd5,0x74,0xf1, }, 256, + { 0x49,0x8b,0x53,0xfd, 0xec,0x87,0xed,0xcb, + 0xf0,0x70,0x97,0xdc, 0xcd,0xe9,0x3a,0x08, + 0x4b,0xad,0x75,0x01, 0xa2,0x24,0xe3,0x88, + 0xdf,0x34,0x9c,0xe1, 0x89,0x59,0xfe,0x84, + 0x85,0xf8,0xad,0x15, 0x37,0xf0,0xd8,0x96, + 0xea,0x73,0xbe,0xdc, 0x72,0x14,0x71,0x3f, }, 384, + { 0xf6,0x2c,0x46,0x32, 0x9b, }, 40, + }, + { NID_des_ede3_cbc, /* Count = 41 from CMACGenTDES3.req */ + { 0x89,0xbc,0xd9,0x52, 0xa8,0xc8,0xab,0x37, + 0x1a,0xf4,0x8a,0xc7, 0xd0,0x70,0x85,0xd5, + 0xef,0xf7,0x02,0xe6, 0xd6,0x2c,0xdc,0x23, }, 192, + { 0xfa,0x62,0x0c,0x1b, 0xbe,0x97,0x31,0x9e, + 0x9a,0x0c,0xf0,0x49, 0x21,0x21,0xf7,0xa2, + 0x0e,0xb0,0x8a,0x6a, 0x70,0x9d,0xcb,0xd0, + 0x0a,0xaf,0x38,0xe4, 0xf9,0x9e,0x75,0x4e, }, 256, + { 0x8f,0x49,0xa1,0xb7, 0xd6,0xaa,0x22,0x58, }, 64, + }, +}; + +int FIPS_selftest_cmac() + { + size_t n, outlen; + unsigned char out[32]; + const EVP_CIPHER *cipher; + CMAC_CTX *ctx = CMAC_CTX_new(); + const CMAC_KAT *t; + int rv = 1; + + for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++) + { + cipher = FIPS_get_cipherbynid(t->nid); + if (!cipher) + { + rv = -1; + goto err; + } + if (!CMAC_Init(ctx, t->key, t->keysize/8, cipher, 0)) + { + rv = -1; + goto err; + } + if (!CMAC_Update(ctx, t->msg, t->msgsize/8)) + { + rv = -1; + goto err; + } + + if (!CMAC_Final(ctx, out, &outlen)) + { + rv = -1; + goto err; + } + CMAC_CTX_cleanup(ctx); + + if(outlen < t->macsize/8 || memcmp(out,t->mac,t->macsize/8)) + { + rv = 0; + } + } + + err: + CMAC_CTX_free(ctx); + + if (rv == -1) + { + rv = 0; + } + if (!rv) + FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC,FIPS_R_SELFTEST_FAILED); + + return rv; + } +#endif Index: openssl-1.0.1h/crypto/fips/fips_des_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_des_selftest.c @@ -0,0 +1,147 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +#include <openssl/evp.h> +#include <openssl/opensslconf.h> + +#ifdef OPENSSL_FIPS + +static const struct + { + const unsigned char key[16]; + const unsigned char plaintext[8]; + const unsigned char ciphertext[8]; + } tests2[]= + { + { + { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec, + 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 }, + { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef }, + { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd } + }, + { + { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34, + 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 }, + { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e }, + { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff }, + } + }; + +static const struct + { + const unsigned char key[24]; + const unsigned char plaintext[8]; + const unsigned char ciphertext[8]; + } tests3[]= + { + { + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10, + 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 }, + { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c }, + { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b }, + }, + { + { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 }, + { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, + { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 }, + }, + }; + + +static int corrupt_des; + +void FIPS_corrupt_des() + { + corrupt_des = 1; + } + +int FIPS_selftest_des() + { + int n, ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + /* Encrypt/decrypt with 2-key 3DES and compare to known answers */ + for(n=0 ; n < 2 ; ++n) + { + unsigned char plaintext[8]; + + memcpy(plaintext, tests2[n].plaintext, sizeof(plaintext)); + if (corrupt_des) + plaintext[0]++; + if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(), + tests2[n].key, NULL, + plaintext, tests2[n].ciphertext, 8)) + goto err; + } + + /* Encrypt/decrypt with 3DES and compare to known answers */ + for(n=0 ; n < 2 ; ++n) + { + if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(), + tests3[n].key, NULL, + tests3[n].plaintext, tests3[n].ciphertext, 8)) + goto err; + } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); + + return ret; + } +#endif Index: openssl-1.0.1h/crypto/fips/fips_drbg_ctr.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_ctr.c @@ -0,0 +1,436 @@ +/* fips/rand/fips_drbg_ctr.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +#include <stdlib.h> +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +static void inc_128(DRBG_CTR_CTX *cctx) + { + int i; + unsigned char c; + unsigned char *p = cctx->V + 15; + for (i = 0; i < 16; i++) + { + c = *p; + c++; + *p = c; + if (c) + return; + p--; + } + } + +static void ctr_XOR(DRBG_CTR_CTX *cctx, const unsigned char *in, size_t inlen) + { + size_t i, n; + /* Any zero padding will have no effect on the result as we + * are XORing. So just process however much input we have. + */ + + if (!in || !inlen) + return; + + if (inlen < cctx->keylen) + n = inlen; + else + n = cctx->keylen; + + for (i = 0; i < n; i++) + cctx->K[i] ^= in[i]; + if (inlen <= cctx->keylen) + return; + + n = inlen - cctx->keylen; + /* Should never happen */ + if (n > 16) + n = 16; + for (i = 0; i < 16; i++) + cctx->V[i] ^= in[i + cctx->keylen]; + } + +/* Process a complete block using BCC algorithm of SPP 800-90 10.4.3 */ + +static void ctr_BCC_block(DRBG_CTR_CTX *cctx, unsigned char *out, + const unsigned char *in) + { + int i; + for (i = 0; i < 16; i++) + out[i] ^= in[i]; + AES_encrypt(out, out, &cctx->df_ks); +#if 0 +fprintf(stderr, "BCC in+out\n"); +BIO_dump_fp(stderr, in, 16); +BIO_dump_fp(stderr, out, 16); +#endif + } + +/* Handle several BCC operations for as much data as we need for K and X */ +static void ctr_BCC_blocks(DRBG_CTR_CTX *cctx, const unsigned char *in) + { + ctr_BCC_block(cctx, cctx->KX, in); + ctr_BCC_block(cctx, cctx->KX + 16, in); + if (cctx->keylen != 16) + ctr_BCC_block(cctx, cctx->KX + 32, in); + } +/* Initialise BCC blocks: these have the value 0,1,2 in leftmost positions: + * see 10.4.2 stage 7. + */ +static void ctr_BCC_init(DRBG_CTR_CTX *cctx) + { + memset(cctx->KX, 0, 48); + memset(cctx->bltmp, 0, 16); + ctr_BCC_block(cctx, cctx->KX, cctx->bltmp); + cctx->bltmp[3] = 1; + ctr_BCC_block(cctx, cctx->KX + 16, cctx->bltmp); + if (cctx->keylen != 16) + { + cctx->bltmp[3] = 2; + ctr_BCC_block(cctx, cctx->KX + 32, cctx->bltmp); + } + } + +/* Process several blocks into BCC algorithm, some possibly partial */ +static void ctr_BCC_update(DRBG_CTR_CTX *cctx, + const unsigned char *in, size_t inlen) + { + if (!in || !inlen) + return; + /* If we have partial block handle it first */ + if (cctx->bltmp_pos) + { + size_t left = 16 - cctx->bltmp_pos; + /* If we now have a complete block process it */ + if (inlen >= left) + { + memcpy(cctx->bltmp + cctx->bltmp_pos, in, left); + ctr_BCC_blocks(cctx, cctx->bltmp); + cctx->bltmp_pos = 0; + inlen -= left; + in += left; + } + } + /* Process zero or more complete blocks */ + while (inlen >= 16) + { + ctr_BCC_blocks(cctx, in); + in += 16; + inlen -= 16; + } + /* Copy any remaining partial block to the temporary buffer */ + if (inlen > 0) + { + memcpy(cctx->bltmp + cctx->bltmp_pos, in, inlen); + cctx->bltmp_pos += inlen; + } + } + +static void ctr_BCC_final(DRBG_CTR_CTX *cctx) + { + if (cctx->bltmp_pos) + { + memset(cctx->bltmp + cctx->bltmp_pos, 0, 16 - cctx->bltmp_pos); + ctr_BCC_blocks(cctx, cctx->bltmp); + } + } + +static void ctr_df(DRBG_CTR_CTX *cctx, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *in3, size_t in3len) + { + size_t inlen; + unsigned char *p = cctx->bltmp; + static unsigned char c80 = 0x80; + + ctr_BCC_init(cctx); + if (!in1) + in1len = 0; + if (!in2) + in2len = 0; + if (!in3) + in3len = 0; + inlen = in1len + in2len + in3len; + /* Initialise L||N in temporary block */ + *p++ = (inlen >> 24) & 0xff; + *p++ = (inlen >> 16) & 0xff; + *p++ = (inlen >> 8) & 0xff; + *p++ = inlen & 0xff; + /* NB keylen is at most 32 bytes */ + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p = (unsigned char)((cctx->keylen + 16) & 0xff); + cctx->bltmp_pos = 8; + ctr_BCC_update(cctx, in1, in1len); + ctr_BCC_update(cctx, in2, in2len); + ctr_BCC_update(cctx, in3, in3len); + ctr_BCC_update(cctx, &c80, 1); + ctr_BCC_final(cctx); + /* Set up key K */ + AES_set_encrypt_key(cctx->KX, cctx->keylen * 8, &cctx->df_kxks); + /* X follows key K */ + AES_encrypt(cctx->KX + cctx->keylen, cctx->KX, &cctx->df_kxks); + AES_encrypt(cctx->KX, cctx->KX + 16, &cctx->df_kxks); + if (cctx->keylen != 16) + AES_encrypt(cctx->KX + 16, cctx->KX + 32, &cctx->df_kxks); +#if 0 +fprintf(stderr, "Output of ctr_df:\n"); +BIO_dump_fp(stderr, cctx->KX, cctx->keylen + 16); +#endif + } + +/* NB the no-df Update in SP800-90 specifies a constant input length + * of seedlen, however other uses of this algorithm pad the input with + * zeroes if necessary and have up to two parameters XORed together, + * handle both cases in this function instead. + */ + +static void ctr_Update(DRBG_CTX *dctx, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *nonce, size_t noncelen) + { + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + /* ks is already setup for correct key */ + inc_128(cctx); + AES_encrypt(cctx->V, cctx->K, &cctx->ks); + /* If keylen longer than 128 bits need extra encrypt */ + if (cctx->keylen != 16) + { + inc_128(cctx); + AES_encrypt(cctx->V, cctx->K + 16, &cctx->ks); + } + inc_128(cctx); + AES_encrypt(cctx->V, cctx->V, &cctx->ks); + /* If 192 bit key part of V is on end of K */ + if (cctx->keylen == 24) + { + memcpy(cctx->V + 8, cctx->V, 8); + memcpy(cctx->V, cctx->K + 24, 8); + } + + if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) + { + /* If no input reuse existing derived value */ + if (in1 || nonce || in2) + ctr_df(cctx, in1, in1len, nonce, noncelen, in2, in2len); + /* If this a reuse input in1len != 0 */ + if (in1len) + ctr_XOR(cctx, cctx->KX, dctx->seedlen); + } + else + { + ctr_XOR(cctx, in1, in1len); + ctr_XOR(cctx, in2, in2len); + } + + AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); +#if 0 +fprintf(stderr, "K+V after update is:\n"); +BIO_dump_fp(stderr, cctx->K, cctx->keylen); +BIO_dump_fp(stderr, cctx->V, 16); +#endif + } + +static int drbg_ctr_instantiate(DRBG_CTX *dctx, + const unsigned char *ent, size_t entlen, + const unsigned char *nonce, size_t noncelen, + const unsigned char *pers, size_t perslen) + { + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + memset(cctx->K, 0, sizeof(cctx->K)); + memset(cctx->V, 0, sizeof(cctx->V)); + AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); + ctr_Update(dctx, ent, entlen, pers, perslen, nonce, noncelen); + return 1; + } + +static int drbg_ctr_reseed(DRBG_CTX *dctx, + const unsigned char *ent, size_t entlen, + const unsigned char *adin, size_t adinlen) + { + ctr_Update(dctx, ent, entlen, adin, adinlen, NULL, 0); + return 1; + } + +static int drbg_ctr_generate(DRBG_CTX *dctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adinlen) + { + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + if (adin && adinlen) + { + ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); + /* This means we reuse derived value */ + if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) + { + adin = NULL; + adinlen = 1; + } + } + else + adinlen = 0; + + for (;;) + { + inc_128(cctx); + if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) + { + AES_encrypt(cctx->V, dctx->lb, &cctx->ks); + dctx->lb_valid = 1; + continue; + } + if (outlen < 16) + { + /* Use K as temp space as it will be updated */ + AES_encrypt(cctx->V, cctx->K, &cctx->ks); + if (!fips_drbg_cprng_test(dctx, cctx->K)) + return 0; + memcpy(out, cctx->K, outlen); + break; + } + AES_encrypt(cctx->V, out, &cctx->ks); + if (!fips_drbg_cprng_test(dctx, out)) + return 0; + out += 16; + outlen -= 16; + if (outlen == 0) + break; + } + + ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); + + return 1; + + } + +static int drbg_ctr_uninstantiate(DRBG_CTX *dctx) + { + memset(&dctx->d.ctr, 0, sizeof(DRBG_CTR_CTX)); + return 1; + } + +int fips_drbg_ctr_init(DRBG_CTX *dctx) + { + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + + size_t keylen; + + switch (dctx->type) + { + case NID_aes_128_ctr: + keylen = 16; + break; + + case NID_aes_192_ctr: + keylen = 24; + break; + + case NID_aes_256_ctr: + keylen = 32; + break; + + default: + return -2; + } + + dctx->instantiate = drbg_ctr_instantiate; + dctx->reseed = drbg_ctr_reseed; + dctx->generate = drbg_ctr_generate; + dctx->uninstantiate = drbg_ctr_uninstantiate; + + cctx->keylen = keylen; + dctx->strength = keylen * 8; + dctx->blocklength = 16; + dctx->seedlen = keylen + 16; + + if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) + { + /* df initialisation */ + static unsigned char df_key[32] = + { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f + }; + /* Set key schedule for df_key */ + AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks); + + dctx->min_entropy = cctx->keylen; + dctx->max_entropy = DRBG_MAX_LENGTH; + dctx->min_nonce = dctx->min_entropy / 2; + dctx->max_nonce = DRBG_MAX_LENGTH; + dctx->max_pers = DRBG_MAX_LENGTH; + dctx->max_adin = DRBG_MAX_LENGTH; + } + else + { + dctx->min_entropy = dctx->seedlen; + dctx->max_entropy = dctx->seedlen; + /* Nonce not used */ + dctx->min_nonce = 0; + dctx->max_nonce = 0; + dctx->max_pers = dctx->seedlen; + dctx->max_adin = dctx->seedlen; + } + + dctx->max_request = 1<<16; + dctx->reseed_interval = 1<<24; + + return 1; + } Index: openssl-1.0.1h/crypto/fips/fips_drbg_hash.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_hash.c @@ -0,0 +1,378 @@ +/* fips/rand/fips_drbg_hash.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include <stdlib.h> +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +/* This is Hash_df from SP 800-90 10.4.1 */ + +static int hash_df(DRBG_CTX *dctx, unsigned char *out, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *in3, size_t in3len, + const unsigned char *in4, size_t in4len) + { + EVP_MD_CTX *mctx = &dctx->d.hash.mctx; + unsigned char *vtmp = dctx->d.hash.vtmp; + unsigned char tmp[6]; + /* Standard only ever needs seedlen bytes which is always less than + * maximum permitted so no need to check length. + */ + size_t outlen = dctx->seedlen; + tmp[0] = 1; + tmp[1] = ((outlen * 8) >> 24) & 0xff; + tmp[2] = ((outlen * 8) >> 16) & 0xff; + tmp[3] = ((outlen * 8) >> 8) & 0xff; + tmp[4] = (outlen * 8) & 0xff; + if (!in1) + { + tmp[5] = (unsigned char)in1len; + in1 = tmp + 5; + in1len = 1; + } + for (;;) + { + if (!FIPS_digestinit(mctx, dctx->d.hash.md)) + return 0; + if (!FIPS_digestupdate(mctx, tmp, 5)) + return 0; + if (in1 && !FIPS_digestupdate(mctx, in1, in1len)) + return 0; + if (in2 && !FIPS_digestupdate(mctx, in2, in2len)) + return 0; + if (in3 && !FIPS_digestupdate(mctx, in3, in3len)) + return 0; + if (in4 && !FIPS_digestupdate(mctx, in4, in4len)) + return 0; + if (outlen < dctx->blocklength) + { + if (!FIPS_digestfinal(mctx, vtmp, NULL)) + return 0; + memcpy(out, vtmp, outlen); + OPENSSL_cleanse(vtmp, dctx->blocklength); + return 1; + } + else if(!FIPS_digestfinal(mctx, out, NULL)) + return 0; + + outlen -= dctx->blocklength; + if (outlen == 0) + return 1; + tmp[0]++; + out += dctx->blocklength; + } + } + + +/* Add an unsigned buffer to the buf value, storing the result in buf. For + * this algorithm the length of input never exceeds the seed length. + */ + +static void ctx_add_buf(DRBG_CTX *dctx, unsigned char *buf, + unsigned char *in, size_t inlen) + { + size_t i = inlen; + const unsigned char *q; + unsigned char c, *p; + p = buf + dctx->seedlen; + q = in + inlen; + + OPENSSL_assert(i <= dctx->seedlen); + + /* Special case: zero length, just increment buffer */ + if (i) + c = 0; + else + c = 1; + + while (i) + { + int r; + p--; + q--; + r = *p + *q + c; + /* Carry */ + if (r > 0xff) + c = 1; + else + c = 0; + *p = r & 0xff; + i--; + } + + i = dctx->seedlen - inlen; + + /* If not adding whole buffer handle final carries */ + if (c && i) + { + do + { + p--; + c = *p; + c++; + *p = c; + if(c) + return; + } while(i--); + } + } + +/* Finalise and add hash to V */ + +static int ctx_add_md(DRBG_CTX *dctx) + { + if (!FIPS_digestfinal(&dctx->d.hash.mctx, dctx->d.hash.vtmp, NULL)) + return 0; + ctx_add_buf(dctx, dctx->d.hash.V, dctx->d.hash.vtmp, dctx->blocklength); + return 1; + } + +static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen) + { + DRBG_HASH_CTX *hctx = &dctx->d.hash; + if (outlen == 0) + return 1; + memcpy(hctx->vtmp, hctx->V, dctx->seedlen); + for(;;) + { + FIPS_digestinit(&hctx->mctx, hctx->md); + FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen); + if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) + { + FIPS_digestfinal(&hctx->mctx, dctx->lb, NULL); + dctx->lb_valid = 1; + } + else if (outlen < dctx->blocklength) + { + FIPS_digestfinal(&hctx->mctx, hctx->vtmp, NULL); + if (!fips_drbg_cprng_test(dctx, hctx->vtmp)) + return 0; + memcpy(out, hctx->vtmp, outlen); + return 1; + } + else + { + FIPS_digestfinal(&hctx->mctx, out, NULL); + if (!fips_drbg_cprng_test(dctx, out)) + return 0; + outlen -= dctx->blocklength; + if (outlen == 0) + return 1; + out += dctx->blocklength; + } + ctx_add_buf(dctx, hctx->vtmp, NULL, 0); + } + } + +static int drbg_hash_instantiate(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len) + { + DRBG_HASH_CTX *hctx = &dctx->d.hash; + if (!hash_df(dctx, hctx->V, + ent, ent_len, nonce, nonce_len, pstr, pstr_len, + NULL, 0)) + return 0; + if (!hash_df(dctx, hctx->C, + NULL, 0, hctx->V, dctx->seedlen, + NULL, 0, NULL, 0)) + return 0; + +#ifdef HASH_DRBG_TRACE + fprintf(stderr, "V+C after instantiate:\n"); + hexprint(stderr, hctx->V, dctx->seedlen); + hexprint(stderr, hctx->C, dctx->seedlen); +#endif + return 1; + } + + +static int drbg_hash_reseed(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adin_len) + { + DRBG_HASH_CTX *hctx = &dctx->d.hash; + /* V about to be updated so use C as output instead */ + if (!hash_df(dctx, hctx->C, + NULL, 1, hctx->V, dctx->seedlen, + ent, ent_len, adin, adin_len)) + return 0; + memcpy(hctx->V, hctx->C, dctx->seedlen); + if (!hash_df(dctx, hctx->C, NULL, 0, + hctx->V, dctx->seedlen, NULL, 0, NULL, 0)) + return 0; +#ifdef HASH_DRBG_TRACE + fprintf(stderr, "V+C after reseed:\n"); + hexprint(stderr, hctx->V, dctx->seedlen); + hexprint(stderr, hctx->C, dctx->seedlen); +#endif + return 1; + } + +static int drbg_hash_generate(DRBG_CTX *dctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len) + { + DRBG_HASH_CTX *hctx = &dctx->d.hash; + EVP_MD_CTX *mctx = &hctx->mctx; + unsigned char tmp[4]; + if (adin && adin_len) + { + tmp[0] = 2; + if (!FIPS_digestinit(mctx, hctx->md)) + return 0; + if (!EVP_DigestUpdate(mctx, tmp, 1)) + return 0; + if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen)) + return 0; + if (!EVP_DigestUpdate(mctx, adin, adin_len)) + return 0; + if (!ctx_add_md(dctx)) + return 0; + } + if (!hash_gen(dctx, out, outlen)) + return 0; + + tmp[0] = 3; + if (!FIPS_digestinit(mctx, hctx->md)) + return 0; + if (!EVP_DigestUpdate(mctx, tmp, 1)) + return 0; + if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen)) + return 0; + + if (!ctx_add_md(dctx)) + return 0; + + ctx_add_buf(dctx, hctx->V, hctx->C, dctx->seedlen); + + tmp[0] = (dctx->reseed_counter >> 24) & 0xff; + tmp[1] = (dctx->reseed_counter >> 16) & 0xff; + tmp[2] = (dctx->reseed_counter >> 8) & 0xff; + tmp[3] = dctx->reseed_counter & 0xff; + ctx_add_buf(dctx, hctx->V, tmp, 4); +#ifdef HASH_DRBG_TRACE + fprintf(stderr, "V+C after generate:\n"); + hexprint(stderr, hctx->V, dctx->seedlen); + hexprint(stderr, hctx->C, dctx->seedlen); +#endif + return 1; + } + +static int drbg_hash_uninstantiate(DRBG_CTX *dctx) + { + EVP_MD_CTX_cleanup(&dctx->d.hash.mctx); + OPENSSL_cleanse(&dctx->d.hash, sizeof(DRBG_HASH_CTX)); + return 1; + } + +int fips_drbg_hash_init(DRBG_CTX *dctx) + { + const EVP_MD *md; + DRBG_HASH_CTX *hctx = &dctx->d.hash; + md = FIPS_get_digestbynid(dctx->type); + if (!md) + return -2; + switch (dctx->type) + { + case NID_sha1: + dctx->strength = 128; + break; + + case NID_sha224: + dctx->strength = 192; + break; + + default: + dctx->strength = 256; + break; + } + + dctx->instantiate = drbg_hash_instantiate; + dctx->reseed = drbg_hash_reseed; + dctx->generate = drbg_hash_generate; + dctx->uninstantiate = drbg_hash_uninstantiate; + + dctx->d.hash.md = md; + EVP_MD_CTX_init(&hctx->mctx); + + /* These are taken from SP 800-90 10.1 table 2 */ + + dctx->blocklength = M_EVP_MD_size(md); + if (dctx->blocklength > 32) + dctx->seedlen = 111; + else + dctx->seedlen = 55; + + + dctx->min_entropy = dctx->strength / 8; + dctx->max_entropy = DRBG_MAX_LENGTH; + + dctx->min_nonce = dctx->min_entropy / 2; + dctx->max_nonce = DRBG_MAX_LENGTH; + + dctx->max_pers = DRBG_MAX_LENGTH; + dctx->max_adin = DRBG_MAX_LENGTH; + + dctx->max_request = 1<<16; + dctx->reseed_interval = 1<<24; + + return 1; + } Index: openssl-1.0.1h/crypto/fips/fips_drbg_hmac.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_hmac.c @@ -0,0 +1,281 @@ +/* fips/rand/fips_drbg_hmac.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +#include <stdlib.h> +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/aes.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +static int drbg_hmac_update(DRBG_CTX *dctx, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *in3, size_t in3len + ) + { + static unsigned char c0 = 0, c1 = 1; + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + HMAC_CTX *hctx = &hmac->hctx; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + if (!HMAC_Update(hctx, &c0, 1)) + return 0; + if (in1len && !HMAC_Update(hctx, in1, in1len)) + return 0; + if (in2len && !HMAC_Update(hctx, in2, in2len)) + return 0; + if (in3len && !HMAC_Update(hctx, in3, in3len)) + return 0; + + if (!HMAC_Final(hctx, hmac->K, NULL)) + return 0; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + + if (!HMAC_Final(hctx, hmac->V, NULL)) + return 0; + + if (!in1len && !in2len && !in3len) + return 1; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + if (!HMAC_Update(hctx, &c1, 1)) + return 0; + if (in1len && !HMAC_Update(hctx, in1, in1len)) + return 0; + if (in2len && !HMAC_Update(hctx, in2, in2len)) + return 0; + if (in3len && !HMAC_Update(hctx, in3, in3len)) + return 0; + + if (!HMAC_Final(hctx, hmac->K, NULL)) + return 0; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + + if (!HMAC_Final(hctx, hmac->V, NULL)) + return 0; + + return 1; + + } + +static int drbg_hmac_instantiate(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len) + { + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + memset(hmac->K, 0, dctx->blocklength); + memset(hmac->V, 1, dctx->blocklength); + if (!drbg_hmac_update(dctx, + ent, ent_len, nonce, nonce_len, pstr, pstr_len)) + return 0; + +#ifdef HMAC_DRBG_TRACE + fprintf(stderr, "K+V after instantiate:\n"); + hexprint(stderr, hmac->K, hmac->blocklength); + hexprint(stderr, hmac->V, hmac->blocklength); +#endif + return 1; + } + +static int drbg_hmac_reseed(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adin_len) + { + if (!drbg_hmac_update(dctx, + ent, ent_len, adin, adin_len, NULL, 0)) + return 0; + +#ifdef HMAC_DRBG_TRACE + { + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + fprintf(stderr, "K+V after reseed:\n"); + hexprint(stderr, hmac->K, hmac->blocklength); + hexprint(stderr, hmac->V, hmac->blocklength); + } +#endif + return 1; + } + +static int drbg_hmac_generate(DRBG_CTX *dctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len) + { + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + HMAC_CTX *hctx = &hmac->hctx; + const unsigned char *Vtmp = hmac->V; + if (adin_len && !drbg_hmac_update(dctx, adin, adin_len, + NULL, 0, NULL, 0)) + return 0; + for (;;) + { + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, + hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, Vtmp, dctx->blocklength)) + return 0; + if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) + { + if (!HMAC_Final(hctx, dctx->lb, NULL)) + return 0; + dctx->lb_valid = 1; + Vtmp = dctx->lb; + continue; + } + else if (outlen > dctx->blocklength) + { + if (!HMAC_Final(hctx, out, NULL)) + return 0; + if (!fips_drbg_cprng_test(dctx, out)) + return 0; + Vtmp = out; + } + else + { + if (!HMAC_Final(hctx, hmac->V, NULL)) + return 0; + if (!fips_drbg_cprng_test(dctx, hmac->V)) + return 0; + memcpy(out, hmac->V, outlen); + break; + } + out += dctx->blocklength; + outlen -= dctx->blocklength; + } + if (!drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0)) + return 0; + + return 1; + } + +static int drbg_hmac_uninstantiate(DRBG_CTX *dctx) + { + HMAC_CTX_cleanup(&dctx->d.hmac.hctx); + OPENSSL_cleanse(&dctx->d.hmac, sizeof(DRBG_HMAC_CTX)); + return 1; + } + +int fips_drbg_hmac_init(DRBG_CTX *dctx) + { + const EVP_MD *md = NULL; + DRBG_HMAC_CTX *hctx = &dctx->d.hmac; + dctx->strength = 256; + switch (dctx->type) + { + case NID_hmacWithSHA1: + md = EVP_sha1(); + dctx->strength = 128; + break; + + case NID_hmacWithSHA224: + md = EVP_sha224(); + dctx->strength = 192; + break; + + case NID_hmacWithSHA256: + md = EVP_sha256(); + break; + + case NID_hmacWithSHA384: + md = EVP_sha384(); + break; + + case NID_hmacWithSHA512: + md = EVP_sha512(); + break; + + default: + dctx->strength = 0; + return -2; + } + dctx->instantiate = drbg_hmac_instantiate; + dctx->reseed = drbg_hmac_reseed; + dctx->generate = drbg_hmac_generate; + dctx->uninstantiate = drbg_hmac_uninstantiate; + HMAC_CTX_init(&hctx->hctx); + hctx->md = md; + dctx->blocklength = M_EVP_MD_size(md); + dctx->seedlen = M_EVP_MD_size(md); + + dctx->min_entropy = dctx->strength / 8; + dctx->max_entropy = DRBG_MAX_LENGTH; + + dctx->min_nonce = dctx->min_entropy / 2; + dctx->max_nonce = DRBG_MAX_LENGTH; + + dctx->max_pers = DRBG_MAX_LENGTH; + dctx->max_adin = DRBG_MAX_LENGTH; + + dctx->max_request = 1<<16; + dctx->reseed_interval = 1<<24; + + return 1; + } Index: openssl-1.0.1h/crypto/fips/fips_drbg_lib.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_lib.c @@ -0,0 +1,578 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/fips_rand.h> +#include "fips_locl.h" +#include "fips_rand_lcl.h" + +/* Support framework for SP800-90 DRBGs */ + +int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags) + { + int rv; + memset(dctx, 0, sizeof(DRBG_CTX)); + dctx->status = DRBG_STATUS_UNINITIALISED; + dctx->xflags = flags; + dctx->type = type; + + dctx->iflags = 0; + dctx->entropy_blocklen = 0; + dctx->health_check_cnt = 0; + dctx->health_check_interval = DRBG_HEALTH_INTERVAL; + + rv = fips_drbg_hash_init(dctx); + + if (rv == -2) + rv = fips_drbg_ctr_init(dctx); + if (rv == -2) + rv = fips_drbg_hmac_init(dctx); + + if (rv <= 0) + { + if (rv == -2) + FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_UNSUPPORTED_DRBG_TYPE); + else + FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_ERROR_INITIALISING_DRBG); + } + + /* If not in test mode run selftests on DRBG of the same type */ + + if (!(dctx->xflags & DRBG_FLAG_TEST)) + { + if (!FIPS_drbg_health_check(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_SELFTEST_FAILURE); + return 0; + } + } + + return rv; + } + +DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags) + { + DRBG_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DRBG_CTX)); + if (!dctx) + { + FIPSerr(FIPS_F_FIPS_DRBG_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (type == 0) + { + memset(dctx, 0, sizeof(DRBG_CTX)); + dctx->type = 0; + dctx->status = DRBG_STATUS_UNINITIALISED; + return dctx; + } + + if (FIPS_drbg_init(dctx, type, flags) <= 0) + { + OPENSSL_free(dctx); + return NULL; + } + + return dctx; + } + +void FIPS_drbg_free(DRBG_CTX *dctx) + { + if (dctx->uninstantiate) + dctx->uninstantiate(dctx); + /* Don't free up default DRBG */ + if (dctx == FIPS_get_default_drbg()) + { + memset(dctx, 0, sizeof(DRBG_CTX)); + dctx->type = 0; + dctx->status = DRBG_STATUS_UNINITIALISED; + } + else + { + OPENSSL_cleanse(&dctx->d, sizeof(dctx->d)); + OPENSSL_free(dctx); + } + } + +static size_t fips_get_entropy(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) + { + unsigned char *tout, *p; + size_t bl = dctx->entropy_blocklen, rv; + if (!dctx->get_entropy) + return 0; + if (dctx->xflags & DRBG_FLAG_TEST || !bl) + return dctx->get_entropy(dctx, pout, entropy, min_len, max_len); + rv = dctx->get_entropy(dctx, &tout, entropy + bl, + min_len + bl, max_len + bl); + if (tout == NULL) + return 0; + *pout = tout + bl; + if (rv < (min_len + bl) || (rv % bl)) + return 0; + /* Compare consecutive blocks for continuous PRNG test */ + for (p = tout; p < tout + rv - bl; p += bl) + { + if (!memcmp(p, p + bl, bl)) + { + FIPSerr(FIPS_F_FIPS_GET_ENTROPY, FIPS_R_ENTROPY_SOURCE_STUCK); + return 0; + } + } + rv -= bl; + if (rv > max_len) + return max_len; + return rv; + } + +static void fips_cleanup_entropy(DRBG_CTX *dctx, + unsigned char *out, size_t olen) + { + size_t bl; + if (dctx->xflags & DRBG_FLAG_TEST) + bl = 0; + else + bl = dctx->entropy_blocklen; + /* Call cleanup with original arguments */ + dctx->cleanup_entropy(dctx, out - bl, olen + bl); + } + + +int FIPS_drbg_instantiate(DRBG_CTX *dctx, + const unsigned char *pers, size_t perslen) + { + size_t entlen = 0, noncelen = 0; + unsigned char *nonce = NULL, *entropy = NULL; + +#if 0 + /* Put here so error script picks them up */ + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, + FIPS_R_PERSONALISATION_STRING_TOO_LONG); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_IN_ERROR_STATE); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ALREADY_INSTANTIATED); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_ENTROPY); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_NONCE); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_INSTANTIATE_ERROR); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_DRBG_NOT_INITIALISED); +#endif + + int r = 0; + + if (perslen > dctx->max_pers) + { + r = FIPS_R_PERSONALISATION_STRING_TOO_LONG; + goto end; + } + + if (!dctx->instantiate) + { + r = FIPS_R_DRBG_NOT_INITIALISED; + goto end; + } + + if (dctx->status != DRBG_STATUS_UNINITIALISED) + { + if (dctx->status == DRBG_STATUS_ERROR) + r = FIPS_R_IN_ERROR_STATE; + else + r = FIPS_R_ALREADY_INSTANTIATED; + goto end; + } + + dctx->status = DRBG_STATUS_ERROR; + + entlen = fips_get_entropy(dctx, &entropy, dctx->strength, + dctx->min_entropy, dctx->max_entropy); + + if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) + { + r = FIPS_R_ERROR_RETRIEVING_ENTROPY; + goto end; + } + + if (dctx->max_nonce > 0 && dctx->get_nonce) + { + noncelen = dctx->get_nonce(dctx, &nonce, + dctx->strength / 2, + dctx->min_nonce, dctx->max_nonce); + + if (noncelen < dctx->min_nonce || noncelen > dctx->max_nonce) + { + r = FIPS_R_ERROR_RETRIEVING_NONCE; + goto end; + } + + } + + if (!dctx->instantiate(dctx, + entropy, entlen, + nonce, noncelen, + pers, perslen)) + { + r = FIPS_R_ERROR_INSTANTIATING_DRBG; + goto end; + } + + + dctx->status = DRBG_STATUS_READY; + if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) + dctx->reseed_counter = 1; + + end: + + if (entropy && dctx->cleanup_entropy) + fips_cleanup_entropy(dctx, entropy, entlen); + + if (nonce && dctx->cleanup_nonce) + dctx->cleanup_nonce(dctx, nonce, noncelen); + + if (dctx->status == DRBG_STATUS_READY) + return 1; + + if (r && !(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, r); + + return 0; + + } + +static int drbg_reseed(DRBG_CTX *dctx, + const unsigned char *adin, size_t adinlen, int hcheck) + { + unsigned char *entropy = NULL; + size_t entlen = 0; + int r = 0; + +#if 0 + FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_NOT_INSTANTIATED); + FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_ADDITIONAL_INPUT_TOO_LONG); +#endif + if (dctx->status != DRBG_STATUS_READY + && dctx->status != DRBG_STATUS_RESEED) + { + if (dctx->status == DRBG_STATUS_ERROR) + r = FIPS_R_IN_ERROR_STATE; + else if(dctx->status == DRBG_STATUS_UNINITIALISED) + r = FIPS_R_NOT_INSTANTIATED; + goto end; + } + + if (!adin) + adinlen = 0; + else if (adinlen > dctx->max_adin) + { + r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG; + goto end; + } + + dctx->status = DRBG_STATUS_ERROR; + /* Peform health check on all reseed operations if not a prediction + * resistance request and not in test mode. + */ + if (hcheck && !(dctx->xflags & DRBG_FLAG_TEST)) + { + if (!FIPS_drbg_health_check(dctx)) + { + r = FIPS_R_SELFTEST_FAILURE; + goto end; + } + } + + entlen = fips_get_entropy(dctx, &entropy, dctx->strength, + dctx->min_entropy, dctx->max_entropy); + + if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) + { + r = FIPS_R_ERROR_RETRIEVING_ENTROPY; + goto end; + } + + if (!dctx->reseed(dctx, entropy, entlen, adin, adinlen)) + goto end; + + dctx->status = DRBG_STATUS_READY; + if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) + dctx->reseed_counter = 1; + end: + + if (entropy && dctx->cleanup_entropy) + fips_cleanup_entropy(dctx, entropy, entlen); + + if (dctx->status == DRBG_STATUS_READY) + return 1; + + if (r && !(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_DRBG_RESEED, r); + + return 0; + } + +int FIPS_drbg_reseed(DRBG_CTX *dctx, + const unsigned char *adin, size_t adinlen) + { + return drbg_reseed(dctx, adin, adinlen, 1); + } + +static int fips_drbg_check(DRBG_CTX *dctx) + { + if (dctx->xflags & DRBG_FLAG_TEST) + return 1; + dctx->health_check_cnt++; + if (dctx->health_check_cnt >= dctx->health_check_interval) + { + if (!FIPS_drbg_health_check(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_CHECK, FIPS_R_SELFTEST_FAILURE); + return 0; + } + } + return 1; + } + +int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen) + { + int r = 0; + + if (FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, FIPS_R_SELFTEST_FAILED); + return 0; + } + + if (!fips_drbg_check(dctx)) + return 0; + + if (dctx->status != DRBG_STATUS_READY + && dctx->status != DRBG_STATUS_RESEED) + { + if (dctx->status == DRBG_STATUS_ERROR) + r = FIPS_R_IN_ERROR_STATE; + else if(dctx->status == DRBG_STATUS_UNINITIALISED) + r = FIPS_R_NOT_INSTANTIATED; + goto end; + } + + if (outlen > dctx->max_request) + { + r = FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG; + return 0; + } + + if (adinlen > dctx->max_adin) + { + r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG; + goto end; + } + + if (dctx->iflags & DRBG_CUSTOM_RESEED) + dctx->generate(dctx, NULL, outlen, NULL, 0); + else if (dctx->reseed_counter >= dctx->reseed_interval) + dctx->status = DRBG_STATUS_RESEED; + + if (dctx->status == DRBG_STATUS_RESEED || prediction_resistance) + { + /* If prediction resistance request don't do health check */ + int hcheck = prediction_resistance ? 0 : 1; + + if (!drbg_reseed(dctx, adin, adinlen, hcheck)) + { + r = FIPS_R_RESEED_ERROR; + goto end; + } + adin = NULL; + adinlen = 0; + } + + if (!dctx->generate(dctx, out, outlen, adin, adinlen)) + { + r = FIPS_R_GENERATE_ERROR; + dctx->status = DRBG_STATUS_ERROR; + goto end; + } + if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) + { + if (dctx->reseed_counter >= dctx->reseed_interval) + dctx->status = DRBG_STATUS_RESEED; + else + dctx->reseed_counter++; + } + + end: + if (r) + { + if (!(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r); + return 0; + } + + return 1; + } + +int FIPS_drbg_uninstantiate(DRBG_CTX *dctx) + { + int rv; + if (!dctx->uninstantiate) + rv = 1; + else + rv = dctx->uninstantiate(dctx); + /* Although we'd like to cleanse here we can't because we have to + * test the uninstantiate really zeroes the data. + */ + memset(&dctx->d, 0, sizeof(dctx->d)); + dctx->status = DRBG_STATUS_UNINITIALISED; + /* If method has problems uninstantiating, return error */ + return rv; + } + +int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len), + void (*cleanup_entropy)(DRBG_CTX *ctx, unsigned char *out, size_t olen), + size_t entropy_blocklen, + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len), + void (*cleanup_nonce)(DRBG_CTX *ctx, unsigned char *out, size_t olen)) + { + if (dctx->status != DRBG_STATUS_UNINITIALISED) + return 0; + dctx->entropy_blocklen = entropy_blocklen; + dctx->get_entropy = get_entropy; + dctx->cleanup_entropy = cleanup_entropy; + dctx->get_nonce = get_nonce; + dctx->cleanup_nonce = cleanup_nonce; + return 1; + } + +int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx, + size_t (*get_adin)(DRBG_CTX *ctx, unsigned char **pout), + void (*cleanup_adin)(DRBG_CTX *ctx, unsigned char *out, size_t olen), + int (*rand_seed_cb)(DRBG_CTX *ctx, const void *buf, int num), + int (*rand_add_cb)(DRBG_CTX *ctx, + const void *buf, int num, double entropy)) + { + if (dctx->status != DRBG_STATUS_UNINITIALISED) + return 0; + dctx->get_adin = get_adin; + dctx->cleanup_adin = cleanup_adin; + dctx->rand_seed_cb = rand_seed_cb; + dctx->rand_add_cb = rand_add_cb; + return 1; + } + +void *FIPS_drbg_get_app_data(DRBG_CTX *dctx) + { + return dctx->app_data; + } + +void FIPS_drbg_set_app_data(DRBG_CTX *dctx, void *app_data) + { + dctx->app_data = app_data; + } + +size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx) + { + return dctx->blocklength; + } + +int FIPS_drbg_get_strength(DRBG_CTX *dctx) + { + return dctx->strength; + } + +void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval) + { + dctx->health_check_interval = interval; + } + +void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval) + { + dctx->reseed_interval = interval; + } + +static int drbg_stick = 0; + +void FIPS_drbg_stick(int onoff) + { + drbg_stick = onoff; + } + +/* Continuous DRBG utility function */ +int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out) + { + /* No CPRNG in test mode */ + if (dctx->xflags & DRBG_FLAG_TEST) + return 1; + /* Check block is valid: should never happen */ + if (dctx->lb_valid == 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_CPRNG_TEST, FIPS_R_INTERNAL_ERROR); + fips_set_selftest_fail(); + return 0; + } + if (drbg_stick) + memcpy(dctx->lb, out, dctx->blocklength); + /* Check against last block: fail if match */ + if (!memcmp(dctx->lb, out, dctx->blocklength)) + { + FIPSerr(FIPS_F_FIPS_DRBG_CPRNG_TEST, FIPS_R_DRBG_STUCK); + fips_set_selftest_fail(); + return 0; + } + /* Save last block for next comparison */ + memcpy(dctx->lb, out, dctx->blocklength); + return 1; + } Index: openssl-1.0.1h/crypto/fips/fips_drbg_rand.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_rand.c @@ -0,0 +1,172 @@ +/* fips/rand/fips_drbg_rand.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +/* Mapping of SP800-90 DRBGs to OpenSSL RAND_METHOD */ + +/* Since we only have one global PRNG used at any time in OpenSSL use a global + * variable to store context. + */ + +static DRBG_CTX ossl_dctx; + +DRBG_CTX *FIPS_get_default_drbg(void) + { + return &ossl_dctx; + } + +static int fips_drbg_bytes(unsigned char *out, int count) + { + DRBG_CTX *dctx = &ossl_dctx; + int rv = 0; + unsigned char *adin = NULL; + size_t adinlen = 0; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + do + { + size_t rcnt; + if (count > (int)dctx->max_request) + rcnt = dctx->max_request; + else + rcnt = count; + if (dctx->get_adin) + { + adinlen = dctx->get_adin(dctx, &adin); + if (adinlen && !adin) + { + FIPSerr(FIPS_F_FIPS_DRBG_BYTES, FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT); + goto err; + } + } + rv = FIPS_drbg_generate(dctx, out, rcnt, 0, adin, adinlen); + if (adin) + { + if (dctx->cleanup_adin) + dctx->cleanup_adin(dctx, adin, adinlen); + adin = NULL; + } + if (!rv) + goto err; + out += rcnt; + count -= rcnt; + } + while (count); + rv = 1; + err: + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return rv; + } + +static int fips_drbg_pseudo(unsigned char *out, int count) + { + if (fips_drbg_bytes(out, count) <= 0) + return -1; + return 1; + } + +static int fips_drbg_status(void) + { + DRBG_CTX *dctx = &ossl_dctx; + int rv; + CRYPTO_r_lock(CRYPTO_LOCK_RAND); + rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; + CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + return rv; + } + +static void fips_drbg_cleanup(void) + { + DRBG_CTX *dctx = &ossl_dctx; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + FIPS_drbg_uninstantiate(dctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + +static int fips_drbg_seed(const void *seed, int seedlen) + { + DRBG_CTX *dctx = &ossl_dctx; + if (dctx->rand_seed_cb) + return dctx->rand_seed_cb(dctx, seed, seedlen); + return 1; + } + +static int fips_drbg_add(const void *seed, int seedlen, + double add_entropy) + { + DRBG_CTX *dctx = &ossl_dctx; + if (dctx->rand_add_cb) + return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); + return 1; + } + +static const RAND_METHOD rand_drbg_meth = + { + fips_drbg_seed, + fips_drbg_bytes, + fips_drbg_cleanup, + fips_drbg_add, + fips_drbg_pseudo, + fips_drbg_status + }; + +const RAND_METHOD *FIPS_drbg_method(void) + { + return &rand_drbg_meth; + } + Index: openssl-1.0.1h/crypto/fips/fips_drbg_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_selftest.c @@ -0,0 +1,862 @@ +/* fips/rand/fips_drbg_selftest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" +#include "fips_locl.h" + +#include "fips_drbg_selftest.h" + +typedef struct { + int post; + int nid; + unsigned int flags; + + /* KAT data for no PR */ + const unsigned char *ent; + size_t entlen; + const unsigned char *nonce; + size_t noncelen; + const unsigned char *pers; + size_t perslen; + const unsigned char *adin; + size_t adinlen; + const unsigned char *entreseed; + size_t entreseedlen; + const unsigned char *adinreseed; + size_t adinreseedlen; + const unsigned char *adin2; + size_t adin2len; + const unsigned char *kat; + size_t katlen; + const unsigned char *kat2; + size_t kat2len; + + /* KAT data for PR */ + const unsigned char *ent_pr; + size_t entlen_pr; + const unsigned char *nonce_pr; + size_t noncelen_pr; + const unsigned char *pers_pr; + size_t perslen_pr; + const unsigned char *adin_pr; + size_t adinlen_pr; + const unsigned char *entpr_pr; + size_t entprlen_pr; + const unsigned char *ading_pr; + size_t adinglen_pr; + const unsigned char *entg_pr; + size_t entglen_pr; + const unsigned char *kat_pr; + size_t katlen_pr; + const unsigned char *kat2_pr; + size_t kat2len_pr; + + } DRBG_SELFTEST_DATA; + +#define make_drbg_test_data(nid, flag, pr, p) {p, nid, flag | DRBG_FLAG_TEST, \ + pr##_entropyinput, sizeof(pr##_entropyinput), \ + pr##_nonce, sizeof(pr##_nonce), \ + pr##_personalizationstring, sizeof(pr##_personalizationstring), \ + pr##_additionalinput, sizeof(pr##_additionalinput), \ + pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \ + pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \ + pr##_additionalinput2, sizeof(pr##_additionalinput2), \ + pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \ + pr##_returnedbits, sizeof(pr##_returnedbits), \ + pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \ + pr##_pr_nonce, sizeof(pr##_pr_nonce), \ + pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \ + pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \ + pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \ + pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \ + pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \ + pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \ + pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits), \ + } + +#define make_drbg_test_data_df(nid, pr, p) \ + make_drbg_test_data(nid, DRBG_FLAG_CTR_USE_DF, pr, p) + +#define make_drbg_test_data_ec(curve, md, pr, p) \ + make_drbg_test_data((curve << 16) | md , 0, pr, p) + +static DRBG_SELFTEST_DATA drbg_test[] = { + make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0), + make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0), + make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1), + make_drbg_test_data(NID_aes_128_ctr, 0, aes_128_no_df, 0), + make_drbg_test_data(NID_aes_192_ctr, 0, aes_192_no_df, 0), + make_drbg_test_data(NID_aes_256_ctr, 0, aes_256_no_df, 1), + make_drbg_test_data(NID_sha1, 0, sha1, 0), + make_drbg_test_data(NID_sha224, 0, sha224, 0), + make_drbg_test_data(NID_sha256, 0, sha256, 1), + make_drbg_test_data(NID_sha384, 0, sha384, 0), + make_drbg_test_data(NID_sha512, 0, sha512, 0), + make_drbg_test_data(NID_hmacWithSHA1, 0, hmac_sha1, 0), + make_drbg_test_data(NID_hmacWithSHA224, 0, hmac_sha224, 0), + make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256, 1), + make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384, 0), + make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512, 0), + {0,0,0} + }; + +typedef struct + { + const unsigned char *ent; + size_t entlen; + int entcnt; + const unsigned char *nonce; + size_t noncelen; + int noncecnt; + } TEST_ENT; + +static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) + { + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + *pout = (unsigned char *)t->ent; + t->entcnt++; + return t->entlen; + } + +static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) + { + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + *pout = (unsigned char *)t->nonce; + t->noncecnt++; + return t->noncelen; + } + +static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, + int quick) + { + TEST_ENT t; + int rv = 0; + size_t adinlen; + unsigned char randout[1024]; + + /* Initial test without PR */ + + /* Instantiate DRBG with test entropy, nonce and personalisation + * string. + */ + + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, &t); + + t.ent = td->ent; + t.entlen = td->entlen; + t.nonce = td->nonce; + t.noncelen = td->noncelen; + t.entcnt = 0; + t.noncecnt = 0; + + if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + goto err; + + /* Note for CTR without DF some additional input values + * ignore bytes after the keylength: so reduce adinlen + * to half to ensure invalid data is fed in. + */ + if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) + adinlen = td->adinlen / 2; + else + adinlen = td->adinlen; + + /* Generate with no PR and verify output matches expected data */ + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, adinlen)) + goto err; + + if (memcmp(randout, td->kat, td->katlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE); + goto err2; + } + /* If abbreviated POST end of test */ + if (quick) + { + rv = 1; + goto err; + } + /* Reseed DRBG with test entropy and additional input */ + t.ent = td->entreseed; + t.entlen = td->entreseedlen; + + if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen)) + goto err; + + /* Generate with no PR and verify output matches expected data */ + if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0, + td->adin2, td->adin2len)) + goto err; + + if (memcmp(randout, td->kat2, td->kat2len)) + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE); + goto err2; + } + + FIPS_drbg_uninstantiate(dctx); + + /* Now test with PR */ + + /* Instantiate DRBG with test entropy, nonce and personalisation + * string. + */ + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, &t); + + t.ent = td->ent_pr; + t.entlen = td->entlen_pr; + t.nonce = td->nonce_pr; + t.noncelen = td->noncelen_pr; + t.entcnt = 0; + t.noncecnt = 0; + + if (!FIPS_drbg_instantiate(dctx, td->pers_pr, td->perslen_pr)) + goto err; + + /* Now generate with PR: we need to supply entropy as this will + * perform a reseed operation. Check output matches expected value. + */ + + t.ent = td->entpr_pr; + t.entlen = td->entprlen_pr; + + /* Note for CTR without DF some additional input values + * ignore bytes after the keylength: so reduce adinlen + * to half to ensure invalid data is fed in. + */ + if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) + adinlen = td->adinlen_pr / 2; + else + adinlen = td->adinlen_pr; + if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1, + td->adin_pr, adinlen)) + goto err; + + if (memcmp(randout, td->kat_pr, td->katlen_pr)) + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE); + goto err2; + } + + /* Now generate again with PR: supply new entropy again. + * Check output matches expected value. + */ + + t.ent = td->entg_pr; + t.entlen = td->entglen_pr; + + if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1, + td->ading_pr, td->adinglen_pr)) + goto err; + + if (memcmp(randout, td->kat2_pr, td->kat2len_pr)) + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE); + goto err2; + } + /* All OK, test complete */ + rv = 1; + + err: + if (rv == 0) + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED); + err2: + FIPS_drbg_uninstantiate(dctx); + + return rv; + + } + +/* Initialise a DRBG based on selftest data */ + +static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, TEST_ENT *t) + { + + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, t); + + t->ent = td->ent; + t->entlen = td->entlen; + t->nonce = td->nonce; + t->noncelen = td->noncelen; + t->entcnt = 0; + t->noncecnt = 0; + return 1; + } + +/* Initialise and instantiate DRBG based on selftest data */ +static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, + TEST_ENT *t) + { + if (!do_drbg_init(dctx, td, t)) + return 0; + if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + return 0; + + return 1; + } + +/* This function performs extensive error checking as required by SP800-90. + * Induce several failure modes and check an error condition is set. + * This function along with fips_drbg_single_kat peforms the health checking + * operation. + */ + +static int fips_drbg_error_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) + { + unsigned char randout[1024]; + TEST_ENT t; + size_t i; + unsigned int reseed_counter_tmp; + unsigned char *p = (unsigned char *)dctx; + + /* Initialise DRBG */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + /* Don't report induced errors */ + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Personalisation string tests */ + + /* Test detection of too large personlisation string */ + + if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_PERSONALISATION_ERROR_UNDETECTED); + goto err; + } + + /* Entropy source tests */ + + /* Test entropy source failure detecion: i.e. returns no data */ + + t.entlen = 0; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + /* Try to generate output from uninstantiated DRBG */ + if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_GENERATE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Test insufficient entropy */ + + t.entlen = dctx->min_entropy - 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test too much entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->max_entropy + 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Nonce tests */ + + /* Test too small nonce */ + + if (dctx->min_nonce) + { + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.noncelen = dctx->min_nonce - 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + } + + /* Test too large nonce */ + + if (dctx->max_nonce) + { + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.noncelen = dctx->max_nonce + 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + } + + /* Instantiate with valid data. */ + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + + /* Check generation is now OK */ + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Request too much data for one request */ + if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0, + td->adin, td->adinlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED); + goto err; + } + + /* Try too large additional input */ + if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, dctx->max_adin + 1)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); + goto err; + } + + /* Check prediction resistance request fails if entropy source + * failure. + */ + + t.entlen = 0; + + if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, + td->adin, td->adinlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + + /* Instantiate again with valid data */ + + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + /* Test reseed counter works */ + /* Save initial reseed counter */ + reseed_counter_tmp = dctx->reseed_counter; + /* Set reseed counter to beyond interval */ + dctx->reseed_counter = dctx->reseed_interval; + + /* Generate output and check entropy has been requested for reseed */ + t.entcnt = 0; + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + if (t.entcnt != 1) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); + goto err; + } + /* Check reseed counter has been reset */ + if (dctx->reseed_counter != reseed_counter_tmp + 1) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Check prediction resistance request fails if entropy source + * failure. + */ + + t.entlen = 0; + + dctx->iflags |= DRBG_FLAG_NOERR; + if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, + td->adin, td->adinlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + /* Test reseed counter works */ + /* Save initial reseed counter */ + reseed_counter_tmp = dctx->reseed_counter; + /* Set reseed counter to beyond interval */ + dctx->reseed_counter = dctx->reseed_interval; + + /* Generate output and check entropy has been requested for reseed */ + t.entcnt = 0; + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + if (t.entcnt != 1) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); + goto err; + } + /* Check reseed counter has been reset */ + if (dctx->reseed_counter != reseed_counter_tmp + 1) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Explicit reseed tests */ + + /* Test explicit reseed with too large additional input */ + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); + goto err; + } + + /* Test explicit reseed with entropy source failure */ + + t.entlen = 0; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test explicit reseed with too much entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->max_entropy + 1; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test explicit reseed with too little entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->min_entropy - 1; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + p = (unsigned char *)&dctx->d; + /* Standard says we have to check uninstantiate really zeroes + * the data... + */ + for (i = 0; i < sizeof(dctx->d); i++) + { + if (*p != 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ZEROISE_ERROR); + goto err; + } + p++; + } + + return 1; + + err: + /* A real error as opposed to an induced one: underlying function will + * indicate the error. + */ + if (!(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_FUNCTION_ERROR); + FIPS_drbg_uninstantiate(dctx); + return 0; + + } + +int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags) + { + DRBG_SELFTEST_DATA *td; + flags |= DRBG_FLAG_TEST; + for (td = drbg_test; td->nid != 0; td++) + { + if (td->nid == nid && td->flags == flags) + { + if (!fips_drbg_single_kat(dctx, td, 0)) + return 0; + return fips_drbg_error_check(dctx, td); + } + } + return 0; + } + +int FIPS_drbg_health_check(DRBG_CTX *dctx) + { + int rv; + DRBG_CTX *tctx = NULL; + tctx = FIPS_drbg_new(0, 0); + fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + if (!tctx) + return 0; + rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags); + if (tctx) + FIPS_drbg_free(tctx); + if (rv) + fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + else + fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + if (!rv) + dctx->status = DRBG_STATUS_ERROR; + else + dctx->health_check_cnt = 0; + return rv; + } + +int FIPS_selftest_drbg(void) + { + DRBG_CTX *dctx; + DRBG_SELFTEST_DATA *td; + int rv = 1; + dctx = FIPS_drbg_new(0, 0); + if (!dctx) + return 0; + for (td = drbg_test; td->nid != 0; td++) + { + if (td->post != 1) + continue; + if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 1; + if (!fips_drbg_single_kat(dctx, td, 1)) + { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 0; + } + FIPS_drbg_free(dctx); + return rv; + } + + +int FIPS_selftest_drbg_all(void) + { + DRBG_CTX *dctx; + DRBG_SELFTEST_DATA *td; + int rv = 1; + dctx = FIPS_drbg_new(0, 0); + if (!dctx) + return 0; + for (td = drbg_test; td->nid != 0; td++) + { + if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 1; + if (!fips_drbg_single_kat(dctx, td, 0)) + { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_drbg_error_check(dctx, td)) + { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 0; + } + FIPS_drbg_free(dctx); + return rv; + } + Index: openssl-1.0.1h/crypto/fips/fips_drbg_selftest.h =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_drbg_selftest.h @@ -0,0 +1,2335 @@ +/* ==================================================================== + * Copyright (c) 2011 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.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. + * + */ + +/* Selftest and health check data for the SP800-90 DRBG */ + +#define __fips_constseg + +/* AES-128 use df PR */ +__fips_constseg +static const unsigned char aes_128_use_df_pr_entropyinput[] = + { + 0x61,0x52,0x7c,0xe3,0x23,0x7d,0x0a,0x07,0x10,0x0c,0x50,0x33, + 0xc8,0xdb,0xff,0x12 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_nonce[] = + { + 0x51,0x0d,0x85,0x77,0xed,0x22,0x97,0x28 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_personalizationstring[] = + { + 0x59,0x9f,0xbb,0xcd,0xd5,0x25,0x69,0xb5,0xcb,0xb5,0x03,0xfe, + 0xd7,0xd7,0x01,0x67 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_additionalinput[] = + { + 0xef,0x88,0x76,0x01,0xaf,0x3c,0xfe,0x8b,0xaf,0x26,0x06,0x9e, + 0x9a,0x47,0x08,0x76 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_entropyinputpr[] = + { + 0xe2,0x76,0xf9,0xf6,0x3a,0xba,0x10,0x9f,0xbf,0x47,0x0e,0x51, + 0x09,0xfb,0xa3,0xb6 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_int_returnedbits[] = + { + 0xd4,0x98,0x8a,0x46,0x80,0x4c,0xdb,0xa3,0x59,0x02,0x57,0x52, + 0x66,0x1c,0xea,0x5b + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_additionalinput2[] = + { + 0x88,0x8c,0x91,0xd6,0xbe,0x56,0x6e,0x08,0x9a,0x62,0x2b,0x11, + 0x3f,0x5e,0x31,0x06 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_entropyinputpr2[] = + { + 0xc0,0x5c,0x6b,0x98,0x01,0x0d,0x58,0x18,0x51,0x18,0x96,0xae, + 0xa7,0xe3,0xa8,0x67 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_pr_returnedbits[] = + { + 0xcf,0x01,0xac,0x22,0x31,0x06,0x8e,0xfc,0xce,0x56,0xea,0x24, + 0x0f,0x38,0x43,0xc6 + }; + + +/* AES-128 use df No PR */ +__fips_constseg +static const unsigned char aes_128_use_df_entropyinput[] = + { + 0x1f,0x8e,0x34,0x82,0x0c,0xb7,0xbe,0xc5,0x01,0x3e,0xd0,0xa3, + 0x9d,0x7d,0x1c,0x9b + }; + +__fips_constseg +static const unsigned char aes_128_use_df_nonce[] = + { + 0xd5,0x4d,0xbd,0x4a,0x93,0x7f,0xb8,0x96 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_personalizationstring[] = + { + 0xab,0xd6,0x3f,0x04,0xfe,0x27,0x6b,0x2d,0xd7,0xc3,0x1c,0xf3, + 0x38,0x66,0xba,0x1b + }; + +__fips_constseg +static const unsigned char aes_128_use_df_additionalinput[] = + { + 0xfe,0xf4,0x09,0xa8,0xb7,0x73,0x27,0x9c,0x5f,0xa7,0xea,0x46, + 0xb5,0xe2,0xb2,0x41 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_int_returnedbits[] = + { + 0x42,0xe4,0x4e,0x7b,0x27,0xdd,0xcb,0xbc,0x0a,0xcf,0xa6,0x67, + 0xe7,0x57,0x11,0xb4 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_entropyinputreseed[] = + { + 0x14,0x26,0x69,0xd9,0xf3,0x65,0x03,0xd6,0x6b,0xb9,0x44,0x0b, + 0xc7,0xc4,0x9e,0x39 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_additionalinputreseed[] = + { + 0x55,0x2e,0x60,0x9a,0x05,0x72,0x8a,0xa8,0xef,0x22,0x81,0x5a, + 0xc8,0x93,0xfa,0x84 + }; + +__fips_constseg +static const unsigned char aes_128_use_df_additionalinput2[] = + { + 0x3c,0x40,0xc8,0xc4,0x16,0x0c,0x21,0xa4,0x37,0x2c,0x8f,0xa5, + 0x06,0x0c,0x15,0x2c + }; + +__fips_constseg +static const unsigned char aes_128_use_df_returnedbits[] = + { + 0xe1,0x3e,0x99,0x98,0x86,0x67,0x0b,0x63,0x7b,0xbe,0x3f,0x88, + 0x46,0x81,0xc7,0x19 + }; + + +/* AES-192 use df PR */ +__fips_constseg +static const unsigned char aes_192_use_df_pr_entropyinput[] = + { + 0x2b,0x4e,0x8b,0xe1,0xf1,0x34,0x80,0x56,0x81,0xf9,0x74,0xec, + 0x17,0x44,0x2a,0xf1,0x14,0xb0,0xbf,0x97,0x39,0xb7,0x04,0x7d + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_nonce[] = + { + 0xd6,0x9d,0xeb,0x14,0x4e,0x6c,0x30,0x1e,0x39,0x55,0x73,0xd0, + 0xd1,0x80,0x78,0xfa + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_personalizationstring[] = + { + 0xfc,0x43,0x4a,0xf8,0x9a,0x55,0xb3,0x53,0x83,0xe2,0x18,0x16, + 0x0c,0xdc,0xcd,0x5e,0x4f,0xa0,0x03,0x01,0x2b,0x9f,0xe4,0xd5, + 0x7d,0x49,0xf0,0x41,0x9e,0x3d,0x99,0x04 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_additionalinput[] = + { + 0x5e,0x9f,0x49,0x6f,0x21,0x8b,0x1d,0x32,0xd5,0x84,0x5c,0xac, + 0xaf,0xdf,0xe4,0x79,0x9e,0xaf,0xa9,0x82,0xd0,0xf8,0x4f,0xcb, + 0x69,0x10,0x0a,0x7e,0x81,0x57,0xb5,0x36 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_entropyinputpr[] = + { + 0xd4,0x81,0x0c,0xd7,0x66,0x39,0xec,0x42,0x53,0x87,0x41,0xa5, + 0x1e,0x7d,0x80,0x91,0x8e,0xbb,0xed,0xac,0x14,0x02,0x1a,0xd5 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_int_returnedbits[] = + { + 0xdf,0x1d,0x39,0x45,0x7c,0x9b,0xc6,0x2b,0x7d,0x8c,0x93,0xe9, + 0x19,0x30,0x6b,0x67 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_additionalinput2[] = + { + 0x00,0x71,0x27,0x4e,0xd3,0x14,0xf1,0x20,0x7f,0x4a,0x41,0x32, + 0x2a,0x97,0x11,0x43,0x8f,0x4a,0x15,0x7b,0x9b,0x51,0x79,0xda, + 0x49,0x3d,0xde,0xe8,0xbc,0x93,0x91,0x99 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_entropyinputpr2[] = + { + 0x90,0xee,0x76,0xa1,0x45,0x8d,0xb7,0x40,0xb0,0x11,0xbf,0xd0, + 0x65,0xd7,0x3c,0x7c,0x4f,0x20,0x3f,0x4e,0x11,0x9d,0xb3,0x5e + }; + +__fips_constseg +static const unsigned char aes_192_use_df_pr_returnedbits[] = + { + 0x24,0x3b,0x20,0xa4,0x37,0x66,0xba,0x72,0x39,0x3f,0xcf,0x3c, + 0x7e,0x1a,0x2b,0x83 + }; + + +/* AES-192 use df No PR */ +__fips_constseg +static const unsigned char aes_192_use_df_entropyinput[] = + { + 0x8d,0x74,0xa4,0x50,0x1a,0x02,0x68,0x0c,0x2a,0x69,0xc4,0x82, + 0x3b,0xbb,0xda,0x0e,0x7f,0x77,0xa3,0x17,0x78,0x57,0xb2,0x7b + }; + +__fips_constseg +static const unsigned char aes_192_use_df_nonce[] = + { + 0x75,0xd5,0x1f,0xac,0xa4,0x8d,0x42,0x78,0xd7,0x69,0x86,0x9d, + 0x77,0xd7,0x41,0x0e + }; + +__fips_constseg +static const unsigned char aes_192_use_df_personalizationstring[] = + { + 0x4e,0x33,0x41,0x3c,0x9c,0xc2,0xd2,0x53,0xaf,0x90,0xea,0xcf, + 0x19,0x50,0x1e,0xe6,0x6f,0x63,0xc8,0x32,0x22,0xdc,0x07,0x65, + 0x9c,0xd3,0xf8,0x30,0x9e,0xed,0x35,0x70 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_additionalinput[] = + { + 0x5d,0x8b,0x8c,0xc1,0xdf,0x0e,0x02,0x78,0xfb,0x19,0xb8,0x69, + 0x78,0x4e,0x9c,0x52,0xbc,0xc7,0x20,0xc9,0xe6,0x5e,0x77,0x22, + 0x28,0x3d,0x0c,0x9e,0x68,0xa8,0x45,0xd7 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_int_returnedbits[] = + { + 0xd5,0xe7,0x08,0xc5,0x19,0x99,0xd5,0x31,0x03,0x0a,0x74,0xb6, + 0xb7,0xed,0xe9,0xea + }; + +__fips_constseg +static const unsigned char aes_192_use_df_entropyinputreseed[] = + { + 0x9c,0x26,0xda,0xf1,0xac,0xd9,0x5a,0xd6,0xa8,0x65,0xf5,0x02, + 0x8f,0xdc,0xa2,0x09,0x54,0xa6,0xe2,0xa4,0xde,0x32,0xe0,0x01 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_additionalinputreseed[] = + { + 0x9b,0x90,0xb0,0x3a,0x0e,0x3a,0x80,0x07,0x4a,0xf4,0xda,0x76, + 0x28,0x30,0x3c,0xee,0x54,0x1b,0x94,0x59,0x51,0x43,0x56,0x77, + 0xaf,0x88,0xdd,0x63,0x89,0x47,0x06,0x65 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_additionalinput2[] = + { + 0x3c,0x11,0x64,0x7a,0x96,0xf5,0xd8,0xb8,0xae,0xd6,0x70,0x4e, + 0x16,0x96,0xde,0xe9,0x62,0xbc,0xee,0x28,0x2f,0x26,0xa6,0xf0, + 0x56,0xef,0xa3,0xf1,0x6b,0xa1,0xb1,0x77 + }; + +__fips_constseg +static const unsigned char aes_192_use_df_returnedbits[] = + { + 0x0b,0xe2,0x56,0x03,0x1e,0xdb,0x2c,0x6d,0x7f,0x1b,0x15,0x58, + 0x1a,0xf9,0x13,0x28 + }; + + +/* AES-256 use df PR */ +__fips_constseg +static const unsigned char aes_256_use_df_pr_entropyinput[] = + { + 0x61,0x68,0xfc,0x1a,0xf0,0xb5,0x95,0x6b,0x85,0x09,0x9b,0x74, + 0x3f,0x13,0x78,0x49,0x3b,0x85,0xec,0x93,0x13,0x3b,0xa9,0x4f, + 0x96,0xab,0x2c,0xe4,0xc8,0x8f,0xdd,0x6a + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_nonce[] = + { + 0xad,0xd2,0xbb,0xba,0xb7,0x65,0x89,0xc3,0x21,0x6c,0x55,0x33, + 0x2b,0x36,0xff,0xa4 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_personalizationstring[] = + { + 0x6e,0xca,0xe7,0x20,0x72,0xd3,0x84,0x5a,0x32,0xd3,0x4b,0x24, + 0x72,0xc4,0x63,0x2b,0x9d,0x12,0x24,0x0c,0x23,0x26,0x8e,0x83, + 0x16,0x37,0x0b,0xd1,0x06,0x4f,0x68,0x6d + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_additionalinput[] = + { + 0x7e,0x08,0x4a,0xbb,0xe3,0x21,0x7c,0xc9,0x23,0xd2,0xf8,0xb0, + 0x73,0x98,0xba,0x84,0x74,0x23,0xab,0x06,0x8a,0xe2,0x22,0xd3, + 0x7b,0xce,0x9b,0xd2,0x4a,0x76,0xb8,0xde + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_entropyinputpr[] = + { + 0x0b,0x23,0xaf,0xdf,0xf1,0x62,0xd7,0xd3,0x43,0x97,0xf8,0x77, + 0x04,0xa8,0x42,0x20,0xbd,0xf6,0x0f,0xc1,0x17,0x2f,0x9f,0x54, + 0xbb,0x56,0x17,0x86,0x68,0x0e,0xba,0xa9 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_int_returnedbits[] = + { + 0x31,0x8e,0xad,0xaf,0x40,0xeb,0x6b,0x74,0x31,0x46,0x80,0xc7, + 0x17,0xab,0x3c,0x7a + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_additionalinput2[] = + { + 0x94,0x6b,0xc9,0x9f,0xab,0x8d,0xc5,0xec,0x71,0x88,0x1d,0x00, + 0x8c,0x89,0x68,0xe4,0xc8,0x07,0x77,0x36,0x17,0x6d,0x79,0x78, + 0xc7,0x06,0x4e,0x99,0x04,0x28,0x29,0xc3 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_entropyinputpr2[] = + { + 0xbf,0x6c,0x59,0x2a,0x0d,0x44,0x0f,0xae,0x9a,0x5e,0x03,0x73, + 0xd8,0xa6,0xe1,0xcf,0x25,0x61,0x38,0x24,0x86,0x9e,0x53,0xe8, + 0xa4,0xdf,0x56,0xf4,0x06,0x07,0x9c,0x0f + }; + +__fips_constseg +static const unsigned char aes_256_use_df_pr_returnedbits[] = + { + 0x22,0x4a,0xb4,0xb8,0xb6,0xee,0x7d,0xb1,0x9e,0xc9,0xf9,0xa0, + 0xd9,0xe2,0x97,0x00 + }; + + +/* AES-256 use df No PR */ +__fips_constseg +static const unsigned char aes_256_use_df_entropyinput[] = + { + 0xa5,0x3e,0x37,0x10,0x17,0x43,0x91,0x93,0x59,0x1e,0x47,0x50, + 0x87,0xaa,0xdd,0xd5,0xc1,0xc3,0x86,0xcd,0xca,0x0d,0xdb,0x68, + 0xe0,0x02,0xd8,0x0f,0xdc,0x40,0x1a,0x47 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_nonce[] = + { + 0xa9,0x4d,0xa5,0x5a,0xfd,0xc5,0x0c,0xe5,0x1c,0x9a,0x3b,0x8a, + 0x4c,0x44,0x84,0x40 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_personalizationstring[] = + { + 0x8b,0x52,0xa2,0x4a,0x93,0xc3,0x4e,0xa7,0x1e,0x1c,0xa7,0x05, + 0xeb,0x82,0x9b,0xa6,0x5d,0xe4,0xd4,0xe0,0x7f,0xa3,0xd8,0x6b, + 0x37,0x84,0x5f,0xf1,0xc7,0xd5,0xf6,0xd2 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_additionalinput[] = + { + 0x20,0xf4,0x22,0xed,0xf8,0x5c,0xa1,0x6a,0x01,0xcf,0xbe,0x5f, + 0x8d,0x6c,0x94,0x7f,0xae,0x12,0xa8,0x57,0xdb,0x2a,0xa9,0xbf, + 0xc7,0xb3,0x65,0x81,0x80,0x8d,0x0d,0x46 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_int_returnedbits[] = + { + 0x4e,0x44,0xfd,0xf3,0x9e,0x29,0xa2,0xb8,0x0f,0x5d,0x6c,0xe1, + 0x28,0x0c,0x3b,0xc1 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_entropyinputreseed[] = + { + 0xdd,0x40,0xe5,0x98,0x7b,0x27,0x16,0x73,0x15,0x68,0xd2,0x76, + 0xbf,0x0c,0x67,0x15,0x75,0x79,0x03,0xd3,0xde,0xde,0x91,0x46, + 0x42,0xdd,0xd4,0x67,0xc8,0x79,0xc8,0x1e + }; + +__fips_constseg +static const unsigned char aes_256_use_df_additionalinputreseed[] = + { + 0x7f,0xd8,0x1f,0xbd,0x2a,0xb5,0x1c,0x11,0x5d,0x83,0x4e,0x99, + 0xf6,0x5c,0xa5,0x40,0x20,0xed,0x38,0x8e,0xd5,0x9e,0xe0,0x75, + 0x93,0xfe,0x12,0x5e,0x5d,0x73,0xfb,0x75 + }; + +__fips_constseg +static const unsigned char aes_256_use_df_additionalinput2[] = + { + 0xcd,0x2c,0xff,0x14,0x69,0x3e,0x4c,0x9e,0xfd,0xfe,0x26,0x0d, + 0xe9,0x86,0x00,0x49,0x30,0xba,0xb1,0xc6,0x50,0x57,0x77,0x2a, + 0x62,0x39,0x2c,0x3b,0x74,0xeb,0xc9,0x0d + }; + +__fips_constseg +static const unsigned char aes_256_use_df_returnedbits[] = + { + 0x4f,0x78,0xbe,0xb9,0x4d,0x97,0x8c,0xe9,0xd0,0x97,0xfe,0xad, + 0xfa,0xfd,0x35,0x5e + }; + + +/* AES-128 no df PR */ +__fips_constseg +static const unsigned char aes_128_no_df_pr_entropyinput[] = + { + 0x9a,0x25,0x65,0x10,0x67,0xd5,0xb6,0x6b,0x70,0xa1,0xb3,0xa4, + 0x43,0x95,0x80,0xc0,0x84,0x0a,0x79,0xb0,0x88,0x74,0xf2,0xbf, + 0x31,0x6c,0x33,0x38,0x0b,0x00,0xb2,0x5a + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_nonce[] = + { + 0x78,0x47,0x6b,0xf7,0x90,0x8e,0x87,0xf1 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_personalizationstring[] = + { + 0xf7,0x22,0x1d,0x3a,0xbe,0x1d,0xca,0x32,0x1b,0xbd,0x87,0x0c, + 0x51,0x24,0x19,0xee,0xa3,0x23,0x09,0x63,0x33,0x3d,0xa8,0x0c, + 0x1c,0xfa,0x42,0x89,0xcc,0x6f,0xa0,0xa8 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_additionalinput[] = + { + 0xc9,0xe0,0x80,0xbf,0x8c,0x45,0x58,0x39,0xff,0x00,0xab,0x02, + 0x4c,0x3e,0x3a,0x95,0x9b,0x80,0xa8,0x21,0x2a,0xee,0xba,0x73, + 0xb1,0xd9,0xcf,0x28,0xf6,0x8f,0x9b,0x12 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_entropyinputpr[] = + { + 0x4c,0xa8,0xc5,0xf0,0x59,0x9e,0xa6,0x8d,0x26,0x53,0xd7,0x8a, + 0xa9,0xd8,0xf7,0xed,0xb2,0xf9,0x12,0x42,0xe1,0xe5,0xbd,0xe7, + 0xe7,0x1d,0x74,0x99,0x00,0x9d,0x31,0x3e + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_int_returnedbits[] = + { + 0xe2,0xac,0x20,0xf0,0x80,0xe7,0xbc,0x7e,0x9c,0x7b,0x65,0x71, + 0xaf,0x19,0x32,0x16 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_additionalinput2[] = + { + 0x32,0x7f,0x38,0x8b,0x73,0x0a,0x78,0x83,0xdc,0x30,0xbe,0x9f, + 0x10,0x1f,0xf5,0x1f,0xca,0x00,0xb5,0x0d,0xd6,0x9d,0x60,0x83, + 0x51,0x54,0x7d,0x38,0x23,0x3a,0x52,0x50 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_entropyinputpr2[] = + { + 0x18,0x61,0x53,0x56,0xed,0xed,0xd7,0x20,0xfb,0x71,0x04,0x7a, + 0xb2,0xac,0xc1,0x28,0xcd,0xf2,0xc2,0xfc,0xaa,0xb1,0x06,0x07, + 0xe9,0x46,0x95,0x02,0x48,0x01,0x78,0xf9 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_pr_returnedbits[] = + { + 0x29,0xc8,0x1b,0x15,0xb1,0xd1,0xc2,0xf6,0x71,0x86,0x68,0x33, + 0x57,0x82,0x33,0xaf + }; + + +/* AES-128 no df No PR */ +__fips_constseg +static const unsigned char aes_128_no_df_entropyinput[] = + { + 0xc9,0xc5,0x79,0xbc,0xe8,0xc5,0x19,0xd8,0xbc,0x66,0x73,0x67, + 0xf6,0xd3,0x72,0xaa,0xa6,0x16,0xb8,0x50,0xb7,0x47,0x3a,0x42, + 0xab,0xf4,0x16,0xb2,0x96,0xd2,0xb6,0x60 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_nonce[] = + { + 0x5f,0xbf,0x97,0x0c,0x4b,0xa4,0x87,0x13 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_personalizationstring[] = + { + 0xce,0xfb,0x7b,0x3f,0xd4,0x6b,0x29,0x0d,0x69,0x06,0xff,0xbb, + 0xf2,0xe5,0xc6,0x6c,0x0a,0x10,0xa0,0xcf,0x1a,0x48,0xc7,0x8b, + 0x3c,0x16,0x88,0xed,0x50,0x13,0x81,0xce + }; + +__fips_constseg +static const unsigned char aes_128_no_df_additionalinput[] = + { + 0x4b,0x22,0x46,0x18,0x02,0x7b,0xd2,0x1b,0x22,0x42,0x7c,0x37, + 0xd9,0xf6,0xe8,0x9b,0x12,0x30,0x5f,0xe9,0x90,0xe8,0x08,0x24, + 0x4f,0x06,0x66,0xdb,0x19,0x2b,0x13,0x95 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_int_returnedbits[] = + { + 0x2e,0x96,0x70,0x64,0xfa,0xdf,0xdf,0x57,0xb5,0x82,0xee,0xd6, + 0xed,0x3e,0x65,0xc2 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_entropyinputreseed[] = + { + 0x26,0xc0,0x72,0x16,0x3a,0x4b,0xb7,0x99,0xd4,0x07,0xaf,0x66, + 0x62,0x36,0x96,0xa4,0x51,0x17,0xfa,0x07,0x8b,0x17,0x5e,0xa1, + 0x2f,0x3c,0x10,0xe7,0x90,0xd0,0x46,0x00 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_additionalinputreseed[] = + { + 0x83,0x39,0x37,0x7b,0x02,0x06,0xd2,0x12,0x13,0x8d,0x8b,0xf2, + 0xf0,0xf6,0x26,0xeb,0xa4,0x22,0x7b,0xc2,0xe7,0xba,0x79,0xe4, + 0x3b,0x77,0x5d,0x4d,0x47,0xb2,0x2d,0xb4 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_additionalinput2[] = + { + 0x0b,0xb9,0x67,0x37,0xdb,0x83,0xdf,0xca,0x81,0x8b,0xf9,0x3f, + 0xf1,0x11,0x1b,0x2f,0xf0,0x61,0xa6,0xdf,0xba,0xa3,0xb1,0xac, + 0xd3,0xe6,0x09,0xb8,0x2c,0x6a,0x67,0xd6 + }; + +__fips_constseg +static const unsigned char aes_128_no_df_returnedbits[] = + { + 0x1e,0xa7,0xa4,0xe4,0xe1,0xa6,0x7c,0x69,0x9a,0x44,0x6c,0x36, + 0x81,0x37,0x19,0xd4 + }; + + +/* AES-192 no df PR */ +__fips_constseg +static const unsigned char aes_192_no_df_pr_entropyinput[] = + { + 0x9d,0x2c,0xd2,0x55,0x66,0xea,0xe0,0xbe,0x18,0xb7,0x76,0xe7, + 0x73,0x35,0xd8,0x1f,0xad,0x3a,0xe3,0x81,0x0e,0x92,0xd0,0x61, + 0xc9,0x12,0x26,0xf6,0x1c,0xdf,0xfe,0x47,0xaa,0xfe,0x7d,0x5a, + 0x17,0x1f,0x8d,0x9a + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_nonce[] = + { + 0x44,0x82,0xed,0xe8,0x4c,0x28,0x5a,0x14,0xff,0x88,0x8d,0x19, + 0x61,0x5c,0xee,0x0f + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_personalizationstring[] = + { + 0x47,0xd7,0x9b,0x99,0xaa,0xcb,0xe7,0xd2,0x57,0x66,0x2c,0xe1, + 0x78,0xd6,0x2c,0xea,0xa3,0x23,0x5f,0x2a,0xc1,0x3a,0xf0,0xa4, + 0x20,0x3b,0xfa,0x07,0xd5,0x05,0x02,0xe4,0x57,0x01,0xb6,0x10, + 0x57,0x2e,0xe7,0x55 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_additionalinput[] = + { + 0x4b,0x74,0x0b,0x40,0xce,0x6b,0xc2,0x6a,0x24,0xb4,0xf3,0xad, + 0x7a,0xa5,0x7a,0xa2,0x15,0xe2,0xc8,0x61,0x15,0xc6,0xb7,0x85, + 0x69,0x11,0xad,0x7b,0x14,0xd2,0xf6,0x12,0xa1,0x95,0x5d,0x3f, + 0xe2,0xd0,0x0c,0x2f + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_entropyinputpr[] = + { + 0x0c,0x9c,0xad,0x05,0xee,0xae,0x48,0x23,0x89,0x59,0xa1,0x94, + 0xd7,0xd8,0x75,0xd5,0x54,0x93,0xc7,0x4a,0xd9,0x26,0xde,0xeb, + 0xba,0xb0,0x7e,0x30,0x1d,0x5f,0x69,0x40,0x9c,0x3b,0x17,0x58, + 0x1d,0x30,0xb3,0x78 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_int_returnedbits[] = + { + 0xf7,0x93,0xb0,0x6d,0x77,0x83,0xd5,0x38,0x01,0xe1,0x52,0x40, + 0x7e,0x3e,0x0c,0x26 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_additionalinput2[] = + { + 0xbc,0x4b,0x37,0x44,0x1c,0xc5,0x45,0x5f,0x8f,0x51,0x62,0x8a, + 0x85,0x30,0x1d,0x7c,0xe4,0xcf,0xf7,0x44,0xce,0x32,0x3e,0x57, + 0x95,0xa4,0x2a,0xdf,0xfd,0x9e,0x38,0x41,0xb3,0xf6,0xc5,0xee, + 0x0c,0x4b,0xee,0x6e + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_entropyinputpr2[] = + { + 0xec,0xaf,0xf6,0x4f,0xb1,0xa0,0x54,0xb5,0x5b,0xe3,0x46,0xb0, + 0x76,0x5a,0x7c,0x3f,0x7b,0x94,0x69,0x21,0x51,0x02,0xe5,0x9f, + 0x04,0x59,0x02,0x98,0xc6,0x43,0x2c,0xcc,0x26,0x4c,0x87,0x6b, + 0x8e,0x0a,0x83,0xdf + }; + +__fips_constseg +static const unsigned char aes_192_no_df_pr_returnedbits[] = + { + 0x74,0x45,0xfb,0x53,0x84,0x96,0xbe,0xff,0x15,0xcc,0x41,0x91, + 0xb9,0xa1,0x21,0x68 + }; + + +/* AES-192 no df No PR */ +__fips_constseg +static const unsigned char aes_192_no_df_entropyinput[] = + { + 0x3c,0x7d,0xb5,0xe0,0x54,0xd9,0x6e,0x8c,0xa9,0x86,0xce,0x4e, + 0x6b,0xaf,0xeb,0x2f,0xe7,0x75,0xe0,0x8b,0xa4,0x3b,0x07,0xfe, + 0xbe,0x33,0x75,0x93,0x80,0x27,0xb5,0x29,0x47,0x8b,0xc7,0x28, + 0x94,0xc3,0x59,0x63 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_nonce[] = + { + 0x43,0xf1,0x7d,0xb8,0xc3,0xfe,0xd0,0x23,0x6b,0xb4,0x92,0xdb, + 0x29,0xfd,0x45,0x71 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_personalizationstring[] = + { + 0x9f,0x24,0x29,0x99,0x9e,0x01,0xab,0xe9,0x19,0xd8,0x23,0x08, + 0xb7,0xd6,0x7e,0x8c,0xc0,0x9e,0x7f,0x6e,0x5b,0x33,0x20,0x96, + 0x0b,0x23,0x2c,0xa5,0x6a,0xf8,0x1b,0x04,0x26,0xdb,0x2e,0x2b, + 0x3b,0x88,0xce,0x35 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_additionalinput[] = + { + 0x94,0xe9,0x7c,0x3d,0xa7,0xdb,0x60,0x83,0x1f,0x98,0x3f,0x0b, + 0x88,0x59,0x57,0x51,0x88,0x9f,0x76,0x49,0x9f,0xa6,0xda,0x71, + 0x1d,0x0d,0x47,0x16,0x63,0xc5,0x68,0xe4,0x5d,0x39,0x69,0xb3, + 0x3e,0xbe,0xd4,0x8e + }; + +__fips_constseg +static const unsigned char aes_192_no_df_int_returnedbits[] = + { + 0xf9,0xd7,0xad,0x69,0xab,0x8f,0x23,0x56,0x70,0x17,0x4f,0x2a, + 0x45,0xe7,0x4a,0xc5 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_entropyinputreseed[] = + { + 0xa6,0x71,0x6a,0x3d,0xba,0xd1,0xe8,0x66,0xa6,0xef,0xb2,0x0e, + 0xa8,0x9c,0xaa,0x4e,0xaf,0x17,0x89,0x50,0x00,0xda,0xa1,0xb1, + 0x0b,0xa4,0xd9,0x35,0x89,0xc8,0xe5,0xb0,0xd9,0xb7,0xc4,0x33, + 0x9b,0xcb,0x7e,0x75 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_additionalinputreseed[] = + { + 0x27,0x21,0xfc,0xc2,0xbd,0xf3,0x3c,0xce,0xc3,0xca,0xc1,0x01, + 0xe0,0xff,0x93,0x12,0x7d,0x54,0x42,0xe3,0x9f,0x03,0xdf,0x27, + 0x04,0x07,0x3c,0x53,0x7f,0xa8,0x66,0xc8,0x97,0x4b,0x61,0x40, + 0x5d,0x7a,0x25,0x79 + }; + +__fips_constseg +static const unsigned char aes_192_no_df_additionalinput2[] = + { + 0x2d,0x8e,0x16,0x5d,0x0b,0x9f,0xeb,0xaa,0xd6,0xec,0x28,0x71, + 0x7c,0x0b,0xc1,0x1d,0xd4,0x44,0x19,0x47,0xfd,0x1d,0x7c,0xe5, + 0xf3,0x27,0xe1,0xb6,0x72,0x0a,0xe0,0xec,0x0e,0xcd,0xef,0x1a, + 0x91,0x6a,0xe3,0x5f + }; + +__fips_constseg +static const unsigned char aes_192_no_df_returnedbits[] = + { + 0xe5,0xda,0xb8,0xe0,0x63,0x59,0x5a,0xcc,0x3d,0xdc,0x9f,0xe8, + 0x66,0x67,0x2c,0x92 + }; + + +/* AES-256 no df PR */ +__fips_constseg +static const unsigned char aes_256_no_df_pr_entropyinput[] = + { + 0x15,0xc7,0x5d,0xcb,0x41,0x4b,0x16,0x01,0x3a,0xd1,0x44,0xe8, + 0x22,0x32,0xc6,0x9c,0x3f,0xe7,0x43,0xf5,0x9a,0xd3,0xea,0xf2, + 0xd7,0x4e,0x6e,0x6a,0x55,0x73,0x40,0xef,0x89,0xad,0x0d,0x03, + 0x96,0x7e,0x78,0x81,0x2f,0x91,0x1b,0x44,0xb0,0x02,0xba,0x1c + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_nonce[] = + { + 0xdc,0xe4,0xd4,0x27,0x7a,0x90,0xd7,0x99,0x43,0xa1,0x3c,0x30, + 0xcc,0x4b,0xee,0x2e + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_personalizationstring[] = + { + 0xe3,0xe6,0xb9,0x11,0xe4,0x7a,0xa4,0x40,0x6b,0xf8,0x73,0xf7, + 0x7e,0xec,0xc7,0xb9,0x97,0xbf,0xf8,0x25,0x7b,0xbe,0x11,0x9b, + 0x5b,0x6a,0x0c,0x2e,0x2b,0x01,0x51,0xcd,0x41,0x4b,0x6b,0xac, + 0x31,0xa8,0x0b,0xf7,0xe6,0x59,0x42,0xb8,0x03,0x0c,0xf8,0x06 + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_additionalinput[] = + { + 0x6a,0x9f,0x00,0x91,0xae,0xfe,0xcf,0x84,0x99,0xce,0xb1,0x40, + 0x6d,0x5d,0x33,0x28,0x84,0xf4,0x8c,0x63,0x4c,0x7e,0xbd,0x2c, + 0x80,0x76,0xee,0x5a,0xaa,0x15,0x07,0x31,0xd8,0xbb,0x8c,0x69, + 0x9d,0x9d,0xbc,0x7e,0x49,0xae,0xec,0x39,0x6b,0xd1,0x1f,0x7e + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_entropyinputpr[] = + { + 0xf3,0xb9,0x75,0x9c,0xbd,0x88,0xea,0xa2,0x50,0xad,0xd6,0x16, + 0x1a,0x12,0x3c,0x86,0x68,0xaf,0x6f,0xbe,0x19,0xf2,0xee,0xcc, + 0xa5,0x70,0x84,0x53,0x50,0xcb,0x9f,0x14,0xa9,0xe5,0xee,0xb9, + 0x48,0x45,0x40,0xe2,0xc7,0xc9,0x9a,0x74,0xff,0x8c,0x99,0x1f + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_int_returnedbits[] = + { + 0x2e,0xf2,0x45,0x4c,0x62,0x2e,0x0a,0xb9,0x6b,0xa2,0xfd,0x56, + 0x79,0x60,0x93,0xcf + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_additionalinput2[] = + { + 0xaf,0x69,0x20,0xe9,0x3b,0x37,0x9d,0x3f,0xb4,0x80,0x02,0x7a, + 0x25,0x7d,0xb8,0xde,0x71,0xc5,0x06,0x0c,0xb4,0xe2,0x8f,0x35, + 0xd8,0x14,0x0d,0x7f,0x76,0x63,0x4e,0xb5,0xee,0xe9,0x6f,0x34, + 0xc7,0x5f,0x56,0x14,0x4a,0xe8,0x73,0x95,0x5b,0x1c,0xb9,0xcb + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_entropyinputpr2[] = + { + 0xe5,0xb0,0x2e,0x7e,0x52,0x30,0xe3,0x63,0x82,0xb6,0x44,0xd3, + 0x25,0x19,0x05,0x24,0x9a,0x9f,0x5f,0x27,0x6a,0x29,0xab,0xfa, + 0x07,0xa2,0x42,0x0f,0xc5,0xa8,0x94,0x7c,0x17,0x7b,0x85,0x83, + 0x0c,0x25,0x0e,0x63,0x0b,0xe9,0x12,0x60,0xcd,0xef,0x80,0x0f + }; + +__fips_constseg +static const unsigned char aes_256_no_df_pr_returnedbits[] = + { + 0x5e,0xf2,0x26,0xef,0x9f,0x58,0x5d,0xd5,0x4a,0x10,0xfe,0xa7, + 0x2d,0x5f,0x4a,0x46 + }; + + +/* AES-256 no df No PR */ +__fips_constseg +static const unsigned char aes_256_no_df_entropyinput[] = + { + 0xfb,0xcf,0x1b,0x61,0x16,0x89,0x78,0x23,0xf5,0xd8,0x96,0xe3, + 0x4e,0x64,0x0b,0x29,0x9a,0x3f,0xf8,0xa5,0xed,0xf2,0xfe,0xdb, + 0x16,0xca,0x7f,0x10,0xfa,0x5e,0x18,0x76,0x2c,0x63,0x5e,0x96, + 0xcf,0xb3,0xd6,0xfc,0xaf,0x99,0x39,0x28,0x9c,0x61,0xe8,0xb3 + }; + +__fips_constseg +static const unsigned char aes_256_no_df_nonce[] = + { + 0x12,0x96,0xf0,0x52,0xf3,0x8d,0x81,0xcf,0xde,0x86,0xf2,0x99, + 0x43,0x96,0xb9,0xf0 + }; + +__fips_constseg +static const unsigned char aes_256_no_df_personalizationstring[] = + { + 0x63,0x0d,0x78,0xf5,0x90,0x8e,0x32,0x47,0xb0,0x4d,0x37,0x60, + 0x09,0x96,0xbc,0xbf,0x97,0x7a,0x62,0x14,0x45,0xbd,0x8d,0xcc, + 0x69,0xfb,0x03,0xe1,0x80,0x1c,0xc7,0xe2,0x2a,0xf9,0x37,0x3f, + 0x66,0x4d,0x62,0xd9,0x10,0xe0,0xad,0xc8,0x9a,0xf0,0xa8,0x6d + }; + +__fips_constseg +static const unsigned char aes_256_no_df_additionalinput[] = + { + 0x36,0xc6,0x13,0x60,0xbb,0x14,0xad,0x22,0xb0,0x38,0xac,0xa6, + 0x18,0x16,0x93,0x25,0x86,0xb7,0xdc,0xdc,0x36,0x98,0x2b,0xf9, + 0x68,0x33,0xd3,0xc6,0xff,0xce,0x8d,0x15,0x59,0x82,0x76,0xed, + 0x6f,0x8d,0x49,0x74,0x2f,0xda,0xdc,0x1f,0x17,0xd0,0xde,0x17 + }; + +__fips_constseg +static const unsigned char aes_256_no_df_int_returnedbits[] = + { + 0x16,0x2f,0x8e,0x3f,0x21,0x7a,0x1c,0x20,0x56,0xd1,0x92,0xf6, + 0xd2,0x25,0x75,0x0e + }; + +__fips_constseg +static const unsigned char aes_256_no_df_entropyinputreseed[] = + { + 0x91,0x79,0x76,0xee,0xe0,0xcf,0x9e,0xc2,0xd5,0xd4,0x23,0x9b, + 0x12,0x8c,0x7e,0x0a,0xb7,0xd2,0x8b,0xd6,0x7c,0xa3,0xc6,0xe5, + 0x0e,0xaa,0xc7,0x6b,0xae,0x0d,0xfa,0x53,0x06,0x79,0xa1,0xed, + 0x4d,0x6a,0x0e,0xd8,0x9d,0xbe,0x1b,0x31,0x93,0x7b,0xec,0xfb + }; + +__fips_constseg +static const unsigned char aes_256_no_df_additionalinputreseed[] = + { + 0xd2,0x46,0x50,0x22,0x10,0x14,0x63,0xf7,0xea,0x0f,0xb9,0x7e, + 0x0d,0xe1,0x94,0x07,0xaf,0x09,0x44,0x31,0xea,0x64,0xa4,0x18, + 0x5b,0xf9,0xd8,0xc2,0xfa,0x03,0x47,0xc5,0x39,0x43,0xd5,0x3b, + 0x62,0x86,0x64,0xea,0x2c,0x73,0x8c,0xae,0x9d,0x98,0x98,0x29 + }; + +__fips_constseg +static const unsigned char aes_256_no_df_additionalinput2[] = + { + 0x8c,0xab,0x18,0xf8,0xc3,0xec,0x18,0x5c,0xb3,0x1e,0x9d,0xbe, + 0x3f,0x03,0xb4,0x00,0x98,0x9d,0xae,0xeb,0xf4,0x94,0xf8,0x42, + 0x8f,0xe3,0x39,0x07,0xe1,0xc9,0xad,0x0b,0x1f,0xed,0xc0,0xba, + 0xf6,0xd1,0xec,0x27,0x86,0x7b,0xd6,0x55,0x9b,0x60,0xa5,0xc6 + }; + +__fips_constseg +static const unsigned char aes_256_no_df_returnedbits[] = + { + 0xef,0xd2,0xd8,0x5c,0xdc,0x62,0x25,0x9f,0xaa,0x1e,0x2c,0x67, + 0xf6,0x02,0x32,0xe2 + }; + + +/* SHA-1 PR */ +__fips_constseg +static const unsigned char sha1_pr_entropyinput[] = + { + 0xd2,0x36,0xa5,0x27,0x31,0x73,0xdd,0x11,0x4f,0x93,0xbd,0xe2, + 0x31,0xa5,0x91,0x13 + }; + +__fips_constseg +static const unsigned char sha1_pr_nonce[] = + { + 0xb5,0xb3,0x60,0xef,0xf7,0x63,0x31,0xf3 + }; + +__fips_constseg +static const unsigned char sha1_pr_personalizationstring[] = + { + 0xd4,0xbb,0x02,0x10,0xb2,0x71,0xdb,0x81,0xd6,0xf0,0x42,0x60, + 0xda,0xea,0x77,0x52 + }; + +__fips_constseg +static const unsigned char sha1_pr_additionalinput[] = + { + 0x4d,0xd2,0x6c,0x87,0xfb,0x2c,0x4f,0xa6,0x8d,0x16,0x63,0x22, + 0x6a,0x51,0xe3,0xf8 + }; + +__fips_constseg +static const unsigned char sha1_pr_entropyinputpr[] = + { + 0xc9,0x83,0x9e,0x16,0xf6,0x1c,0x0f,0xb2,0xec,0x60,0x31,0xa9, + 0xcb,0xa9,0x36,0x7a + }; + +__fips_constseg +static const unsigned char sha1_pr_int_returnedbits[] = + { + 0xa8,0x13,0x4f,0xf4,0x31,0x02,0x44,0xe3,0xd3,0x3d,0x61,0x9e, + 0xe5,0xc6,0x3e,0x89,0xb5,0x9b,0x0f,0x35 + }; + +__fips_constseg +static const unsigned char sha1_pr_additionalinput2[] = + { + 0xf9,0xe8,0xd2,0x72,0x13,0x34,0x95,0x6f,0x15,0x49,0x47,0x99, + 0x16,0x03,0x19,0x47 + }; + +__fips_constseg +static const unsigned char sha1_pr_entropyinputpr2[] = + { + 0x4e,0x8c,0x49,0x9b,0x4a,0x5c,0x9b,0x9c,0x3a,0xee,0xfb,0xd2, + 0xae,0xcd,0x8c,0xc4 + }; + +__fips_constseg +static const unsigned char sha1_pr_returnedbits[] = + { + 0x50,0xb4,0xb4,0xcd,0x68,0x57,0xfc,0x2e,0xc1,0x52,0xcc,0xf6, + 0x68,0xa4,0x81,0xed,0x7e,0xe4,0x1d,0x87 + }; + + +/* SHA-1 No PR */ +__fips_constseg +static const unsigned char sha1_entropyinput[] = + { + 0xa9,0x47,0x1b,0x29,0x2d,0x1c,0x05,0xdf,0x76,0xd0,0x62,0xf9, + 0xe2,0x7f,0x4c,0x7b + }; + +__fips_constseg +static const unsigned char sha1_nonce[] = + { + 0x53,0x23,0x24,0xe3,0xec,0x0c,0x54,0x14 + }; + +__fips_constseg +static const unsigned char sha1_personalizationstring[] = + { + 0x7a,0x87,0xa1,0xac,0x1c,0xfd,0xab,0xae,0xf7,0xd6,0xfb,0x76, + 0x28,0xec,0x6d,0xca + }; + +__fips_constseg +static const unsigned char sha1_additionalinput[] = + { + 0xfc,0x92,0x35,0xd6,0x7e,0xb7,0x24,0x65,0xfd,0x12,0x27,0x35, + 0xc0,0x72,0xca,0x28 + }; + +__fips_constseg +static const unsigned char sha1_int_returnedbits[] = + { + 0x57,0x88,0x82,0xe5,0x25,0xa5,0x2c,0x4a,0x06,0x20,0x6c,0x72, + 0x55,0x61,0xdd,0x90,0x71,0x9f,0x95,0xea + }; + +__fips_constseg +static const unsigned char sha1_entropyinputreseed[] = + { + 0x69,0xa5,0x40,0x62,0x98,0x47,0x56,0x73,0x4a,0x8f,0x60,0x96, + 0xd6,0x99,0x27,0xed + }; + +__fips_constseg +static const unsigned char sha1_additionalinputreseed[] = + { + 0xe5,0x40,0x4e,0xbd,0x50,0x00,0xf5,0x15,0xa6,0xee,0x45,0xda, + 0x84,0x3d,0xd4,0xc0 + }; + +__fips_constseg +static const unsigned char sha1_additionalinput2[] = + { + 0x11,0x51,0x14,0xf0,0x09,0x1b,0x4e,0x56,0x0d,0xe9,0xf6,0x1e, + 0x52,0x65,0xcd,0x96 + }; + +__fips_constseg +static const unsigned char sha1_returnedbits[] = + { + 0xa1,0x9c,0x94,0x6e,0x29,0xe1,0x33,0x0d,0x32,0xd6,0xaa,0xce, + 0x71,0x3f,0x52,0x72,0x8b,0x42,0xa8,0xd7 + }; + + +/* SHA-224 PR */ +__fips_constseg +static const unsigned char sha224_pr_entropyinput[] = + { + 0x12,0x69,0x32,0x4f,0x83,0xa6,0xf5,0x14,0xe3,0x49,0x3e,0x75, + 0x3e,0xde,0xad,0xa1,0x29,0xc3,0xf3,0x19,0x20,0xb5,0x4c,0xd9 + }; + +__fips_constseg +static const unsigned char sha224_pr_nonce[] = + { + 0x6a,0x78,0xd0,0xeb,0xbb,0x5a,0xf0,0xee,0xe8,0xc3,0xba,0x71 + }; + +__fips_constseg +static const unsigned char sha224_pr_personalizationstring[] = + { + 0xd5,0xb8,0xb6,0xbc,0xc1,0x5b,0x60,0x31,0x3c,0xf5,0xe5,0xc0, + 0x8e,0x52,0x7a,0xbd,0xea,0x47,0xa9,0x5f,0x8f,0xf9,0x8b,0xae + }; + +__fips_constseg +static const unsigned char sha224_pr_additionalinput[] = + { + 0x1f,0x55,0xec,0xae,0x16,0x12,0x84,0xba,0x84,0x16,0x19,0x88, + 0x8e,0xb8,0x33,0x25,0x54,0xff,0xca,0x79,0xaf,0x07,0x25,0x50 + }; + +__fips_constseg +static const unsigned char sha224_pr_entropyinputpr[] = + { + 0x92,0xa3,0x32,0xa8,0x9a,0x0a,0x58,0x7c,0x1d,0x5a,0x7e,0xe1, + 0xb2,0x73,0xab,0x0e,0x16,0x79,0x23,0xd3,0x29,0x89,0x81,0xe1 + }; + +__fips_constseg +static const unsigned char sha224_pr_int_returnedbits[] = + { + 0xf3,0x38,0x91,0x40,0x37,0x7a,0x51,0x72,0x42,0x74,0x78,0x0a, + 0x69,0xfd,0xa6,0x44,0x43,0x45,0x6c,0x0c,0x5a,0x19,0xff,0xf1, + 0x54,0x60,0xee,0x6a + }; + +__fips_constseg +static const unsigned char sha224_pr_additionalinput2[] = + { + 0x75,0xf3,0x04,0x25,0xdd,0x36,0xa8,0x37,0x46,0xae,0x0c,0x52, + 0x05,0x79,0x4c,0x26,0xdb,0xe9,0x71,0x16,0x4c,0x0a,0xf2,0x60 + }; + +__fips_constseg +static const unsigned char sha224_pr_entropyinputpr2[] = + { + 0xea,0xc5,0x03,0x0a,0x4f,0xb0,0x38,0x8d,0x23,0xd4,0xc8,0x77, + 0xe2,0x6d,0x9c,0x0b,0x44,0xf7,0x2d,0x5b,0xbf,0x5d,0x2a,0x11 + }; + +__fips_constseg +static const unsigned char sha224_pr_returnedbits[] = + { + 0x60,0x50,0x2b,0xe7,0x86,0xd8,0x26,0x73,0xe3,0x1d,0x95,0x20, + 0xb3,0x2c,0x32,0x1c,0xf5,0xce,0x57,0xa6,0x67,0x2b,0xdc,0x4e, + 0xdd,0x11,0x4c,0xc4 + }; + + +/* SHA-224 No PR */ +__fips_constseg +static const unsigned char sha224_entropyinput[] = + { + 0xb2,0x1c,0x77,0x4d,0xf6,0xd3,0xb6,0x40,0xb7,0x30,0x3e,0x29, + 0xb0,0x85,0x1c,0xbe,0x4a,0xea,0x6b,0x5a,0xb5,0x8a,0x97,0xeb + }; + +__fips_constseg +static const unsigned char sha224_nonce[] = + { + 0x42,0x02,0x0a,0x1c,0x98,0x9a,0x77,0x9e,0x9f,0x80,0xba,0xe0 + }; + +__fips_constseg +static const unsigned char sha224_personalizationstring[] = + { + 0x98,0xb8,0x04,0x41,0xfc,0xc1,0x5d,0xc5,0xe9,0xb9,0x08,0xda, + 0xf9,0xfa,0x0d,0x90,0xce,0xdf,0x1d,0x10,0xa9,0x8d,0x50,0x0c + }; + +__fips_constseg +static const unsigned char sha224_additionalinput[] = + { + 0x9a,0x8d,0x39,0x49,0x42,0xd5,0x0b,0xae,0xe1,0xaf,0xb7,0x00, + 0x02,0xfa,0x96,0xb1,0xa5,0x1d,0x2d,0x25,0x78,0xee,0x83,0x3f + }; + +__fips_constseg +static const unsigned char sha224_int_returnedbits[] = + { + 0xe4,0xf5,0x53,0x79,0x5a,0x97,0x58,0x06,0x08,0xba,0x7b,0xfa, + 0xf0,0x83,0x05,0x8c,0x22,0xc0,0xc9,0xdb,0x15,0xe7,0xde,0x20, + 0x55,0x22,0x9a,0xad + }; + +__fips_constseg +static const unsigned char sha224_entropyinputreseed[] = + { + 0x67,0x09,0x48,0xaa,0x07,0x16,0x99,0x89,0x7f,0x6d,0xa0,0xe5, + 0x8f,0xdf,0xbc,0xdb,0xfe,0xe5,0x6c,0x7a,0x95,0x4a,0x66,0x17 + }; + +__fips_constseg +static const unsigned char sha224_additionalinputreseed[] = + { + 0x0f,0x4b,0x1c,0x6f,0xb7,0xe3,0x47,0xe5,0x5d,0x7d,0x38,0xd6, + 0x28,0x9b,0xeb,0x55,0x63,0x09,0x3e,0x7c,0x56,0xea,0xf8,0x19 + }; + +__fips_constseg +static const unsigned char sha224_additionalinput2[] = + { + 0x2d,0x26,0x7c,0x37,0xe4,0x7a,0x28,0x5e,0x5a,0x3c,0xaf,0x3d, + 0x5a,0x8e,0x55,0xa2,0x1a,0x6e,0xc0,0xe5,0xf6,0x21,0xd3,0xf6 + }; + +__fips_constseg +static const unsigned char sha224_returnedbits[] = + { + 0x4d,0x83,0x35,0xdf,0x67,0xa9,0xfc,0x17,0xda,0x70,0xcc,0x8b, + 0x7f,0x77,0xae,0xa2,0x5f,0xb9,0x7e,0x74,0x4c,0x26,0xc1,0x7a, + 0x3b,0xa7,0x5c,0x93 + }; + + +/* SHA-256 PR */ +__fips_constseg +static const unsigned char sha256_pr_entropyinput[] = + { + 0xce,0x49,0x00,0x7a,0x56,0xe3,0x67,0x8f,0xe1,0xb6,0xa7,0xd4, + 0x4f,0x08,0x7a,0x1b,0x01,0xf4,0xfa,0x6b,0xef,0xb7,0xe5,0xeb, + 0x07,0x3d,0x11,0x0d,0xc8,0xea,0x2b,0xfe + }; + +__fips_constseg +static const unsigned char sha256_pr_nonce[] = + { + 0x73,0x41,0xc8,0x92,0x94,0xe2,0xc5,0x5f,0x93,0xfd,0x39,0x5d, + 0x2b,0x91,0x4d,0x38 + }; + +__fips_constseg +static const unsigned char sha256_pr_personalizationstring[] = + { + 0x50,0x6d,0x01,0x01,0x07,0x5a,0x80,0x35,0x7a,0x56,0x1a,0x56, + 0x2f,0x9a,0x0b,0x35,0xb2,0xb1,0xc9,0xe5,0xca,0x69,0x61,0x48, + 0xff,0xfb,0x0f,0xd9,0x4b,0x79,0x1d,0xba + }; + +__fips_constseg +static const unsigned char sha256_pr_additionalinput[] = + { + 0x20,0xb8,0xdf,0x44,0x77,0x5a,0xb8,0xd3,0xbf,0xf6,0xcf,0xac, + 0x5e,0xa6,0x96,0x62,0x73,0x44,0x40,0x4a,0x30,0xfb,0x38,0xa5, + 0x7b,0x0d,0xe4,0x0d,0xc6,0xe4,0x9a,0x1f + }; + +__fips_constseg +static const unsigned char sha256_pr_entropyinputpr[] = + { + 0x04,0xc4,0x65,0xf4,0xd3,0xbf,0x83,0x4b,0xab,0xc8,0x41,0xa8, + 0xc2,0xe0,0x44,0x63,0x77,0x4c,0x6f,0x6c,0x49,0x46,0xff,0x94, + 0x17,0xea,0xe6,0x1a,0x9d,0x5e,0x66,0x78 + }; + +__fips_constseg +static const unsigned char sha256_pr_int_returnedbits[] = + { + 0x07,0x4d,0xac,0x9b,0x86,0xca,0x4a,0xaa,0x6e,0x7a,0x03,0xa2, + 0x5d,0x10,0xea,0x0b,0xf9,0x83,0xcc,0xd1,0xfc,0xe2,0x07,0xc7, + 0x06,0x34,0x60,0x6f,0x83,0x94,0x99,0x76 + }; + +__fips_constseg +static const unsigned char sha256_pr_additionalinput2[] = + { + 0x89,0x4e,0x45,0x8c,0x11,0xf9,0xbc,0x5b,0xac,0x74,0x8b,0x4b, + 0x5f,0xf7,0x19,0xf3,0xf5,0x24,0x54,0x14,0xd1,0x15,0xb1,0x43, + 0x12,0xa4,0x5f,0xd4,0xec,0xfc,0xcd,0x09 + }; + +__fips_constseg +static const unsigned char sha256_pr_entropyinputpr2[] = + { + 0x0e,0xeb,0x1f,0xd7,0xfc,0xd1,0x9d,0xd4,0x05,0x36,0x8b,0xb2, + 0xfb,0xe4,0xf4,0x51,0x0c,0x87,0x9b,0x02,0x44,0xd5,0x92,0x4d, + 0x44,0xfe,0x1a,0x03,0x43,0x56,0xbd,0x86 + }; + +__fips_constseg +static const unsigned char sha256_pr_returnedbits[] = + { + 0x02,0xaa,0xb6,0x1d,0x7e,0x2a,0x40,0x03,0x69,0x2d,0x49,0xa3, + 0x41,0xe7,0x44,0x0b,0xaf,0x7b,0x85,0xe4,0x5f,0x53,0x3b,0x64, + 0xbc,0x89,0xc8,0x82,0xd4,0x78,0x37,0xa2 + }; + + +/* SHA-256 No PR */ +__fips_constseg +static const unsigned char sha256_entropyinput[] = + { + 0x5b,0x1b,0xec,0x4d,0xa9,0x38,0x74,0x5a,0x34,0x0b,0x7b,0xc5, + 0xe5,0xd7,0x66,0x7c,0xbc,0x82,0xb9,0x0e,0x2d,0x1f,0x92,0xd7, + 0xc1,0xbc,0x67,0x69,0xec,0x6b,0x03,0x3c + }; + +__fips_constseg +static const unsigned char sha256_nonce[] = + { + 0xa4,0x0c,0xd8,0x9c,0x61,0xd8,0xc3,0x54,0xfe,0x53,0xc9,0xe5, + 0x5d,0x6f,0x6d,0x35 + }; + +__fips_constseg +static const unsigned char sha256_personalizationstring[] = + { + 0x22,0x5e,0x62,0x93,0x42,0x83,0x78,0x24,0xd8,0x40,0x8c,0xde, + 0x6f,0xf9,0xa4,0x7a,0xc5,0xa7,0x3b,0x88,0xa3,0xee,0x42,0x20, + 0xfd,0x61,0x56,0xc6,0x4c,0x13,0x41,0x9c + }; + +__fips_constseg +static const unsigned char sha256_additionalinput[] = + { + 0xbf,0x74,0x5b,0xf6,0xc5,0x64,0x5e,0x99,0x34,0x8f,0xbc,0xa4, + 0xe2,0xbd,0xd8,0x85,0x26,0x37,0xea,0xba,0x4f,0xf2,0x9a,0x9a, + 0x66,0xfc,0xdf,0x63,0x26,0x26,0x19,0x87 + }; + +__fips_constseg +static const unsigned char sha256_int_returnedbits[] = + { + 0xb3,0xc6,0x07,0x07,0xd6,0x75,0xf6,0x2b,0xd6,0x21,0x96,0xf1, + 0xae,0xdb,0x2b,0xac,0x25,0x2a,0xae,0xae,0x41,0x72,0x03,0x5e, + 0xbf,0xd3,0x64,0xbc,0x59,0xf9,0xc0,0x76 + }; + +__fips_constseg +static const unsigned char sha256_entropyinputreseed[] = + { + 0xbf,0x20,0x33,0x56,0x29,0xa8,0x37,0x04,0x1f,0x78,0x34,0x3d, + 0x81,0x2a,0xc9,0x86,0xc6,0x7a,0x2f,0x88,0x5e,0xd5,0xbe,0x34, + 0x46,0x20,0xa4,0x35,0xeb,0xc7,0xe2,0x9d + }; + +__fips_constseg +static const unsigned char sha256_additionalinputreseed[] = + { + 0x9b,0xae,0x2d,0x2d,0x61,0xa4,0x89,0xeb,0x43,0x46,0xa7,0xda, + 0xef,0x40,0xca,0x4a,0x99,0x11,0x41,0xdc,0x5c,0x94,0xe9,0xac, + 0xd4,0xd0,0xe6,0xbd,0xfb,0x03,0x9c,0xa8 + }; + +__fips_constseg +static const unsigned char sha256_additionalinput2[] = + { + 0x23,0xaa,0x0c,0xbd,0x28,0x33,0xe2,0x51,0xfc,0x71,0xd2,0x15, + 0x1f,0x76,0xfd,0x0d,0xe0,0xb7,0xb5,0x84,0x75,0x5b,0xbe,0xf3, + 0x5c,0xca,0xc5,0x30,0xf2,0x75,0x1f,0xda + }; + +__fips_constseg +static const unsigned char sha256_returnedbits[] = + { + 0x90,0x3c,0xc1,0x10,0x8c,0x12,0x01,0xc6,0xa6,0x3a,0x0f,0x4d, + 0xb6,0x3a,0x4f,0x41,0x9c,0x61,0x75,0x84,0xe9,0x74,0x75,0xfd, + 0xfe,0xf2,0x1f,0x43,0xd8,0x5e,0x24,0xa3 + }; + + +/* SHA-384 PR */ +__fips_constseg +static const unsigned char sha384_pr_entropyinput[] = + { + 0x71,0x9d,0xb2,0x5a,0x71,0x6d,0x04,0xe9,0x1e,0xc7,0x92,0x24, + 0x6e,0x12,0x33,0xa9,0x52,0x64,0x31,0xef,0x71,0xeb,0x22,0x55, + 0x28,0x97,0x06,0x6a,0xc0,0x0c,0xa0,0x7e + }; + +__fips_constseg +static const unsigned char sha384_pr_nonce[] = + { + 0xf5,0x0d,0xfa,0xb0,0xec,0x6a,0x7c,0xd6,0xbd,0x9b,0x05,0xfd, + 0x38,0x3e,0x2e,0x56 + }; + +__fips_constseg +static const unsigned char sha384_pr_personalizationstring[] = + { + 0x74,0xac,0x7e,0x6d,0xb1,0xa4,0xe7,0x21,0xd1,0x1e,0x6e,0x96, + 0x6d,0x4d,0x53,0x46,0x82,0x96,0x6e,0xcf,0xaa,0x81,0x8d,0x7d, + 0x9e,0xe1,0x0f,0x15,0xea,0x41,0xbf,0xe3 + }; + +__fips_constseg +static const unsigned char sha384_pr_additionalinput[] = + { + 0xda,0x95,0xd4,0xd0,0xb8,0x11,0xd3,0x49,0x27,0x5d,0xa9,0x39, + 0x68,0xf3,0xa8,0xe9,0x5d,0x19,0x8a,0x2b,0x66,0xe8,0x69,0x06, + 0x7c,0x9e,0x03,0xa1,0x8b,0x26,0x2d,0x6e + }; + +__fips_constseg +static const unsigned char sha384_pr_entropyinputpr[] = + { + 0x49,0xdf,0x44,0x00,0xe4,0x1c,0x75,0x0b,0x26,0x5a,0x59,0x64, + 0x1f,0x4e,0xb1,0xb2,0x13,0xf1,0x22,0x4e,0xb4,0x6d,0x9a,0xcc, + 0xa0,0x48,0xe6,0xcf,0x1d,0xd1,0x92,0x0d + }; + +__fips_constseg +static const unsigned char sha384_pr_int_returnedbits[] = + { + 0xc8,0x52,0xae,0xbf,0x04,0x3c,0x27,0xb7,0x78,0x18,0xaa,0x8f, + 0xff,0xcf,0xa4,0xf1,0xcc,0xe7,0x68,0xfa,0x22,0xa2,0x13,0x45, + 0xe8,0xdd,0x87,0xe6,0xf2,0x6e,0xdd,0xc7,0x52,0x90,0x9f,0x7b, + 0xfa,0x61,0x2d,0x9d,0x9e,0xcf,0x98,0xac,0x52,0x40,0xce,0xaf + }; + +__fips_constseg +static const unsigned char sha384_pr_additionalinput2[] = + { + 0x61,0x7c,0x03,0x9a,0x3e,0x50,0x57,0x60,0xc5,0x83,0xc9,0xb2, + 0xd1,0x87,0x85,0x66,0x92,0x5d,0x84,0x0e,0x53,0xfb,0x70,0x03, + 0x72,0xfd,0xba,0xae,0x9c,0x8f,0xf8,0x18 + }; + +__fips_constseg +static const unsigned char sha384_pr_entropyinputpr2[] = + { + 0xf8,0xeb,0x89,0xb1,0x8d,0x78,0xbe,0x21,0xe0,0xbb,0x9d,0xb7, + 0x95,0x0e,0xd9,0x46,0x0c,0x8c,0xe2,0x63,0xb7,0x9d,0x67,0x90, + 0xbd,0xc7,0x0b,0xa5,0xce,0xb2,0x65,0x81 + }; + +__fips_constseg +static const unsigned char sha384_pr_returnedbits[] = + { + 0xe6,0x9f,0xfe,0x68,0xd6,0xb5,0x79,0xf1,0x06,0x5f,0xa3,0xbb, + 0x23,0x85,0xd8,0xf0,0x29,0x5a,0x68,0x9e,0xf5,0xf4,0xa6,0x12, + 0xe0,0x9a,0xe2,0xac,0x00,0x1d,0x98,0x26,0xfc,0x53,0x95,0x53, + 0xe4,0x3e,0x17,0xd5,0x08,0x0b,0x70,0x3d,0x67,0x99,0xac,0x66 + }; + + +/* SHA-384 No PR */ +__fips_constseg +static const unsigned char sha384_entropyinput[] = + { + 0x07,0x15,0x27,0x2a,0xaf,0x74,0x24,0x37,0xbc,0xd5,0x14,0x69, + 0xce,0x11,0xff,0xa2,0x6b,0xb8,0x05,0x67,0x34,0xf8,0xbd,0x6d, + 0x6a,0xcc,0xcd,0x60,0xa3,0x68,0xca,0xf4 + }; + +__fips_constseg +static const unsigned char sha384_nonce[] = + { + 0x70,0x17,0xc2,0x5b,0x5d,0x22,0x0b,0x06,0x15,0x54,0x78,0x77, + 0x44,0xaf,0x2f,0x09 + }; + +__fips_constseg +static const unsigned char sha384_personalizationstring[] = + { + 0x89,0x39,0x28,0xb0,0x60,0xeb,0x3d,0xdc,0x55,0x75,0x86,0xeb, + 0xae,0xa2,0x8f,0xbc,0x1b,0x75,0xd4,0xe1,0x0f,0xaa,0x38,0xca, + 0x62,0x8b,0xcb,0x2c,0x26,0xf6,0xbc,0xb1 + }; + +__fips_constseg +static const unsigned char sha384_additionalinput[] = + { + 0x30,0x2b,0x42,0x35,0xef,0xda,0x40,0x55,0x28,0xc6,0x95,0xfb, + 0x54,0x01,0x62,0xd7,0x87,0x14,0x48,0x6d,0x90,0x4c,0xa9,0x02, + 0x54,0x40,0x22,0xc8,0x66,0xa5,0x48,0x48 + }; + +__fips_constseg +static const unsigned char sha384_int_returnedbits[] = + { + 0x82,0xc4,0xa1,0x9c,0x21,0xd2,0xe7,0xa5,0xa6,0xf6,0x5f,0x04, + 0x5c,0xc7,0x31,0x9d,0x8d,0x59,0x74,0x50,0x19,0x89,0x2f,0x63, + 0xd5,0xb7,0x7e,0xeb,0x15,0xe3,0x70,0x83,0xa1,0x24,0x59,0xfa, + 0x2c,0x56,0xf6,0x88,0x3a,0x92,0x93,0xa1,0xfb,0x79,0xc1,0x7a + }; + +__fips_constseg +static const unsigned char sha384_entropyinputreseed[] = + { + 0x39,0xa6,0xe8,0x5c,0x82,0x17,0x71,0x26,0x57,0x4f,0x9f,0xc2, + 0x55,0xff,0x5c,0x9b,0x53,0x1a,0xd1,0x5f,0xbc,0x62,0xe4,0x27, + 0x2d,0x32,0xf0,0xe4,0x52,0x8c,0xc5,0x0c + }; + +__fips_constseg +static const unsigned char sha384_additionalinputreseed[] = + { + 0x8d,0xcb,0x8d,0xce,0x08,0xea,0x80,0xe8,0x9b,0x61,0xa8,0x0f, + 0xaf,0x49,0x20,0x9e,0x74,0xcb,0x57,0x80,0x42,0xb0,0x84,0x5e, + 0x30,0x2a,0x67,0x08,0xf4,0xe3,0x40,0x22 + }; + +__fips_constseg +static const unsigned char sha384_additionalinput2[] = + { + 0x7c,0x8f,0xc2,0xae,0x22,0x4a,0xd6,0xf6,0x05,0xa4,0x7a,0xea, + 0xbb,0x25,0xd0,0xb7,0x5a,0xd6,0xcf,0x9d,0xf3,0x6c,0xe2,0xb2, + 0x4e,0xb4,0xbd,0xf4,0xe5,0x40,0x80,0x94 + }; + +__fips_constseg +static const unsigned char sha384_returnedbits[] = + { + 0x9e,0x7e,0xfb,0x59,0xbb,0xaa,0x3c,0xf7,0xe1,0xf8,0x76,0xdd, + 0x63,0x5f,0xaf,0x23,0xd6,0x64,0x61,0xc0,0x9a,0x09,0x47,0xc9, + 0x33,0xdf,0x6d,0x55,0x91,0x34,0x79,0x70,0xc4,0x99,0x6e,0x54, + 0x09,0x64,0x21,0x1a,0xbd,0x1e,0x80,0x40,0x34,0xad,0xfa,0xd7 + }; + + +/* SHA-512 PR */ +__fips_constseg +static const unsigned char sha512_pr_entropyinput[] = + { + 0x13,0xf7,0x61,0x75,0x65,0x28,0xa2,0x59,0x13,0x5a,0x4a,0x4f, + 0x56,0x60,0x8c,0x53,0x7d,0xb0,0xbd,0x06,0x4f,0xed,0xcc,0xd2, + 0xa2,0xb5,0xfd,0x5b,0x3a,0xab,0xec,0x28 + }; + +__fips_constseg +static const unsigned char sha512_pr_nonce[] = + { + 0xbe,0xa3,0x91,0x93,0x1d,0xc3,0x31,0x3a,0x23,0x33,0x50,0x67, + 0x88,0xc7,0xa2,0xc4 + }; + +__fips_constseg +static const unsigned char sha512_pr_personalizationstring[] = + { + 0x1f,0x59,0x4d,0x7b,0xe6,0x46,0x91,0x48,0xc1,0x25,0xfa,0xff, + 0x89,0x12,0x77,0x35,0xdf,0x3e,0xf4,0x80,0x5f,0xd9,0xb0,0x07, + 0x22,0x41,0xdd,0x48,0x78,0x6b,0x77,0x2b + }; + +__fips_constseg +static const unsigned char sha512_pr_additionalinput[] = + { + 0x30,0xff,0x63,0x6f,0xac,0xd9,0x84,0x39,0x6f,0xe4,0x99,0xce, + 0x91,0x7d,0x7e,0xc8,0x58,0xf2,0x12,0xc3,0xb6,0xad,0xda,0x22, + 0x04,0xa0,0xd2,0x21,0xfe,0xf2,0x95,0x1d + }; + +__fips_constseg +static const unsigned char sha512_pr_entropyinputpr[] = + { + 0x64,0x54,0x13,0xec,0x4f,0x77,0xda,0xb2,0x92,0x2e,0x52,0x80, + 0x11,0x10,0xc2,0xf8,0xe6,0xa7,0xcd,0x4b,0xfc,0x32,0x2e,0x9e, + 0xeb,0xbb,0xb1,0xbf,0x15,0x5c,0x73,0x08 + }; + +__fips_constseg +static const unsigned char sha512_pr_int_returnedbits[] = + { + 0xef,0x1e,0xdc,0x0a,0xa4,0x36,0x91,0x9c,0x3d,0x27,0x97,0x50, + 0x8d,0x36,0x29,0x8d,0xce,0x6a,0x0c,0xf7,0x21,0xc0,0x91,0xae, + 0x0c,0x96,0x72,0xbd,0x52,0x81,0x58,0xfc,0x6d,0xe5,0xf7,0xa5, + 0xfd,0x5d,0xa7,0x58,0x68,0xc8,0x99,0x58,0x8e,0xc8,0xce,0x95, + 0x01,0x7d,0xff,0xa4,0xc8,0xf7,0x63,0xfe,0x5f,0x69,0x83,0x53, + 0xe2,0xc6,0x8b,0xc3 + }; + +__fips_constseg +static const unsigned char sha512_pr_additionalinput2[] = + { + 0xe6,0x9b,0xc4,0x88,0x34,0xca,0xea,0x29,0x2f,0x98,0x05,0xa4, + 0xd3,0xc0,0x7b,0x11,0xe8,0xbb,0x75,0xf2,0xbd,0x29,0xb7,0x40, + 0x25,0x7f,0xc1,0xb7,0xb1,0xf1,0x25,0x61 + }; + +__fips_constseg +static const unsigned char sha512_pr_entropyinputpr2[] = + { + 0x23,0x6d,0xff,0xde,0xfb,0xd1,0xba,0x33,0x18,0xe6,0xbe,0xb5, + 0x48,0x77,0x6d,0x7f,0xa7,0xe1,0x4d,0x48,0x1e,0x3c,0xa7,0x34, + 0x1a,0xc8,0x60,0xdb,0x8f,0x99,0x15,0x99 + }; + +__fips_constseg +static const unsigned char sha512_pr_returnedbits[] = + { + 0x70,0x27,0x31,0xdb,0x92,0x70,0x21,0xfe,0x16,0xb6,0xc8,0x51, + 0x34,0x87,0x65,0xd0,0x4e,0xfd,0xfe,0x68,0xec,0xac,0xdc,0x93, + 0x41,0x38,0x92,0x90,0xb4,0x94,0xf9,0x0d,0xa4,0xf7,0x4e,0x80, + 0x92,0x67,0x48,0x40,0xa7,0x08,0xc7,0xbc,0x66,0x00,0xfd,0xf7, + 0x4c,0x8b,0x17,0x6e,0xd1,0x8f,0x9b,0xf3,0x6f,0xf6,0x34,0xdd, + 0x67,0xf7,0x68,0xdd + }; + + +/* SHA-512 No PR */ +__fips_constseg +static const unsigned char sha512_entropyinput[] = + { + 0xb6,0x0b,0xb7,0xbc,0x84,0x56,0xf6,0x12,0xaf,0x45,0x67,0x17, + 0x7c,0xd1,0xb2,0x78,0x2b,0xa0,0xf2,0xbe,0xb6,0x6d,0x8b,0x56, + 0xc6,0xbc,0x4d,0xe1,0xf7,0xbe,0xce,0xbd + }; + +__fips_constseg +static const unsigned char sha512_nonce[] = + { + 0x9d,0xed,0xc0,0xe5,0x5a,0x98,0x6a,0xcb,0x51,0x7d,0x76,0x31, + 0x5a,0x64,0xf0,0xf7 + }; + +__fips_constseg +static const unsigned char sha512_personalizationstring[] = + { + 0xc2,0x6d,0xa3,0xc3,0x06,0x74,0xe5,0x01,0x5c,0x10,0x17,0xc7, + 0xaf,0x83,0x9d,0x59,0x8d,0x2d,0x29,0x38,0xc5,0x59,0x70,0x8b, + 0x46,0x48,0x2d,0xcf,0x36,0x7d,0x59,0xc0 + }; + +__fips_constseg +static const unsigned char sha512_additionalinput[] = + { + 0xec,0x8c,0xd4,0xf7,0x61,0x6e,0x0d,0x95,0x79,0xb7,0x28,0xad, + 0x5f,0x69,0x74,0x5f,0x2d,0x36,0x06,0x8a,0x6b,0xac,0x54,0x97, + 0xc4,0xa1,0x12,0x85,0x0a,0xdf,0x4b,0x34 + }; + +__fips_constseg +static const unsigned char sha512_int_returnedbits[] = + { + 0x84,0x2f,0x1f,0x68,0x6a,0xa3,0xad,0x1e,0xfb,0xf4,0x15,0xbd, + 0xde,0x38,0xd4,0x30,0x80,0x51,0xe9,0xd3,0xc7,0x20,0x88,0xe9, + 0xf5,0xcc,0xdf,0x57,0x5c,0x47,0x2f,0x57,0x3c,0x5f,0x13,0x56, + 0xcc,0xc5,0x4f,0x84,0xf8,0x10,0x41,0xd5,0x7e,0x58,0x6e,0x19, + 0x19,0x9e,0xaf,0xc2,0x22,0x58,0x41,0x50,0x79,0xc2,0xd8,0x04, + 0x28,0xd4,0x39,0x9a + }; + +__fips_constseg +static const unsigned char sha512_entropyinputreseed[] = + { + 0xfa,0x7f,0x46,0x51,0x83,0x62,0x98,0x16,0x9a,0x19,0xa2,0x49, + 0xa9,0xe6,0x4a,0xd8,0x85,0xe7,0xd4,0x3b,0x2c,0x82,0xc5,0x82, + 0xbf,0x11,0xf9,0x9e,0xbc,0xd0,0x01,0xee + }; + +__fips_constseg +static const unsigned char sha512_additionalinputreseed[] = + { + 0xb9,0x12,0xe0,0x4f,0xf7,0xa7,0xc4,0xd8,0xd0,0x8e,0x99,0x29, + 0x7c,0x9a,0xe9,0xcf,0xc4,0x6c,0xf8,0xc3,0xa7,0x41,0x83,0xd6, + 0x2e,0xfa,0xb8,0x5e,0x8e,0x6b,0x78,0x20 + }; + +__fips_constseg +static const unsigned char sha512_additionalinput2[] = + { + 0xd7,0x07,0x52,0xb9,0x83,0x2c,0x03,0x71,0xee,0xc9,0xc0,0x85, + 0xe1,0x57,0xb2,0xcd,0x3a,0xf0,0xc9,0x34,0x24,0x41,0x1c,0x42, + 0x99,0xb2,0x84,0xe9,0x17,0xd2,0x76,0x92 + }; + +__fips_constseg +static const unsigned char sha512_returnedbits[] = + { + 0x36,0x17,0x5d,0x98,0x2b,0x65,0x25,0x8e,0xc8,0x29,0xdf,0x27, + 0x05,0x36,0x26,0x12,0x8a,0x68,0x74,0x27,0x37,0xd4,0x7f,0x32, + 0xb1,0x12,0xd6,0x85,0x83,0xeb,0x2e,0xa0,0xed,0x4b,0xb5,0x7b, + 0x6f,0x39,0x3c,0x71,0x77,0x02,0x12,0xcc,0x2c,0x3a,0x8e,0x63, + 0xdf,0x4a,0xbd,0x6f,0x6e,0x2e,0xed,0x0a,0x85,0xa5,0x2f,0xa2, + 0x68,0xde,0x42,0xb5 + }; + + +/* HMAC SHA-1 PR */ +__fips_constseg +static const unsigned char hmac_sha1_pr_entropyinput[] = + { + 0x26,0x5f,0x36,0x14,0xff,0x3d,0x83,0xfa,0x73,0x5e,0x75,0xdc, + 0x2c,0x18,0x17,0x1b + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_nonce[] = + { + 0xc8,0xe3,0x57,0xa5,0x7b,0x74,0x86,0x6e + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_personalizationstring[] = + { + 0x6e,0xdb,0x0d,0xfe,0x7d,0xac,0x79,0xd0,0xa5,0x3a,0x48,0x85, + 0x80,0xe2,0x7f,0x2a + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_additionalinput[] = + { + 0x31,0xcd,0x5e,0x43,0xdc,0xfb,0x7a,0x79,0xca,0x88,0xde,0x1f, + 0xd7,0xbb,0x42,0x09 + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_entropyinputpr[] = + { + 0x7c,0x23,0x95,0x38,0x00,0x95,0xc1,0x78,0x1f,0x8f,0xd7,0x63, + 0x23,0x87,0x2a,0xed + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_int_returnedbits[] = + { + 0xbb,0x34,0xe7,0x93,0xa3,0x02,0x2c,0x4a,0xd0,0x89,0xda,0x7f, + 0xed,0xf4,0x4c,0xde,0x17,0xec,0xe5,0x6c + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_additionalinput2[] = + { + 0x49,0xbc,0x2d,0x2c,0xb7,0x32,0xcb,0x20,0xdf,0xf5,0x77,0x58, + 0xa0,0x4b,0x93,0x6e + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_entropyinputpr2[] = + { + 0x3c,0xaa,0xb0,0x21,0x42,0xb0,0xdd,0x34,0xf0,0x16,0x7f,0x0c, + 0x0f,0xff,0x2e,0xaf + }; + +__fips_constseg +static const unsigned char hmac_sha1_pr_returnedbits[] = + { + 0x8e,0xcb,0xa3,0x64,0xb2,0xb8,0x33,0x6c,0x64,0x3b,0x78,0x16, + 0x99,0x35,0xc8,0x30,0xcb,0x3e,0xa0,0xd8 + }; + + +/* HMAC SHA-1 No PR */ +__fips_constseg +static const unsigned char hmac_sha1_entropyinput[] = + { + 0x32,0x9a,0x2a,0x87,0x7b,0x89,0x7c,0xf6,0xcb,0x95,0xd5,0x40, + 0x17,0xfe,0x47,0x70 + }; + +__fips_constseg +static const unsigned char hmac_sha1_nonce[] = + { + 0x16,0xd8,0xe0,0xc7,0x52,0xcf,0x4a,0x25 + }; + +__fips_constseg +static const unsigned char hmac_sha1_personalizationstring[] = + { + 0x35,0x35,0xa9,0xa5,0x40,0xbe,0x9b,0xd1,0x56,0xdd,0x44,0x00, + 0x72,0xf7,0xd3,0x5e + }; + +__fips_constseg +static const unsigned char hmac_sha1_additionalinput[] = + { + 0x1b,0x2c,0x84,0x2d,0x4a,0x89,0x8f,0x69,0x19,0xf1,0xf3,0xdb, + 0xbb,0xe3,0xaa,0xea + }; + +__fips_constseg +static const unsigned char hmac_sha1_int_returnedbits[] = + { + 0xcf,0xfa,0x7d,0x72,0x0f,0xe6,0xc7,0x96,0xa0,0x69,0x31,0x11, + 0x9b,0x0b,0x1a,0x20,0x1f,0x3f,0xaa,0xd1 + }; + +__fips_constseg +static const unsigned char hmac_sha1_entropyinputreseed[] = + { + 0x90,0x75,0x15,0x04,0x95,0xf1,0xba,0x81,0x0c,0x37,0x94,0x6f, + 0x86,0x52,0x6d,0x9c + }; + +__fips_constseg +static const unsigned char hmac_sha1_additionalinputreseed[] = + { + 0x5b,0x40,0xba,0x5f,0x17,0x70,0xf0,0x4b,0xdf,0xc9,0x97,0x92, + 0x79,0xc5,0x82,0x28 + }; + +__fips_constseg +static const unsigned char hmac_sha1_additionalinput2[] = + { + 0x97,0xc8,0x80,0x90,0xb3,0xaa,0x6e,0x60,0xea,0x83,0x7a,0xe3, + 0x8a,0xca,0xa4,0x7f + }; + +__fips_constseg +static const unsigned char hmac_sha1_returnedbits[] = + { + 0x90,0xbd,0x05,0x56,0x6d,0xb5,0x22,0xd5,0xb9,0x5a,0x29,0x2d, + 0xe9,0x0b,0xe1,0xac,0xde,0x27,0x0b,0xb0 + }; + + +/* HMAC SHA-224 PR */ +__fips_constseg +static const unsigned char hmac_sha224_pr_entropyinput[] = + { + 0x17,0x32,0x2b,0x2e,0x6f,0x1b,0x9c,0x6d,0x31,0xe0,0x34,0x07, + 0xcf,0xed,0xf6,0xb6,0x5a,0x76,0x4c,0xbc,0x62,0x85,0x01,0x90 + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_nonce[] = + { + 0x38,0xbf,0x5f,0x20,0xb3,0x68,0x2f,0x43,0x61,0x05,0x8f,0x23 + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_personalizationstring[] = + { + 0xc0,0xc9,0x45,0xac,0x8d,0x27,0x77,0x08,0x0b,0x17,0x6d,0xed, + 0xc1,0x7d,0xd5,0x07,0x9d,0x6e,0xf8,0x23,0x2a,0x22,0x13,0xbd + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_additionalinput[] = + { + 0xa4,0x3c,0xe7,0x3b,0xea,0x19,0x45,0x32,0xc2,0x83,0x6d,0x21, + 0x8a,0xc0,0xee,0x67,0x45,0xde,0x13,0x7d,0x9d,0x61,0x00,0x3b + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_entropyinputpr[] = + { + 0x15,0x05,0x74,0x4a,0x7f,0x8d,0x5c,0x60,0x16,0xe5,0x7b,0xad, + 0xf5,0x41,0x8f,0x55,0x60,0xc4,0x09,0xee,0x1e,0x11,0x81,0xab + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_int_returnedbits[] = + { + 0x6f,0xf5,0x9a,0xe2,0x54,0x53,0x30,0x3d,0x5a,0x27,0x29,0x38, + 0x27,0xf2,0x0d,0x05,0xe9,0x26,0xcb,0x16,0xc3,0x51,0x5f,0x13, + 0x41,0xfe,0x99,0xf2 + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_additionalinput2[] = + { + 0x73,0x81,0x88,0x84,0x8f,0xed,0x6f,0x10,0x9f,0x93,0xbf,0x17, + 0x35,0x7c,0xef,0xd5,0x8d,0x26,0xa6,0x7a,0xe8,0x09,0x36,0x4f + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_entropyinputpr2[] = + { + 0xe6,0xcf,0xcf,0x7e,0x12,0xe5,0x43,0xd2,0x38,0xd8,0x24,0x6f, + 0x5a,0x37,0x68,0xbf,0x4f,0xa0,0xff,0xd5,0x61,0x8a,0x93,0xe0 + }; + +__fips_constseg +static const unsigned char hmac_sha224_pr_returnedbits[] = + { + 0xaf,0xf9,0xd8,0x19,0x91,0x30,0x82,0x6f,0xa9,0x1e,0x9d,0xd7, + 0xf3,0x50,0xe0,0xc7,0xd5,0x64,0x96,0x7d,0x4c,0x4d,0x78,0x03, + 0x6d,0xd8,0x9e,0x72 + }; + + +/* HMAC SHA-224 No PR */ +__fips_constseg +static const unsigned char hmac_sha224_entropyinput[] = + { + 0x11,0x82,0xfd,0xd9,0x42,0xf4,0xfa,0xc8,0xf2,0x41,0xe6,0x54, + 0x01,0xae,0x22,0x6e,0xc6,0xaf,0xaf,0xd0,0xa6,0xb2,0xe2,0x6d + }; + +__fips_constseg +static const unsigned char hmac_sha224_nonce[] = + { + 0xa9,0x48,0xd7,0x92,0x39,0x7e,0x2a,0xdc,0x30,0x1f,0x0e,0x2b + }; + +__fips_constseg +static const unsigned char hmac_sha224_personalizationstring[] = + { + 0x11,0xd5,0xf4,0xbd,0x67,0x8c,0x31,0xcf,0xa3,0x3f,0x1e,0x6b, + 0xa8,0x07,0x02,0x0b,0xc8,0x2e,0x6c,0x64,0x41,0x5b,0xc8,0x37 + }; + +__fips_constseg +static const unsigned char hmac_sha224_additionalinput[] = + { + 0x68,0x18,0xc2,0x06,0xeb,0x3e,0x04,0x95,0x44,0x5e,0xfb,0xe6, + 0x41,0xc1,0x5c,0xcc,0x40,0x2f,0xb7,0xd2,0x0f,0xf3,0x6b,0xe7 + }; + +__fips_constseg +static const unsigned char hmac_sha224_int_returnedbits[] = + { + 0x7f,0x45,0xc7,0x5d,0x32,0xe6,0x17,0x60,0xba,0xdc,0xb8,0x42, + 0x1b,0x9c,0xf1,0xfa,0x3b,0x4d,0x29,0x54,0xc6,0x90,0xff,0x5c, + 0xcd,0xd6,0xa9,0xcc + }; + +__fips_constseg +static const unsigned char hmac_sha224_entropyinputreseed[] = + { + 0xc4,0x8e,0x37,0x95,0x69,0x53,0x28,0xd7,0x37,0xbb,0x70,0x95, + 0x1c,0x07,0x1d,0xd9,0xb7,0xe6,0x1b,0xbb,0xfe,0x41,0xeb,0xc9 + }; + +__fips_constseg +static const unsigned char hmac_sha224_additionalinputreseed[] = + { + 0x53,0x17,0xa1,0x6a,0xfa,0x77,0x47,0xb0,0x95,0x56,0x9a,0x20, + 0x57,0xde,0x5c,0x89,0x9f,0x7f,0xe2,0xde,0x17,0x3a,0x50,0x23 + }; + +__fips_constseg +static const unsigned char hmac_sha224_additionalinput2[] = + { + 0x3a,0x32,0xf9,0x85,0x0c,0xc1,0xed,0x76,0x2d,0xdf,0x40,0xc3, + 0x06,0x22,0x66,0xd4,0x9a,0x9a,0xff,0x5a,0x7e,0x7a,0xf3,0x96 + }; + +__fips_constseg +static const unsigned char hmac_sha224_returnedbits[] = + { + 0x43,0xb4,0x57,0x5c,0x38,0x25,0x9d,0xae,0xec,0x96,0xd1,0x85, + 0x3a,0x84,0x8d,0xfe,0x68,0xd5,0x0e,0x5c,0x8f,0x65,0xa5,0x4e, + 0x45,0x84,0xa8,0x94 + }; + + +/* HMAC SHA-256 PR */ +__fips_constseg +static const unsigned char hmac_sha256_pr_entropyinput[] = + { + 0x4d,0xb0,0x43,0xd8,0x34,0x4b,0x10,0x70,0xb1,0x8b,0xed,0xea, + 0x07,0x92,0x9f,0x6c,0x79,0x31,0xaf,0x81,0x29,0xeb,0x6e,0xca, + 0x32,0x48,0x28,0xe7,0x02,0x5d,0xa6,0xa6 + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_nonce[] = + { + 0x3a,0xae,0x15,0xa9,0x99,0xdc,0xe4,0x67,0x34,0x3b,0x70,0x15, + 0xaa,0xd3,0x30,0x9a + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_personalizationstring[] = + { + 0x13,0x1d,0x24,0x04,0xb0,0x18,0x81,0x15,0x21,0x51,0x2a,0x24, + 0x52,0x61,0xbe,0x64,0x82,0x6b,0x55,0x2f,0xe2,0xf1,0x40,0x7d, + 0x71,0xd8,0x01,0x86,0x15,0xb7,0x8b,0xb5 + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_additionalinput[] = + { + 0x8f,0xa6,0x54,0x5f,0xb1,0xd0,0xd8,0xc3,0xe7,0x0c,0x15,0xa9, + 0x23,0x6e,0xfe,0xfb,0x93,0xf7,0x3a,0xbd,0x59,0x01,0xfa,0x18, + 0x8e,0xe9,0x1a,0xa9,0x78,0xfc,0x79,0x0b + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_entropyinputpr[] = + { + 0xcf,0x24,0xb9,0xeb,0xb3,0xd4,0xcd,0x17,0x37,0x38,0x75,0x79, + 0x15,0xcb,0x2d,0x75,0x51,0xf1,0xcc,0xaa,0x32,0xa4,0xa7,0x36, + 0x7c,0x5c,0xe4,0x47,0xf1,0x3e,0x1d,0xe5 + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_int_returnedbits[] = + { + 0x52,0x42,0xfa,0xeb,0x85,0xe0,0x30,0x22,0x79,0x00,0x16,0xb2, + 0x88,0x2f,0x14,0x6a,0xb7,0xfc,0xb7,0x53,0xdc,0x4a,0x12,0xef, + 0x54,0xd6,0x33,0xe9,0x20,0xd6,0xfd,0x56 + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_additionalinput2[] = + { + 0xf4,0xf6,0x49,0xa1,0x2d,0x64,0x2b,0x30,0x58,0xf8,0xbd,0xb8, + 0x75,0xeb,0xbb,0x5e,0x1c,0x9b,0x81,0x6a,0xda,0x14,0x86,0x6e, + 0xd0,0xda,0x18,0xb7,0x88,0xfb,0x59,0xf3 + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_entropyinputpr2[] = + { + 0x21,0xcd,0x6e,0x46,0xad,0x99,0x07,0x17,0xb4,0x3d,0x76,0x0a, + 0xff,0x5b,0x52,0x50,0x78,0xdf,0x1f,0x24,0x06,0x0d,0x3f,0x74, + 0xa9,0xc9,0x37,0xcf,0xd8,0x26,0x25,0x91 + }; + +__fips_constseg +static const unsigned char hmac_sha256_pr_returnedbits[] = + { + 0xa7,0xaf,0x2f,0x29,0xe0,0x3a,0x72,0x95,0x96,0x1c,0xa9,0xf0, + 0x4a,0x17,0x4d,0x66,0x06,0x10,0xbf,0x39,0x89,0x88,0xb8,0x91, + 0x37,0x18,0x99,0xcf,0x8c,0x53,0x3b,0x7e + }; + + +/* HMAC SHA-256 No PR */ +__fips_constseg +static const unsigned char hmac_sha256_entropyinput[] = + { + 0x96,0xb7,0x53,0x22,0x1e,0x52,0x2a,0x96,0xb1,0x15,0x3c,0x35, + 0x5a,0x8b,0xd3,0x4a,0xa6,0x6c,0x83,0x0a,0x7d,0xa3,0x23,0x3d, + 0x43,0xa1,0x07,0x2c,0x2d,0xe3,0x81,0xcc + }; + +__fips_constseg +static const unsigned char hmac_sha256_nonce[] = + { + 0xf1,0xac,0x97,0xcb,0x5e,0x06,0x48,0xd2,0x94,0xbe,0x15,0x2e, + 0xc7,0xfc,0xc2,0x01 + }; + +__fips_constseg +static const unsigned char hmac_sha256_personalizationstring[] = + { + 0x98,0xc5,0x1e,0x35,0x5e,0x89,0x0d,0xce,0x64,0x6d,0x18,0xa7, + 0x5a,0xc6,0xf3,0xe7,0xd6,0x9e,0xc0,0xea,0xb7,0x3a,0x8d,0x65, + 0xb8,0xeb,0x10,0xd7,0x57,0x18,0xa0,0x32 + }; + +__fips_constseg +static const unsigned char hmac_sha256_additionalinput[] = + { + 0x1b,0x10,0xaf,0xac,0xd0,0x65,0x95,0xad,0x04,0xad,0x03,0x1c, + 0xe0,0x40,0xd6,0x3e,0x1c,0x46,0x53,0x39,0x7c,0xe2,0xbc,0xda, + 0x8c,0xa2,0x33,0xa7,0x9a,0x26,0xd3,0x27 + }; + +__fips_constseg +static const unsigned char hmac_sha256_int_returnedbits[] = + { + 0xba,0x61,0x0e,0x55,0xfe,0x11,0x8a,0x9e,0x0f,0x80,0xdf,0x1d, + 0x03,0x0a,0xfe,0x15,0x94,0x28,0x4b,0xba,0xf4,0x9f,0x51,0x25, + 0x88,0xe5,0x4e,0xfb,0xaf,0xce,0x69,0x90 + }; + +__fips_constseg +static const unsigned char hmac_sha256_entropyinputreseed[] = + { + 0x62,0x7f,0x1e,0x6b,0xe8,0x8e,0xe1,0x35,0x7d,0x9b,0x4f,0xc7, + 0xec,0xc8,0xac,0xef,0x6b,0x13,0x9e,0x05,0x56,0xc1,0x08,0xf9, + 0x2f,0x0f,0x27,0x9c,0xd4,0x15,0xed,0x2d + }; + +__fips_constseg +static const unsigned char hmac_sha256_additionalinputreseed[] = + { + 0xc7,0x76,0x6e,0xa9,0xd2,0xb2,0x76,0x40,0x82,0x25,0x2c,0xb3, + 0x6f,0xac,0xe9,0x74,0xef,0x8f,0x3c,0x8e,0xcd,0xf1,0xbf,0xb3, + 0x49,0x77,0x34,0x88,0x52,0x36,0xe6,0x2e + }; + +__fips_constseg +static const unsigned char hmac_sha256_additionalinput2[] = + { + 0x8d,0xb8,0x0c,0xd1,0xbf,0x70,0xf6,0x19,0xc3,0x41,0x80,0x9f, + 0xe1,0xa5,0xa4,0x1f,0x2c,0x26,0xb1,0xe5,0xd8,0xeb,0xbe,0xf8, + 0xdf,0x88,0x6a,0x89,0xd6,0x05,0xd8,0x9d + }; + +__fips_constseg +static const unsigned char hmac_sha256_returnedbits[] = + { + 0x43,0x12,0x2a,0x2c,0x40,0x53,0x2e,0x7c,0x66,0x34,0xac,0xc3, + 0x43,0xe3,0xe0,0x6a,0xfc,0xfa,0xea,0x87,0x21,0x1f,0xe2,0x26, + 0xc4,0xf9,0x09,0x9a,0x0d,0x6e,0x7f,0xe0 + }; + + +/* HMAC SHA-384 PR */ +__fips_constseg +static const unsigned char hmac_sha384_pr_entropyinput[] = + { + 0x69,0x81,0x98,0x88,0x44,0xf5,0xd6,0x2e,0x00,0x08,0x3b,0xc5, + 0xfb,0xd7,0x8e,0x6f,0x23,0xf8,0x6d,0x09,0xd6,0x85,0x49,0xd1, + 0xf8,0x6d,0xa4,0x58,0x54,0xfd,0x88,0xa9 + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_nonce[] = + { + 0x6e,0x38,0x81,0xca,0xb7,0xe8,0x6e,0x66,0x49,0x8a,0xb2,0x59, + 0xee,0x16,0xc9,0xde + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_personalizationstring[] = + { + 0xfe,0x4c,0xd9,0xf4,0x78,0x3b,0x08,0x41,0x8d,0x8f,0x55,0xc4, + 0x43,0x56,0xb6,0x12,0x36,0x6b,0x30,0xb7,0x5e,0xe1,0xb9,0x47, + 0x04,0xb1,0x4e,0xa9,0x00,0xa1,0x52,0xa1 + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_additionalinput[] = + { + 0x89,0xe9,0xcc,0x8f,0x27,0x3c,0x26,0xd1,0x95,0xc8,0x7d,0x0f, + 0x5b,0x1a,0xf0,0x78,0x39,0x56,0x6f,0xa4,0x23,0xe7,0xd1,0xda, + 0x7c,0x66,0x33,0xa0,0x90,0xc9,0x92,0x88 + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_entropyinputpr[] = + { + 0xbe,0x3d,0x7c,0x0d,0xca,0xda,0x7c,0x49,0xb8,0x12,0x36,0xc0, + 0xdb,0xad,0x35,0xa8,0xc7,0x0b,0x2a,0x2c,0x69,0x6d,0x25,0x56, + 0x63,0x82,0x11,0x3e,0xa7,0x33,0x70,0x72 + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_int_returnedbits[] = + { + 0x82,0x3d,0xe6,0x54,0x80,0x42,0xf8,0xba,0x90,0x4f,0x06,0xa6, + 0xd2,0x7f,0xbf,0x79,0x7c,0x12,0x7d,0xa6,0xa2,0x66,0xe8,0xa6, + 0xc0,0xd6,0x4a,0x55,0xbf,0xd8,0x0a,0xc5,0xf8,0x03,0x88,0xdd, + 0x8e,0x87,0xd1,0x5a,0x48,0x26,0x72,0x2a,0x8e,0xcf,0xee,0xba + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_additionalinput2[] = + { + 0x8f,0xff,0xd9,0x84,0xbb,0x85,0x3a,0x66,0xa1,0x21,0xce,0xb2, + 0x3a,0x3a,0x17,0x22,0x19,0xae,0xc7,0xb6,0x63,0x81,0xd5,0xff, + 0x0d,0xc8,0xe1,0xaf,0x57,0xd2,0xcb,0x60 + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_entropyinputpr2[] = + { + 0xd7,0xfb,0xc9,0xe8,0xe2,0xf2,0xaa,0x4c,0xb8,0x51,0x2f,0xe1, + 0x22,0xba,0xf3,0xda,0x0a,0x19,0x76,0x71,0x57,0xb2,0x1d,0x94, + 0x09,0x69,0x6c,0xd3,0x97,0x51,0x81,0x87 + }; + +__fips_constseg +static const unsigned char hmac_sha384_pr_returnedbits[] = + { + 0xe6,0x19,0x28,0xa8,0x21,0xce,0x5e,0xdb,0x24,0x79,0x8c,0x76, + 0x5d,0x73,0xb2,0xdf,0xac,0xef,0x85,0xa7,0x3b,0x19,0x09,0x8b, + 0x7f,0x98,0x28,0xa9,0x93,0xd8,0x7a,0xad,0x55,0x8b,0x24,0x9d, + 0xe6,0x98,0xfe,0x47,0xd5,0x48,0xc1,0x23,0xd8,0x1d,0x62,0x75 + }; + + +/* HMAC SHA-384 No PR */ +__fips_constseg +static const unsigned char hmac_sha384_entropyinput[] = + { + 0xc3,0x56,0x2b,0x1d,0xc2,0xbb,0xa8,0xf0,0xae,0x1b,0x0d,0xd3, + 0x5a,0x6c,0xda,0x57,0x8e,0xa5,0x8a,0x0d,0x6c,0x4b,0x18,0xb1, + 0x04,0x3e,0xb4,0x99,0x35,0xc4,0xc0,0x5f + }; + +__fips_constseg +static const unsigned char hmac_sha384_nonce[] = + { + 0xc5,0x49,0x1e,0x66,0x27,0x92,0xbe,0xec,0xb5,0x1e,0x4b,0xb1, + 0x38,0xe3,0xeb,0x62 + }; + +__fips_constseg +static const unsigned char hmac_sha384_personalizationstring[] = + { + 0xbe,0xe7,0x6b,0x57,0xde,0x88,0x11,0x96,0x9b,0x6e,0xea,0xe5, + 0x63,0x83,0x4c,0xb6,0x8d,0x66,0xaa,0x1f,0x8b,0x54,0xe7,0x62, + 0x6d,0x5a,0xfc,0xbf,0x97,0xba,0xcd,0x77 + }; + +__fips_constseg +static const unsigned char hmac_sha384_additionalinput[] = + { + 0xe5,0x28,0x5f,0x43,0xf5,0x83,0x6e,0x0a,0x83,0x5c,0xe3,0x81, + 0x03,0xf2,0xf8,0x78,0x00,0x7c,0x95,0x87,0x16,0xd6,0x6c,0x58, + 0x33,0x6c,0x53,0x35,0x0d,0x66,0xe3,0xce + }; + +__fips_constseg +static const unsigned char hmac_sha384_int_returnedbits[] = + { + 0xe2,0x1f,0xf3,0xda,0x0d,0x19,0x99,0x87,0xc4,0x90,0xa2,0x31, + 0xca,0x2a,0x89,0x58,0x43,0x44,0xb8,0xde,0xcf,0xa4,0xbe,0x3b, + 0x53,0x26,0x22,0x31,0x76,0x41,0x22,0xb5,0xa8,0x70,0x2f,0x4b, + 0x64,0x95,0x4d,0x48,0x96,0x35,0xe6,0xbd,0x3c,0x34,0xdb,0x1b + }; + +__fips_constseg +static const unsigned char hmac_sha384_entropyinputreseed[] = + { + 0x77,0x61,0xba,0xbc,0xf2,0xc1,0xf3,0x4b,0x86,0x65,0xfd,0x48, + 0x0e,0x3c,0x02,0x5e,0xa2,0x7a,0x6b,0x7c,0xed,0x21,0x5e,0xf9, + 0xcd,0xcd,0x77,0x07,0x2b,0xbe,0xc5,0x5c + }; + +__fips_constseg +static const unsigned char hmac_sha384_additionalinputreseed[] = + { + 0x18,0x24,0x5f,0xc6,0x84,0xd1,0x67,0xc3,0x9a,0x11,0xa5,0x8c, + 0x07,0x39,0x21,0x83,0x4d,0x04,0xc4,0x6a,0x28,0x19,0xcf,0x92, + 0x21,0xd9,0x9e,0x41,0x72,0x6c,0x9e,0x63 + }; + +__fips_constseg +static const unsigned char hmac_sha384_additionalinput2[] = + { + 0x96,0x67,0x41,0x28,0x9b,0xb7,0x92,0x8d,0x64,0x3b,0xe4,0xcf, + 0x7e,0xaa,0x1e,0xb1,0x4b,0x1d,0x09,0x56,0x67,0x9c,0xc6,0x6d, + 0x3b,0xe8,0x91,0x9d,0xe1,0x8a,0xb7,0x32 + }; + +__fips_constseg +static const unsigned char hmac_sha384_returnedbits[] = + { + 0xe3,0x59,0x61,0x38,0x92,0xec,0xe2,0x3c,0xff,0xb7,0xdb,0x19, + 0x0f,0x5b,0x93,0x68,0x0d,0xa4,0x94,0x40,0x72,0x0b,0xe0,0xed, + 0x4d,0xcd,0x68,0xa0,0x1e,0xfe,0x67,0xb2,0xfa,0x21,0x56,0x74, + 0xa4,0xad,0xcf,0xb7,0x60,0x66,0x2e,0x40,0xde,0x82,0xca,0xfb + }; + + +/* HMAC SHA-512 PR */ +__fips_constseg +static const unsigned char hmac_sha512_pr_entropyinput[] = + { + 0xaa,0x9e,0x45,0x67,0x0e,0x00,0x2a,0x67,0x98,0xd6,0xda,0x0b, + 0x0f,0x17,0x7e,0xac,0xfd,0x27,0xc4,0xca,0x84,0xdf,0xde,0xba, + 0x85,0xd9,0xbe,0x8f,0xf3,0xff,0x91,0x4d + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_nonce[] = + { + 0x8c,0x49,0x2f,0x58,0x1e,0x7a,0xda,0x4b,0x7e,0x8a,0x30,0x7b, + 0x86,0xea,0xaf,0xa2 + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_personalizationstring[] = + { + 0x71,0xe1,0xbb,0xad,0xa7,0x4b,0x2e,0x31,0x3b,0x0b,0xec,0x24, + 0x99,0x38,0xbc,0xaa,0x05,0x4c,0x46,0x44,0xfa,0xad,0x8e,0x02, + 0xc1,0x7e,0xad,0xec,0x54,0xa6,0xd0,0xad + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_additionalinput[] = + { + 0x3d,0x6e,0xa6,0xa8,0x29,0x2a,0xb2,0xf5,0x98,0x42,0xe4,0x92, + 0x78,0x22,0x67,0xfd,0x1b,0x15,0x1e,0x29,0xaa,0x71,0x3c,0x3c, + 0xe7,0x05,0x20,0xa9,0x29,0xc6,0x75,0x71 + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_entropyinputpr[] = + { + 0xab,0xb9,0x16,0xd8,0x55,0x35,0x54,0xb7,0x97,0x3f,0x94,0xbc, + 0x2f,0x7c,0x70,0xc7,0xd0,0xed,0xb7,0x4b,0xf7,0xf6,0x6c,0x03, + 0x0c,0xb0,0x03,0xd8,0xbb,0x71,0xd9,0x10 + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_int_returnedbits[] = + { + 0x8e,0xd3,0xfd,0x52,0x9e,0x83,0x08,0x49,0x18,0x6e,0x23,0x56, + 0x5c,0x45,0x93,0x34,0x05,0xe2,0x98,0x8f,0x0c,0xd4,0x32,0x0c, + 0xfd,0xda,0x5f,0x92,0x3a,0x8c,0x81,0xbd,0xf6,0x6c,0x55,0xfd, + 0xb8,0x20,0xce,0x8d,0x97,0x27,0xe8,0xe8,0xe0,0xb3,0x85,0x50, + 0xa2,0xc2,0xb2,0x95,0x1d,0x48,0xd3,0x7b,0x4b,0x78,0x13,0x35, + 0x05,0x17,0xbe,0x0d + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_additionalinput2[] = + { + 0xc3,0xfc,0x95,0xaa,0x69,0x06,0xae,0x59,0x41,0xce,0x26,0x08, + 0x29,0x6d,0x45,0xda,0xe8,0xb3,0x6c,0x95,0x60,0x0f,0x70,0x2c, + 0x10,0xba,0x38,0x8c,0xcf,0x29,0x99,0xaa + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_entropyinputpr2[] = + { + 0x3b,0x9a,0x25,0xce,0xd7,0xf9,0x5c,0xd1,0x3a,0x3e,0xaa,0x71, + 0x14,0x3e,0x19,0xe8,0xce,0xe6,0xfe,0x51,0x84,0xe9,0x1b,0xfe, + 0x3f,0xa7,0xf2,0xfd,0x76,0x5f,0x6a,0xe7 + }; + +__fips_constseg +static const unsigned char hmac_sha512_pr_returnedbits[] = + { + 0xb7,0x82,0xa9,0x57,0x81,0x67,0x53,0xb5,0xa1,0xe9,0x3d,0x35, + 0xf9,0xe4,0x97,0xbe,0xa6,0xca,0xf1,0x01,0x13,0x09,0xe7,0x21, + 0xc0,0xed,0x93,0x5d,0x4b,0xf4,0xeb,0x8d,0x53,0x25,0x8a,0xc4, + 0xb1,0x6f,0x6e,0x37,0xcd,0x2e,0xac,0x39,0xb2,0xb6,0x99,0xa3, + 0x82,0x00,0xb0,0x21,0xf0,0xc7,0x2f,0x4c,0x73,0x92,0xfd,0x00, + 0xb6,0xaf,0xbc,0xd3 + }; + + +/* HMAC SHA-512 No PR */ +__fips_constseg +static const unsigned char hmac_sha512_entropyinput[] = + { + 0x6e,0x85,0xe6,0x25,0x96,0x29,0xa7,0x52,0x5b,0x60,0xba,0xaa, + 0xde,0xdb,0x36,0x0a,0x51,0x9a,0x15,0xae,0x6e,0x18,0xd3,0xfe, + 0x39,0xb9,0x4a,0x96,0xf8,0x77,0xcb,0x95 + }; + +__fips_constseg +static const unsigned char hmac_sha512_nonce[] = + { + 0xe0,0xa6,0x5d,0x08,0xc3,0x7c,0xae,0x25,0x2e,0x80,0xd1,0x3e, + 0xd9,0xaf,0x43,0x3c + }; + +__fips_constseg +static const unsigned char hmac_sha512_personalizationstring[] = + { + 0x53,0x99,0x52,0x5f,0x11,0xa9,0x64,0x66,0x20,0x5e,0x1b,0x5f, + 0x42,0xb3,0xf4,0xda,0xed,0xbb,0x63,0xc1,0x23,0xaf,0xd0,0x01, + 0x90,0x3b,0xd0,0x78,0xe4,0x0b,0xa7,0x20 + }; + +__fips_constseg +static const unsigned char hmac_sha512_additionalinput[] = + { + 0x85,0x90,0x80,0xd3,0x98,0xf1,0x53,0x6d,0x68,0x15,0x8f,0xe5, + 0x60,0x3f,0x17,0x29,0x55,0x8d,0x33,0xb1,0x45,0x64,0x64,0x8d, + 0x50,0x21,0x89,0xae,0xf6,0xfd,0x32,0x73 + }; + +__fips_constseg +static const unsigned char hmac_sha512_int_returnedbits[] = + { + 0x28,0x56,0x30,0x6f,0xf4,0xa1,0x48,0xe0,0xc9,0xf5,0x75,0x90, + 0xcc,0xfb,0xdf,0xdf,0x71,0x3d,0x0a,0x9a,0x03,0x65,0x3b,0x18, + 0x61,0xe3,0xd1,0xda,0xcc,0x4a,0xfe,0x55,0x38,0xf8,0x21,0x6b, + 0xfa,0x18,0x01,0x42,0x39,0x2f,0x99,0x53,0x38,0x15,0x82,0x34, + 0xc5,0x93,0x92,0xbc,0x4d,0x75,0x1a,0x5f,0x21,0x27,0xcc,0xa1, + 0xb1,0x57,0x69,0xe8 + }; + +__fips_constseg +static const unsigned char hmac_sha512_entropyinputreseed[] = + { + 0x8c,0x52,0x7e,0x77,0x72,0x3f,0xa3,0x04,0x97,0x10,0x9b,0x41, + 0xbd,0xe8,0xff,0x89,0xed,0x80,0xe3,0xbd,0xaa,0x12,0x2d,0xca, + 0x75,0x82,0x36,0x77,0x88,0xcd,0xa6,0x73 + }; + +__fips_constseg +static const unsigned char hmac_sha512_additionalinputreseed[] = + { + 0x7e,0x32,0xe3,0x69,0x69,0x07,0x34,0xa2,0x16,0xa2,0x5d,0x1a, + 0x10,0x91,0xd3,0xe2,0x21,0xa2,0xa3,0xdd,0xcd,0x0c,0x09,0x86, + 0x11,0xe1,0x50,0xff,0x5c,0xb7,0xeb,0x5c + }; + +__fips_constseg +static const unsigned char hmac_sha512_additionalinput2[] = + { + 0x7f,0x78,0x66,0xd8,0xfb,0x67,0xcf,0x8d,0x8c,0x08,0x30,0xa5, + 0xf8,0x7d,0xcf,0x44,0x59,0xce,0xf8,0xdf,0x58,0xd3,0x60,0xcb, + 0xa8,0x60,0xb9,0x07,0xc4,0xb1,0x95,0x48 + }; + +__fips_constseg +static const unsigned char hmac_sha512_returnedbits[] = + { + 0xdf,0xa7,0x36,0xd4,0xdc,0x5d,0x4d,0x31,0xad,0x69,0x46,0x9f, + 0xf1,0x7c,0xd7,0x3b,0x4f,0x55,0xf2,0xd7,0xb9,0x9d,0xad,0x7a, + 0x79,0x08,0x59,0xa5,0xdc,0x74,0xf5,0x9b,0x73,0xd2,0x13,0x25, + 0x0b,0x81,0x08,0x08,0x25,0xfb,0x39,0xf2,0xf0,0xa3,0xa4,0x8d, + 0xef,0x05,0x9e,0xb8,0xc7,0x52,0xe4,0x0e,0x42,0xaa,0x7c,0x79, + 0xc2,0xd6,0xfd,0xa5 + }; + Index: openssl-1.0.1h/crypto/fips/fips_dsa_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_dsa_selftest.c @@ -0,0 +1,193 @@ +/* ==================================================================== + * Copyright (c) 2011 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. + * + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/dsa.h> +#include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +static const unsigned char dsa_test_2048_p[] = { + 0xa8,0x53,0x78,0xd8,0xfd,0x3f,0x8d,0x72,0xec,0x74,0x18,0x08, + 0x0d,0xa2,0x13,0x17,0xe4,0x3e,0xc4,0xb6,0x2b,0xa8,0xc8,0x62, + 0x3b,0x7e,0x4d,0x04,0x44,0x1d,0xd1,0xa0,0x65,0x86,0x62,0x59, + 0x64,0x93,0xca,0x8e,0x9e,0x8f,0xbb,0x7e,0x34,0xaa,0xdd,0xb6, + 0x2e,0x5d,0x67,0xb6,0xd0,0x9a,0x6e,0x61,0xb7,0x69,0xe7,0xc3, + 0x52,0xaa,0x2b,0x10,0xe2,0x0c,0xa0,0x63,0x69,0x63,0xb5,0x52, + 0x3e,0x86,0x47,0x0d,0xec,0xbb,0xed,0xa0,0x27,0xe7,0x97,0xe7, + 0xb6,0x76,0x35,0xd4,0xd4,0x9c,0x30,0x70,0x0e,0x74,0xaf,0x8a, + 0x0f,0xf1,0x56,0xa8,0x01,0xaf,0x57,0xa2,0x6e,0x70,0x78,0xf1, + 0xd8,0x2f,0x74,0x90,0x8e,0xcb,0x6d,0x07,0xe7,0x0b,0x35,0x03, + 0xee,0xd9,0x4f,0xa3,0x2c,0xf1,0x7a,0x7f,0xc3,0xd6,0xcf,0x40, + 0xdc,0x7b,0x00,0x83,0x0e,0x6a,0x25,0x66,0xdc,0x07,0x3e,0x34, + 0x33,0x12,0x51,0x7c,0x6a,0xa5,0x15,0x2b,0x4b,0xfe,0xcd,0x2e, + 0x55,0x1f,0xee,0x34,0x63,0x18,0xa1,0x53,0x42,0x3c,0x99,0x6b, + 0x0d,0x5d,0xcb,0x91,0x02,0xae,0xdd,0x38,0x79,0x86,0x16,0xf1, + 0xf1,0xe0,0xd6,0xc4,0x03,0x52,0x5b,0x1f,0x9b,0x3d,0x4d,0xc7, + 0x66,0xde,0x2d,0xfc,0x4a,0x56,0xd7,0xb8,0xba,0x59,0x63,0xd6, + 0x0f,0x3e,0x16,0x31,0x88,0x70,0xad,0x43,0x69,0x52,0xe5,0x57, + 0x65,0x37,0x4e,0xab,0x85,0xe8,0xec,0x17,0xd6,0xb9,0xa4,0x54, + 0x7b,0x9b,0x5f,0x27,0x52,0xf3,0x10,0x5b,0xe8,0x09,0xb2,0x3a, + 0x2c,0x8d,0x74,0x69,0xdb,0x02,0xe2,0x4d,0x59,0x23,0x94,0xa7, + 0xdb,0xa0,0x69,0xe9 +}; + +static const unsigned char dsa_test_2048_q[] = { + 0xd2,0x77,0x04,0x4e,0x50,0xf5,0xa4,0xe3,0xf5,0x10,0xa5,0x0a, + 0x0b,0x84,0xfd,0xff,0xbc,0xa0,0x47,0xed,0x27,0x60,0x20,0x56, + 0x74,0x41,0xa0,0xa5 +}; + +static const unsigned char dsa_test_2048_g[] = { + 0x13,0xd7,0x54,0xe2,0x1f,0xd2,0x41,0x65,0x5d,0xa8,0x91,0xc5, + 0x22,0xa6,0x5a,0x72,0xa8,0x9b,0xdc,0x64,0xec,0x9b,0x54,0xa8, + 0x21,0xed,0x4a,0x89,0x8b,0x49,0x0e,0x0c,0x4f,0xcb,0x72,0x19, + 0x2a,0x4a,0x20,0xf5,0x41,0xf3,0xf2,0x92,0x53,0x99,0xf0,0xba, + 0xec,0xf9,0x29,0xaa,0xfb,0xf7,0x9d,0xfe,0x43,0x32,0x39,0x3b, + 0x32,0xcd,0x2e,0x2f,0xcf,0x27,0x2f,0x32,0xa6,0x27,0x43,0x4a, + 0x0d,0xf2,0x42,0xb7,0x5b,0x41,0x4d,0xf3,0x72,0x12,0x1e,0x53, + 0xa5,0x53,0xf2,0x22,0xf8,0x36,0xb0,0x00,0xf0,0x16,0x48,0x5b, + 0x6b,0xd0,0x89,0x84,0x51,0x80,0x1d,0xcd,0x8d,0xe6,0x4c,0xd5, + 0x36,0x56,0x96,0xff,0xc5,0x32,0xd5,0x28,0xc5,0x06,0x62,0x0a, + 0x94,0x2a,0x03,0x05,0x04,0x6d,0x8f,0x18,0x76,0x34,0x1f,0x1e, + 0x57,0x0b,0xc3,0x97,0x4b,0xa6,0xb9,0xa4,0x38,0xe9,0x70,0x23, + 0x02,0xa2,0xe6,0xe6,0x7b,0xfd,0x06,0xd3,0x2b,0xc6,0x79,0x96, + 0x22,0x71,0xd7,0xb4,0x0c,0xd7,0x2f,0x38,0x6e,0x64,0xe0,0xd7, + 0xef,0x86,0xca,0x8c,0xa5,0xd1,0x42,0x28,0xdc,0x2a,0x4f,0x16, + 0xe3,0x18,0x98,0x86,0xb5,0x99,0x06,0x74,0xf4,0x20,0x0f,0x3a, + 0x4c,0xf6,0x5a,0x3f,0x0d,0xdb,0xa1,0xfa,0x67,0x2d,0xff,0x2f, + 0x5e,0x14,0x3d,0x10,0xe4,0xe9,0x7a,0xe8,0x4f,0x6d,0xa0,0x95, + 0x35,0xd5,0xb9,0xdf,0x25,0x91,0x81,0xa7,0x9b,0x63,0xb0,0x69, + 0xe9,0x49,0x97,0x2b,0x02,0xba,0x36,0xb3,0x58,0x6a,0xab,0x7e, + 0x45,0xf3,0x22,0xf8,0x2e,0x4e,0x85,0xca,0x3a,0xb8,0x55,0x91, + 0xb3,0xc2,0xa9,0x66 +}; + +static const unsigned char dsa_test_2048_pub_key[] = { + 0x24,0x52,0xf3,0xcc,0xbe,0x9e,0xd5,0xca,0x7d,0xc7,0x4c,0x60, + 0x2b,0x99,0x22,0x6e,0x8f,0x2f,0xab,0x38,0xe7,0xd7,0xdd,0xfb, + 0x75,0x53,0x9b,0x17,0x15,0x5e,0x9f,0xcf,0xd1,0xab,0xa5,0x64, + 0xeb,0x85,0x35,0xd8,0x12,0xc9,0xc2,0xdc,0xf9,0x72,0x84,0x44, + 0x1b,0xc4,0x82,0x24,0x36,0x24,0xc7,0xf4,0x57,0x58,0x0c,0x1c, + 0x38,0xa5,0x7c,0x46,0xc4,0x57,0x39,0x24,0x70,0xed,0xb5,0x2c, + 0xb5,0xa6,0xe0,0x3f,0xe6,0x28,0x7b,0xb6,0xf4,0x9a,0x42,0xa2, + 0x06,0x5a,0x05,0x4f,0x03,0x08,0x39,0xdf,0x1f,0xd3,0x14,0x9c, + 0x4c,0xa0,0x53,0x1d,0xd8,0xca,0x8a,0xaa,0x9c,0xc7,0x33,0x71, + 0x93,0x38,0x73,0x48,0x33,0x61,0x18,0x22,0x45,0x45,0xe8,0x8c, + 0x80,0xff,0xd8,0x76,0x5d,0x74,0x36,0x03,0x33,0xcc,0xab,0x99, + 0x72,0x77,0x9b,0x65,0x25,0xa6,0x5b,0xdd,0x0d,0x10,0xc6,0x75, + 0xc1,0x09,0xbb,0xd3,0xe5,0xbe,0x4d,0x72,0xef,0x6e,0xba,0x6e, + 0x43,0x8d,0x52,0x26,0x23,0x7d,0xb8,0x88,0x37,0x9c,0x5f,0xcc, + 0x47,0xa3,0x84,0x7f,0xf6,0x37,0x11,0xba,0xed,0x6d,0x03,0xaf, + 0xe8,0x1e,0x69,0x4a,0x41,0x3b,0x68,0x0b,0xd3,0x8a,0xb4,0x90, + 0x3f,0x83,0x70,0xa7,0x07,0xef,0x55,0x1d,0x49,0x41,0x02,0x6d, + 0x95,0x79,0xd6,0x91,0xde,0x8e,0xda,0xa1,0x61,0x05,0xeb,0x9d, + 0xba,0x3c,0x2f,0x4c,0x1b,0xec,0x50,0x82,0x75,0xaa,0x02,0x07, + 0xe2,0x51,0xb5,0xec,0xcb,0x28,0x6a,0x4b,0x01,0xd4,0x49,0xd3, + 0x0a,0xcb,0x67,0x37,0x17,0xa0,0xd2,0xfb,0x3b,0x50,0xc8,0x93, + 0xf7,0xda,0xb1,0x4f +}; + +static const unsigned char dsa_test_2048_priv_key[] = { + 0x0c,0x4b,0x30,0x89,0xd1,0xb8,0x62,0xcb,0x3c,0x43,0x64,0x91, + 0xf0,0x91,0x54,0x70,0xc5,0x27,0x96,0xe3,0xac,0xbe,0xe8,0x00, + 0xec,0x55,0xf6,0xcc +}; + +static int corrupt_dsa; + +void FIPS_corrupt_dsa() + { + corrupt_dsa = 1; + } + +int FIPS_selftest_dsa() + { + DSA *dsa = NULL; + EVP_PKEY *pk = NULL; + int ret = 0; + + dsa = DSA_new(); + + if(dsa == NULL) + goto err; + + fips_load_key_component(dsa, p, dsa_test_2048); + fips_load_key_component(dsa, q, dsa_test_2048); + fips_load_key_component(dsa, g, dsa_test_2048); + fips_load_key_component(dsa, pub_key, dsa_test_2048); + fips_load_key_component(dsa, priv_key, dsa_test_2048); + + if (corrupt_dsa) + BN_set_bit(dsa->pub_key, 2047); + + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_assign_DSA(pk, dsa); + + if (!fips_pkey_signature_test(pk, NULL, 0, + NULL, 0, EVP_sha256(), 0, + "DSA SHA256")) + goto err; + ret = 1; + + err: + if (pk) + EVP_PKEY_free(pk); + else if (dsa) + DSA_free(dsa); + return ret; + } +#endif Index: openssl-1.0.1h/crypto/fips/fips_enc.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_enc.c @@ -0,0 +1,191 @@ +/* fipe/evp/fips_enc.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 <stdio.h> +#include <string.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/fips.h> + +const EVP_CIPHER *FIPS_get_cipherbynid(int nid) + { + switch (nid) + { + case NID_aes_128_cbc: + return EVP_aes_128_cbc(); + + case NID_aes_128_ccm: + return EVP_aes_128_ccm(); + + case NID_aes_128_cfb1: + return EVP_aes_128_cfb1(); + + case NID_aes_128_cfb128: + return EVP_aes_128_cfb128(); + + case NID_aes_128_cfb8: + return EVP_aes_128_cfb8(); + + case NID_aes_128_ctr: + return EVP_aes_128_ctr(); + + case NID_aes_128_ecb: + return EVP_aes_128_ecb(); + + case NID_aes_128_gcm: + return EVP_aes_128_gcm(); + + case NID_aes_128_ofb128: + return EVP_aes_128_ofb(); + + case NID_aes_128_xts: + return EVP_aes_128_xts(); + + case NID_aes_192_cbc: + return EVP_aes_192_cbc(); + + case NID_aes_192_ccm: + return EVP_aes_192_ccm(); + + case NID_aes_192_cfb1: + return EVP_aes_192_cfb1(); + + case NID_aes_192_cfb128: + return EVP_aes_192_cfb128(); + + case NID_aes_192_cfb8: + return EVP_aes_192_cfb8(); + + case NID_aes_192_ctr: + return EVP_aes_192_ctr(); + + case NID_aes_192_ecb: + return EVP_aes_192_ecb(); + + case NID_aes_192_gcm: + return EVP_aes_192_gcm(); + + case NID_aes_192_ofb128: + return EVP_aes_192_ofb(); + + case NID_aes_256_cbc: + return EVP_aes_256_cbc(); + + case NID_aes_256_ccm: + return EVP_aes_256_ccm(); + + case NID_aes_256_cfb1: + return EVP_aes_256_cfb1(); + + case NID_aes_256_cfb128: + return EVP_aes_256_cfb128(); + + case NID_aes_256_cfb8: + return EVP_aes_256_cfb8(); + + case NID_aes_256_ctr: + return EVP_aes_256_ctr(); + + case NID_aes_256_ecb: + return EVP_aes_256_ecb(); + + case NID_aes_256_gcm: + return EVP_aes_256_gcm(); + + case NID_aes_256_ofb128: + return EVP_aes_256_ofb(); + + case NID_aes_256_xts: + return EVP_aes_256_xts(); + + case NID_des_ede_ecb: + return EVP_des_ede(); + + case NID_des_ede3_ecb: + return EVP_des_ede3(); + + case NID_des_ede3_cbc: + return EVP_des_ede3_cbc(); + + case NID_des_ede3_cfb1: + return EVP_des_ede3_cfb1(); + + case NID_des_ede3_cfb64: + return EVP_des_ede3_cfb64(); + + case NID_des_ede3_cfb8: + return EVP_des_ede3_cfb8(); + + case NID_des_ede3_ofb64: + return EVP_des_ede3_ofb(); + + case NID_des_ede_cbc: + return EVP_des_ede_cbc(); + + case NID_des_ede_cfb64: + return EVP_des_ede_cfb64(); + + case NID_des_ede_ofb64: + return EVP_des_ede_ofb(); + + default: + return NULL; + + } + } + Index: openssl-1.0.1h/crypto/fips/fips_hmac_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_hmac_selftest.c @@ -0,0 +1,137 @@ +/* ==================================================================== + * 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 + * 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +#include <openssl/hmac.h> + +#ifdef OPENSSL_FIPS +typedef struct { + const EVP_MD *(*alg)(void); + const char *key, *iv; + unsigned char kaval[EVP_MAX_MD_SIZE]; +} HMAC_KAT; + +static const HMAC_KAT vector[] = { + { EVP_sha1, + /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */ + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19, + 0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c, + 0xc6,0xc7,0x5d,0x24 } + }, + { EVP_sha224, + /* just keep extending the above... */ + "0123456789:;<=>?@ABC", + "Sample #2", + { 0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb, + 0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa, + 0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b, + 0x8c,0x8d,0x12,0xc7 } + }, + { EVP_sha256, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09, + 0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34, + 0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38, + 0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9 } + }, + { EVP_sha384, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad, + 0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6, + 0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04, + 0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f, + 0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50, + 0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f } + }, + { EVP_sha512, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41, + 0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac, + 0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0, + 0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68, + 0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f, + 0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7, + 0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45, + 0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05 } + }, +}; + +int FIPS_selftest_hmac() + { + int n; + unsigned int outlen; + unsigned char out[EVP_MAX_MD_SIZE]; + const EVP_MD *md; + const HMAC_KAT *t; + + for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++) + { + md = (*t->alg)(); + HMAC(md,t->key,strlen(t->key), + (const unsigned char *)t->iv,strlen(t->iv), + out,&outlen); + + if(memcmp(out,t->kaval,outlen)) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED); + return 0; + } + } + return 1; + } +#endif Index: openssl-1.0.1h/crypto/fips/fips_locl.h =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_locl.h @@ -0,0 +1,71 @@ +/* ==================================================================== + * Copyright (c) 2011 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. + * + */ + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +#define FIPS_MAX_CIPHER_TEST_SIZE 32 +#define fips_load_key_component(key, comp, pre) \ + key->comp = BN_bin2bn(pre##_##comp, sizeof(pre##_##comp), key->comp); \ + if (!key->comp) \ + goto err + +#define fips_post_started(id, subid, ex) 1 +#define fips_post_success(id, subid, ex) 1 +#define fips_post_failed(id, subid, ex) 1 +#define fips_post_corrupt(id, subid, ex) 1 +#define fips_post_status() 1 + +#ifdef __cplusplus +} +#endif +#endif Index: openssl-1.0.1h/crypto/fips/fips_md.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_md.c @@ -0,0 +1,145 @@ +/* fips/evp/fips_md.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Minimal standalone FIPS versions of Digest operations */ + +#define OPENSSL_FIPSAPI + +#include <stdio.h> +#include <string.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/fips.h> + +const EVP_MD *FIPS_get_digestbynid(int nid) + { + switch (nid) + { + case NID_sha1: + return EVP_sha1(); + + case NID_sha224: + return EVP_sha224(); + + case NID_sha256: + return EVP_sha256(); + + case NID_sha384: + return EVP_sha384(); + + case NID_sha512: + return EVP_sha512(); + + default: + return NULL; + } + } Index: openssl-1.0.1h/crypto/fips/fips_post.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_post.c @@ -0,0 +1,205 @@ +/* ==================================================================== + * Copyright (c) 2011 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_FIPSAPI + +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bio.h> +#include <openssl/hmac.h> +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <string.h> +#include <limits.h> + +#ifdef OPENSSL_FIPS + +/* Power on self test (POST) support functions */ + +#include <openssl/fips.h> +#include "fips_locl.h" + +/* Run all selftests */ +int FIPS_selftest(void) + { + int rv = 1; + if (!FIPS_selftest_drbg()) + rv = 0; + if (!FIPS_selftest_x931()) + rv = 0; + if (!FIPS_selftest_sha1()) + rv = 0; + if (!FIPS_selftest_sha2()) + rv = 0; + if (!FIPS_selftest_hmac()) + rv = 0; + if (!FIPS_selftest_cmac()) + rv = 0; + if (!FIPS_selftest_aes()) + rv = 0; + if (!FIPS_selftest_aes_ccm()) + rv = 0; + if (!FIPS_selftest_aes_gcm()) + rv = 0; + if (!FIPS_selftest_aes_xts()) + rv = 0; + if (!FIPS_selftest_des()) + rv = 0; + if (!FIPS_selftest_rsa()) + rv = 0; + if (!FIPS_selftest_dsa()) + rv = 0; + return rv; + } + +/* Generalized public key test routine. Signs and verifies the data + * supplied in tbs using mesage digest md and setting option digest + * flags md_flags. If the 'kat' parameter is not NULL it will + * additionally check the signature matches it: a known answer test + * The string "fail_str" is used for identification purposes in case + * of failure. If "pkey" is NULL just perform a message digest check. + */ + +int fips_pkey_signature_test(EVP_PKEY *pkey, + const unsigned char *tbs, int tbslen, + const unsigned char *kat, unsigned int katlen, + const EVP_MD *digest, unsigned int md_flags, + const char *fail_str) + { + int ret = 0; + unsigned char sigtmp[256], *sig = sigtmp; + unsigned int siglen; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + + if (digest == NULL) + digest = EVP_sha256(); + + if ((pkey->type == EVP_PKEY_RSA) + && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp))) + { + sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa)); + if (!sig) + { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (tbslen == -1) + tbslen = strlen((char *)tbs); + + if (md_flags) + EVP_MD_CTX_set_flags(&mctx, md_flags); + + if (!EVP_SignInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_SignUpdate(&mctx, tbs, tbslen)) + goto error; + if (!EVP_SignFinal(&mctx, sig, &siglen, pkey)) + goto error; + + if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) + goto error; + + if (!EVP_VerifyInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_VerifyUpdate(&mctx, tbs, tbslen)) + goto error; + ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey); + + error: + if (sig != sigtmp) + OPENSSL_free(sig); + EVP_MD_CTX_cleanup(&mctx); + if (ret != 1) + { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE); + if (fail_str) + ERR_add_error_data(2, "Type=", fail_str); + return 0; + } + return 1; + } + +/* Generalized symmetric cipher test routine. Encrypt data, verify result + * against known answer, decrypt and compare with original plaintext. + */ + +int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len) + { + unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; + unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; + + OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); + memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); + memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); + + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) + return 0; + if (EVP_Cipher(ctx, citmp, plaintext, len) <= 0) + return 0; + if (memcmp(citmp, ciphertext, len)) + return 0; + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) + return 0; + if (EVP_Cipher(ctx, pltmp, citmp, len) <= 0) + return 0; + if (memcmp(pltmp, plaintext, len)) + return 0; + return 1; + } +#endif Index: openssl-1.0.1h/crypto/fips/fips_rand.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rand.c @@ -0,0 +1,457 @@ +/* ==================================================================== + * 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 + * 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. + * + */ + +/* + * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4. + */ +#include <openssl/crypto.h> +#include "e_os.h" + +/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't + be defined and gettimeofday() won't be declared with strict compilers + like DEC C in ANSI C mode. */ +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED 1 +#endif + +#include <openssl/rand.h> +#include <openssl/aes.h> +#include <openssl/err.h> +#include <openssl/fips_rand.h> +#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)) +# include <sys/time.h> +#endif +#if defined(OPENSSL_SYS_VXWORKS) +# include <time.h> +#endif +#include <assert.h> +#ifndef OPENSSL_SYS_WIN32 +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include <unistd.h> +# endif +#endif +#include <string.h> +#include <openssl/fips.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +void *OPENSSL_stderr(void); + +#define AES_BLOCK_LENGTH 16 + + +/* AES FIPS PRNG implementation */ + +typedef struct + { + int seeded; + int keyed; + int test_mode; + int second; + int error; + unsigned long counter; + AES_KEY ks; + int vpos; + /* Temporary storage for key if it equals seed length */ + unsigned char tmp_key[AES_BLOCK_LENGTH]; + unsigned char V[AES_BLOCK_LENGTH]; + unsigned char DT[AES_BLOCK_LENGTH]; + unsigned char last[AES_BLOCK_LENGTH]; + } FIPS_PRNG_CTX; + +static FIPS_PRNG_CTX sctx; + +static int fips_prng_fail = 0; + +void FIPS_x931_stick(int onoff) + { + fips_prng_fail = onoff; + } + +void FIPS_rng_stick(void) + { + FIPS_x931_stick(1); + } + +static void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx) + { + ctx->seeded = 0; + ctx->keyed = 0; + ctx->test_mode = 0; + ctx->counter = 0; + ctx->second = 0; + ctx->error = 0; + ctx->vpos = 0; + OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH); + OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY)); + } + + +static int fips_set_prng_key(FIPS_PRNG_CTX *ctx, + const unsigned char *key, unsigned int keylen) + { + if (FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_FIPS_SET_PRNG_KEY, FIPS_R_SELFTEST_FAILED); + return 0; + } + if (keylen != 16 && keylen != 24 && keylen != 32) + { + /* error: invalid key size */ + return 0; + } + AES_set_encrypt_key(key, keylen << 3, &ctx->ks); + if (keylen == 16) + { + memcpy(ctx->tmp_key, key, 16); + ctx->keyed = 2; + } + else + ctx->keyed = 1; + ctx->seeded = 0; + ctx->second = 0; + return 1; + } + +static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx, + const unsigned char *seed, unsigned int seedlen) + { + unsigned int i; + if (!ctx->keyed) + return 0; + /* In test mode seed is just supplied data */ + if (ctx->test_mode) + { + if (seedlen != AES_BLOCK_LENGTH) + return 0; + memcpy(ctx->V, seed, AES_BLOCK_LENGTH); + ctx->seeded = 1; + return 1; + } + /* Outside test mode XOR supplied data with existing seed */ + for (i = 0; i < seedlen; i++) + { + ctx->V[ctx->vpos++] ^= seed[i]; + if (ctx->vpos == AES_BLOCK_LENGTH) + { + ctx->vpos = 0; + /* Special case if first seed and key length equals + * block size check key and seed do not match. + */ + if (ctx->keyed == 2) + { + if (!memcmp(ctx->tmp_key, ctx->V, 16)) + { + RANDerr(RAND_F_FIPS_SET_PRNG_SEED, + RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY); + return 0; + } + OPENSSL_cleanse(ctx->tmp_key, 16); + ctx->keyed = 1; + } + ctx->seeded = 1; + } + } + return 1; + } + +static int fips_set_test_mode(FIPS_PRNG_CTX *ctx) + { + if (ctx->keyed) + { + RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED); + return 0; + } + ctx->test_mode = 1; + return 1; + } + +int FIPS_x931_test_mode(void) + { + return fips_set_test_mode(&sctx); + } + +int FIPS_rand_test_mode(void) + { + return fips_set_test_mode(&sctx); + } + + +int FIPS_x931_set_dt(unsigned char *dt) + { + if (!sctx.test_mode) + { + RANDerr(RAND_F_FIPS_X931_SET_DT,RAND_R_NOT_IN_TEST_MODE); + return 0; + } + memcpy(sctx.DT, dt, AES_BLOCK_LENGTH); + return 1; + } + +int FIPS_rand_set_dt(unsigned char *dt) + { + if (!sctx.test_mode) + { + RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE); + return 0; + } + memcpy(sctx.DT, dt, AES_BLOCK_LENGTH); + return 1; + } + +void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr) + { +#ifdef OPENSSL_SYS_WIN32 + FILETIME ft; +#elif defined(OPENSSL_SYS_VXWORKS) + struct timespec ts; +#else + struct timeval tv; +#endif + +#ifndef GETPID_IS_MEANINGLESS + unsigned long pid; +#endif + +#ifdef OPENSSL_SYS_WIN32 + GetSystemTimeAsFileTime(&ft); + buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff); + buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff); + buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff); + buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff); + buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff); + buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff); + buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff); + buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff); +#elif defined(OPENSSL_SYS_VXWORKS) + clock_gettime(CLOCK_REALTIME, &ts); + buf[0] = (unsigned char) (ts.tv_sec & 0xff); + buf[1] = (unsigned char) ((ts.tv_sec >> 8) & 0xff); + buf[2] = (unsigned char) ((ts.tv_sec >> 16) & 0xff); + buf[3] = (unsigned char) ((ts.tv_sec >> 24) & 0xff); + buf[4] = (unsigned char) (ts.tv_nsec & 0xff); + buf[5] = (unsigned char) ((ts.tv_nsec >> 8) & 0xff); + buf[6] = (unsigned char) ((ts.tv_nsec >> 16) & 0xff); + buf[7] = (unsigned char) ((ts.tv_nsec >> 24) & 0xff); +#else + gettimeofday(&tv,NULL); + buf[0] = (unsigned char) (tv.tv_sec & 0xff); + buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff); + buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff); + buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff); + buf[4] = (unsigned char) (tv.tv_usec & 0xff); + buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff); + buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff); + buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff); +#endif + buf[8] = (unsigned char) (*pctr & 0xff); + buf[9] = (unsigned char) ((*pctr >> 8) & 0xff); + buf[10] = (unsigned char) ((*pctr >> 16) & 0xff); + buf[11] = (unsigned char) ((*pctr >> 24) & 0xff); + + (*pctr)++; + + +#ifndef GETPID_IS_MEANINGLESS + pid=(unsigned long)getpid(); + buf[12] = (unsigned char) (pid & 0xff); + buf[13] = (unsigned char) ((pid >> 8) & 0xff); + buf[14] = (unsigned char) ((pid >> 16) & 0xff); + buf[15] = (unsigned char) ((pid >> 24) & 0xff); +#endif + } + +static int fips_rand(FIPS_PRNG_CTX *ctx, + unsigned char *out, unsigned int outlen) + { + unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH]; + unsigned char tmp[AES_BLOCK_LENGTH]; + int i; + if (ctx->error) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR); + return 0; + } + if (!ctx->keyed) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET); + return 0; + } + if (!ctx->seeded) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED); + return 0; + } + for (;;) + { + if (!ctx->test_mode) + FIPS_get_timevec(ctx->DT, &ctx->counter); + AES_encrypt(ctx->DT, I, &ctx->ks); + for (i = 0; i < AES_BLOCK_LENGTH; i++) + tmp[i] = I[i] ^ ctx->V[i]; + AES_encrypt(tmp, R, &ctx->ks); + for (i = 0; i < AES_BLOCK_LENGTH; i++) + tmp[i] = R[i] ^ I[i]; + AES_encrypt(tmp, ctx->V, &ctx->ks); + /* Continuous PRNG test */ + if (ctx->second) + { + if (fips_prng_fail) + memcpy(ctx->last, R, AES_BLOCK_LENGTH); + if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH)) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK); + ctx->error = 1; + fips_set_selftest_fail(); + return 0; + } + } + memcpy(ctx->last, R, AES_BLOCK_LENGTH); + if (!ctx->second) + { + ctx->second = 1; + if (!ctx->test_mode) + continue; + } + + if (outlen <= AES_BLOCK_LENGTH) + { + memcpy(out, R, outlen); + break; + } + + memcpy(out, R, AES_BLOCK_LENGTH); + out += AES_BLOCK_LENGTH; + outlen -= AES_BLOCK_LENGTH; + } + return 1; + } + + +int FIPS_x931_set_key(const unsigned char *key, int keylen) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_set_prng_key(&sctx, key, keylen); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen) + { + return FIPS_x931_set_key(key, keylen); + } + +int FIPS_x931_seed(const void *seed, int seedlen) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_set_prng_seed(&sctx, seed, seedlen); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + + +int FIPS_x931_bytes(unsigned char *out, int count) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_rand(&sctx, out, count); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +int FIPS_x931_status(void) + { + int ret; + CRYPTO_r_lock(CRYPTO_LOCK_RAND); + ret = sctx.seeded; + CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +void FIPS_x931_reset(void) + { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + fips_rand_prng_reset(&sctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + +static int fips_do_rand_seed(const void *seed, int seedlen) + { + FIPS_x931_seed(seed, seedlen); + return 1; + } + +static int fips_do_rand_add(const void *seed, int seedlen, + double add_entropy) + { + FIPS_x931_seed(seed, seedlen); + return 1; + } + +static const RAND_METHOD rand_x931_meth= + { + fips_do_rand_seed, + FIPS_x931_bytes, + FIPS_x931_reset, + fips_do_rand_add, + FIPS_x931_bytes, + FIPS_x931_status + }; + +const RAND_METHOD *FIPS_x931_method(void) +{ + return &rand_x931_meth; +} + +#endif Index: openssl-1.0.1h/crypto/fips/fips_rand.h =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rand.h @@ -0,0 +1,145 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#ifndef HEADER_FIPS_RAND_H +#define HEADER_FIPS_RAND_H + +#include <openssl/aes.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/rand.h> + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +int FIPS_x931_set_key(const unsigned char *key, int keylen); +int FIPS_x931_seed(const void *buf, int num); +int FIPS_x931_bytes(unsigned char *out, int outlen); + +int FIPS_x931_test_mode(void); +void FIPS_x931_reset(void); +int FIPS_x931_set_dt(unsigned char *dt); + +int FIPS_x931_status(void); + +const RAND_METHOD *FIPS_x931_method(void); + +typedef struct drbg_ctx_st DRBG_CTX; +/* DRBG external flags */ +/* Flag for CTR mode only: use derivation function ctr_df */ +#define DRBG_FLAG_CTR_USE_DF 0x1 +/* PRNG is in test state */ +#define DRBG_FLAG_TEST 0x2 + +DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags); +int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags); +int FIPS_drbg_instantiate(DRBG_CTX *dctx, + const unsigned char *pers, size_t perslen); +int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin, size_t adinlen); +int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); + +int FIPS_drbg_uninstantiate(DRBG_CTX *dctx); +void FIPS_drbg_free(DRBG_CTX *dctx); + +int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len), + void (*cleanup_entropy)(DRBG_CTX *ctx, unsigned char *out, size_t olen), + size_t entropy_blocklen, + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len), + void (*cleanup_nonce)(DRBG_CTX *ctx, unsigned char *out, size_t olen)); + +int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx, + size_t (*get_adin)(DRBG_CTX *ctx, unsigned char **pout), + void (*cleanup_adin)(DRBG_CTX *ctx, unsigned char *out, size_t olen), + int (*rand_seed_cb)(DRBG_CTX *ctx, const void *buf, int num), + int (*rand_add_cb)(DRBG_CTX *ctx, + const void *buf, int num, double entropy)); + +void *FIPS_drbg_get_app_data(DRBG_CTX *ctx); +void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data); +size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx); +int FIPS_drbg_get_strength(DRBG_CTX *dctx); +void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval); +void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval); + +int FIPS_drbg_health_check(DRBG_CTX *dctx); + +DRBG_CTX *FIPS_get_default_drbg(void); +const RAND_METHOD *FIPS_drbg_method(void); + + +int FIPS_rand_set_method(const RAND_METHOD *meth); +const RAND_METHOD *FIPS_rand_get_method(void); + +void FIPS_rand_set_bits(int nbits); + +int FIPS_rand_strength(void); + +/* 1.0.0 compat functions */ +int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen); +int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num); +int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen); +int FIPS_rand_test_mode(void); +void FIPS_rand_reset(void); +int FIPS_rand_set_dt(unsigned char *dt); +int FIPS_rand_status(void); +const RAND_METHOD *FIPS_rand_method(void); + +#ifdef __cplusplus +} +#endif +#endif +#endif Index: openssl-1.0.1h/crypto/fips/fips_rand_lcl.h =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rand_lcl.h @@ -0,0 +1,219 @@ +/* fips/rand/fips_rand_lcl.h */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 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. + * ==================================================================== + */ + +typedef struct drbg_hash_ctx_st DRBG_HASH_CTX; +typedef struct drbg_hmac_ctx_st DRBG_HMAC_CTX; +typedef struct drbg_ctr_ctx_st DRBG_CTR_CTX; + +/* 888 bits from 10.1 table 2 */ +#define HASH_PRNG_MAX_SEEDLEN 111 + +struct drbg_hash_ctx_st + { + const EVP_MD *md; + EVP_MD_CTX mctx; + unsigned char V[HASH_PRNG_MAX_SEEDLEN]; + unsigned char C[HASH_PRNG_MAX_SEEDLEN]; + /* Temporary value storage: should always exceed max digest length */ + unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN]; + }; + +struct drbg_hmac_ctx_st + { + const EVP_MD *md; + HMAC_CTX hctx; + unsigned char K[EVP_MAX_MD_SIZE]; + unsigned char V[EVP_MAX_MD_SIZE]; + }; + +struct drbg_ctr_ctx_st + { + AES_KEY ks; + size_t keylen; + unsigned char K[32]; + unsigned char V[16]; + /* Temp variables used by derivation function */ + AES_KEY df_ks; + AES_KEY df_kxks; + /* Temporary block storage used by ctr_df */ + unsigned char bltmp[16]; + size_t bltmp_pos; + unsigned char KX[48]; + }; + +/* DRBG internal flags */ + +/* Functions shouldn't call err library */ +#define DRBG_FLAG_NOERR 0x1 +/* Custom reseed checking */ +#define DRBG_CUSTOM_RESEED 0x2 + +/* DRBG status values */ +/* not initialised */ +#define DRBG_STATUS_UNINITIALISED 0 +/* ok and ready to generate random bits */ +#define DRBG_STATUS_READY 1 +/* reseed required */ +#define DRBG_STATUS_RESEED 2 +/* fatal error condition */ +#define DRBG_STATUS_ERROR 3 + +/* A default maximum length: larger than any reasonable value used in pratice */ + +#define DRBG_MAX_LENGTH 0x7ffffff0 +/* Maximum DRBG block length: all md sizes are bigger than cipher blocks sizes + * so use max digest length. + */ +#define DRBG_MAX_BLOCK EVP_MAX_MD_SIZE + +#define DRBG_HEALTH_INTERVAL (1 << 24) + +/* DRBG context structure */ + +struct drbg_ctx_st + { + /* First types common to all implementations */ + /* DRBG type: a NID for the underlying algorithm */ + int type; + /* Various external flags */ + unsigned int xflags; + /* Various internal use only flags */ + unsigned int iflags; + /* Used for periodic health checks */ + int health_check_cnt, health_check_interval; + + /* The following parameters are setup by mechanism drbg_init() call */ + int strength; + size_t blocklength; + size_t max_request; + + size_t min_entropy, max_entropy; + size_t min_nonce, max_nonce; + size_t max_pers, max_adin; + unsigned int reseed_counter; + unsigned int reseed_interval; + size_t seedlen; + int status; + /* Application data: typically used by test get_entropy */ + void *app_data; + /* Implementation specific structures */ + union + { + DRBG_HASH_CTX hash; + DRBG_HMAC_CTX hmac; + DRBG_CTR_CTX ctr; + } d; + /* Initialiase PRNG and setup callbacks below */ + int (*init)(DRBG_CTX *ctx, int nid, int security, unsigned int flags); + /* Intantiate PRNG */ + int (*instantiate)(DRBG_CTX *ctx, + const unsigned char *ent, size_t entlen, + const unsigned char *nonce, size_t noncelen, + const unsigned char *pers, size_t perslen); + /* reseed */ + int (*reseed)(DRBG_CTX *ctx, + const unsigned char *ent, size_t entlen, + const unsigned char *adin, size_t adinlen); + /* generat output */ + int (*generate)(DRBG_CTX *ctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adinlen); + /* uninstantiate */ + int (*uninstantiate)(DRBG_CTX *ctx); + + /* Entropy source block length */ + size_t entropy_blocklen; + + /* entropy gathering function */ + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len); + /* Indicates we have finished with entropy buffer */ + void (*cleanup_entropy)(DRBG_CTX *ctx, unsigned char *out, size_t olen); + + /* nonce gathering function */ + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len); + /* Indicates we have finished with nonce buffer */ + void (*cleanup_nonce)(DRBG_CTX *ctx, unsigned char *out, size_t olen); + + /* Continuous random number test temporary area */ + /* Last block */ + unsigned char lb[EVP_MAX_MD_SIZE]; + /* set if lb is valid */ + int lb_valid; + + /* Callbacks used when called through RAND interface */ + /* Get any additional input for generate */ + size_t (*get_adin)(DRBG_CTX *ctx, unsigned char **pout); + void (*cleanup_adin)(DRBG_CTX *ctx, unsigned char *out, size_t olen); + /* Callback for RAND_seed(), RAND_add() */ + int (*rand_seed_cb)(DRBG_CTX *ctx, const void *buf, int num); + int (*rand_add_cb)(DRBG_CTX *ctx, + const void *buf, int num, double entropy); + }; + + +int fips_drbg_ctr_init(DRBG_CTX *dctx); +int fips_drbg_hash_init(DRBG_CTX *dctx); +int fips_drbg_hmac_init(DRBG_CTX *dctx); +int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags); +int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out); + +const struct env_md_st *FIPS_get_digestbynid(int nid); + +const struct evp_cipher_st *FIPS_get_cipherbynid(int nid); + +#define FIPS_digestinit EVP_DigestInit +#define FIPS_digestupdate EVP_DigestUpdate +#define FIPS_digestfinal EVP_DigestFinal +#define M_EVP_MD_size EVP_MD_size Index: openssl-1.0.1h/crypto/fips/fips_rand_lib.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rand_lib.c @@ -0,0 +1,191 @@ +/* ==================================================================== + * Copyright (c) 2011 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. + * + */ + +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "e_os.h" + +/* FIPS API for PRNG use. Similar to RAND functionality but without + * ENGINE and additional checking for non-FIPS rand methods. + */ + +static const RAND_METHOD *fips_rand_meth = NULL; +static int fips_approved_rand_meth = 0; +static int fips_rand_bits = 0; + +/* Allows application to override number of bits and uses non-FIPS methods */ +void FIPS_rand_set_bits(int nbits) + { + fips_rand_bits = nbits; + } + +int FIPS_rand_set_method(const RAND_METHOD *meth) + { + if (!fips_rand_bits) + { + if (meth == FIPS_drbg_method()) + fips_approved_rand_meth = 1; + else if (meth == FIPS_x931_method()) + fips_approved_rand_meth = 2; + else + { + fips_approved_rand_meth = 0; + if (FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD, + FIPS_R_NON_FIPS_METHOD); + return 0; + } + } + } + fips_rand_meth = meth; + return 1; + } + +const RAND_METHOD *FIPS_rand_get_method(void) + { + return fips_rand_meth; + } + +const RAND_METHOD *FIPS_rand_method(void) + { + return FIPS_rand_get_method(); + } + +void FIPS_rand_reset(void) + { + if (fips_rand_meth && fips_rand_meth->cleanup) + fips_rand_meth->cleanup(); + } + +int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num) + { + if (!fips_approved_rand_meth && FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->seed) + fips_rand_meth->seed(buf,num); + return 1; + } + +void FIPS_rand_add(const void *buf, int num, double entropy) + { + if (!fips_approved_rand_meth && FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_RAND_ADD, FIPS_R_NON_FIPS_METHOD); + return; + } + if (fips_rand_meth && fips_rand_meth->add) + fips_rand_meth->add(buf,num,entropy); + } + +int FIPS_rand_bytes(unsigned char *buf, FIPS_RAND_SIZE_T num) + { + if (!fips_approved_rand_meth && FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->bytes) + return fips_rand_meth->bytes(buf,num); + return 0; + } + +int FIPS_rand_pseudo_bytes(unsigned char *buf, int num) + { + if (!fips_approved_rand_meth && FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_RAND_PSEUDO_BYTES, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->pseudorand) + return fips_rand_meth->pseudorand(buf,num); + return -1; + } + +int FIPS_rand_status(void) + { + if (!fips_approved_rand_meth && FIPS_module_mode()) + { + FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->status) + return fips_rand_meth->status(); + return 0; + } + +/* Return instantiated strength of PRNG. For DRBG this is an internal + * parameter. For X9.31 PRNG it is 80 bits (from SP800-131). Any other + * type of PRNG is not approved and returns 0 in FIPS mode and maximum + * 256 outside FIPS mode. + */ + +int FIPS_rand_strength(void) + { + if (fips_rand_bits) + return fips_rand_bits; + if (fips_approved_rand_meth == 1) + return FIPS_drbg_get_strength(FIPS_get_default_drbg()); + else if (fips_approved_rand_meth == 2) + return 80; + else if (fips_approved_rand_meth == 0) + { + if (FIPS_module_mode()) + return 0; + else + return 256; + } + return 0; + } Index: openssl-1.0.1h/crypto/fips/fips_rand_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rand_selftest.c @@ -0,0 +1,183 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + + + +typedef struct + { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; + } AES_PRNG_TV; + +/* The following test vectors are taken directly from the RGNVS spec */ + +static unsigned char aes_128_key[16] = + {0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42, + 0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02}; + +static AES_PRNG_TV aes_128_tv = + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55, + 0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41} + }; + +static unsigned char aes_192_key[24] = + {0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e, + 0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc, + 0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b}; + +static AES_PRNG_TV aes_192_tv = + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef, + 0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93} + }; + +static unsigned char aes_256_key[32] = + {0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d, + 0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f, + 0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5, + 0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb}; + +static AES_PRNG_TV aes_256_tv = + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc, + 0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72} + }; + +void FIPS_corrupt_rng() + { + aes_192_tv.V[0]++; + } + +#define fips_x931_test(key, tv) \ + do_x931_test(key, sizeof key, &tv) + +static int do_x931_test(unsigned char *key, int keylen, + AES_PRNG_TV *tv) + { + unsigned char R[16], V[16]; + int rv = 1; + memcpy(V, tv->V, sizeof(V)); + if (!FIPS_x931_set_key(key, keylen)) + return 0; + if (!fips_post_started(FIPS_TEST_X931, keylen, NULL)) + return 1; + if (!fips_post_corrupt(FIPS_TEST_X931, keylen, NULL)) + V[0]++; + FIPS_x931_seed(V, 16); + FIPS_x931_set_dt(tv->DT); + FIPS_x931_bytes(R, 16); + if (memcmp(R, tv->R, 16)) + { + fips_post_failed(FIPS_TEST_X931, keylen, NULL); + rv = 0; + } + else if (!fips_post_success(FIPS_TEST_X931, keylen, NULL)) + return 0; + return rv; + } + +int FIPS_selftest_x931() + { + int rv = 1; + FIPS_x931_reset(); + if (!FIPS_x931_test_mode()) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_X931,FIPS_R_SELFTEST_FAILED); + return 0; + } + if (!fips_x931_test(aes_128_key,aes_128_tv)) + rv = 0; + if (!fips_x931_test(aes_192_key, aes_192_tv)) + rv = 0; + if (!fips_x931_test(aes_256_key, aes_256_tv)) + rv = 0; + FIPS_x931_reset(); + if (!rv) + FIPSerr(FIPS_F_FIPS_SELFTEST_X931,FIPS_R_SELFTEST_FAILED); + return rv; + } + +int FIPS_selftest_rng(void) + { + return FIPS_selftest_x931(); + } + +#endif Index: openssl-1.0.1h/crypto/fips/fips_randtest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_randtest.c @@ -0,0 +1,250 @@ +/* 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.] + */ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bn.h> + +#include "e_os.h" + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) +{ + printf("No FIPS RAND support\n"); + return(0); +} + +#else + +#include "fips_utl.h" +#include <openssl/fips.h> + +typedef struct + { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; + } AES_PRNG_MCT; + +static const unsigned char aes_128_mct_key[16] = + {0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5, + 0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48}; + +static const AES_PRNG_MCT aes_128_mct_tv = { + /* DT */ + {0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b, + 0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac}, + /* V */ + {0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97, + 0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1}, + /* R */ + {0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb, + 0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73} +}; + +static const unsigned char aes_192_mct_key[24] = + {0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73, + 0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91, + 0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a}; + +static const AES_PRNG_MCT aes_192_mct_tv = { + /* DT */ + {0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9, + 0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52}, + /* V */ + {0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64, + 0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d}, + /* R */ + {0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21, + 0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47} +}; + +static const unsigned char aes_256_mct_key[32] = + {0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a, + 0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0, + 0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d, + 0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50}; + +static const AES_PRNG_MCT aes_256_mct_tv = { + /* DT */ + {0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee, + 0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c}, + /* V */ + {0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1, + 0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca}, + /* R */ + {0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1, + 0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d} +}; + +static void dump(const unsigned char *b,int n) + { + while(n-- > 0) + { + printf(" %02x",*b++); + } + } + +static void compare(const unsigned char *result,const unsigned char *expected, + int n) + { + int i; + + for(i=0 ; i < n ; ++i) + if(result[i] != expected[i]) + { + puts("Random test failed, got:"); + dump(result,n); + puts("\n expected:"); + dump(expected,n); + putchar('\n'); + EXIT(1); + } + } + + +static void run_test(const unsigned char *key, int keylen, + const AES_PRNG_MCT *tv) + { + unsigned char buf[16], dt[16]; + int i, j; + FIPS_x931_reset(); + FIPS_x931_test_mode(); + FIPS_x931_set_key(key, keylen); + FIPS_x931_seed(tv->V, 16); + memcpy(dt, tv->DT, 16); + for (i = 0; i < 10000; i++) + { + FIPS_x931_set_dt(dt); + FIPS_x931_bytes(buf, 16); + /* Increment DT */ + for (j = 15; j >= 0; j--) + { + dt[j]++; + if (dt[j]) + break; + } + } + + compare(buf,tv->R, 16); + } + +int main() + { + run_test(aes_128_mct_key, 16, &aes_128_mct_tv); + printf("FIPS PRNG test 1 done\n"); + run_test(aes_192_mct_key, 24, &aes_192_mct_tv); + printf("FIPS PRNG test 2 done\n"); + run_test(aes_256_mct_key, 32, &aes_256_mct_tv); + printf("FIPS PRNG test 3 done\n"); + return 0; + } + +#endif Index: openssl-1.0.1h/crypto/fips/fips_rsa_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rsa_selftest.c @@ -0,0 +1,444 @@ +/* ==================================================================== + * 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/opensslconf.h> + +#ifdef OPENSSL_FIPS + +static const 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 corrupt_rsa; + +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); + if (corrupt_rsa) + BN_set_bit(key->n, 1024); + 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() + { + corrupt_rsa = 1; + } + +/* 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; + EVP_PKEY *pk = NULL; + + if ((key=RSA_new()) == NULL) + goto err; + setrsakey(key); + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_assign_RSA(pk, key); + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA1, sizeof(kat_RSA_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "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(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "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(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "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(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "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(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "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(), EVP_MD_CTX_FLAG_PAD_PSS, + "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(), EVP_MD_CTX_FLAG_PAD_PSS, + "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(), EVP_MD_CTX_FLAG_PAD_PSS, + "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(), EVP_MD_CTX_FLAG_PAD_PSS, + "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(), EVP_MD_CTX_FLAG_PAD_PSS, + "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(), EVP_MD_CTX_FLAG_PAD_X931, + "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(), EVP_MD_CTX_FLAG_PAD_X931, + "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(), EVP_MD_CTX_FLAG_PAD_X931, + "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(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA512 X931")) + goto err; + + + ret = 1; + + err: + if (pk) + EVP_PKEY_free(pk); + else if (key) + RSA_free(key); + return ret; + } + +#endif /* def OPENSSL_FIPS */ Index: openssl-1.0.1h/crypto/fips/fips_rsa_x931g.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_rsa_x931g.c @@ -0,0 +1,282 @@ +/* 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 <stdio.h> +#include <string.h> +#include <time.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> + +extern int fips_check_rsa(RSA *rsa); +#endif + +/* 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(); + if (!ctx) + goto err; + BN_CTX_start(ctx); + + 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 && 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; + +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) && + (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; + } +#endif + + 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; + +#ifdef OPENSSL_FIPS + if(!fips_check_rsa(rsa)) + goto error; +#endif + + ok = 1; + + error: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (ok) + return 1; + + return 0; + + } Index: openssl-1.0.1h/crypto/fips/fips_sha_selftest.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_sha_selftest.c @@ -0,0 +1,140 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +#include <openssl/evp.h> +#include <openssl/sha.h> + +#ifdef OPENSSL_FIPS +static const char test[][60]= + { + "", + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + }; + +static const unsigned char ret[][SHA_DIGEST_LENGTH]= + { + { 0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55, + 0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09 }, + { 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e, + 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d }, + { 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae, + 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1 }, + }; + +static int corrupt_sha; + +void FIPS_corrupt_sha1() + { + corrupt_sha = 1; + } + +int FIPS_selftest_sha1() + { + int n; + + for(n=0 ; n<sizeof(test)/sizeof(test[0]) ; ++n) + { + unsigned char md[SHA_DIGEST_LENGTH]; + + EVP_Digest(test[n],strlen(test[n])+corrupt_sha,md, NULL, EVP_sha1(), NULL); + if(memcmp(md,ret[n],sizeof md)) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1,FIPS_R_SELFTEST_FAILED); + return 0; + } + } + return 1; + } + +static const unsigned char msg_sha256[] = { 0xfa, 0x48, 0x59, 0x2a, 0xe1, 0xae, 0x1f, 0x30, + 0xfc }; +static const unsigned char dig_sha256[] = { 0xf7, 0x26, 0xd8, 0x98, 0x47, 0x91, 0x68, 0x5b, + 0x9e, 0x39, 0xb2, 0x58, 0xbb, 0x75, 0xbf, 0x01, + 0x17, 0x0c, 0x84, 0x00, 0x01, 0x7a, 0x94, 0x83, + 0xf3, 0x0b, 0x15, 0x84, 0x4b, 0x69, 0x88, 0x8a }; + +static const unsigned char msg_sha512[] = { 0x37, 0xd1, 0x35, 0x9d, 0x18, 0x41, 0xe9, 0xb7, + 0x6d, 0x9a, 0x13, 0xda, 0x5f, 0xf3, 0xbd }; +static const unsigned char dig_sha512[] = { 0x11, 0x13, 0xc4, 0x19, 0xed, 0x2b, 0x1d, 0x16, + 0x11, 0xeb, 0x9b, 0xbe, 0xf0, 0x7f, 0xcf, 0x44, + 0x8b, 0xd7, 0x57, 0xbd, 0x8d, 0xa9, 0x25, 0xb0, + 0x47, 0x25, 0xd6, 0x6c, 0x9a, 0x54, 0x7f, 0x8f, + 0x0b, 0x53, 0x1a, 0x10, 0x68, 0x32, 0x03, 0x38, + 0x82, 0xc4, 0x87, 0xc4, 0xea, 0x0e, 0xd1, 0x04, + 0xa9, 0x98, 0xc1, 0x05, 0xa3, 0xf3, 0xf8, 0xb1, + 0xaf, 0xbc, 0xd9, 0x78, 0x7e, 0xee, 0x3d, 0x43 }; + +int FIPS_selftest_sha2(void) + { + unsigned char md[SHA512_DIGEST_LENGTH]; + + EVP_Digest(msg_sha256, sizeof(msg_sha256), md, NULL, EVP_sha256(), NULL); + if(memcmp(dig_sha256, md, sizeof(dig_sha256))) + { + FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED); + return 0; + } + + EVP_Digest(msg_sha512, sizeof(msg_sha512), md, NULL, EVP_sha512(), NULL); + if(memcmp(dig_sha512, md, sizeof(dig_sha512))) + { + FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED); + return 0; + } + + return 1; + } + +#endif Index: openssl-1.0.1h/crypto/fips/fips_standalone_hmac.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_standalone_hmac.c @@ -0,0 +1,180 @@ +/* ==================================================================== + * Copyright (c) 2003 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. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <openssl/opensslconf.h> +#include <openssl/sha.h> +#include <openssl/hmac.h> + +#ifndef FIPSCANISTER_O +int FIPS_selftest_failed() { return 0; } +void FIPS_selftest_check() {} +void OPENSSL_cleanse(void *p,size_t len) {} +#endif + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) + +unsigned int OPENSSL_ia32cap_P[2]; +#endif + +#ifdef OPENSSL_FIPS + +static void hmac_init(SHA256_CTX *md_ctx,SHA256_CTX *o_ctx, + const char *key) + { + size_t len=strlen(key); + int i; + unsigned char keymd[HMAC_MAX_MD_CBLOCK]; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + if (len > SHA_CBLOCK) + { + SHA256_Init(md_ctx); + SHA256_Update(md_ctx,key,len); + SHA256_Final(keymd,md_ctx); + len=SHA256_DIGEST_LENGTH; + } + else + memcpy(keymd,key,len); + memset(&keymd[len],'\0',HMAC_MAX_MD_CBLOCK-len); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x36^keymd[i]; + SHA256_Init(md_ctx); + SHA256_Update(md_ctx,pad,SHA256_CBLOCK); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x5c^keymd[i]; + SHA256_Init(o_ctx); + SHA256_Update(o_ctx,pad,SHA256_CBLOCK); + } + +static void hmac_final(unsigned char *md,SHA256_CTX *md_ctx,SHA256_CTX *o_ctx) + { + unsigned char buf[SHA256_DIGEST_LENGTH]; + + SHA256_Final(buf,md_ctx); + SHA256_Update(o_ctx,buf,sizeof buf); + SHA256_Final(md,o_ctx); + } + +#endif + +int main(int argc,char **argv) + { +#ifdef OPENSSL_FIPS + static char key[]="orboDeJITITejsirpADONivirpUkvarP"; + int n,binary=0; + + if(argc < 2) + { + fprintf(stderr,"%s [<file>]+\n",argv[0]); + exit(1); + } + + n=1; + if (!strcmp(argv[n],"-binary")) + { + n++; + binary=1; /* emit binary fingerprint... */ + } + + for(; n < argc ; ++n) + { + FILE *f=fopen(argv[n],"rb"); + SHA256_CTX md_ctx,o_ctx; + unsigned char md[SHA256_DIGEST_LENGTH]; + int i; + + if(!f) + { + perror(argv[n]); + exit(2); + } + + hmac_init(&md_ctx,&o_ctx,key); + for( ; ; ) + { + char buf[1024]; + size_t l=fread(buf,1,sizeof buf,f); + + if(l == 0) + { + if(ferror(f)) + { + perror(argv[n]); + exit(3); + } + else + break; + } + SHA256_Update(&md_ctx,buf,l); + } + hmac_final(md,&md_ctx,&o_ctx); + + if (binary) + { + fwrite(md,SHA256_DIGEST_LENGTH,1,stdout); + break; /* ... for single(!) file */ + } + +/* printf("HMAC-SHA1(%s)= ",argv[n]); */ + for(i=0 ; i < SHA256_DIGEST_LENGTH ; ++i) + printf("%02x",md[i]); + printf("\n"); + } +#endif + return 0; + } + + Index: openssl-1.0.1h/crypto/fips/fips_test_suite.c =================================================================== --- /dev/null +++ openssl-1.0.1h/crypto/fips/fips_test_suite.c @@ -0,0 +1,588 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * + * This command is intended as a test driver for the FIPS-140 testing + * lab performing FIPS-140 validation. It demonstrates the use of the + * OpenSSL library ito perform a variety of common cryptographic + * functions. A power-up self test is demonstrated by deliberately + * pointing to an invalid executable hash + * + * Contributed by Steve Marquess. + * + */ +#include <stdio.h> +#include <assert.h> +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <openssl/aes.h> +#include <openssl/des.h> +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/dh.h> +#include <openssl/hmac.h> +#include <openssl/err.h> + +#include <openssl/bn.h> +#include <openssl/rand.h> +#include <openssl/sha.h> + + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) + { + printf("No FIPS support\n"); + return(0); + } +#else + +#include <openssl/fips.h> +#include "fips_utl.h" + +/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext +*/ +static int FIPS_aes_test(void) + { + int ret = 0; + unsigned char pltmp[16]; + unsigned char citmp[16]; + unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned char plaintext[16] = "etaonrishdlcu"; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 16); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 16); + if (memcmp(pltmp, plaintext, 16)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; + } + +static int FIPS_des3_test(void) + { + int ret = 0; + unsigned char pltmp[8]; + unsigned char citmp[8]; + unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, + 19,20,21,22,23,24}; + unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 8); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 8); + if (memcmp(pltmp, plaintext, 8)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; + } + +/* + * DSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_dsa_test(int bad) + { + DSA *dsa = NULL; + EVP_PKEY pk; + unsigned char dgst[] = "etaonrishdlc"; + unsigned char buf[60]; + unsigned int slen; + int r = 0; + EVP_MD_CTX mctx; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + dsa = DSA_new(); + if (!dsa) + goto end; + if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL)) + goto end; + if (!DSA_generate_key(dsa)) + goto end; + if (bad) + BN_add_word(dsa->pub_key, 1); + + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (dsa) + DSA_free(dsa); + if (r != 1) + return 0; + return 1; + } + +/* + * RSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_rsa_test(int bad) + { + RSA *key; + unsigned char input_ptext[] = "etaonrishdlc"; + unsigned char buf[256]; + unsigned int slen; + BIGNUM *bn; + EVP_MD_CTX mctx; + EVP_PKEY pk; + int r = 0; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + key = RSA_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024,bn,NULL)) + return 0; + BN_free(bn); + if (bad) + BN_add_word(key->n, 1); + + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (key) + RSA_free(key); + if (r != 1) + return 0; + return 1; + } + +/* SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha1_test() + { + unsigned char digest[SHA_DIGEST_LENGTH] = + { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 }; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha1(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha256_test() + { + unsigned char digest[SHA256_DIGEST_LENGTH] = + {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91, + 0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57}; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA256_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha256(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha512_test() + { + unsigned char digest[SHA512_DIGEST_LENGTH] = + {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca, + 0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a, + 0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22, + 0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3}; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA512_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha512(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* HMAC-SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha1_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70, + 0xb2, 0xfb, 0xec, 0xc6}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA224: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha224_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35, + 0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha256_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87, + 0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA384: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha384_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10, + 0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08, + 0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha512_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6, + 0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1, + 0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c, + 0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + + +/* DH: generate shared parameters +*/ +static int dh_test() + { + DH *dh; + ERR_clear_error(); + dh = FIPS_dh_new(); + if (!dh) + return 0; + if (!DH_generate_parameters_ex(dh, 1024, 2, NULL)) + return 0; + FIPS_dh_free(dh); + return 1; + } + +/* Zeroize +*/ +static int Zeroize() + { + RSA *key; + BIGNUM *bn; + unsigned char userkey[16] = + { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 }; + int i, n; + + key = FIPS_rsa_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024,bn,NULL)) + return 0; + BN_free(bn); + + n = BN_num_bytes(key->d); + printf(" Generated %d byte RSA private key\n", n); + printf("\tBN key before overwriting:\n"); + do_bn_print(stdout, key->d); + BN_rand(key->d,n*8,-1,0); + printf("\tBN key after overwriting:\n"); + do_bn_print(stdout, key->d); + + printf("\tchar buffer key before overwriting: \n\t\t"); + for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); + printf("\n"); + RAND_bytes(userkey, sizeof userkey); + printf("\tchar buffer key after overwriting: \n\t\t"); + for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); + printf("\n"); + + return 1; + } + +static int Error; +const char * Fail(const char *msg) + { + do_print_errors(); + Error++; + return msg; + } + +int main(int argc,char **argv) + { + + int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0; + int bad_rsa = 0, bad_dsa = 0; + int do_rng_stick = 0; + int no_exit = 0; + + printf("\tFIPS-mode test application\n\n"); + + /* Load entropy from external file, if any */ + RAND_load_file(".rnd", 1024); + + if (argv[1]) { + /* Corrupted KAT tests */ + if (!strcmp(argv[1], "aes")) { + FIPS_corrupt_aes(); + printf("AES encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "des")) { + FIPS_corrupt_des(); + printf("DES3-ECB encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "dsa")) { + FIPS_corrupt_dsa(); + printf("DSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsa")) { + FIPS_corrupt_rsa(); + printf("RSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsakey")) { + printf("RSA key generation and signature validation with corrupted key...\n"); + bad_rsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "rsakeygen")) { + do_corrupt_rsa_keygen = 1; + no_exit = 1; + printf("RSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "dsakey")) { + printf("DSA key generation and signature validation with corrupted key...\n"); + bad_dsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "dsakeygen")) { + do_corrupt_dsa_keygen = 1; + no_exit = 1; + printf("DSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "sha1")) { + FIPS_corrupt_sha1(); + printf("SHA-1 hash with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rng")) { + FIPS_corrupt_rng(); + } else if (!strcmp(argv[1], "rngstick")) { + do_rng_stick = 1; + no_exit = 1; + printf("RNG test with stuck continuous test...\n"); + } else { + printf("Bad argument \"%s\"\n", argv[1]); + exit(1); + } + if (!no_exit) { + if (!FIPS_mode_set(1)) { + do_print_errors(); + printf("Power-up self test failed\n"); + exit(1); + } + printf("Power-up self test successful\n"); + exit(0); + } + } + + /* Non-Approved cryptographic operation + */ + printf("1. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf( dh_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* Power-up self test + */ + ERR_clear_error(); + printf("2. Automatic power-up self test..."); + if (!FIPS_mode_set(1)) + { + do_print_errors(); + printf(Fail("FAILED!\n")); + exit(1); + } + printf("successful\n"); + if (do_corrupt_dsa_keygen) + FIPS_corrupt_dsa_keygen(); + if (do_corrupt_rsa_keygen) + FIPS_corrupt_rsa_keygen(); + if (do_rng_stick) + FIPS_rng_stick(); + + /* AES encryption/decryption + */ + printf("3. AES encryption/decryption..."); + printf( FIPS_aes_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* RSA key generation and encryption/decryption + */ + printf("4. RSA key generation and encryption/decryption..."); + printf( FIPS_rsa_test(bad_rsa) ? "successful\n" : Fail("FAILED!\n") ); + + /* DES-CBC encryption/decryption + */ + printf("5. DES-ECB encryption/decryption..."); + printf( FIPS_des3_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* DSA key generation and signature validation + */ + printf("6. DSA key generation and signature validation..."); + printf( FIPS_dsa_test(bad_dsa) ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-1 hash + */ + printf("7a. SHA-1 hash..."); + printf( FIPS_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-256 hash + */ + printf("7b. SHA-256 hash..."); + printf( FIPS_sha256_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-512 hash + */ + printf("7c. SHA-512 hash..."); + printf( FIPS_sha512_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-1 hash + */ + printf("7d. HMAC-SHA-1 hash..."); + printf( FIPS_hmac_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-224 hash + */ + printf("7e. HMAC-SHA-224 hash..."); + printf( FIPS_hmac_sha224_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-256 hash + */ + printf("7f. HMAC-SHA-256 hash..."); + printf( FIPS_hmac_sha256_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-384 hash + */ + printf("7g. HMAC-SHA-384 hash..."); + printf( FIPS_hmac_sha384_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-512 hash + */ + printf("7h. HMAC-SHA-512 hash..."); + printf( FIPS_hmac_sha512_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* Non-Approved cryptographic operation + */ + printf("8. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf( dh_test() ? "successful as expected\n" + : Fail("failed INCORRECTLY!\n") ); + + /* Zeroization + */ + printf("9. Zero-ization...\n"); + printf( Zeroize() ? "\tsuccessful as expected\n" + : Fail("\tfailed INCORRECTLY!\n") ); + + printf("\nAll tests completed with %d errors\n", Error); + return Error ? 1 : 0; + } + +#endif Index: openssl-1.0.1h/crypto/hmac/hmac.c =================================================================== --- openssl-1.0.1h.orig/crypto/hmac/hmac.c +++ openssl-1.0.1h/crypto/hmac/hmac.c @@ -81,11 +81,6 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS); return 0; } - /* Other algorithm blocking will be done in FIPS_cmac_init, - * via FIPS_hmac_init_ex(). - */ - if (!impl && !ctx->i_ctx.engine) - return FIPS_hmac_init_ex(ctx, key, len, md, NULL); } #endif @@ -99,6 +94,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo if (key != NULL) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS) + && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))) + goto err; +#endif reset=1; j=EVP_MD_block_size(md); OPENSSL_assert(j <= (int)sizeof(ctx->key)); @@ -155,10 +157,6 @@ int HMAC_Init(HMAC_CTX *ctx, const void int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - return FIPS_hmac_update(ctx, data, len); -#endif return EVP_DigestUpdate(&ctx->md_ctx,data,len); } @@ -166,10 +164,6 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned c { unsigned int i; unsigned char buf[EVP_MAX_MD_SIZE]; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - return FIPS_hmac_final(ctx, md, len); -#endif if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i)) goto err; @@ -209,13 +203,6 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_C void HMAC_CTX_cleanup(HMAC_CTX *ctx) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - { - FIPS_hmac_ctx_cleanup(ctx); - return; - } -#endif EVP_MD_CTX_cleanup(&ctx->i_ctx); EVP_MD_CTX_cleanup(&ctx->o_ctx); EVP_MD_CTX_cleanup(&ctx->md_ctx); Index: openssl-1.0.1h/crypto/md2/md2_dgst.c =================================================================== --- openssl-1.0.1h.orig/crypto/md2/md2_dgst.c +++ openssl-1.0.1h/crypto/md2/md2_dgst.c @@ -62,6 +62,11 @@ #include <openssl/md2.h> #include <openssl/opensslv.h> #include <openssl/crypto.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + +#include <openssl/err.h> const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT; @@ -116,7 +121,7 @@ const char *MD2_options(void) return("md2(int)"); } -fips_md_init(MD2) +nonfips_md_init(MD2) { c->num=0; memset(c->state,0,sizeof c->state); Index: openssl-1.0.1h/crypto/md4/md4_dgst.c =================================================================== --- openssl-1.0.1h.orig/crypto/md4/md4_dgst.c +++ openssl-1.0.1h/crypto/md4/md4_dgst.c @@ -71,7 +71,7 @@ const char MD4_version[]="MD4" OPENSSL_V #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -fips_md_init(MD4) +nonfips_md_init(MD4) { memset (c,0,sizeof(*c)); c->A=INIT_DATA_A; Index: openssl-1.0.1h/crypto/md5/md5_dgst.c =================================================================== --- openssl-1.0.1h.orig/crypto/md5/md5_dgst.c +++ openssl-1.0.1h/crypto/md5/md5_dgst.c @@ -71,7 +71,7 @@ const char MD5_version[]="MD5" OPENSSL_V #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -fips_md_init(MD5) +nonfips_md_init(MD5) { memset (c,0,sizeof(*c)); c->A=INIT_DATA_A; Index: openssl-1.0.1h/crypto/mdc2/mdc2dgst.c =================================================================== --- openssl-1.0.1h.orig/crypto/mdc2/mdc2dgst.c +++ openssl-1.0.1h/crypto/mdc2/mdc2dgst.c @@ -76,7 +76,7 @@ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); -fips_md_init(MDC2) +nonfips_md_init(MDC2) { c->num=0; c->pad_type=1; Index: openssl-1.0.1h/crypto/o_fips.c =================================================================== --- openssl-1.0.1h.orig/crypto/o_fips.c +++ openssl-1.0.1h/crypto/o_fips.c @@ -79,6 +79,8 @@ int FIPS_mode_set(int r) #ifndef FIPS_AUTH_USER_PASS #define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password" #endif + if (r && FIPS_module_mode()) /* can be implicitly initialized by OPENSSL_init() */ + return 1; if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS)) return 0; if (r) Index: openssl-1.0.1h/crypto/o_init.c =================================================================== --- openssl-1.0.1h.orig/crypto/o_init.c +++ openssl-1.0.1h/crypto/o_init.c @@ -55,28 +55,68 @@ #include <e_os.h> #include <openssl/err.h> #ifdef OPENSSL_FIPS +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> #include <openssl/fips.h> #include <openssl/rand.h> + +#define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" + +static void init_fips_mode(void) + { + char buf[2] = "0"; + int fd; + + if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) + { + buf[0] = '1'; + } + else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) + { + while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); + close(fd); + } + /* Failure reading the fips mode switch file means just not + * switching into FIPS mode. We would break too many things + * otherwise. + */ + + if (buf[0] == '1') + { + FIPS_mode_set(1); + } + } #endif /* Perform any essential OpenSSL initialization operations. * Currently only sets FIPS callbacks */ -void OPENSSL_init(void) +void OPENSSL_init_library(void) { static int done = 0; if (done) return; done = 1; #ifdef OPENSSL_FIPS - FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); - FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); - FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); RAND_init_fips(); + init_fips_mode(); + if (!FIPS_mode()) + { + /* Clean up prematurely set default rand method */ + RAND_set_rand_method(NULL); + } #endif #if 0 fprintf(stderr, "Called OPENSSL_init\n"); #endif } +void OPENSSL_init(void) + { + OPENSSL_init_library(); + } Index: openssl-1.0.1h/crypto/opensslconf.h =================================================================== --- openssl-1.0.1h.orig/crypto/opensslconf.h +++ openssl-1.0.1h/crypto/opensslconf.h @@ -1,6 +1,9 @@ /* opensslconf.h */ /* WARNING: Generated automatically from opensslconf.h.in by Configure. */ +/* FIPS */ +#define OPENSSL_FIPS + /* OpenSSL was configured with the following options: */ #ifndef OPENSSL_DOING_MAKEDEPEND Index: openssl-1.0.1h/crypto/opensslconf.h.in =================================================================== --- openssl-1.0.1h.orig/crypto/opensslconf.h.in +++ openssl-1.0.1h/crypto/opensslconf.h.in @@ -1,5 +1,20 @@ /* crypto/opensslconf.h.in */ +#ifdef OPENSSL_DOING_MAKEDEPEND + +/* Include any symbols here that have to be explicitly set to enable a feature + * that should be visible to makedepend. + * + * [Our "make depend" doesn't actually look at this, we use actual build settings + * instead; we want to make it easy to remove subdirectories with disabled algorithms.] + */ + +#ifndef OPENSSL_FIPS +#define OPENSSL_FIPS +#endif + +#endif + /* Generate 80386 code? */ #undef I386_ONLY Index: openssl-1.0.1h/crypto/pkcs12/p12_crt.c =================================================================== --- openssl-1.0.1h.orig/crypto/pkcs12/p12_crt.c +++ openssl-1.0.1h/crypto/pkcs12/p12_crt.c @@ -59,6 +59,10 @@ #include <stdio.h> #include "cryptlib.h" #include <openssl/pkcs12.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); Index: openssl-1.0.1h/crypto/rand/md_rand.c =================================================================== --- openssl-1.0.1h.orig/crypto/rand/md_rand.c +++ openssl-1.0.1h/crypto/rand/md_rand.c @@ -395,7 +395,10 @@ static int ssleay_rand_bytes(unsigned ch CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); crypto_lock_rand = 1; - if (!initialized) + /* always poll for external entropy in FIPS mode, drbg provides the + * expansion + */ + if (!initialized || FIPS_module_mode()) { RAND_poll(); initialized = 1; Index: openssl-1.0.1h/crypto/rand/rand.h =================================================================== --- openssl-1.0.1h.orig/crypto/rand/rand.h +++ openssl-1.0.1h/crypto/rand/rand.h @@ -133,16 +133,34 @@ void ERR_load_RAND_strings(void); /* Error codes for the RAND functions. */ /* Function codes. */ +#define RAND_F_ENG_RAND_GET_RAND_METHOD 108 +#define RAND_F_FIPS_RAND 103 +#define RAND_F_FIPS_RAND_BYTES 102 +#define RAND_F_FIPS_RAND_SET_DT 106 +#define RAND_F_FIPS_X931_SET_DT 106 +#define RAND_F_FIPS_SET_DT 104 +#define RAND_F_FIPS_SET_PRNG_SEED 107 +#define RAND_F_FIPS_SET_TEST_MODE 105 #define RAND_F_RAND_GET_RAND_METHOD 101 -#define RAND_F_RAND_INIT_FIPS 102 +#define RAND_F_RAND_INIT_FIPS 109 #define RAND_F_SSLEAY_RAND_BYTES 100 /* Reason codes. */ -#define RAND_R_DUAL_EC_DRBG_DISABLED 104 -#define RAND_R_ERROR_INITIALISING_DRBG 102 -#define RAND_R_ERROR_INSTANTIATING_DRBG 103 -#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +#define RAND_R_DUAL_EC_DRBG_DISABLED 114 +#define RAND_R_ERROR_INITIALISING_DRBG 112 +#define RAND_R_ERROR_INSTANTIATING_DRBG 113 +#define RAND_R_NON_FIPS_METHOD 105 +#define RAND_R_NOT_IN_TEST_MODE 106 +#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 111 +#define RAND_R_NO_KEY_SET 107 +#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101 +#define RAND_R_PRNG_ERROR 108 +#define RAND_R_PRNG_KEYED 109 +#define RAND_R_PRNG_NOT_REKEYED 102 +#define RAND_R_PRNG_NOT_RESEEDED 103 #define RAND_R_PRNG_NOT_SEEDED 100 +#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110 +#define RAND_R_PRNG_STUCK 104 #ifdef __cplusplus } Index: openssl-1.0.1h/crypto/ripemd/rmd_dgst.c =================================================================== --- openssl-1.0.1h.orig/crypto/ripemd/rmd_dgst.c +++ openssl-1.0.1h/crypto/ripemd/rmd_dgst.c @@ -70,7 +70,7 @@ const char RMD160_version[]="RIPE-MD160" void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num); # endif -fips_md_init(RIPEMD160) +nonfips_md_init(RIPEMD160) { memset (c,0,sizeof(*c)); c->A=RIPEMD160_A; Index: openssl-1.0.1h/crypto/rsa/rsa.h =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa.h +++ openssl-1.0.1h/crypto/rsa/rsa.h @@ -164,6 +164,8 @@ struct rsa_st # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif +#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif @@ -290,6 +292,11 @@ RSA * RSA_generate_key(int bits, unsigne /* New version */ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +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); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb); int RSA_check_key(const RSA *); /* next 4 return -1 on error */ @@ -487,7 +494,7 @@ void ERR_load_RSA_strings(void); #define RSA_F_RSA_PADDING_ADD_NONE 107 #define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 #define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 -#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 158 #define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 #define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 #define RSA_F_RSA_PADDING_ADD_SSLV23 110 @@ -500,20 +507,22 @@ void ERR_load_RSA_strings(void); #define RSA_F_RSA_PADDING_CHECK_X931 128 #define RSA_F_RSA_PRINT 115 #define RSA_F_RSA_PRINT_FP 116 -#define RSA_F_RSA_PRIVATE_DECRYPT 150 -#define RSA_F_RSA_PRIVATE_ENCRYPT 151 +#define RSA_F_RSA_PRIVATE_DECRYPT 157 +#define RSA_F_RSA_PRIVATE_ENCRYPT 148 #define RSA_F_RSA_PRIV_DECODE 137 #define RSA_F_RSA_PRIV_ENCODE 138 -#define RSA_F_RSA_PUBLIC_DECRYPT 152 +#define RSA_F_RSA_PUBLIC_DECRYPT 149 #define RSA_F_RSA_PUBLIC_ENCRYPT 153 #define RSA_F_RSA_PUB_DECODE 139 #define RSA_F_RSA_SETUP_BLINDING 136 +#define RSA_F_RSA_SET_DEFAULT_METHOD 150 +#define RSA_F_RSA_SET_METHOD 151 #define RSA_F_RSA_SIGN 117 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 #define RSA_F_RSA_VERIFY 119 #define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 #define RSA_F_RSA_VERIFY_PKCS1_PSS 126 -#define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 +#define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 152 /* Reason codes. */ #define RSA_R_ALGORITHM_MISMATCH 100 @@ -542,21 +551,22 @@ void ERR_load_RSA_strings(void); #define RSA_R_INVALID_MGF1_MD 156 #define RSA_R_INVALID_PADDING 138 #define RSA_R_INVALID_PADDING_MODE 141 -#define RSA_R_INVALID_PSS_PARAMETERS 149 +#define RSA_R_INVALID_PSS_PARAMETERS 157 #define RSA_R_INVALID_PSS_SALTLEN 146 -#define RSA_R_INVALID_SALT_LENGTH 150 +#define RSA_R_INVALID_SALT_LENGTH 158 #define RSA_R_INVALID_TRAILER 139 #define RSA_R_INVALID_X931_DIGEST 142 #define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 #define RSA_R_KEY_SIZE_TOO_SMALL 120 #define RSA_R_LAST_OCTET_INVALID 134 #define RSA_R_MODULUS_TOO_LARGE 105 -#define RSA_R_NON_FIPS_RSA_METHOD 157 +#define RSA_R_NON_FIPS_RSA_METHOD 149 +#define RSA_R_NON_FIPS_METHOD 149 #define RSA_R_NO_PUBLIC_EXPONENT 140 #define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 #define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 #define RSA_R_OAEP_DECODING_ERROR 121 -#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 150 #define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 #define RSA_R_PADDING_CHECK_FAILED 114 #define RSA_R_P_NOT_PRIME 128 Index: openssl-1.0.1h/crypto/rsa/rsa_crpt.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_crpt.c +++ openssl-1.0.1h/crypto/rsa/rsa_crpt.c @@ -90,10 +90,9 @@ int RSA_private_encrypt(int flen, const RSA *rsa, int padding) { #ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); + RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif @@ -118,10 +117,9 @@ int RSA_public_decrypt(int flen, const u RSA *rsa, int padding) { #ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); + RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif Index: openssl-1.0.1h/crypto/rsa/rsa_eay.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_eay.c +++ openssl-1.0.1h/crypto/rsa/rsa_eay.c @@ -114,6 +114,10 @@ #include <openssl/bn.h> #include <openssl/rsa.h> #include <openssl/rand.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif #ifndef RSA_NULL @@ -138,7 +142,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth={ BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ RSA_eay_init, RSA_eay_finish, - 0, /* flags */ + RSA_FLAG_FIPS_METHOD, /* flags */ NULL, 0, /* rsa_sign */ 0, /* rsa_verify */ @@ -158,6 +162,24 @@ static int RSA_eay_public_encrypt(int fl unsigned char *buf=NULL; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if(FIPS_mode()) + { + if (FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); @@ -361,6 +383,24 @@ static int RSA_eay_private_encrypt(int f BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -504,6 +544,24 @@ static int RSA_eay_private_decrypt(int f BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -639,6 +697,24 @@ static int RSA_eay_public_decrypt(int fl unsigned char *buf=NULL; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); @@ -897,6 +973,9 @@ err: static int RSA_eay_init(RSA *rsa) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE; return(1); } Index: openssl-1.0.1h/crypto/rsa/rsa_err.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_err.c +++ openssl-1.0.1h/crypto/rsa/rsa_err.c @@ -121,6 +121,8 @@ static ERR_STRING_DATA RSA_str_functs[]= {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"}, {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, +{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"}, +{ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"}, {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"}, {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, Index: openssl-1.0.1h/crypto/rsa/rsa_gen.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_gen.c +++ openssl-1.0.1h/crypto/rsa/rsa_gen.c @@ -69,6 +69,78 @@ #include <openssl/rsa.h> #ifdef OPENSSL_FIPS #include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/evp.h> + +static int fips_rsa_pairwise_fail = 0; + +void FIPS_corrupt_rsa_keygen(void) + { + fips_rsa_pairwise_fail = 1; + } + +int fips_check_rsa(RSA *rsa) + { + const unsigned char tbs[] = "RSA Pairwise Check Data"; + unsigned char *ctbuf = NULL, *ptbuf = NULL; + int len, ret = 0; + EVP_PKEY *pk; + + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_set1_RSA(pk, rsa); + + /* Perform pairwise consistency signature test */ + if (!fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL) + || !fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL) + || !fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL)) + goto err; + /* Now perform pairwise consistency encrypt/decrypt test */ + ctbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ctbuf) + goto err; + + len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING); + if (len <= 0) + goto err; + /* Check ciphertext doesn't match plaintext */ + if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len)) + goto err; + ptbuf = OPENSSL_malloc(RSA_size(rsa)); + + if (!ptbuf) + goto err; + len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); + if (len != (sizeof(tbs) - 1)) + goto err; + if (memcmp(ptbuf, tbs, len)) + goto err; + + ret = 1; + + if (!ptbuf) + goto err; + + err: + if (ret == 0) + { + fips_set_selftest_fail(); + FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); + } + + if (ctbuf) + OPENSSL_free(ctbuf); + if (ptbuf) + OPENSSL_free(ptbuf); + if (pk) + EVP_PKEY_free(pk); + + return ret; + } #endif static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); @@ -81,7 +153,7 @@ static int rsa_builtin_keygen(RSA *rsa, int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { #ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + if (FIPS_module_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD); @@ -90,10 +162,6 @@ int RSA_generate_key_ex(RSA *rsa, int bi #endif if(rsa->meth->rsa_keygen) return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_rsa_generate_key_ex(rsa, bits, e_value, cb); -#endif return rsa_builtin_keygen(rsa, bits, e_value, cb); } @@ -105,6 +173,23 @@ static int rsa_builtin_keygen(RSA *rsa, int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_module_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT); + return 0; + } + } +#endif + ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -216,6 +301,17 @@ static int rsa_builtin_keygen(RSA *rsa, p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; +#ifdef OPENSSL_FIPS + if (FIPS_module_mode()) + { + if (fips_rsa_pairwise_fail) + BN_add_word(rsa->n, 1); + + if(!fips_check_rsa(rsa)) + goto err; + } +#endif + ok=1; err: if (ok == -1) Index: openssl-1.0.1h/crypto/rsa/rsa_lib.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_lib.c +++ openssl-1.0.1h/crypto/rsa/rsa_lib.c @@ -84,6 +84,13 @@ RSA *RSA_new(void) void RSA_set_default_method(const RSA_METHOD *meth) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) + { + RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD); + return; + } +#endif default_RSA_meth = meth; } @@ -91,18 +98,11 @@ const RSA_METHOD *RSA_get_default_method { if (default_RSA_meth == NULL) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_rsa_pkcs1_ssleay(); - else - return RSA_PKCS1_SSLeay(); -#else #ifdef RSA_NULL default_RSA_meth=RSA_null_method(); #else default_RSA_meth=RSA_PKCS1_SSLeay(); #endif -#endif } return default_RSA_meth; @@ -118,6 +118,13 @@ int RSA_set_method(RSA *rsa, const RSA_M /* NB: The caller is specifically setting a method, so it's not up to us * to deal with which ENGINE it comes from. */ const RSA_METHOD *mtmp; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) + { + RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD); + return 0; + } +#endif mtmp = rsa->meth; if (mtmp->finish) mtmp->finish(rsa); #ifndef OPENSSL_NO_ENGINE @@ -170,6 +177,18 @@ RSA *RSA_new_method(ENGINE *engine) } } #endif +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) + { + RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD); +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return NULL; + } +#endif ret->pad=0; ret->version=0; @@ -188,7 +207,7 @@ RSA *RSA_new_method(ENGINE *engine) ret->blinding=NULL; ret->mt_blinding=NULL; ret->bignum_data=NULL; - ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + ret->flags=ret->meth->flags; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { #ifndef OPENSSL_NO_ENGINE Index: openssl-1.0.1h/crypto/rsa/rsa_pmeth.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_pmeth.c +++ openssl-1.0.1h/crypto/rsa/rsa_pmeth.c @@ -206,22 +206,6 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *c RSA_R_INVALID_DIGEST_LENGTH); return -1; } -#ifdef OPENSSL_FIPS - if (ret > 0) - { - unsigned int slen; - ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, - sig, &slen); - if (ret > 0) - *siglen = slen; - else - *siglen = 0; - return ret; - } -#endif if (EVP_MD_type(rctx->md) == NID_mdc2) { @@ -354,19 +338,6 @@ static int pkey_rsa_verify(EVP_PKEY_CTX #endif if (rctx->md) { -#ifdef OPENSSL_FIPS - if (rv > 0) - { - return FIPS_rsa_verify_digest(rsa, - tbs, tbslen, - rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, - sig, siglen); - - } -#endif if (rctx->pad_mode == RSA_PKCS1_PADDING) return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); Index: openssl-1.0.1h/crypto/rsa/rsa_sign.c =================================================================== --- openssl-1.0.1h.orig/crypto/rsa/rsa_sign.c +++ openssl-1.0.1h/crypto/rsa/rsa_sign.c @@ -138,7 +138,8 @@ int RSA_sign(int type, const unsigned ch i2d_X509_SIG(&sig,&p); s=tmps; } - i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING); + /* NB: call underlying method directly to avoid FIPS blocking */ + i = rsa->meth->rsa_priv_enc ? rsa->meth->rsa_priv_enc(i,s,sigret,rsa,RSA_PKCS1_PADDING) : 0; if (i <= 0) ret=0; else @@ -178,8 +179,8 @@ int int_rsa_verify(int dtype, const unsi if((dtype == NID_md5_sha1) && rm) { - i = RSA_public_decrypt((int)siglen, - sigbuf,rm,rsa,RSA_PKCS1_PADDING); + i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen, + sigbuf,rm,rsa,RSA_PKCS1_PADDING) : 0; if (i <= 0) return 0; *prm_len = i; @@ -196,7 +197,8 @@ int int_rsa_verify(int dtype, const unsi RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; } - i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); + /* NB: call underlying method directly to avoid FIPS blocking */ + i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING) : 0; if (i <= 0) goto err; /* Oddball MDC2 case: signature can be OCTET STRING. Index: openssl-1.0.1h/crypto/sha/sha.h =================================================================== --- openssl-1.0.1h.orig/crypto/sha/sha.h +++ openssl-1.0.1h/crypto/sha/sha.h @@ -116,9 +116,6 @@ unsigned char *SHA(const unsigned char * void SHA_Transform(SHA_CTX *c, const unsigned char *data); #endif #ifndef OPENSSL_NO_SHA1 -#ifdef OPENSSL_FIPS -int private_SHA1_Init(SHA_CTX *c); -#endif int SHA1_Init(SHA_CTX *c); int SHA1_Update(SHA_CTX *c, const void *data, size_t len); int SHA1_Final(unsigned char *md, SHA_CTX *c); @@ -141,10 +138,6 @@ typedef struct SHA256state_st } SHA256_CTX; #ifndef OPENSSL_NO_SHA256 -#ifdef OPENSSL_FIPS -int private_SHA224_Init(SHA256_CTX *c); -int private_SHA256_Init(SHA256_CTX *c); -#endif int SHA224_Init(SHA256_CTX *c); int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); int SHA224_Final(unsigned char *md, SHA256_CTX *c); @@ -192,10 +185,6 @@ typedef struct SHA512state_st #endif #ifndef OPENSSL_NO_SHA512 -#ifdef OPENSSL_FIPS -int private_SHA384_Init(SHA512_CTX *c); -int private_SHA512_Init(SHA512_CTX *c); -#endif int SHA384_Init(SHA512_CTX *c); int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); int SHA384_Final(unsigned char *md, SHA512_CTX *c); Index: openssl-1.0.1h/crypto/sha/sha256.c =================================================================== --- openssl-1.0.1h.orig/crypto/sha/sha256.c +++ openssl-1.0.1h/crypto/sha/sha256.c @@ -12,12 +12,19 @@ #include <openssl/crypto.h> #include <openssl/sha.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + #include <openssl/opensslv.h> const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; fips_md_init_ctx(SHA224, SHA256) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset (c,0,sizeof(*c)); c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; @@ -29,6 +36,9 @@ fips_md_init_ctx(SHA224, SHA256) fips_md_init(SHA256) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset (c,0,sizeof(*c)); c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; Index: openssl-1.0.1h/crypto/sha/sha512.c =================================================================== --- openssl-1.0.1h.orig/crypto/sha/sha512.c +++ openssl-1.0.1h/crypto/sha/sha512.c @@ -5,6 +5,10 @@ * ==================================================================== */ #include <openssl/opensslconf.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) /* * IMPLEMENTATION NOTES. @@ -61,6 +65,9 @@ const char SHA512_version[]="SHA-512" OP fips_md_init_ctx(SHA384, SHA512) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif c->h[0]=U64(0xcbbb9d5dc1059ed8); c->h[1]=U64(0x629a292a367cd507); c->h[2]=U64(0x9159015a3070dd17); @@ -77,6 +84,9 @@ fips_md_init_ctx(SHA384, SHA512) fips_md_init(SHA512) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif c->h[0]=U64(0x6a09e667f3bcc908); c->h[1]=U64(0xbb67ae8584caa73b); c->h[2]=U64(0x3c6ef372fe94f82b); Index: openssl-1.0.1h/crypto/sha/sha_locl.h =================================================================== --- openssl-1.0.1h.orig/crypto/sha/sha_locl.h +++ openssl-1.0.1h/crypto/sha/sha_locl.h @@ -123,11 +123,14 @@ void sha1_block_data_order (SHA_CTX *c, #define INIT_DATA_h4 0xc3d2e1f0UL #ifdef SHA_0 -fips_md_init(SHA) +nonfips_md_init(SHA) #else fips_md_init_ctx(SHA1, SHA) #endif { +#if defined(SHA_1) && defined(OPENSSL_FIPS) + FIPS_selftest_check(); +#endif memset (c,0,sizeof(*c)); c->h0=INIT_DATA_h0; c->h1=INIT_DATA_h1; Index: openssl-1.0.1h/crypto/whrlpool/wp_dgst.c =================================================================== --- openssl-1.0.1h.orig/crypto/whrlpool/wp_dgst.c +++ openssl-1.0.1h/crypto/whrlpool/wp_dgst.c @@ -55,7 +55,7 @@ #include <openssl/crypto.h> #include <string.h> -fips_md_init(WHIRLPOOL) +nonfips_md_init(WHIRLPOOL) { memset (c,0,sizeof(*c)); return(1); Index: openssl-1.0.1h/ssl/d1_srvr.c =================================================================== --- openssl-1.0.1h.orig/ssl/d1_srvr.c +++ openssl-1.0.1h/ssl/d1_srvr.c @@ -1384,6 +1384,8 @@ int dtls1_send_server_key_exchange(SSL * j=0; for (num=2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); Index: openssl-1.0.1h/ssl/ssl_algs.c =================================================================== --- openssl-1.0.1h.orig/ssl/ssl_algs.c +++ openssl-1.0.1h/ssl/ssl_algs.c @@ -64,6 +64,12 @@ int SSL_library_init(void) { +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (!FIPS_mode()) + { +#endif + #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); @@ -137,6 +143,50 @@ int SSL_library_init(void) EVP_add_digest(EVP_sha()); EVP_add_digest(EVP_dss()); #endif +#ifdef OPENSSL_FIPS + } + else + { +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_ede3_cbc()); +#endif +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_256_gcm()); +#endif +#ifndef OPENSSL_NO_MD5 + /* needed even in the FIPS mode for TLS MAC */ + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5,"ssl2-md5"); + EVP_add_digest_alias(SN_md5,"ssl3-md5"); +#endif +#ifndef OPENSSL_NO_SHA + EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) + EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ + EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1,"dss1"); +#endif +#ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +#endif + } +#endif #ifndef OPENSSL_NO_COMP /* This will initialise the built-in compression algorithms. The value returned is a STACK_OF(SSL_COMP), but that can
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor