diff options
Diffstat (limited to 'lib/crypto/src/crypto.erl')
-rw-r--r-- | lib/crypto/src/crypto.erl | 157 |
1 files changed, 142 insertions, 15 deletions
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 5b1ce96caf..d6e2e033c0 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -40,8 +40,8 @@ -export([exor/2]). -export([rc4_encrypt/2, rc4_set_key/1, rc4_encrypt_with_state/2]). -export([rc2_40_cbc_encrypt/3, rc2_40_cbc_decrypt/3]). --export([dss_verify/3, rsa_verify/3, rsa_verify/4]). --export([dss_sign/2, rsa_sign/2, rsa_sign/3]). +-export([dss_verify/3, dss_verify/4, rsa_verify/3, rsa_verify/4]). +-export([dss_sign/2, dss_sign/3, rsa_sign/2, rsa_sign/3]). -export([rsa_public_encrypt/3, rsa_private_decrypt/3]). -export([rsa_private_encrypt/3, rsa_public_decrypt/3]). -export([dh_generate_key/1, dh_generate_key/2, dh_compute_key/3]). @@ -51,6 +51,7 @@ -export([aes_cbc_128_encrypt/3, aes_cbc_128_decrypt/3]). -export([aes_cbc_256_encrypt/3, aes_cbc_256_decrypt/3]). -export([aes_cbc_ivec/1]). +-export([aes_ctr_encrypt/3, aes_ctr_decrypt/3]). -export([dh_generate_parameters/2, dh_check/1]). %% Testing see below @@ -80,8 +81,13 @@ rc2_40_cbc_encrypt, rc2_40_cbc_decrypt, %% idea_cbc_encrypt, idea_cbc_decrypt, aes_cbc_256_encrypt, aes_cbc_256_decrypt, + aes_ctr_encrypt, aes_ctr_decrypt, info_lib]). +-type rsa_digest_type() :: 'md5' | 'sha'. +-type dss_digest_type() :: 'none' | 'sha'. +-type crypto_integer() :: binary() | integer(). + -define(nif_stub,nif_stub_error(?LINE)). -on_load(on_load/0). @@ -89,22 +95,42 @@ -define(CRYPTO_NIF_VSN,101). on_load() -> - LibName = "crypto", + LibBaseName = "crypto", PrivDir = code:priv_dir(crypto), - Lib1 = filename:join([PrivDir, "lib", LibName]), - Status = case erlang:load_nif(Lib1, ?CRYPTO_NIF_VSN) of + LibName = case erlang:system_info(build_type) of + opt -> + LibBaseName; + Type -> + LibTypeName = LibBaseName ++ "." ++ atom_to_list(Type), + case (filelib:wildcard( + filename:join( + [PrivDir, + "lib", + LibTypeName ++ "*"])) /= []) orelse + (filelib:wildcard( + filename:join( + [PrivDir, + "lib", + erlang:system_info(system_architecture), + LibTypeName ++ "*"])) /= []) of + true -> LibTypeName; + false -> LibBaseName + end + end, + Lib = filename:join([PrivDir, "lib", LibName]), + Status = case erlang:load_nif(Lib, ?CRYPTO_NIF_VSN) of ok -> ok; {error, {load_failed, _}}=Error1 -> - LibDir2 = + ArchLibDir = filename:join([PrivDir, "lib", erlang:system_info(system_architecture)]), Candidate = - filelib:wildcard(filename:join([LibDir2,LibName ++ "*" ])), + filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])), case Candidate of [] -> Error1; _ -> - Lib2 = filename:join([LibDir2, LibName]), - erlang:load_nif(Lib2, ?CRYPTO_NIF_VSN) + ArchLib = filename:join([ArchLibDir, LibName]), + erlang:load_nif(ArchLib, ?CRYPTO_NIF_VSN) end; Error1 -> Error1 end, @@ -115,10 +141,9 @@ on_load() -> "OpenSSL might not be installed on this system.~n",[E,Str]), Status end. - nif_stub_error(Line) -> - erlang:error({nif_not_loaded,module,?MODULE,line,Line}). + erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). start() -> application:start(crypto). @@ -146,6 +171,12 @@ version() -> ?CRYPTO_VSN. %% %% MD5 %% + +-spec md5(iodata()) -> binary(). +-spec md5_init() -> binary(). +-spec md5_update(binary(), iodata()) -> binary(). +-spec md5_final(binary()) -> binary(). + md5(_Data) -> ?nif_stub. md5_init() -> ?nif_stub. md5_update(_Context, _Data) -> ?nif_stub. @@ -154,6 +185,11 @@ md5_final(_Context) -> ?nif_stub. %% %% MD4 %% +-spec md4(iodata()) -> binary(). +-spec md4_init() -> binary(). +-spec md4_update(binary(), iodata()) -> binary(). +-spec md4_final(binary()) -> binary(). + md4(_Data) -> ?nif_stub. md4_init() -> ?nif_stub. md4_update(_Context, _Data) -> ?nif_stub. @@ -162,6 +198,11 @@ md4_final(_Context) -> ?nif_stub. %% %% SHA %% +-spec sha(iodata()) -> binary(). +-spec sha_init() -> binary(). +-spec sha_update(binary(), iodata()) -> binary(). +-spec sha_final(binary()) -> binary(). + sha(_Data) -> ?nif_stub. sha_init() -> ?nif_stub. sha_update(_Context, _Data) -> ?nif_stub. @@ -175,6 +216,9 @@ sha_final(_Context) -> ?nif_stub. %% %% MD5_MAC %% +-spec md5_mac(iodata(), iodata()) -> binary(). +-spec md5_mac_96(iodata(), iodata()) -> binary(). + md5_mac(Key, Data) -> md5_mac_n(Key,Data,16). @@ -186,6 +230,9 @@ md5_mac_n(_Key,_Data,_MacSz) -> ?nif_stub. %% %% SHA_MAC %% +-spec sha_mac(iodata(), iodata()) -> binary(). +-spec sha_mac_96(iodata(), iodata()) -> binary(). + sha_mac(Key, Data) -> sha_mac_n(Key,Data,20). @@ -201,6 +248,9 @@ sha_mac_n(_Key,_Data,_MacSz) -> ?nif_stub. %% %% DES - in cipher block chaining mode (CBC) %% +-spec des_cbc_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec des_cbc_decrypt(iodata(), binary(), iodata()) -> binary(). + des_cbc_encrypt(Key, IVec, Data) -> des_cbc_crypt(Key, IVec, Data, true). @@ -215,6 +265,8 @@ des_cbc_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% Returns the IVec to be used in the next iteration of %% des_cbc_[encrypt|decrypt]. %% +-spec des_cbc_ivec(iodata()) -> binary(). + des_cbc_ivec(Data) when is_binary(Data) -> {_, IVec} = split_binary(Data, size(Data) - 8), IVec; @@ -224,6 +276,9 @@ des_cbc_ivec(Data) when is_list(Data) -> %% %% DES - in electronic codebook mode (ECB) %% +-spec des_ecb_encrypt(iodata(), iodata()) -> binary(). +-spec des_ecb_decrypt(iodata(), iodata()) -> binary(). + des_ecb_encrypt(Key, Data) -> des_ecb_crypt(Key, Data, true). des_ecb_decrypt(Key, Data) -> @@ -233,6 +288,11 @@ des_ecb_crypt(_Key, _Data, _IsEncrypt) -> ?nif_stub. %% %% DES3 - in cipher block chaining mode (CBC) %% +-spec des3_cbc_encrypt(iodata(), iodata(), iodata(), binary(), iodata()) -> + binary(). +-spec des3_cbc_decrypt(iodata(), iodata(), iodata(), binary(), iodata()) -> + binary(). + des3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) -> des_ede3_cbc_encrypt(Key1, Key2, Key3, IVec, Data). des_ede3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) -> @@ -248,6 +308,14 @@ des_ede3_cbc_crypt(_Key1, _Key2, _Key3, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% Blowfish %% +-spec blowfish_ecb_encrypt(iodata(), iodata()) -> binary(). +-spec blowfish_ecb_decrypt(iodata(), iodata()) -> binary(). +-spec blowfish_cbc_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_cbc_decrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_cfb64_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_cfb64_decrypt(iodata(), binary(), iodata()) -> binary(). +-spec blowfish_ofb64_encrypt(iodata(), binary(), iodata()) -> binary(). + blowfish_ecb_encrypt(Key, Data) -> bf_ecb_crypt(Key,Data, true). @@ -277,6 +345,9 @@ blowfish_ofb64_encrypt(_Key, _IVec, _Data) -> ?nif_stub. %% %% AES in cipher feedback mode (CFB) %% +-spec aes_cfb_128_encrypt(iodata(), binary(), iodata()) -> binary(). +-spec aes_cfb_128_decrypt(iodata(), binary(), iodata()) -> binary(). + aes_cfb_128_encrypt(Key, IVec, Data) -> aes_cfb_128_crypt(Key, IVec, Data, true). @@ -289,6 +360,10 @@ aes_cfb_128_crypt(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. %% %% RAND - pseudo random numbers using RN_ functions in crypto lib %% +-spec rand_bytes(non_neg_integer()) -> binary(). +-spec rand_uniform(crypto_integer(), crypto_integer()) -> + crypto_integer(). + rand_bytes(_Bytes) -> ?nif_stub. rand_bytes(_Bytes, _Topmask, _Bottommask) -> ?nif_stub. @@ -331,9 +406,16 @@ mod_exp_nif(_Base,_Exp,_Mod) -> ?nif_stub. %% %% DSS, RSA - verify %% +-spec dss_verify(binary(), binary(), [binary()]) -> boolean(). +-spec dss_verify(dss_digest_type(), binary(), binary(), [binary()]) -> boolean(). +-spec rsa_verify(binary(), binary(), [binary()]) -> boolean(). +-spec rsa_verify(rsa_digest_type(), binary(), binary(), [binary()]) -> + boolean(). %% Key = [P,Q,G,Y] P,Q,G=DSSParams Y=PublicKey -dss_verify(_Data,_Signature,_Key) -> ?nif_stub. +dss_verify(Data,Signature,Key) -> + dss_verify(sha, Data, Signature, Key). +dss_verify(_Type,_Data,_Signature,_Key) -> ?nif_stub. % Key = [E,N] E=PublicExponent N=PublicModulus rsa_verify(Data,Signature,Key) -> @@ -345,13 +427,20 @@ rsa_verify(_Type,_Data,_Signature,_Key) -> ?nif_stub. %% DSS, RSA - sign %% %% Key = [P,Q,G,X] P,Q,G=DSSParams X=PrivateKey -dss_sign(Data, Key) -> - case dss_sign_nif(Data,Key) of +-spec dss_sign(binary(), [binary()]) -> binary(). +-spec dss_sign(dss_digest_type(), binary(), [binary()]) -> binary(). +-spec rsa_sign(binary(), [binary()]) -> binary(). +-spec rsa_sign(rsa_digest_type(), binary(), [binary()]) -> binary(). + +dss_sign(Data,Key) -> + dss_sign(sha,Data,Key). +dss_sign(Type, Data, Key) -> + case dss_sign_nif(Type,Data,Key) of error -> erlang:error(badkey, [Data, Key]); Sign -> Sign end. -dss_sign_nif(_Data,_Key) -> ?nif_stub. +dss_sign_nif(_Type,_Data,_Key) -> ?nif_stub. %% Key = [E,N,D] E=PublicExponent N=PublicModulus D=PrivateExponent rsa_sign(Data,Key) -> @@ -368,6 +457,16 @@ rsa_sign_nif(_Type,_Data,_Key) -> ?nif_stub. %% %% rsa_public_encrypt %% rsa_private_decrypt +-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'. + +-spec rsa_public_encrypt(binary(), [binary()], rsa_padding()) -> + binary(). +-spec rsa_public_decrypt(binary(), [binary()], rsa_padding()) -> + binary(). +-spec rsa_private_encrypt(binary(), [binary()], rsa_padding()) -> + binary(). +-spec rsa_private_decrypt(binary(), [binary()], rsa_padding()) -> + binary(). %% Binary, Key = [E,N] rsa_public_encrypt(BinMesg, Key, Padding) -> @@ -409,6 +508,14 @@ rsa_public_decrypt(BinMesg, Key, Padding) -> %% %% AES - with 128 or 256 bit key in cipher block chaining mode (CBC) %% +-spec aes_cbc_128_encrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_cbc_128_decrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_cbc_256_encrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_cbc_256_decrypt(iodata(), binary(), iodata()) -> + binary(). aes_cbc_128_encrypt(Key, IVec, Data) -> aes_cbc_crypt(Key, IVec, Data, true). @@ -437,17 +544,31 @@ aes_cbc_ivec(Data) when is_binary(Data) -> aes_cbc_ivec(Data) when is_list(Data) -> aes_cbc_ivec(list_to_binary(Data)). +%% +%% AES - in counter mode (CTR) +%% +-spec aes_ctr_encrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_ctr_decrypt(iodata(), binary(), iodata()) -> + binary(). + +aes_ctr_encrypt(_Key, _IVec, _Data) -> ?nif_stub. +aes_ctr_decrypt(_Key, _IVec, _Cipher) -> ?nif_stub. %% %% XOR - xor to iolists and return a binary %% NB doesn't check that they are the same size, just concatenates %% them and sends them to the driver %% +-spec exor(iodata(), iodata()) -> binary(). + exor(_A, _B) -> ?nif_stub. %% %% RC4 - symmetric stream cipher %% +-spec rc4_encrypt(iodata(), iodata()) -> binary(). + rc4_encrypt(_Key, _Data) -> ?nif_stub. rc4_set_key(_Key) -> ?nif_stub. rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. @@ -490,6 +611,10 @@ dh_check([_Prime,_Gen]) -> ?nif_stub. %% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] %% PrivKey = mpint() +-spec dh_generate_key([binary()]) -> {binary(),binary()}. +-spec dh_generate_key(binary()|undefined, [binary()]) -> + {binary(),binary()}. + dh_generate_key(DHParameters) -> dh_generate_key(undefined, DHParameters). dh_generate_key(PrivateKey, DHParameters) -> @@ -502,6 +627,8 @@ dh_generate_key_nif(_PrivateKey, _DHParameters) -> ?nif_stub. %% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] %% MyPrivKey, OthersPublicKey = mpint() +-spec dh_compute_key(binary(), binary(), [binary()]) -> binary(). + dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) -> case dh_compute_key_nif(OthersPublicKey,MyPrivateKey,DHParameters) of error -> erlang:error(computation_failed, [OthersPublicKey,MyPrivateKey,DHParameters]); |