diff options
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/Makefile | 1 | ||||
-rw-r--r-- | lib/crypto/c_src/Makefile.in | 34 | ||||
-rw-r--r-- | lib/crypto/c_src/crypto.c | 129 | ||||
-rw-r--r-- | lib/crypto/doc/src/book.xml | 4 | ||||
-rw-r--r-- | lib/crypto/doc/src/crypto.xml | 16 | ||||
-rw-r--r-- | lib/crypto/doc/src/fascicules.xml | 2 | ||||
-rw-r--r-- | lib/crypto/doc/src/insidecover.xml | 2 | ||||
-rw-r--r-- | lib/crypto/doc/src/licenses.xml | 4 | ||||
-rw-r--r-- | lib/crypto/doc/src/notes.xml | 2 | ||||
-rw-r--r-- | lib/crypto/doc/src/ref_man.xml | 4 | ||||
-rw-r--r-- | lib/crypto/doc/src/release_notes.xml | 4 | ||||
-rw-r--r-- | lib/crypto/doc/src/usersguide.xml | 4 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 81 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 47 |
14 files changed, 262 insertions, 72 deletions
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index 13eebea6a9..2adcfd7f31 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -24,6 +24,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # SUB_DIRECTORIES = src c_src doc/src +static_lib: SUB_DIRECTORIES = c_src include vsn.mk VSN = $(CRYPTO_VSN) diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index a20ddff05c..124d088056 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -70,6 +70,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/crypto-$(VSN) CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o CALLBACK_OBJS = $(OBJDIR)/crypto_callback$(TYPEMARKER).o NIF_MAKEFILE = $(PRIVDIR)/Makefile +CRYPTO_STATIC_OBJS = $(OBJDIR)/crypto_static$(TYPEMARKER).o\ + $(OBJDIR)/crypto_callback_static$(TYPEMARKER).o + +NIF_ARCHIVE = $(LIBDIR)/crypto$(TYPEMARKER).a ifeq ($(findstring win32,$(TARGET)), win32) NIF_LIB = $(LIBDIR)/crypto$(TYPEMARKER).dll @@ -97,7 +101,24 @@ CALLBACK_OBJS = CALLBACK_LIB = endif +ifeq ($(USING_VC),yes) +AR_OUT=-out: +AR_FLAGS= +else +AR_OUT= +ifeq ($(V),0) +AR_FLAGS=rc +else +AR_FLAGS=rcv +endif +endif + +ifndef RANLIB +RANLIB=true +endif + ALL_CFLAGS = $(TYPE_FLAGS) $(EXTRA_FLAGS) $(INCLUDES) +ALL_STATIC_CFLAGS = $(DED_STATIC_CFLAGS) $(INCLUDES) # ---------------------------------------------------- # Targets @@ -107,6 +128,8 @@ _create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR)) debug opt valgrind: $(NIF_LIB) $(CALLBACK_LIB) +static_lib: $(NIF_ARCHIVE) + $(OBJDIR)/%$(TYPEMARKER).o: %.c $(V_at)$(INSTALL_DIR) $(OBJDIR) $(V_CC) -c -o $@ $(ALL_CFLAGS) $< @@ -115,6 +138,14 @@ $(LIBDIR)/crypto$(TYPEMARKER).so: $(CRYPTO_OBJS) $(V_at)$(INSTALL_DIR) $(LIBDIR) $(V_LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB) +$(OBJDIR)/%_static$(TYPEMARKER).o: %.c + $(V_at)$(INSTALL_DIR) $(OBJDIR) + $(V_CC) -c -o $@ $(ALL_STATIC_CFLAGS) $< + +$(LIBDIR)/crypto$(TYPEMARKER).a: $(CRYPTO_STATIC_OBJS) + $(V_AR) $(AR_FLAGS) $(AR_OUT)$@ $(CRYPTO_STATIC_OBJS) + $(V_RANLIB) $@ + $(LIBDIR)/crypto$(TYPEMARKER).dll: $(CRYPTO_OBJS) $(V_at)$(INSTALL_DIR) $(LIBDIR) $(V_LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(CRYPTO_OBJS) -l$(SSL_CRYPTO_LIBNAME) -l$(SSL_SSL_LIBNAME) @@ -145,8 +176,11 @@ else rm -f $(LIBDIR)/crypto_callback.valgrind.so endif rm -f $(OBJDIR)/crypto.o + rm -f $(OBJDIR)/crypto_static.o rm -f $(OBJDIR)/crypto.debug.o + rm -f $(OBJDIR)/crypto_static.debug.o rm -f $(OBJDIR)/crypto.valgrind.o + rm -f $(OBJDIR)/crypto_static.valgrind.o rm -f $(OBJDIR)/crypto_callback.o rm -f $(OBJDIR)/crypto_callback.debug.o rm -f $(OBJDIR)/crypto_callback.valgrind.o diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index c28ff8136c..7567a08894 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -81,12 +81,18 @@ # define HAVE_EC #endif +#if OPENSSL_VERSION_NUMBER >= 0x0090803fL +# define HAVE_AES_IGE +#endif + #if defined(HAVE_EC) #include <openssl/ec.h> #include <openssl/ecdh.h> #include <openssl/ecdsa.h> #endif + + #ifdef VALGRIND # include <valgrind/memcheck.h> @@ -221,6 +227,7 @@ static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg static ERL_NIF_TERM dss_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -249,7 +256,7 @@ static ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF /* helpers */ -static void init_algorithms_types(void); +static void init_algorithms_types(ErlNifEnv*); static void init_digest_types(ErlNifEnv* env); static void hmac_md5(unsigned char *key, int klen, unsigned char *dbuf, int dlen, @@ -349,6 +356,7 @@ static ErlNifFunc nif_funcs[] = { {"dss_verify_nif", 4, dss_verify_nif}, {"rsa_verify_nif", 4, rsa_verify_nif}, {"aes_cbc_crypt", 4, aes_cbc_crypt}, + {"aes_ige_crypt_nif", 4, aes_ige_crypt_nif}, {"do_exor", 2, do_exor}, {"rc4_encrypt", 2, rc4_encrypt}, {"rc4_set_key", 1, rc4_set_key}, @@ -538,16 +546,20 @@ static ERL_NIF_TERM atom_onbasis; #define PRINTF_ERR1(FMT,A1) #ifdef HAVE_DYNAMIC_CRYPTO_LIB -static int change_basename(char* buf, int bufsz, const char* newfile) +static int change_basename(ErlNifBinary* bin, char* buf, int bufsz, const char* newfile) { - char* p = strrchr(buf, '/'); - p = (p == NULL) ? buf : p + 1; + int i; - if ((p - buf) + strlen(newfile) >= bufsz) { + for (i = bin->size; i > 0; i--) { + if (bin->data[i-1] == '/') + break; + } + if (i + strlen(newfile) >= bufsz) { PRINTF_ERR0("CRYPTO: lib name too long"); return 0; } - strcpy(p, newfile); + memcpy(buf, bin->data, i); + strcpy(buf+i, newfile); return 1; } @@ -566,14 +578,15 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info) int tpl_arity; const ERL_NIF_TERM* tpl_array; int vernum; + ErlNifBinary lib_bin; char lib_buf[1000]; - /* load_info: {201, "/full/path/of/this/library"} */ + /* load_info: {301, <<"/full/path/of/this/library">>} */ if (!enif_get_tuple(env, load_info, &tpl_arity, &tpl_array) || tpl_arity != 2 || !enif_get_int(env, tpl_array[0], &vernum) - || vernum != 201 - || enif_get_string(env, tpl_array[1], lib_buf, sizeof(lib_buf), ERL_NIF_LATIN1) <= 0) { + || vernum != 301 + || !enif_inspect_binary(env, tpl_array[1], &lib_bin)) { PRINTF_ERR1("CRYPTO: Invalid load_info '%T'", load_info); return 0; @@ -628,12 +641,12 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info) #endif init_digest_types(env); - init_algorithms_types(); + init_algorithms_types(env); #ifdef HAVE_DYNAMIC_CRYPTO_LIB { void* handle; - if (!change_basename(lib_buf, sizeof(lib_buf), "crypto_callback")) { + if (!change_basename(&lib_bin, lib_buf, sizeof(lib_buf), "crypto_callback")) { return 0; } if (!(handle = enif_dlopen(lib_buf, &error_handler, NULL))) { @@ -709,36 +722,58 @@ static void unload(ErlNifEnv* env, void* priv_data) --library_refc; } -static int algos_cnt; -static ERL_NIF_TERM algos[9]; /* increase when extending the list */ +static int algo_hash_cnt; +static ERL_NIF_TERM algo_hash[8]; /* increase when extending the list */ +static int algo_pubkey_cnt; +static ERL_NIF_TERM algo_pubkey[2]; /* increase when extending the list */ +static int algo_cipher_cnt; +static ERL_NIF_TERM algo_cipher[2]; /* increase when extending the list */ -static void init_algorithms_types(void) +static void init_algorithms_types(ErlNifEnv* env) { - algos_cnt = 0; - algos[algos_cnt++] = atom_md4; - algos[algos_cnt++] = atom_md5; - algos[algos_cnt++] = atom_sha; - algos[algos_cnt++] = atom_ripemd160; + algo_hash_cnt = 0; + algo_hash[algo_hash_cnt++] = atom_md4; + algo_hash[algo_hash_cnt++] = atom_md5; + algo_hash[algo_hash_cnt++] = atom_sha; + algo_hash[algo_hash_cnt++] = atom_ripemd160; #ifdef HAVE_SHA224 - algos[algos_cnt++] = atom_sha224; + algo_hash[algo_hash_cnt++] = atom_sha224; #endif #ifdef HAVE_SHA256 - algos[algos_cnt++] = atom_sha256; + algo_hash[algo_hash_cnt++] = atom_sha256; #endif #ifdef HAVE_SHA384 - algos[algos_cnt++] = atom_sha384; + algo_hash[algo_hash_cnt++] = atom_sha384; #endif #ifdef HAVE_SHA512 - algos[algos_cnt++] = atom_sha512; + algo_hash[algo_hash_cnt++] = atom_sha512; #endif + + algo_pubkey_cnt = 0; #if defined(HAVE_EC) - algos[algos_cnt++] = atom_ec; + algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ecdsa"); + algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ecdh"); +#endif + + algo_cipher_cnt = 0; +#ifdef HAVE_DES_ede3_cfb_encrypt + algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "des3_cbf"); +#endif +#ifdef HAVE_AES_IGE + algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_ige256"); #endif + + ASSERT(algo_hash_cnt <= sizeof(algo_hash)/sizeof(ERL_NIF_TERM)); + ASSERT(algo_pubkey_cnt <= sizeof(algo_pubkey)/sizeof(ERL_NIF_TERM)); + ASSERT(algo_cipher_cnt <= sizeof(algo_cipher)/sizeof(ERL_NIF_TERM)); } static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { - return enif_make_list_from_array(env, algos, algos_cnt); + return enif_make_tuple3(env, + enif_make_list_from_array(env, algo_hash, algo_hash_cnt), + enif_make_list_from_array(env, algo_pubkey, algo_pubkey_cnt), + enif_make_list_from_array(env, algo_cipher, algo_cipher_cnt)); } static ERL_NIF_TERM info_lib(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) @@ -2090,6 +2125,45 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a return ret; } +static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, IVec, Data, IsEncrypt) */ +#ifdef HAVE_AES_IGE + ErlNifBinary key_bin, ivec_bin, data_bin; + AES_KEY aes_key; + unsigned char ivec[32]; + int i; + unsigned char* ret_ptr; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) + || (key_bin.size != 16 && key_bin.size != 32) + || !enif_inspect_binary(env, argv[1], &ivec_bin) + || ivec_bin.size != 32 + || !enif_inspect_iolist_as_binary(env, argv[2], &data_bin) + || data_bin.size % 16 != 0) { + + return enif_make_badarg(env); + } + + if (argv[3] == atom_true) { + i = AES_ENCRYPT; + AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key); + } + else { + i = AES_DECRYPT; + AES_set_decrypt_key(key_bin.data, key_bin.size*8, &aes_key); + } + + ret_ptr = enif_make_new_binary(env, data_bin.size, &ret); + memcpy(ivec, ivec_bin.data, 32); /* writable copy */ + AES_ige_encrypt(data_bin.data, ret_ptr, data_bin.size, &aes_key, ivec, i); + CONSUME_REDS(env,data_bin); + return ret; +#else + return atom_notsup; +#endif +} + static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Data1, Data2) */ ErlNifBinary d1, d2; @@ -2658,8 +2732,9 @@ static ERL_NIF_TERM srp_user_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_ <premaster secret> = (B - (k * g^x)) ^ (a + (u * x)) % N */ BIGNUM *bn_exponent = NULL, *bn_a = NULL; - BIGNUM *bn_u, *bn_multiplier, *bn_exp2, *bn_base, - *bn_prime, *bn_generator, *bn_B, *bn_result; + BIGNUM *bn_u = NULL, *bn_multiplier = NULL, *bn_exp2, + *bn_base, *bn_prime = NULL, *bn_generator = NULL, + *bn_B = NULL, *bn_result; BN_CTX *bn_ctx; unsigned char* ptr; unsigned dlen; diff --git a/lib/crypto/doc/src/book.xml b/lib/crypto/doc/src/book.xml index f07208482c..c477791bf2 100644 --- a/lib/crypto/doc/src/book.xml +++ b/lib/crypto/doc/src/book.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE book SYSTEM "book.dtd"> <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2013</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 99d167bfa9..406fd5e59a 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -118,7 +118,7 @@ <p><code>stream_cipher() = rc4 | aes_ctr </code></p> - <p><code>block_cipher() = aes_cbc128 | aes_cfb128 | blowfish_cbc | + <p><code>block_cipher() = aes_cbc128 | aes_cfb128 | aes_ige256 | blowfish_cbc | blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | rc2_cbc </code></p> @@ -142,7 +142,7 @@ Note that both md4 and md5 are recommended only for compatibility with existing applications. </p> <p><code> cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | - blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb128| aes_cbc256 | rc2_cbc | aes_ctr| rc4 </code> </p> + blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb128| aes_cbc256 | aes_ige256 | rc2_cbc | aes_ctr| rc4 </code> </p> <p><code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh </code> </p> </section> @@ -159,8 +159,9 @@ </type> <desc> <p>Encrypt <c>PlainText</c>according to <c>Type</c> block cipher. - <c>IVec</c> is an arbitrary initializing vector. - </p> + <c>IVec</c> is an arbitrary initializing vector.</p> + <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c> + is not supported by the underlying OpenSSL implementation.</p> </desc> </func> @@ -175,8 +176,9 @@ </type> <desc> <p>Decrypt <c>CipherText</c>according to <c>Type</c> block cipher. - <c>IVec</c> is an arbitrary initializing vector. - </p> + <c>IVec</c> is an arbitrary initializing vector.</p> + <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c> + is not supported by the underlying OpenSSL implementation.</p> </desc> </func> diff --git a/lib/crypto/doc/src/fascicules.xml b/lib/crypto/doc/src/fascicules.xml index 8fc250bc75..cbc266cd30 100644 --- a/lib/crypto/doc/src/fascicules.xml +++ b/lib/crypto/doc/src/fascicules.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE fascicules SYSTEM "fascicules.dtd"> <fascicules> diff --git a/lib/crypto/doc/src/insidecover.xml b/lib/crypto/doc/src/insidecover.xml index e7407b8052..bf2427afdf 100644 --- a/lib/crypto/doc/src/insidecover.xml +++ b/lib/crypto/doc/src/insidecover.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE bookinsidecover SYSTEM "bookinsidecover.dtd"> <bookinsidecover> diff --git a/lib/crypto/doc/src/licenses.xml b/lib/crypto/doc/src/licenses.xml index 0b791acfa2..1c77d1f115 100644 --- a/lib/crypto/doc/src/licenses.xml +++ b/lib/crypto/doc/src/licenses.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2003</year><year>2011</year> + <year>2003</year><year>2013</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 97558ef0e7..0ff0c8aa96 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> diff --git a/lib/crypto/doc/src/ref_man.xml b/lib/crypto/doc/src/ref_man.xml index f801221c81..d14ff053c9 100644 --- a/lib/crypto/doc/src/ref_man.xml +++ b/lib/crypto/doc/src/ref_man.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE application SYSTEM "application.dtd"> <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2013</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/crypto/doc/src/release_notes.xml b/lib/crypto/doc/src/release_notes.xml index 0a84ca1c15..4f9d448ad1 100644 --- a/lib/crypto/doc/src/release_notes.xml +++ b/lib/crypto/doc/src/release_notes.xml @@ -1,11 +1,11 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part> <header> <copyright> <year>1999</year> - <year>2011</year> + <year>2013</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml index dc5bf520a9..e6fd291974 100644 --- a/lib/crypto/doc/src/usersguide.xml +++ b/lib/crypto/doc/src/usersguide.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2013</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 8e8370f3b0..12ff060bf9 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -183,7 +183,7 @@ %%-type ec_key() :: {Curve :: ec_curve(), PrivKey :: binary() | undefined, PubKey :: ec_point() | undefined}. -on_load(on_load/0). --define(CRYPTO_NIF_VSN,201). +-define(CRYPTO_NIF_VSN,301). -define(nif_stub,nif_stub_error(?LINE)). nif_stub_error(Line) -> @@ -204,20 +204,13 @@ stop() -> application:stop(crypto). supports()-> - Algs = algorithms(), - PubKeyAlgs = - case lists:member(ec, Algs) of - true -> - {public_keys, [rsa, dss, ecdsa, dh, srp, ecdh]}; - false -> - {public_keys, [rsa, dss, dh, srp]} - end, - [{hashs, Algs -- [ec]}, - {ciphers, [des_cbc, des_cfb, des3_cbc, des3_cbf, des_ede3, blowfish_cbc, + {Hashs, PubKeys, Ciphers} = algorithms(), + + [{hashs, Hashs}, + {ciphers, [des_cbc, des_cfb, des3_cbc, des_ede3, blowfish_cbc, blowfish_cfb64, blowfish_ofb64, blowfish_ecb, aes_cbc128, aes_cfb128, - aes_cbc256, rc2_cbc, aes_ctr, rc4 - ]}, - PubKeyAlgs + aes_cbc256, rc2_cbc, aes_ctr, rc4] ++ Ciphers}, + {public_keys, [rsa, dss, dh, srp] ++ PubKeys} ]. info_lib() -> ?nif_stub. @@ -309,13 +302,16 @@ block_encrypt(aes_cbc128, Key, Ivec, Data) -> aes_cbc_128_encrypt(Key, Ivec, Data); block_encrypt(aes_cbc256, Key, Ivec, Data) -> aes_cbc_256_encrypt(Key, Ivec, Data); +block_encrypt(aes_ige256, Key, Ivec, Data) -> + aes_ige_256_encrypt(Key, Ivec, Data); block_encrypt(aes_cfb128, Key, Ivec, Data) -> aes_cfb_128_encrypt(Key, Ivec, Data); block_encrypt(rc2_cbc, Key, Ivec, Data) -> rc2_cbc_encrypt(Key, Ivec, Data). -spec block_decrypt(des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | blowfish_cbc | - blowfish_cfb64 | blowfish_ofb64 | aes_cbc128 | aes_cbc256 | aes_cfb128 | rc2_cbc, + blowfish_cfb64 | blowfish_ofb64 | aes_cbc128 | aes_cbc256 | aes_ige256 | + aes_cfb128 | rc2_cbc, Key::iodata(), Ivec::binary(), Data::iodata()) -> binary(). block_decrypt(des_cbc, Key, Ivec, Data) -> @@ -338,6 +334,8 @@ block_decrypt(aes_cbc128, Key, Ivec, Data) -> aes_cbc_128_decrypt(Key, Ivec, Data); block_decrypt(aes_cbc256, Key, Ivec, Data) -> aes_cbc_256_decrypt(Key, Ivec, Data); +block_decrypt(aes_ige256, Key, Ivec, Data) -> + aes_ige_256_decrypt(Key, Ivec, Data); block_decrypt(aes_cfb128, Key, Ivec, Data) -> aes_cfb_128_decrypt(Key, Ivec, Data); block_decrypt(rc2_cbc, Key, Ivec, Data) -> @@ -357,14 +355,16 @@ block_decrypt(des_ecb, Key, Data) -> block_decrypt(blowfish_ecb, Key, Data) -> blowfish_ecb_decrypt(Key, Data). --spec next_iv(des_cbc | des3_cbc | aes_cbc, Data::iodata()) -> binary(). +-spec next_iv(des_cbc | des3_cbc | aes_cbc | aes_ige, Data::iodata()) -> binary(). next_iv(des_cbc, Data) -> des_cbc_ivec(Data); next_iv(des3_cbc, Data) -> des_cbc_ivec(Data); next_iv(aes_cbc, Data) -> - aes_cbc_ivec(Data). + aes_cbc_ivec(Data); +next_iv(aes_ige, Data) -> + aes_ige_ivec(Data). -spec next_iv(des_cfb, Data::iodata(), Ivec::binary()) -> binary(). @@ -640,7 +640,7 @@ on_load() -> end end, Lib = filename:join([PrivDir, "lib", LibName]), - Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,Lib}) of + Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,path2bin(Lib)}) of ok -> ok; {error, {load_failed, _}}=Error1 -> ArchLibDir = @@ -652,7 +652,7 @@ on_load() -> [] -> Error1; _ -> ArchLib = filename:join([ArchLibDir, LibName]), - erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchLib}) + erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,path2bin(ArchLib)}) end; Error1 -> Error1 end, @@ -663,6 +663,14 @@ on_load() -> "OpenSSL might not be installed on this system.~n",[E,Str]), Status end. + +path2bin(Path) when is_list(Path) -> + Encoding = file:native_name_encoding(), + case unicode:characters_to_binary(Path,Encoding,Encoding) of + Bin when is_binary(Bin) -> + Bin + end. + %%-------------------------------------------------------------------- %%% Internal functions (some internal API functions are part of the deprecated API) %%-------------------------------------------------------------------- @@ -1255,6 +1263,41 @@ aes_cbc_ivec(Data) when is_list(Data) -> aes_cbc_ivec(list_to_binary(Data)). +%% +%% AES - with 256 bit key in infinite garble extension mode (IGE) +%% + +-spec aes_ige_256_decrypt(iodata(), binary(), iodata()) -> + binary(). + +aes_ige_256_encrypt(Key, IVec, Data) -> + aes_ige_crypt(Key, IVec, Data, true). + +aes_ige_256_decrypt(Key, IVec, Data) -> + aes_ige_crypt(Key, IVec, Data, false). + +aes_ige_crypt(Key, IVec, Data, IsEncrypt) -> + case aes_ige_crypt_nif(Key,IVec,Data,IsEncrypt) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. + +aes_ige_crypt_nif(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. + +%% +%% aes_ige_ivec(Data) -> binary() +%% +%% Returns the IVec to be used in the next iteration of +%% aes_ige_*_[encrypt|decrypt]. +%% IVec size: 32 bytes +%% +aes_ige_ivec(Data) when is_binary(Data) -> + {_, IVec} = split_binary(Data, size(Data) - 32), + IVec; +aes_ige_ivec(Data) when is_list(Data) -> + aes_ige_ivec(list_to_binary(Data)). + + %% Stream ciphers -------------------------------------------------------------------- stream_crypt(Fun, State, Data, Size, MaxByts, []) when Size =< MaxByts -> diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 58aaa78d28..42e200fcf0 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -56,6 +56,7 @@ all() -> {group, aes_cbc128}, {group, aes_cfb128}, {group, aes_cbc256}, + {group, aes_ige256}, {group, rc2_cbc}, {group, rc4}, {group, aes_ctr}, @@ -90,6 +91,7 @@ groups() -> {aes_cbc128,[], [block]}, {aes_cfb128,[], [block]}, {aes_cbc256,[], [block]}, + {aes_ige256,[], [block]}, {blowfish_cbc, [], [block]}, {blowfish_ecb, [], [block]}, {blowfish_cfb64, [], [block]}, @@ -143,7 +145,8 @@ app(Config) when is_list(Config) -> hash() -> [{doc, "Test all different hash functions"}]. hash(Config) when is_list(Config) -> - {Type, Msgs, Digests} = proplists:get_value(hash, Config), + {Type, MsgsLE, Digests} = proplists:get_value(hash, Config), + Msgs = lazy_eval(MsgsLE), [LongMsg | _] = lists:reverse(Msgs), Inc = iolistify(LongMsg), [IncrDigest | _] = lists:reverse(Digests), @@ -154,7 +157,8 @@ hash(Config) when is_list(Config) -> hmac() -> [{doc, "Test all different hmac functions"}]. hmac(Config) when is_list(Config) -> - {Type, Keys, Data, Expected} = proplists:get_value(hmac, Config), + {Type, Keys, DataLE, Expected} = proplists:get_value(hmac, Config), + Data = lazy_eval(DataLE), hmac(Type, Keys, Data, Expected), hmac(Type, lists:map(fun iolistify/1, Keys), lists:map(fun iolistify/1, Data), Expected), hmac_increment(Type). @@ -171,7 +175,8 @@ block(Config) when is_list(Config) -> stream() -> [{doc, "Test stream ciphers"}]. stream(Config) when is_list(Config) -> - Streams = proplists:get_value(stream, Config), + Streams = lazy_eval(proplists:get_value(stream, Config)), + lists:foreach(fun stream_cipher/1, Streams), lists:foreach(fun stream_cipher/1, stream_iolistify(Streams)), lists:foreach(fun stream_cipher_incment/1, stream_iolistify(Streams)). @@ -692,6 +697,9 @@ group_config(aes_cbc128, Config) -> group_config(aes_cbc256, Config) -> Block = aes_cbc256(), [{block, Block} | Config]; +group_config(aes_ige256, Config) -> + Block = aes_ige256(), + [{block, Block} | Config]; group_config(aes_cfb128, Config) -> Block = aes_cfb128(), [{block, Block} | Config]; @@ -795,7 +803,15 @@ rfc_4634_sha512_digests() -> hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909")]. long_msg() -> - lists:duplicate(1000000, $a). + fun() -> lists:duplicate(1000000, $a) end. + +%% Building huge terms (like long_msg/0) in init_per_group seems to cause +%% test_server crash with 'no_answer_from_tc_supervisor' sometimes on some +%% machines. Therefore lazy evaluation when test case has started. +lazy_eval(F) when is_function(F) -> F(); +lazy_eval(Lst) when is_list(Lst) -> lists:map(fun lazy_eval/1, Lst); +lazy_eval(Tpl) when is_tuple(Tpl) -> list_to_tuple(lists:map(fun lazy_eval/1, tuple_to_list(Tpl))); +lazy_eval(Term) -> Term. long_sha_digest() -> hexstr2bin("34aa973c" "d4c4daa4" "f61eeb2b" "dbad2731" "6534016f"). @@ -1106,6 +1122,25 @@ aes_cbc256() -> hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")} ]. +aes_ige256() -> + [{aes_ige256, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"), + hexstr2bin("6bc1bee22e409f96e93d7e117393172a")}, + {aes_ige256, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("4D0F9E735749215C05CB20DA00F7814B77D33F8A668BEBBAC1739AB20302D4FE"), + hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")}, + {aes_ige256, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("2A5569424DAE1ACEABDEEA108DB4606AE21A9227CAB5F55BF52535CFA2B34717"), + hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")}, + {aes_ige256, + hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + hexstr2bin("15D5A583D2D668E518E683D9BDF1B6D0E0C3B1E5D5C1D51E964822E1ADE88DFA"), + hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")} + ]. + aes_cfb128() -> [{aes_cfb128, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), @@ -1245,7 +1280,7 @@ blowfish_ofb64() -> rc4() -> [{rc4, <<"apaapa">>, <<"Yo baby yo">>}, {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))}, - {rc4, <<"apaapa">>, lists:duplicate(1000000, $a)} + {rc4, <<"apaapa">>, long_msg()} ]. aes_ctr() -> @@ -1293,7 +1328,7 @@ aes_ctr() -> {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), - lists:duplicate(1000000, $a)} + long_msg()} ]. rsa_plain() -> |