aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto')
-rw-r--r--lib/crypto/Makefile1
-rw-r--r--lib/crypto/c_src/Makefile.in34
-rw-r--r--lib/crypto/c_src/crypto.c129
-rw-r--r--lib/crypto/doc/src/book.xml4
-rw-r--r--lib/crypto/doc/src/crypto.xml16
-rw-r--r--lib/crypto/doc/src/fascicules.xml2
-rw-r--r--lib/crypto/doc/src/insidecover.xml2
-rw-r--r--lib/crypto/doc/src/licenses.xml4
-rw-r--r--lib/crypto/doc/src/notes.xml2
-rw-r--r--lib/crypto/doc/src/ref_man.xml4
-rw-r--r--lib/crypto/doc/src/release_notes.xml4
-rw-r--r--lib/crypto/doc/src/usersguide.xml4
-rw-r--r--lib/crypto/src/crypto.erl81
-rw-r--r--lib/crypto/test/crypto_SUITE.erl47
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() ->