From: Nikos Mavrogiannopoulos Date: Sat, 30 Nov 2013 17:50:20 +0000 (+0100) Subject: The library state is used even when not in FIPS mode. X-Git-Tag: gnutls_3_3_0pre0~519 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c6bf6e1da1f70adfa2a91a36143f74e6234fe7ea;p=thirdparty%2Fgnutls.git The library state is used even when not in FIPS mode. This allows having an error state that blocks the library usage even when not in FIPS mode. --- diff --git a/lib/fips.c b/lib/fips.c index 75ce971fb5..ab4f737bb2 100644 --- a/lib/fips.c +++ b/lib/fips.c @@ -30,13 +30,12 @@ #include #include +unsigned int _gnutls_lib_mode = LIB_STATE_POWERON; #ifdef ENABLE_FIPS140 #define FIPS_KERNEL_FILE "/proc/sys/crypto/fips_enabled" #define FIPS_SYSTEM_FILE "/etc/system-fips" -unsigned int _gnutls_fips_mode = FIPS_STATE_POWERON; - unsigned _gnutls_fips_mode_enabled(void) { unsigned f1p, f2p; @@ -61,7 +60,7 @@ FILE* fd; if (f2p != 0) { /* a funny state where self tests are performed * and ignored */ - _gnutls_switch_fips_state(FIPS_STATE_ZOMBIE); + _gnutls_switch_lib_state(LIB_STATE_ZOMBIE); _gnutls_debug_log("FIPS140-2 ZOMBIE mode enabled\n"); return 2; } @@ -137,11 +136,11 @@ static unsigned check_binary_integrity(const char* libname, const char* symbol) return gnutls_assert_val(0); } - prev = _gnutls_get_fips_state(); - _gnutls_switch_fips_state(FIPS_STATE_OPERATIONAL); + prev = _gnutls_get_lib_state(); + _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = gnutls_hmac_fast(HMAC_ALGO, fips_key, sizeof(fips_key)-1, data.data, data.size, new_hmac); - _gnutls_switch_fips_state(prev); + _gnutls_switch_lib_state(prev); gnutls_free(data.data); @@ -180,7 +179,7 @@ int _gnutls_fips_perform_self_checks(void) { int ret; - _gnutls_switch_fips_state(FIPS_STATE_SELFTEST); + _gnutls_switch_lib_state(LIB_STATE_SELFTEST); /* Tests the FIPS algorithms */ @@ -321,7 +320,7 @@ int _gnutls_fips_perform_self_checks(void) return 0; error: - _gnutls_switch_fips_state(FIPS_STATE_ERROR); + _gnutls_switch_lib_state(LIB_STATE_ERROR); _gnutls_audit_log(NULL, "FIPS140-2 self testing failed\n"); return GNUTLS_E_SELF_TEST_ERROR; @@ -367,7 +366,5 @@ int ret = _gnutls_fips_mode_enabled(); void _gnutls_fips140_simulate_error(void) { -#ifdef ENABLE_FIPS140 - _gnutls_switch_fips_state(FIPS_STATE_ERROR); -#endif + _gnutls_switch_lib_state(LIB_STATE_ERROR); } diff --git a/lib/fips.h b/lib/fips.h index eae742c848..bae767412b 100644 --- a/lib/fips.h +++ b/lib/fips.h @@ -29,52 +29,41 @@ #define FIPS140_RND_KEY_SIZE 32 typedef enum { - FIPS_STATE_POWERON, - FIPS_STATE_ZOMBIE, - FIPS_STATE_INIT, - FIPS_STATE_SELFTEST, - FIPS_STATE_OPERATIONAL, - FIPS_STATE_ERROR, - FIPS_STATE_SHUTDOWN -} gnutls_fips_state_t; - -#ifdef ENABLE_FIPS140 + LIB_STATE_POWERON, + LIB_STATE_ZOMBIE, + LIB_STATE_INIT, + LIB_STATE_SELFTEST, + LIB_STATE_OPERATIONAL, + LIB_STATE_ERROR, + LIB_STATE_SHUTDOWN +} gnutls_lib_state_t; /* do not access directly */ -extern unsigned int _gnutls_fips_mode; +extern unsigned int _gnutls_lib_mode; inline static -void _gnutls_switch_fips_state(gnutls_fips_state_t state) +void _gnutls_switch_lib_state(gnutls_lib_state_t state) { /* Once into zombie state no errors can change us */ - if (_gnutls_fips_mode != FIPS_STATE_ZOMBIE) - _gnutls_fips_mode = state; + if (_gnutls_lib_mode != LIB_STATE_ZOMBIE) + _gnutls_lib_mode = state; } -inline static gnutls_fips_state_t _gnutls_get_fips_state(void) +inline static gnutls_lib_state_t _gnutls_get_lib_state(void) { - return _gnutls_fips_mode; + return _gnutls_lib_mode; } int _gnutls_fips_perform_self_checks(void); unsigned _gnutls_fips_mode_enabled(void); -# define FAIL_IF_FIPS_ERROR \ - if (_gnutls_get_fips_state() != FIPS_STATE_OPERATIONAL && \ - _gnutls_get_fips_state() != FIPS_STATE_SELFTEST && \ - _gnutls_get_fips_state() != FIPS_STATE_ZOMBIE) return GNUTLS_E_LIB_IN_ERROR_STATE +# define FAIL_IF_LIB_ERROR \ + if (_gnutls_get_lib_state() != LIB_STATE_OPERATIONAL && \ + _gnutls_get_lib_state() != LIB_STATE_SELFTEST && \ + _gnutls_get_lib_state() != LIB_STATE_ZOMBIE) return GNUTLS_E_LIB_IN_ERROR_STATE -void _gnutls_switch_fips_state(gnutls_fips_state_t state); +void _gnutls_switch_lib_state(gnutls_lib_state_t state); void _gnutls_fips140_simulate_error(void); -#else - -# define _gnutls_switch_fips_state(x) 0 -# define _gnutls_get_fips_state() STATE_OPERATIONAL -# define FAIL_IF_FIPS_ERROR 0 -# define _gnutls_fips_perform_self_checks() 0 -# define _gnutls_fips_mode_enabled() 0 -#endif - #endif /* FIPS_H */ diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c index 184156725e..6b7631b807 100644 --- a/lib/gnutls_cipher_int.c +++ b/lib/gnutls_cipher_int.c @@ -63,7 +63,7 @@ _gnutls_cipher_init(cipher_hd_st * handle, const cipher_entry_st * e, if (unlikely(e == NULL || e->id == GNUTLS_CIPHER_NULL)) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; handle->e = e; @@ -147,7 +147,7 @@ int _gnutls_auth_cipher_init(auth_cipher_hd_st * handle, if (unlikely(e == NULL)) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; memset(handle, 0, sizeof(*handle)); diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index 4dea32003e..2e89feb7a9 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -224,7 +224,7 @@ int gnutls_global_init2(unsigned int flags) loaded_modules |= flags; if (flags & GNUTLS_GLOBAL_INIT_MINIMAL) { - _gnutls_switch_fips_state(FIPS_STATE_INIT); + _gnutls_switch_lib_state(LIB_STATE_INIT); e = getenv("GNUTLS_DEBUG_LEVEL"); if (e != NULL) { @@ -320,18 +320,16 @@ int gnutls_global_init2(unsigned int flags) res = _gnutls_fips_mode_enabled(); if (res != 0) { ret = _gnutls_fips_perform_self_checks(); - if (_gnutls_get_fips_state() != FIPS_STATE_ZOMBIE) { + if (_gnutls_get_lib_state() != LIB_STATE_ZOMBIE) { if (ret < 0) { gnutls_assert(); goto out; } - } else { - ret = 0; } - _gnutls_switch_fips_state(FIPS_STATE_OPERATIONAL); } } #endif + _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = 0; out: diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c index 4e841ca8f8..51a4420194 100644 --- a/lib/gnutls_hash_int.c +++ b/lib/gnutls_hash_int.c @@ -35,7 +35,7 @@ int _gnutls_hash_init(digest_hd_st * dig, const mac_entry_st * e) int result; const gnutls_crypto_digest_st *cc = NULL; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; dig->e = e; @@ -102,7 +102,7 @@ _gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, int ret; const gnutls_crypto_digest_st *cc = NULL; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; /* check if a digest has been registered */ @@ -136,7 +136,7 @@ _gnutls_mac_fast(gnutls_mac_algorithm_t algorithm, const void *key, int ret; const gnutls_crypto_mac_st *cc = NULL; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; /* check if a digest has been registered */ @@ -185,7 +185,7 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e, int result; const gnutls_crypto_mac_st *cc = NULL; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; mac->e = e; mac->mac_len = _gnutls_mac_get_algo_len(e); @@ -268,7 +268,7 @@ _gnutls_mac_init_ssl3(digest_hd_st * ret, const mac_entry_st * e, uint8_t ipad[48]; int padsize, result; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; padsize = get_padsize((gnutls_digest_algorithm_t) e->id); if (padsize == 0) { diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 81507fa7f9..5c307e90ab 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -238,7 +238,7 @@ _gnutls_privkey_get_public_mpis(gnutls_privkey_t key, **/ int gnutls_privkey_init(gnutls_privkey_t * key) { - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st)); if (*key == NULL) { diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 21826b866d..36360b1d15 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -111,7 +111,7 @@ int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage) **/ int gnutls_pubkey_init(gnutls_pubkey_t * key) { - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(struct gnutls_pubkey_st)); if (*key == NULL) { diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 7fae162c72..c648816243 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -309,7 +309,7 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags) int ret; record_parameters_st *epoch; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *session = gnutls_calloc(1, sizeof(struct gnutls_session_int)); if (*session == NULL) diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index def8d6c67a..dc745e99c3 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -342,7 +342,7 @@ _wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo, cleanup: mpz_clear(p); - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return ret; } @@ -419,7 +419,7 @@ _wrap_nettle_pk_decrypt(gnutls_pk_algorithm_t algo, if (ret < 0) gnutls_free(plaintext->data); - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return ret; } @@ -574,7 +574,7 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, cleanup: - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return ret; } @@ -839,7 +839,7 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo, return GNUTLS_E_INVALID_REQUEST; } - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return 0; fail: @@ -849,7 +849,7 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo, } params->params_nr = 0; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return ret; } @@ -1053,7 +1053,7 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, return GNUTLS_E_INVALID_REQUEST; } - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return 0; fail: @@ -1063,7 +1063,7 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, } params->params_nr = 0; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return ret; } diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index d24f6a3dee..e5eeb82fb5 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -52,7 +52,7 @@ struct gnutls_pkcs11_privkey_st { **/ int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key) { - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_privkey_st)); if (*key == NULL) { diff --git a/lib/random.c b/lib/random.c index b5f6cd94f9..f67f947f44 100644 --- a/lib/random.c +++ b/lib/random.c @@ -66,7 +66,7 @@ void _gnutls_rnd_deinit(void) **/ int gnutls_rnd(gnutls_rnd_level_t level, void *data, size_t len) { - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; return _gnutls_rnd(level, data, len); } diff --git a/lib/x509/crl.c b/lib/x509/crl.c index 480074ec39..ab6600dc85 100644 --- a/lib/x509/crl.c +++ b/lib/x509/crl.c @@ -46,7 +46,7 @@ **/ int gnutls_x509_crl_init(gnutls_x509_crl_t * crl) { - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int)); diff --git a/lib/x509/crq.c b/lib/x509/crq.c index 67f425a4a4..9d91a19d4f 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -50,7 +50,7 @@ int gnutls_x509_crq_init(gnutls_x509_crq_t * crq) { int result; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *crq = gnutls_calloc(1, sizeof(gnutls_x509_crq_int)); if (!*crq) diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 06f83fa7e4..4d379a6dd8 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -44,7 +44,7 @@ **/ int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key) { - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(gnutls_x509_privkey_int)); diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c index 28f89edeeb..40b6580b15 100644 --- a/lib/x509/verify-high.c +++ b/lib/x509/verify-high.c @@ -77,7 +77,7 @@ gnutls_x509_trust_list_init(gnutls_x509_trust_list_t * list, { gnutls_x509_trust_list_t tmp; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; tmp = gnutls_calloc(1, sizeof(struct gnutls_x509_trust_list_st)); diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 0bc8617581..b6cc1f5f7b 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -46,7 +46,7 @@ int gnutls_x509_crt_init(gnutls_x509_crt_t * cert) { gnutls_x509_crt_t tmp; - FAIL_IF_FIPS_ERROR; + FAIL_IF_LIB_ERROR; tmp = gnutls_calloc(1, sizeof(gnutls_x509_crt_int));