diff options
author | Dániel Szoboszlay <[email protected]> | 2014-04-28 17:20:24 +0200 |
---|---|---|
committer | Magnus Henoch <[email protected]> | 2016-09-28 15:08:31 +0100 |
commit | 0a1feff48388c8430f5eebd1531f769605601fab (patch) | |
tree | e21885594ce82dac0a7327a6222b959efbc4f4be /lib/crypto/src/crypto.erl | |
parent | 867ef8aab0a32d76e6e66b317ef39c75e84e177e (diff) | |
download | otp-0a1feff48388c8430f5eebd1531f769605601fab.tar.gz otp-0a1feff48388c8430f5eebd1531f769605601fab.tar.bz2 otp-0a1feff48388c8430f5eebd1531f769605601fab.zip |
Support using OpenSSL in FIPS mode
FIPS mode support needs to be enabled at compile time, by configuring
Erlang/OTP with --enable-fips option. In FIPS mode the non-FIPS
algorithms are disabled and raise error notsup.
The supported protocols list is properly updated in FIPS mode to
advertise only the enabled protocols.
FIPS mode is off by default even if Erlang/OTP was built with FIPS
support. It needs to be turned on at runtime.
The official approach is to set the fips_mode application environment
parameter of the crypto application to true. This would turn FIPS mode
on when the NIF is loaded and would prevent loading the module on
error.
Another method is provided via the crypto:enable_fips_mode/1
function, but it is not recommended to be used in production, as it
won't prevent the use of the crypto module in case of an error, and
would risk OpenSSL crashing the emulator. It is very useful for test
suites however that need to check both validated and non-validated
functionality.
This commit is based on commit
00b3a04d17a653b4abddeebd6dd8a2c38df532d0.
Diffstat (limited to 'lib/crypto/src/crypto.erl')
-rw-r--r-- | lib/crypto/src/crypto.erl | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index ca36212ef2..43f9a0f9e7 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -22,7 +22,8 @@ -module(crypto). --export([start/0, stop/0, info_lib/0, supports/0, version/0, bytes_to_integer/1]). +-export([start/0, stop/0, info_lib/0, info_fips/0, supports/0, enable_fips_mode/1, + version/0, bytes_to_integer/1]). -export([hash/2, hash_init/1, hash_update/2, hash_final/1]). -export([sign/4, verify/5]). -export([generate_key/2, generate_key/3, compute_key/4]). @@ -190,7 +191,7 @@ %%-type ec_key() :: {Curve :: ec_curve(), PrivKey :: binary() | undefined, PubKey :: ec_point() | undefined}. -on_load(on_load/0). --define(CRYPTO_NIF_VSN,301). +-define(CRYPTO_NIF_VSN,302). -define(nif_stub,nif_stub_error(?LINE)). nif_stub_error(Line) -> @@ -220,6 +221,14 @@ supports()-> info_lib() -> ?nif_stub. +-spec info_fips() -> not_supported | not_enabled | enabled. + +info_fips() -> ?nif_stub. + +-spec enable_fips_mode(boolean()) -> boolean(). + +enable_fips_mode(_) -> ?nif_stub. + -spec hash(_, iodata()) -> binary(). hash(Hash, Data0) -> @@ -314,7 +323,7 @@ block_encrypt(des3_cfb, Key0, Ivec, Data) -> Key = check_des3_key(Key0), block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, true); block_encrypt(aes_ige256, Key, Ivec, Data) -> - aes_ige_crypt_nif(Key, Ivec, Data, true); + notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, true)); block_encrypt(aes_gcm, Key, Ivec, {AAD, Data}) -> aes_gcm_encrypt(Key, Ivec, AAD, Data); block_encrypt(aes_gcm, Key, Ivec, {AAD, Data, TagLength}) -> @@ -651,7 +660,8 @@ on_load() -> end, Lib = filename:join([PrivDir, "lib", LibName]), LibBin = path2bin(Lib), - Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin}) of + FipsMode = application:get_env(crypto, fips_mode, false) == true, + Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin,FipsMode}) of ok -> ok; {error, {load_failed, _}}=Error1 -> ArchLibDir = @@ -664,7 +674,7 @@ on_load() -> _ -> ArchLib = filename:join([ArchLibDir, LibName]), ArchBin = path2bin(ArchLib), - erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin}) + erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin,FipsMode}) end; Error1 -> Error1 end, @@ -1096,24 +1106,29 @@ rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. %% RC2 block cipher rc2_cbc_encrypt(Key, IVec, Data) -> - block_encrypt(rc2_cbc, Key, IVec, Data). + notsup_to_error(block_encrypt(rc2_cbc, Key, IVec, Data)). rc2_cbc_decrypt(Key, IVec, Data) -> - block_decrypt(rc2_cbc, Key, IVec, Data). + notsup_to_error(block_decrypt(rc2_cbc, Key, IVec, Data)). %% %% RC2 - 40 bits block cipher - Backwards compatibility not documented. %% rc2_40_cbc_encrypt(Key, IVec, Data) when erlang:byte_size(Key) == 5 -> - block_encrypt(rc2_cbc, Key, IVec, Data). + notsup_to_error(block_encrypt(rc2_cbc, Key, IVec, Data)). rc2_40_cbc_decrypt(Key, IVec, Data) when erlang:byte_size(Key) == 5 -> - block_decrypt(rc2_cbc, Key, IVec, Data). + notsup_to_error(block_decrypt(rc2_cbc, Key, IVec, Data)). %% Secure remote password ------------------------------------------------------------------- user_srp_gen_key(Private, Generator, Prime) -> + %% Ensure the SRP algorithm is disabled in FIPS mode + case info_fips() of + enabled -> erlang:error(notsup); + _ -> ok + end, case mod_pow(Generator, Private, Prime) of error -> error; @@ -1532,6 +1547,6 @@ mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub. des_cbc_ivec, des_cfb_ivec, info, %% - info_lib, supports]). + info_lib, info_fips, supports]). info() -> ?FUNC_LIST. |