Line data Source code
1 : /* 2 : * Copyright (C) 2013 Red Hat 3 : * 4 : * Author: Nikos Mavrogiannopoulos 5 : * 6 : * This file is part of GnuTLS. 7 : * 8 : * The GnuTLS is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public License 10 : * as published by the Free Software Foundation; either version 2.1 of 11 : * the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, but 14 : * WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public License 19 : * along with this program. If not, see <https://www.gnu.org/licenses/> 20 : * 21 : */ 22 : 23 : #ifndef GNUTLS_LIB_FIPS_H 24 : #define GNUTLS_LIB_FIPS_H 25 : 26 : #include "gnutls_int.h" 27 : #include <gnutls/gnutls.h> 28 : 29 : #define FIPS140_RND_KEY_SIZE 32 30 : 31 : typedef enum { 32 : LIB_STATE_POWERON, 33 : LIB_STATE_INIT, 34 : LIB_STATE_SELFTEST, 35 : LIB_STATE_OPERATIONAL, 36 : LIB_STATE_ERROR, 37 : LIB_STATE_SHUTDOWN 38 : } gnutls_lib_state_t; 39 : 40 : /* do not access directly */ 41 : extern unsigned int _gnutls_lib_state; 42 : extern gnutls_crypto_rnd_st _gnutls_fips_rnd_ops; 43 : 44 : inline static 45 6776 : void _gnutls_switch_lib_state(gnutls_lib_state_t state) 46 : { 47 : /* Once into zombie state no errors can change us */ 48 6776 : _gnutls_lib_state = state; 49 2 : } 50 : 51 5787038 : inline static gnutls_lib_state_t _gnutls_get_lib_state(void) 52 : { 53 5787033 : return _gnutls_lib_state; 54 : } 55 : 56 : int _gnutls_fips_perform_self_checks1(void); 57 : int _gnutls_fips_perform_self_checks2(void); 58 : void _gnutls_fips_mode_reset_zombie(void); 59 : 60 : #ifdef ENABLE_FIPS140 61 : unsigned _gnutls_fips_mode_enabled(void); 62 : #else 63 : # define _gnutls_fips_mode_enabled() 0 64 : #endif 65 : 66 : # define HAVE_LIB_ERROR() unlikely(_gnutls_get_lib_state() != LIB_STATE_OPERATIONAL && _gnutls_get_lib_state() != LIB_STATE_SELFTEST) 67 : 68 : # define FAIL_IF_LIB_ERROR \ 69 : if (HAVE_LIB_ERROR()) return GNUTLS_E_LIB_IN_ERROR_STATE 70 : 71 : void _gnutls_switch_lib_state(gnutls_lib_state_t state); 72 : 73 : void _gnutls_lib_simulate_error(void); 74 : void _gnutls_lib_force_operational(void); 75 : 76 : #ifdef ENABLE_FIPS140 77 : /* This will test the condition when in FIPS140-2 mode 78 : * and return an error if necessary or ignore */ 79 : # define FIPS_RULE(condition, ret_error, ...) { \ 80 : gnutls_fips_mode_t _mode = _gnutls_fips_mode_enabled(); \ 81 : if (_mode != GNUTLS_FIPS140_DISABLED) { \ 82 : if (condition) { \ 83 : if (_mode == GNUTLS_FIPS140_LOG) { \ 84 : _gnutls_audit_log(NULL, "fips140-2: allowing "__VA_ARGS__); \ 85 : } else if (_mode != GNUTLS_FIPS140_LAX) { \ 86 : _gnutls_debug_log("fips140-2: disallowing "__VA_ARGS__); \ 87 : return ret_error; \ 88 : } \ 89 : } \ 90 : }} 91 : 92 : inline 93 : static unsigned is_mac_algo_forbidden(gnutls_mac_algorithm_t algo) 94 : { 95 : gnutls_fips_mode_t mode = _gnutls_fips_mode_enabled(); 96 : if (mode != GNUTLS_FIPS140_DISABLED && 97 : _gnutls_get_lib_state() != LIB_STATE_SELFTEST) { 98 : switch(algo) { 99 : case GNUTLS_MAC_SHA1: 100 : case GNUTLS_MAC_SHA256: 101 : case GNUTLS_MAC_SHA384: 102 : case GNUTLS_MAC_SHA512: 103 : case GNUTLS_MAC_SHA224: 104 : case GNUTLS_MAC_SHA3_224: 105 : case GNUTLS_MAC_SHA3_256: 106 : case GNUTLS_MAC_SHA3_384: 107 : case GNUTLS_MAC_SHA3_512: 108 : case GNUTLS_MAC_AES_CMAC_128: 109 : case GNUTLS_MAC_AES_CMAC_256: 110 : case GNUTLS_MAC_AES_GMAC_128: 111 : case GNUTLS_MAC_AES_GMAC_192: 112 : case GNUTLS_MAC_AES_GMAC_256: 113 : return 0; 114 : default: 115 : if (mode == GNUTLS_FIPS140_LAX) 116 : return 0; 117 : else if (mode == GNUTLS_FIPS140_LOG) { 118 : _gnutls_audit_log(NULL, "fips140-2: allowing access to %s\n", 119 : gnutls_mac_get_name(algo)); 120 : return 0; 121 : } 122 : return 1; 123 : } 124 : } 125 : 126 : return 0; 127 : } 128 : 129 : inline 130 : static unsigned is_cipher_algo_forbidden(gnutls_cipher_algorithm_t algo) 131 : { 132 : gnutls_fips_mode_t mode = _gnutls_fips_mode_enabled(); 133 : if (mode != GNUTLS_FIPS140_DISABLED && 134 : _gnutls_get_lib_state() != LIB_STATE_SELFTEST) { 135 : 136 : switch(algo) { 137 : case GNUTLS_CIPHER_AES_128_CBC: 138 : case GNUTLS_CIPHER_AES_256_CBC: 139 : case GNUTLS_CIPHER_AES_192_CBC: 140 : case GNUTLS_CIPHER_AES_128_GCM: 141 : case GNUTLS_CIPHER_AES_192_GCM: 142 : case GNUTLS_CIPHER_AES_256_GCM: 143 : case GNUTLS_CIPHER_AES_128_CCM: 144 : case GNUTLS_CIPHER_AES_256_CCM: 145 : case GNUTLS_CIPHER_3DES_CBC: 146 : case GNUTLS_CIPHER_AES_128_CCM_8: 147 : case GNUTLS_CIPHER_AES_256_CCM_8: 148 : case GNUTLS_CIPHER_AES_128_CFB8: 149 : case GNUTLS_CIPHER_AES_192_CFB8: 150 : case GNUTLS_CIPHER_AES_256_CFB8: 151 : case GNUTLS_CIPHER_AES_128_XTS: 152 : case GNUTLS_CIPHER_AES_256_XTS: 153 : return 0; 154 : default: 155 : if (mode == GNUTLS_FIPS140_LAX) 156 : return 0; 157 : else if (mode == GNUTLS_FIPS140_LOG) { 158 : _gnutls_audit_log(NULL, "fips140-2: allowing access to %s\n", 159 : gnutls_cipher_get_name(algo)); 160 : return 0; 161 : } 162 : return 1; 163 : } 164 : } 165 : 166 : return 0; 167 : } 168 : #else 169 : # define is_mac_algo_forbidden(x) 0 170 : # define is_cipher_algo_forbidden(x) 0 171 : # define FIPS_RULE(condition, ret_error, ...) 172 : #endif 173 : 174 : #endif /* GNUTLS_LIB_FIPS_H */