diff options
Diffstat (limited to 'lib/crypto/src')
-rw-r--r-- | lib/crypto/src/crypto.app.src | 2 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 65 | ||||
-rw-r--r-- | lib/crypto/src/crypto_ec_curves.erl | 25 |
3 files changed, 64 insertions, 28 deletions
diff --git a/lib/crypto/src/crypto.app.src b/lib/crypto/src/crypto.app.src index 8a47b8a78b..460894c012 100644 --- a/lib/crypto/src/crypto.app.src +++ b/lib/crypto/src/crypto.app.src @@ -24,7 +24,7 @@ crypto_ec_curves]}, {registered, []}, {applications, [kernel, stdlib]}, - {env, []}, + {env, [{fips_mode, false}]}, {runtime_dependencies, ["erts-6.0","stdlib-2.0","kernel-3.0"]}]}. diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index da8626e38a..43f9a0f9e7 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -22,11 +22,13 @@ -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]). -export([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]). +-export([cmac/3, cmac/4]). -export([exor/2, strong_rand_bytes/1, mod_pow/3]). -export([rand_uniform/2]). -export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]). @@ -189,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) -> @@ -219,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) -> @@ -271,6 +281,14 @@ hmac_final(Context) -> hmac_final_n(Context, HashLen) -> notsup_to_error(hmac_final_nif(Context, HashLen)). +-spec cmac(_, iodata(), iodata()) -> binary(). +-spec cmac(_, iodata(), iodata(), integer()) -> binary(). + +cmac(Type, Key, Data) -> + notsup_to_error(cmac_nif(Type, Key, Data)). +cmac(Type, Key, Data, MacSize) -> + erlang:binary_part(cmac(Type, Key, Data), 0, MacSize). + %% Ecrypt/decrypt %%% -spec block_encrypt(des_cbc | des_cfb | @@ -305,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}) -> @@ -475,17 +493,17 @@ sign(Alg, Type, Data, Key) when is_binary(Data) -> sign(Alg, Type, {digest, hash(Type, Data)}, Key); sign(rsa, Type, {digest, Digest}, Key) -> case rsa_sign_nif(Type, Digest, map_ensure_int_as_bin(Key)) of - error -> erlang:error(badkey, [Type,Digest,Key]); + error -> erlang:error(badkey, [rsa, Type, {digest, Digest}, Key]); Sign -> Sign end; sign(dss, Type, {digest, Digest}, Key) -> case dss_sign_nif(Type, Digest, map_ensure_int_as_bin(Key)) of - error -> erlang:error(badkey, [Digest, Key]); + error -> erlang:error(badkey, [dss, Type, {digest, Digest}, Key]); Sign -> Sign end; sign(ecdsa, Type, {digest, Digest}, [Key, Curve]) -> case ecdsa_sign_nif(Type, Digest, nif_curve_params(Curve), ensure_int_as_bin(Key)) of - error -> erlang:error(badkey, [Type,Digest,Key]); + error -> erlang:error(badkey, [ecdsa, Type, {digest, Digest}, [Key, Curve]]); Sign -> Sign end. @@ -501,7 +519,7 @@ sign(ecdsa, Type, {digest, Digest}, [Key, Curve]) -> public_encrypt(rsa, BinMesg, Key, Padding) -> case rsa_public_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, true) of error -> - erlang:error(encrypt_failed, [BinMesg,Key, Padding]); + erlang:error(encrypt_failed, [rsa, BinMesg,Key, Padding]); Sign -> Sign end. @@ -509,7 +527,7 @@ public_encrypt(rsa, BinMesg, Key, Padding) -> private_decrypt(rsa, BinMesg, Key, Padding) -> case rsa_private_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, false) of error -> - erlang:error(decrypt_failed, [BinMesg,Key, Padding]); + erlang:error(decrypt_failed, [rsa, BinMesg,Key, Padding]); Sign -> Sign end. @@ -518,7 +536,7 @@ private_decrypt(rsa, BinMesg, Key, Padding) -> private_encrypt(rsa, BinMesg, Key, Padding) -> case rsa_private_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, true) of error -> - erlang:error(encrypt_failed, [BinMesg,Key, Padding]); + erlang:error(encrypt_failed, [rsa, BinMesg,Key, Padding]); Sign -> Sign end. @@ -526,7 +544,7 @@ private_encrypt(rsa, BinMesg, Key, Padding) -> public_decrypt(rsa, BinMesg, Key, Padding) -> case rsa_public_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, false) of error -> - erlang:error(decrypt_failed, [BinMesg,Key, Padding]); + erlang:error(decrypt_failed, [rsa, BinMesg,Key, Padding]); Sign -> Sign end. @@ -574,7 +592,7 @@ compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) -> ensure_int_as_bin(MyPrivateKey), map_ensure_int_as_bin(DHParameters)) of error -> erlang:error(computation_failed, - [OthersPublicKey,MyPrivateKey,DHParameters]); + [dh,OthersPublicKey,MyPrivateKey,DHParameters]); Ret -> Ret end; @@ -642,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 = @@ -655,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, @@ -788,6 +807,10 @@ hmac_update_nif(_Context, _Data) -> ?nif_stub. hmac_final_nif(_Context) -> ?nif_stub. hmac_final_nif(_Context, _MacSize) -> ?nif_stub. +%% CMAC + +cmac_nif(_Type, _Key, _Data) -> ?nif_stub. + %% %% MD5_MAC %% @@ -1083,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; @@ -1466,6 +1494,7 @@ mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub. -define(FUNC_LIST, [hash, hash_init, hash_update, hash_final, hmac, hmac_init, hmac_update, hmac_final, hmac_final_n, + cmac, %% deprecated md4, md4_init, md4_update, md4_final, md5, md5_init, md5_update, md5_final, @@ -1518,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. diff --git a/lib/crypto/src/crypto_ec_curves.erl b/lib/crypto/src/crypto_ec_curves.erl index 002b03b80c..9602a7e24b 100644 --- a/lib/crypto/src/crypto_ec_curves.erl +++ b/lib/crypto/src/crypto_ec_curves.erl @@ -7,29 +7,36 @@ curves() -> PubKeys = proplists:get_value(public_keys, CryptoSupport), HasEC = proplists:get_bool(ecdh, PubKeys), HasGF2m = proplists:get_bool(ec_gf2m, PubKeys), - prime_curves(HasEC) ++ characteristic_two_curves(HasGF2m). + FIPSMode = crypto:info_fips() == enabled, + prime_curves(HasEC, FIPSMode) ++ characteristic_two_curves(HasGF2m, FIPSMode). -prime_curves(true) -> - [secp112r1,secp112r2,secp128r1,secp128r2,secp160k1,secp160r1,secp160r2, +prime_curves(true, true) -> + [secp160k1,secp160r1,secp160r2, secp192r1,secp192k1,secp224k1,secp224r1,secp256k1,secp256r1,secp384r1, secp521r1,prime192v1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3, - prime256v1,wtls6,wtls7,wtls8,wtls9,wtls12, + prime256v1,wtls7,wtls9,wtls12, brainpoolP160r1,brainpoolP160t1,brainpoolP192r1,brainpoolP192t1, brainpoolP224r1,brainpoolP224t1,brainpoolP256r1,brainpoolP256t1, brainpoolP320r1,brainpoolP320t1,brainpoolP384r1,brainpoolP384t1, brainpoolP512r1,brainpoolP512t1]; -prime_curves(_) -> +prime_curves(true, false) -> + [secp112r1,secp112r2,secp128r1,secp128r2,wtls6,wtls8] + ++ prime_curves(true, true); +prime_curves(_, _) -> []. -characteristic_two_curves(true) -> - [sect113r1,sect113r2,sect131r1,sect131r2,sect163k1,sect163r1, +characteristic_two_curves(true, true) -> + [sect163k1,sect163r1, sect163r2,sect193r1,sect193r2,sect233k1,sect233r1,sect239k1,sect283k1, sect283r1,sect409k1,sect409r1,sect571k1,sect571r1,c2pnb163v1,c2pnb163v2, c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1, c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359v1,c2pnb368w1,c2tnb431r1, - wtls1,wtls3,wtls4,wtls5,wtls10,wtls11,ipsec3,ipsec4]; -characteristic_two_curves(_) -> + wtls3,wtls5,wtls10,wtls11]; +characteristic_two_curves(true, _) -> + [sect113r1,sect113r2,sect131r1,sect131r2,wtls1,wtls4,ipsec3,ipsec4] + ++ characteristic_two_curves(true, true); +characteristic_two_curves(_, _) -> []. curve(secp112r1) -> |