around them.
NOTE: because two new locks are added, this adds potential binary
incompatibility with earlier versions in the 0.9.7 series. However,
those locks will only ever be touched when FIPS_mode_set() is called
and after, thanks to a variable that's only changed from 0 to 1 once
(when FIPS_mode_set() is called). So basically, as long as FIPS mode
hasn't been engaged explicitely by the calling application, the new
locks are treated as if they didn't exist at all, thus not becoming a
problem. Applications that are built or rebuilt to use FIPS
functionality will need to be recompiled in any case, thus not being a
problem either.
static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
#endif
-#ifdef OPENSSL_FIPS
-int FIPS_mode;
-void *FIPS_rand_check;
-#endif /* def OPENSSL_FIPS */
-
DECLARE_STACK_OF(CRYPTO_dynlock)
IMPLEMENT_STACK_OF(CRYPTO_dynlock)
"engine",
"ui",
"hwcrhk", /* This is a HACK which will disappear in 0.9.8 */
-#if CRYPTO_NUM_LOCKS != 33
+ "fips",
+ "fips2",
+#if CRYPTO_NUM_LOCKS != 35
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
file,line,assertion);
abort();
}
+
+#ifdef OPENSSL_FIPS
+static int fips_started = 0;
+static int fips_mode = 0;
+static void *fips_rand_check = 0;
+static unsigned long fips_thread = 0;
+
+void fips_set_started(void)
+ {
+ fips_started = 1;
+ }
+
+int fips_is_started(void)
+ {
+ return fips_started;
+ }
+
+int fips_is_owning_thread(void)
+ {
+ int ret = 0;
+
+ if (fips_is_started())
+ {
+ CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
+ if (fips_thread != 0 && fips_thread == CRYPTO_thread_id())
+ ret = 1;
+ CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
+ }
+ return ret;
+ }
+
+int fips_set_owning_thread(void)
+ {
+ int ret = 0;
+
+ if (fips_is_started())
+ {
+ CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
+ if (fips_thread == 0)
+ {
+ fips_thread = CRYPTO_thread_id();
+ ret = 1;
+ }
+ CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
+ }
+ return ret;
+ }
+
+int fips_clear_owning_thread(void)
+ {
+ int ret = 0;
+
+ if (fips_is_started())
+ {
+ CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
+ if (fips_thread == CRYPTO_thread_id())
+ {
+ fips_thread = 0;
+ ret = 1;
+ }
+ CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
+ }
+ return ret;
+ }
+
+void fips_set_mode(int onoff)
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) CRYPTO_w_lock(CRYPTO_LOCK_FIPS);
+ fips_mode = onoff;
+ if (!owning_thread) CRYPTO_w_unlock(CRYPTO_LOCK_FIPS);
+ }
+ }
+
+void fips_set_rand_check(void *rand_check)
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) CRYPTO_w_lock(CRYPTO_LOCK_FIPS);
+ fips_rand_check = rand_check;
+ if (!owning_thread) CRYPTO_w_unlock(CRYPTO_LOCK_FIPS);
+ }
+ }
+
+int FIPS_mode(void)
+ {
+ int ret = 0;
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) CRYPTO_r_lock(CRYPTO_LOCK_FIPS);
+ ret = fips_mode;
+ if (!owning_thread) CRYPTO_r_unlock(CRYPTO_LOCK_FIPS);
+ }
+ return ret;
+ }
+
+void *FIPS_rand_check(void)
+ {
+ void *ret = 0;
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) CRYPTO_r_lock(CRYPTO_LOCK_FIPS);
+ ret = fips_rand_check;
+ if (!owning_thread) CRYPTO_r_unlock(CRYPTO_LOCK_FIPS);
+ }
+ return ret;
+ }
+
+#endif /* OPENSSL_FIPS */
+
#define CRYPTO_LOCK_ENGINE 30
#define CRYPTO_LOCK_UI 31
#define CRYPTO_LOCK_HWCRHK 32 /* This is a HACK which will disappear in 0.9.8 */
-#define CRYPTO_NUM_LOCKS 33
+#define CRYPTO_LOCK_FIPS 33
+#define CRYPTO_LOCK_FIPS2 34
+#define CRYPTO_NUM_LOCKS 35
#define CRYPTO_LOCK 1
#define CRYPTO_UNLOCK 2
void OpenSSLDie(const char *file,int line,const char *assertion);
#define OPENSSL_assert(e) ((e) ? (void)0 : OpenSSLDie(__FILE__, __LINE__, #e))
+#ifdef OPENSSL_FIPS
+int FIPS_mode(void);
+void *FIPS_rand_check(void);
+#endif /* def OPENSSL_FIPS */
+
/* 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.
DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
#ifdef OPENSSL_FIPS
- if(FIPS_mode && !FIPS_dsa_check(dsa))
+ if(FIPS_mode() && !FIPS_dsa_check(dsa))
return NULL;
#endif
return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
#ifdef OPENSSL_FIPS
- if(FIPS_mode && !FIPS_dsa_check(dsa))
+ if(FIPS_mode() && !FIPS_dsa_check(dsa))
return 0;
#endif
return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
DSA *dsa)
{
#ifdef OPENSSL_FIPS
- if(FIPS_mode && !FIPS_dsa_check(dsa))
+ if(FIPS_mode() && !FIPS_dsa_check(dsa))
return -1;
#endif
return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
* <appro@fy.chalmers.se>
*/
+#include <openssl/crypto.h>
#include <openssl/fips.h>
#include <openssl/err.h>
-#include "../fips/fips_locl.h"
#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
#error "DATA_ORDER must be defined!"
const unsigned char *cp=end;
#ifdef OPENSSL_FIPS
- if(FIPS_mode && !FIPS_md5_allowed)
+ if(FIPS_mode() && !FIPS_md5_allowed())
{
FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD);
return 0;
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u)
{
- if (FIPS_mode)
+ if (FIPS_mode())
return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
(char *)kstr, klen, cb, u);
else
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u)
{
- if (FIPS_mode)
+ if (FIPS_mode())
return PEM_write_PKCS8PrivateKey(fp, x, enc,
(char *)kstr, klen, cb, u);
else
int do_stir_pool = 0;
#ifdef OPENSSL_FIPS
- if(FIPS_mode)
+ if(FIPS_mode())
{
FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD);
return 0;
const RAND_METHOD *RAND_get_rand_method(void)
{
#ifdef OPENSSL_FIPS
- if(FIPS_mode && default_RAND_meth != FIPS_rand_check)
+ if(FIPS_mode()
+ && default_RAND_meth != FIPS_rand_check())
{
RANDerr(RAND_F_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
return 0;
-HMAC-SHA1(fips_aes_core.c)= e3b9b4ddceaca72392f59ee05164d9e6a81521a7
+HMAC-SHA1(fips_aes_core.c)= b70bbbd675efe0613da0d57055310926a0104d55
HMAC-SHA1(fips_aes_selftest.c)= 98b01502221e7fe529fd981222f2cbb52eb4cbe0
HMAC-SHA1(fips_aes_locl.h)= ded58f0cda8cb967dc5f5f3a860601c0b8744623
return -1;
if (bits != 128 && bits != 192 && bits != 256)
return -2;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
return -3;
rk = key->rd_key;
-HMAC-SHA1(fips_des_enc.c)= ea89417ba58c148c3d72d29438cd0bedc2315f7f
+HMAC-SHA1(fips_des_enc.c)= 9527f8ea81602358f1aa11348237fdb1e9eeff32
HMAC-SHA1(asm/fips-dx86-elf.s)= 2f85e8e86806c92ee4c12cf5354e19eccf6ed47d
HMAC-SHA1(fips_des_selftest.c)= 3bc574e51647c5f5ab45d1007b2cf461d67764a9
-HMAC-SHA1(fips_set_key.c)= dfe1bf8221a8cce7591ad33c9433271613332bd0
+HMAC-SHA1(fips_set_key.c)= 2858450d3d9c8d4ab8edea683baa54fa34f3a605
HMAC-SHA1(fips_des_locl.h)= 7053848e884df47f06de9f2248380b92e58ef4e5
#endif
register DES_LONG *s;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
data[0]=data[1]=0;
return;
#endif
register DES_LONG *s;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
data[0]=data[1]=0;
return;
* 1.0 First working version
*/
#include "fips_des_locl.h"
-#include "../fips.h"
+#include <openssl/fips.h>
#ifdef OPENSSL_FIPS
int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
{
- if (FIPS_selftest_fail)
+ if (FIPS_selftest_failed())
return -3;
if (DES_check_key)
{
return(-1);
if (DES_is_weak_key(key))
return(-2);
- if (FIPS_selftest_fail)
+ if (FIPS_selftest_failed())
return -3;
DES_set_key_unchecked(key, schedule);
HMAC-SHA1(fips_dh_check.c)= 63347e2007e224381d4a7b6d871633889de72cf3
-HMAC-SHA1(fips_dh_gen.c)= 6aaf18dab32bf9a5fb4b7449ac4cbe559040adb4
+HMAC-SHA1(fips_dh_gen.c)= 93fe69b758ca9d70d70cda1c57fff4eb5c668e85
HMAC-SHA1(fips_dh_key.c)= 7bf23b329a776953bbe7c30ebd7f9faf5249ddbe
int g,ok= -1;
BN_CTX *ctx=NULL;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_DH_GENERATE_PARAMETERS,FIPS_R_FIPS_SELFTEST_FAILED);
return NULL;
-HMAC-SHA1(fips_dsa_ossl.c)= b817acc77487f42298205cc5fdd2593e30c66a9d
-HMAC-SHA1(fips_dsa_gen.c)= 6276272125759148b60f2500fa40beea84648a21
+HMAC-SHA1(fips_dsa_ossl.c)= d5f718695397fe56d6bb46f7c410794cb895e206
+HMAC-SHA1(fips_dsa_gen.c)= c252db14699f3ff641db052311da7d7521569c53
HMAC-SHA1(fips_dsa_selftest.c)= 4bfc5d3a6b977527b053f3a03d0760a822a26135
/*#include "cryptlib.h"*/
#include <openssl/evp.h>
#include <openssl/bn.h>
-#ifndef OPENSSL_NO_SHA
+#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_RAND
#endif
#ifndef OPENSSL_NO_SHA
#include <openssl/sha.h>
+#endif
#include <openssl/fips.h>
#include <openssl/err.h>
+#ifndef OPENSSL_NO_DSA
#ifdef OPENSSL_FIPS
static int fips_check_dsa(DSA *dsa)
DSA *ret=NULL;
unsigned char *seed_out=seed_in;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_DSA_GENERATE_PARAMETERS,
FIPS_R_FIPS_SELFTEST_FAILED);
return(ok);
}
#endif
-
#endif
int i,reason=ERR_R_BN_LIB;
DSA_SIG *ret=NULL;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
return NULL;
return -1;
}
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED);
return -1;
-HMAC-SHA1(fips.c)= 5d2cc58767613ab8fb98927eaa2015f357dd4012
+HMAC-SHA1(fips.c)= bb4247d57a16f571ded9b2feea827a90cb2dbb79
HMAC-SHA1(fips_err_wrapper.c)= d3e2be316062510312269e98f964cb87e7577898
-HMAC-SHA1(fips.h)= e793b0a7017d57a37b89743cf59b40a30385b63f
+HMAC-SHA1(fips.h)= fbedad5dbd8986ddd521ea576bf2a20e6881540a
HMAC-SHA1(fips_err.h)= 4a73f2a88e206f1f88edfd9b26609a0eed818491
#define PATH_MAX 1024
#endif
-int FIPS_md5_allowed;
-int FIPS_selftest_fail;
+static int fips_md5_allowed = 0;
+static int fips_selftest_fail = 0;
+
+void FIPS_allow_md5(int onoff)
+ {
+ if (fips_is_started())
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (!owning_thread) CRYPTO_w_lock(CRYPTO_LOCK_FIPS);
+ fips_md5_allowed = onoff;
+ if (!owning_thread) CRYPTO_w_unlock(CRYPTO_LOCK_FIPS);
+ }
+ }
+
+int FIPS_md5_allowed(void)
+ {
+ int ret = 1;
+ if (fips_is_started())
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (!owning_thread) CRYPTO_r_lock(CRYPTO_LOCK_FIPS);
+ ret = fips_md5_allowed;
+ if (!owning_thread) CRYPTO_r_unlock(CRYPTO_LOCK_FIPS);
+ }
+ return ret;
+ }
+
+int FIPS_selftest_failed(void)
+ {
+ int ret = 0;
+ if (fips_is_started())
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (!owning_thread) CRYPTO_r_lock(CRYPTO_LOCK_FIPS);
+ ret = fips_selftest_fail;
+ if (!owning_thread) CRYPTO_r_unlock(CRYPTO_LOCK_FIPS);
+ }
+ return ret;
+ }
int FIPS_selftest()
{
int FIPS_mode_set(int onoff,const char *path)
{
+ void fips_set_mode(int onoff);
+ int fips_set_owning_thread();
+ int fips_clear_owning_thread();
+ int ret = 0;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_FIPS);
+ fips_set_started();
+ fips_set_owning_thread();
+
if(onoff)
{
unsigned char buf[24];
- FIPS_selftest_fail=0;
+ fips_selftest_fail = 0;
/* Don't go into FIPS mode twice, just so we can do automagic
seeding */
- if(FIPS_mode)
+ if(FIPS_mode())
{
FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET);
- FIPS_selftest_fail=1;
- return 0;
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
}
if(!FIPS_check_exe(path))
{
- FIPS_selftest_fail=1;
- return 0;
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
}
/* automagically seed PRNG if not already seeded */
{
if(RAND_bytes(buf,sizeof buf) <= 0)
{
- FIPS_selftest_fail=1;
- return 0;
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
}
FIPS_set_prng_key(buf,buf+8);
FIPS_rand_seed(buf+16,8);
}
/* now switch into FIPS mode */
- FIPS_rand_check=FIPS_rand_method();
+ fips_set_rand_check(FIPS_rand_method());
RAND_set_rand_method(FIPS_rand_method());
if(FIPS_selftest())
- FIPS_mode=1;
+ fips_set_mode(1);
else
{
- FIPS_selftest_fail=1;
- return 0;
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
}
- return 1;
+ ret = 1;
+ goto end;
}
- FIPS_mode=0;
- FIPS_selftest_fail=0;
- return 1;
- }
-
-void FIPS_allow_md5(int onoff)
- {
- FIPS_md5_allowed=onoff;
+ fips_set_mode(0);
+ fips_selftest_fail = 0;
+ ret = 1;
+end:
+ fips_clear_owning_thread();
+ CRYPTO_w_unlock(CRYPTO_LOCK_FIPS);
+ return ret;
}
#if 0
/* Note that these are defined in crypto/cryptlib.c so they're
* available even without -lfips.
*/
-extern int FIPS_mode;
-extern int FIPS_selftest_fail;
-extern void *FIPS_rand_check;
struct dsa_st;
int FIPS_mode_set(int onoff,const char *path);
void FIPS_allow_md5(int onoff);
+int FIPS_md5_allowed(void);
+int FIPS_selftest_failed(void);
int FIPS_dsa_check(struct dsa_st *dsa);
void FIPS_corrupt_sha1(void);
int FIPS_selftest_sha1(void);
extern "C" {
#endif
-/* FIPS 140 allows MD5 to be used during certain parts of TLS */
-extern int FIPS_md5_allowed;
+/* These are really defined in crypto/cryptlib.c */
+void fips_set_started(void);
+int fips_is_started(void);
+int fips_is_owning_thread(void);
+int fips_set_owning_thread(void);
+int fips_clear_owning_thread(void);
+void fips_set_rand_check(void *rand_check);
#ifdef __cplusplus
}
-HMAC-SHA1(fips_rsa_eay.c)= 660512794d0a702fc2bf17ae094e9e3181bf9152
-HMAC-SHA1(fips_rsa_gen.c)= 6bcf339dda5bb7d7e162c30d579431848a5e921f
+HMAC-SHA1(fips_rsa_eay.c)= eabab59a2f11f3da4c21e1144efe1684f5e8f1ec
+HMAC-SHA1(fips_rsa_gen.c)= 4bbc0afcade1ac53f469aaa89f84c413678254bf
HMAC-SHA1(fips_rsa_selftest.c)= ed69ec28f12af451b8e694e52ac8b6c9bffc0db2
BN_init(&f);
BN_init(&ret);
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
goto err;
int bitsp,bitsq,ok= -1,n=0,i;
BN_CTX *ctx=NULL,*ctx2=NULL;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_RSA_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED);
return NULL;
HMAC-SHA1(fips_sha1dgst.c)= 10575600a9540eb15188a7d3b0b031e60aedbc18
HMAC-SHA1(fips_sha1_selftest.c)= 98910a0c85eff1688bd7adb23e738dc75b39546e
HMAC-SHA1(asm/sx86-elf.s)= 6286cba0ea3b071e67ab5c1e607d1387de6a871d
-HMAC-SHA1(fips_sha_locl.h)= b793c80946d1029a630844393e294b27f61b1485
-HMAC-SHA1(fips_md32_common.h)= cd86b0f4a9a22552dce8db3ae5f2614e54a61f15
+HMAC-SHA1(fips_sha_locl.h)= 61e5b59c8a43e21d2f022101852467a7176e52eb
+HMAC-SHA1(fips_md32_common.h)= 1c7e761db430067391b1b7b86da5d2bf6df92834
register HASH_LONG l;
int sw,sc,ew,ec;
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
return 0;
if (len==0) return 1;
SHA_LONG XX[16];
#endif
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
return;
A=c->h0;
SHA_LONG XX[16];
#endif
- if(FIPS_selftest_fail)
+ if(FIPS_selftest_failed())
return;
A=c->h0;
#include <stdlib.h>
#include <string.h>
-int FIPS_selftest_fail;
+int FIPS_selftest_failed() { return 0; }
#ifdef OPENSSL_FIPS
HMAC-SHA1(fips_sha1dgst.c)= 10575600a9540eb15188a7d3b0b031e60aedbc18
HMAC-SHA1(fips_sha1_selftest.c)= 98910a0c85eff1688bd7adb23e738dc75b39546e
HMAC-SHA1(asm/sx86-elf.s)= 6286cba0ea3b071e67ab5c1e607d1387de6a871d
-HMAC-SHA1(fips_standalone_sha1.c)= c17f83ccfe601558b33b6df27d2d82887b8c9dc2
-HMAC-SHA1(fips_sha_locl.h)= b793c80946d1029a630844393e294b27f61b1485
-HMAC-SHA1(fips_md32_common.h)= cd86b0f4a9a22552dce8db3ae5f2614e54a61f15
+HMAC-SHA1(fips_standalone_sha1.c)= 93203c569097189b47a0085bc9fc55193867d4ce
+HMAC-SHA1(fips_sha_locl.h)= 61e5b59c8a43e21d2f022101852467a7176e52eb
+HMAC-SHA1(fips_md32_common.h)= 1c7e761db430067391b1b7b86da5d2bf6df92834
/* drop those that use any of that is not available */
#ifdef OPENSSL_FIPS
if ((c != NULL) && c->valid && !(c->algorithms & mask)
- && (!FIPS_mode || (c->algo_strength & SSL_FIPS)))
+ && (!FIPS_mode() || (c->algo_strength & SSL_FIPS)))
#else
if ((c != NULL) && c->valid && !(c->algorithms & mask))
#endif
for (curr = head; curr != NULL; curr = curr->next)
{
#ifdef OPENSSL_FIPS
- if (curr->active && (!FIPS_mode || curr->cipher->algo_strength & SSL_FIPS))
+ if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
#else
if (curr->active)
#endif