diff options
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/c_src/crypto.c | 76 | ||||
-rw-r--r-- | lib/crypto/doc/src/crypto.xml | 25 | ||||
-rw-r--r-- | lib/crypto/src/crypto.app.src | 12 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 110 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 42 |
5 files changed, 203 insertions, 62 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index a71df1d7fd..68079f06c7 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -198,7 +198,7 @@ static ErlNifFunc nif_funcs[] = { {"rand_bytes", 3, rand_bytes_3}, {"rand_uniform_nif", 2, rand_uniform_nif}, {"mod_exp_nif", 3, mod_exp_nif}, - {"dss_verify", 3, dss_verify}, + {"dss_verify", 4, dss_verify}, {"rsa_verify", 4, rsa_verify}, {"aes_cbc_crypt", 4, aes_cbc_crypt}, {"exor", 2, exor}, @@ -207,7 +207,7 @@ static ErlNifFunc nif_funcs[] = { {"rc4_encrypt_with_state", 2, rc4_encrypt_with_state}, {"rc2_40_cbc_crypt", 4, rc2_40_cbc_crypt}, {"rsa_sign_nif", 3, rsa_sign_nif}, - {"dss_sign_nif", 2, dss_sign_nif}, + {"dss_sign_nif", 3, dss_sign_nif}, {"rsa_public_crypt", 4, rsa_public_crypt}, {"rsa_private_crypt", 4, rsa_private_crypt}, {"dh_generate_parameters_nif", 2, dh_generate_parameters_nif}, @@ -255,6 +255,7 @@ static ERL_NIF_TERM atom_unable_to_check_generator; static ERL_NIF_TERM atom_not_suitable_generator; static ERL_NIF_TERM atom_check_failed; static ERL_NIF_TERM atom_unknown; +static ERL_NIF_TERM atom_none; static int is_ok_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info) @@ -264,15 +265,15 @@ static int is_ok_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info) } static void* crypto_alloc(size_t size) { - return enif_alloc(NULL, size); + return enif_alloc(size); } static void* crypto_realloc(void* ptr, size_t size) { - return enif_realloc(NULL, ptr, size); + return enif_realloc(ptr, size); } static void crypto_free(void* ptr) { - enif_free(NULL, ptr); + enif_free(ptr); } static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) @@ -289,7 +290,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) if (sys_info.scheduler_threads > 1) { int i; - lock_vec = enif_alloc(env,CRYPTO_num_locks()*sizeof(*lock_vec)); + lock_vec = enif_alloc(CRYPTO_num_locks()*sizeof(*lock_vec)); if (lock_vec==NULL) return -1; memset(lock_vec,0,CRYPTO_num_locks()*sizeof(*lock_vec)); @@ -322,6 +323,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) atom_not_suitable_generator = enif_make_atom(env,"not_suitable_generator"); atom_check_failed = enif_make_atom(env,"check_failed"); atom_unknown = enif_make_atom(env,"unknown"); + atom_none = enif_make_atom(env,"none"); *priv_data = NULL; library_refc++; @@ -371,7 +373,7 @@ static void unload(ErlNifEnv* env, void* priv_data) enif_rwlock_destroy(lock_vec[i]); } } - enif_free(env,lock_vec); + enif_free(lock_vec); } } /*else NIF library still used by other (new) module code */ @@ -766,7 +768,7 @@ static int inspect_mpint(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifBinary* bin) } static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Data,Signature,Key=[P, Q, G, Y]) */ +{/* (DigestType,Data,Signature,Key=[P, Q, G, Y]) */ ErlNifBinary data_bin, sign_bin; BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_y; unsigned char hmacbuf[SHA_DIGEST_LENGTH]; @@ -774,9 +776,8 @@ static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv DSA *dsa; int i; - if (!inspect_mpint(env,argv[0],&data_bin) - || !inspect_mpint(env,argv[1],&sign_bin) - || !enif_get_list_cell(env, argv[2], &head, &tail) + if (!inspect_mpint(env, argv[2], &sign_bin) + || !enif_get_list_cell(env, argv[3], &head, &tail) || !get_bn_from_mpint(env, head, &dsa_p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &dsa_q) @@ -785,10 +786,18 @@ static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &dsa_y) || !enif_is_empty_list(env,tail)) { - return enif_make_badarg(env); } - SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + if (argv[0] == atom_sha && inspect_mpint(env, argv[1], &data_bin)) { + SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + } + else if (argv[0] == atom_none && enif_inspect_binary(env, argv[1], &data_bin) + && data_bin.size == SHA_DIGEST_LENGTH) { + memcpy(hmacbuf, data_bin.data, SHA_DIGEST_LENGTH); + } + else { + return enif_make_badarg(env); + } dsa = DSA_new(); dsa->p = dsa_p; @@ -994,7 +1003,7 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar RSA_free(rsa); return enif_make_badarg(env); } - enif_alloc_binary(env, RSA_size(rsa), &ret_bin); + enif_alloc_binary(RSA_size(rsa), &ret_bin); if (is_sha) { SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, SHA_DIGEST_LENGTH); @@ -1011,19 +1020,19 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar if (i) { ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, rsa_s_len); if (rsa_s_len != data_bin.size) { - enif_realloc_binary(env, &ret_bin, rsa_s_len); + enif_realloc_binary(&ret_bin, rsa_s_len); ERL_VALGRIND_ASSERT_MEM_DEFINED(ret_bin.data, rsa_s_len); } return enif_make_binary(env,&ret_bin); } else { - enif_release_binary(env, &ret_bin); + enif_release_binary(&ret_bin); return atom_error; } } static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Data,Key=[P,Q,G,PrivKey]) */ +{/* (DigesType, Data, Key=[P,Q,G,PrivKey]) */ ErlNifBinary data_bin, ret_bin; ERL_NIF_TERM head, tail; unsigned char hmacbuf[SHA_DIGEST_LENGTH]; @@ -1032,8 +1041,7 @@ static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar int i; dsa->pub_key = NULL; - if (!inspect_mpint(env, argv[0], &data_bin) - || !enif_get_list_cell(env, argv[1], &head, &tail) + if (!enif_get_list_cell(env, argv[2], &head, &tail) || !get_bn_from_mpint(env, head, &dsa->p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &dsa->q) @@ -1042,20 +1050,28 @@ static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &dsa->priv_key) || !enif_is_empty_list(env,tail)) { - + goto badarg; + } + if (argv[0] == atom_sha && inspect_mpint(env, argv[1], &data_bin)) { + SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); + } + else if (argv[0] == atom_none && enif_inspect_binary(env,argv[1],&data_bin) + && data_bin.size == SHA_DIGEST_LENGTH) { + memcpy(hmacbuf, data_bin.data, SHA_DIGEST_LENGTH); + } + else { + badarg: DSA_free(dsa); return enif_make_badarg(env); } - SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); - - enif_alloc_binary(env, DSA_size(dsa), &ret_bin); + enif_alloc_binary(DSA_size(dsa), &ret_bin); i = DSA_sign(NID_sha1, hmacbuf, SHA_DIGEST_LENGTH, ret_bin.data, &dsa_s_len, dsa); DSA_free(dsa); if (i) { if (dsa_s_len != ret_bin.size) { - enif_realloc_binary(env, &ret_bin, dsa_s_len); + enif_realloc_binary(&ret_bin, dsa_s_len); } return enif_make_binary(env, &ret_bin); } @@ -1100,7 +1116,7 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER return enif_make_badarg(env); } - enif_alloc_binary(env, RSA_size(rsa), &ret_bin); + enif_alloc_binary(RSA_size(rsa), &ret_bin); if (argv[3] == atom_true) { ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len); @@ -1115,7 +1131,7 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER ret_bin.data, rsa, padding); if (i > 0) { ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i); - enif_realloc_binary(env, &ret_bin, i); + enif_realloc_binary(&ret_bin, i); } } RSA_free(rsa); @@ -1148,7 +1164,7 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE return enif_make_badarg(env); } - enif_alloc_binary(env, RSA_size(rsa), &ret_bin); + enif_alloc_binary(RSA_size(rsa), &ret_bin); if (argv[3] == atom_true) { ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len); @@ -1163,7 +1179,7 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE ret_bin.data, rsa, padding); if (i > 0) { ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i); - enif_realloc_binary(env, &ret_bin, i); + enif_realloc_binary(&ret_bin, i); } } RSA_free(rsa); @@ -1293,11 +1309,11 @@ static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_T ret = enif_make_badarg(env); } else { - enif_alloc_binary(env, DH_size(dh_params), &ret_bin); + enif_alloc_binary(DH_size(dh_params), &ret_bin); i = DH_compute_key(ret_bin.data, pubkey, dh_params); if (i > 0) { if (i != ret_bin.size) { - enif_realloc_binary(env, &ret_bin, i); + enif_realloc_binary(&ret_bin, i); } ret = enif_make_binary(env, &ret_bin); } diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 256eab3e3c..e1431cfd81 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -755,39 +755,44 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <func> <name>dss_sign(Data, Key) -> Signature</name> + <name>dss_sign(DigestType, Data, Key) -> Signature</name> <fsummary>Sign the data using dsa with given private key.</fsummary> <type> - <v>Digest = Mpint</v> + <v>DigestType = sha | none (default is sha)</v> + <v>Data = Mpint | ShaDigest</v> <v>Key = [P, Q, G, X]</v> <v>P, Q, G, X = Mpint</v> <d> Where <c>P</c>, <c>Q</c> and <c>G</c> are the dss parameters and <c>X</c> is the private key.</d> - <v>Mpint = binary()</v> + <v>ShaDigest = binary() with length 20 bytes</v> <v>Signature = binary()</v> </type> <desc> - <p>Calculates the sha digest of the <c>Data</c> - and creates a DSS signature with the private key <c>Key</c> - of the digest.</p> + <p>Creates a DSS signature with the private key <c>Key</c> of a digest. + If <c>DigestType</c> is 'sha', the digest is calculated as SHA1 of <c>Data</c>. + If <c>DigestType</c> is 'none', <c>Data</c> is the precalculated SHA1 digest.</p> </desc> </func> <func> <name>dss_verify(Data, Signature, Key) -> Verified</name> + <name>dss_verify(DigestType, Data, Signature, Key) -> Verified</name> <fsummary>Verify the data and signature using dsa with given public key.</fsummary> <type> <v>Verified = boolean()</v> - <v>Digest, Signature = Mpint</v> + <v>DigestType = sha | none</v> + <v>Data = Mpint | ShaDigest</v> + <v>Signature = Mpint</v> <v>Key = [P, Q, G, Y]</v> <v>P, Q, G, Y = Mpint</v> <d> Where <c>P</c>, <c>Q</c> and <c>G</c> are the dss parameters and <c>Y</c> is the public key.</d> - <v>Mpint = binary()</v> + <v>ShaDigest = binary() with length 20 bytes</v> </type> <desc> - <p>Calculates the sha digest of the <c>Data</c> and verifies that the - digest matches the DSS signature using the public key <c>Key</c>. - </p> + <p>Verifies that a digest matches the DSS signature using the public key <c>Key</c>. + If <c>DigestType</c> is 'sha', the digest is calculated as SHA1 of <c>Data</c>. + If <c>DigestType</c> is 'none', <c>Data</c> is the precalculated SHA1 digest.</p> </desc> </func> diff --git a/lib/crypto/src/crypto.app.src b/lib/crypto/src/crypto.app.src index a24760a781..5548b6a1b5 100644 --- a/lib/crypto/src/crypto.app.src +++ b/lib/crypto/src/crypto.app.src @@ -1,23 +1,23 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% {application, crypto, - [{description, "CRYPTO version 1"}, + [{description, "CRYPTO version 2"}, {vsn, "%VSN%"}, {modules, [crypto, crypto_app, diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 5b1ce96caf..39512d27e1 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]). @@ -82,6 +82,10 @@ aes_cbc_256_encrypt, aes_cbc_256_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). @@ -118,7 +122,7 @@ on_load() -> 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 +150,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 +164,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 +177,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 +195,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 +209,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 +227,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 +244,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 +255,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 +267,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 +287,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 +324,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 +339,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 +385,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 +406,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 +436,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 +487,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). @@ -443,11 +529,15 @@ aes_cbc_ivec(Data) when is_list(Data) -> %% 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 +580,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 +596,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]); diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 08d7a0ce99..576949d38d 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -770,18 +770,18 @@ dsa_verify_test(Config) when is_list(Config) -> crypto:mpint(Key) ], - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob), + ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob), ValidKey), true), BadMsg = one_bit_wrong(Msg), - ?line m(crypto:dss_verify(sized_binary(BadMsg), sized_binary(SigBlob), + ?line m(my_dss_verify(sized_binary(BadMsg), sized_binary(SigBlob), ValidKey), false), BadSig = one_bit_wrong(SigBlob), - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(BadSig), + ?line m(my_dss_verify(sized_binary(Msg), sized_binary(BadSig), ValidKey), false), SizeErr = size(SigBlob) - 13, - BadArg = (catch crypto:dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>, + BadArg = (catch my_dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>, ValidKey)), ?line m(element(1,element(2,BadArg)), badarg), @@ -791,9 +791,12 @@ dsa_verify_test(Config) when is_list(Config) -> crypto:mpint(Key+17) ], - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob), + ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob), InValidKey), false). + +one_bit_wrong(List) when is_list(List) -> + lists:map(fun(Bin) -> one_bit_wrong(Bin) end, List); one_bit_wrong(Bin) -> Half = size(Bin) div 2, <<First:Half/binary, Byte:8, Last/binary>> = Bin, @@ -843,15 +846,15 @@ dsa_sign_test(Config) when is_list(Config) -> ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669, Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)], - ?line Sig1 = crypto:dss_sign(sized_binary(Msg), Params ++ [crypto:mpint(PrivKey)]), + ?line Sig1 = my_dss_sign(sized_binary(Msg), Params ++ [crypto:mpint(PrivKey)]), - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(Sig1), + ?line m(my_dss_verify(sized_binary(Msg), Sig1, Params ++ [crypto:mpint(PubKey)]), true), - ?line m(crypto:dss_verify(sized_binary(one_bit_wrong(Msg)), sized_binary(Sig1), + ?line m(my_dss_verify(sized_binary(one_bit_wrong(Msg)), Sig1, Params ++ [crypto:mpint(PubKey)]), false), - ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(one_bit_wrong(Sig1)), + ?line m(my_dss_verify(sized_binary(Msg), one_bit_wrong(Sig1), Params ++ [crypto:mpint(PubKey)]), false), %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]), @@ -1132,3 +1135,24 @@ zero_bin(N) when is_integer(N) -> <<0:N8/integer>>; zero_bin(B) when is_binary(B) -> zero_bin(size(B)). + +my_dss_verify(Data,[Sign|Tail],Key) -> + Res = my_dss_verify(Data,sized_binary(Sign),Key), + case Tail of + [] -> Res; + _ -> ?line Res = my_dss_verify(Data,Tail,Key) + end; +my_dss_verify(Data,Sign,Key) -> + ?line Res = crypto:dss_verify(Data, Sign, Key), + ?line Res = crypto:dss_verify(sha, Data, Sign, Key), + ?line <<_:32,Raw/binary>> = Data, + ?line Res = crypto:dss_verify(none, crypto:sha(Raw), Sign, Key), + Res. + +my_dss_sign(Data,Key) -> + ?line S1 = crypto:dss_sign(Data, Key), + ?line S2 = crypto:dss_sign(sha, Data, Key), + ?line <<_:32,Raw/binary>> = Data, + ?line S3 = crypto:dss_sign(none, crypto:sha(Raw), Key), + [S1,S2,S3]. + |