aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto')
-rw-r--r--lib/crypto/c_src/crypto.c47
-rw-r--r--lib/crypto/doc/src/crypto.xml30
-rw-r--r--lib/crypto/doc/src/crypto_app.xml2
-rw-r--r--lib/crypto/doc/src/notes.xml30
-rw-r--r--lib/crypto/doc/src/release_notes.xml2
-rw-r--r--lib/crypto/src/crypto.erl12
-rw-r--r--lib/crypto/test/Makefile2
-rw-r--r--lib/crypto/test/blowfish_SUITE.erl35
-rw-r--r--lib/crypto/test/crypto.cover2
-rw-r--r--lib/crypto/test/crypto.spec3
-rw-r--r--lib/crypto/test/crypto_SUITE.erl134
-rw-r--r--lib/crypto/vsn.mk2
12 files changed, 235 insertions, 66 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 85614a84c2..b8786f6f94 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2011. 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
@@ -62,10 +62,16 @@
# define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) \
VALGRIND_MAKE_MEM_DEFINED(ptr,size)
- # define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size) \
- ((void) ((VALGRIND_CHECK_MEM_IS_DEFINED(ptr,size) == 0) ? 1 : \
- (fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%ld) failed at %s:%d\r\n",\
- (ptr),(long)(size), __FILE__, __LINE__), abort(), 0)))
+ # define ERL_VALGRIND_ASSERT_MEM_DEFINED(Ptr,Size) \
+ do { \
+ int __erl_valgrind_mem_defined = VALGRIND_CHECK_MEM_IS_DEFINED((Ptr),(Size)); \
+ if (__erl_valgrind_mem_defined != 0) { \
+ fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%ld) failed at %s:%d\r\n", \
+ (Ptr),(long)(Size), __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while (0)
+
#else
# define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size)
# define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size)
@@ -126,6 +132,7 @@ static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -194,6 +201,8 @@ static ErlNifFunc nif_funcs[] = {
{"des_ecb_crypt", 3, des_ecb_crypt},
{"des_ede3_cbc_crypt", 6, des_ede3_cbc_crypt},
{"aes_cfb_128_crypt", 4, aes_cfb_128_crypt},
+ {"aes_ctr_encrypt", 3, aes_ctr_encrypt},
+ {"aes_ctr_decrypt", 3, aes_ctr_encrypt},
{"rand_bytes", 1, rand_bytes_1},
{"rand_bytes", 3, rand_bytes_3},
{"rand_uniform_nif", 2, rand_uniform_nif},
@@ -654,6 +663,34 @@ static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
return ret;
}
+/* Common for both encrypt and decrypt
+*/
+static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key, IVec, Data) */
+ ErlNifBinary key, ivec, text;
+ AES_KEY aes_key;
+ unsigned char ivec_clone[16]; /* writable copy */
+ unsigned char ecount_buf[AES_BLOCK_SIZE];
+ unsigned int num = 0;
+ ERL_NIF_TERM ret;
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
+ || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
+ || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
+ || !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
+ return enif_make_badarg(env);
+ }
+ memcpy(ivec_clone, ivec.data, 16);
+ memset(ecount_buf, 0, sizeof(ecount_buf));
+ AES_ctr128_encrypt((unsigned char *) text.data,
+ enif_make_new_binary(env, text.size, &ret),
+ text.size, &aes_key, ivec_clone, ecount_buf, &num);
+
+ /* To do an incremental {en|de}cryption, the state to to keep between calls
+ must include ivec_clone, ecount_buf and num. */
+ return ret;
+}
+
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
unsigned bytes;
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index e1431cfd81..c407350c47 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -53,7 +53,7 @@
<p>aes: Advanced Encryption Standard (AES) (FIPS 197) </p>
</item>
<item>
- <p>ecb, cbc, cfb, ofb: Recommendation for Block Cipher Modes
+ <p>ecb, cbc, cfb, ofb, ctr: Recommendation for Block Cipher Modes
of Operation (NIST SP 800-38A).</p>
</item>
<item>
@@ -557,6 +557,34 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
</desc>
</func>
<func>
+ <name>aes_ctr_encrypt(Key, IVec, Text) -> Cipher</name>
+ <fsummary>Encrypt <c>Text</c>according to AES in Counter mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts <c>Text</c> according to AES in Counter mode (CTR). <c>Text</c>
+ can be any number of bytes. <c>Key</c> is the AES key and must be either
+ 128, 192 or 256 bits long. <c>IVec</c> is an arbitrary initializing vector of 128 bits
+ (16 bytes).</p>
+ </desc>
+ </func>
+ <func>
+ <name>aes_ctr_decrypt(Key, IVec, Cipher) -> Text</name>
+ <fsummary>Decrypt <c>Cipher</c>according to AES in Counter mode</fsummary>
+ <type>
+ <v>Key = Cipher = iolist() | binary()</v>
+ <v>IVec = Text = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts <c>Cipher</c> according to AES in Counter mode (CTR). <c>Cipher</c>
+ can be any number of bytes. <c>Key</c> is the AES key and must be either
+ 128, 192 or 256 bits long. <c>IVec</c> is an arbitrary initializing vector of 128 bits
+ (16 bytes).</p>
+ </desc>
+ </func>
+ <func>
<name>erlint(Mpint) -> N</name>
<name>mpint(N) -> Mpint</name>
<fsummary>Convert between binary multi-precision integer and erlang big integer</fsummary>
diff --git a/lib/crypto/doc/src/crypto_app.xml b/lib/crypto/doc/src/crypto_app.xml
index bf1d1ae1f7..1c01e3f099 100644
--- a/lib/crypto/doc/src/crypto_app.xml
+++ b/lib/crypto/doc/src/crypto_app.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2007</year>
+ <year>2011</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 3c571eb2a3..5e9bda3920 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -30,6 +30,36 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 2.0.2.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Misc. Updates.</p>
+ <p>
+ Own Id: OTP-9132</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 2.0.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ AES CTR encryption support in <c>crypto</c>.</p>
+ <p>
+ Own Id: OTP-8752 Aux Id: seq11642 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 2.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/crypto/doc/src/release_notes.xml b/lib/crypto/doc/src/release_notes.xml
index 0c2ee23e22..0a84ca1c15 100644
--- a/lib/crypto/doc/src/release_notes.xml
+++ b/lib/crypto/doc/src/release_notes.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2007</year>
+ <year>2011</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 71fd91cafd..d6e2e033c0 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -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,6 +81,7 @@
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'.
@@ -542,6 +544,16 @@ 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
diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile
index b8a1e11982..3150bd472d 100644
--- a/lib/crypto/test/Makefile
+++ b/lib/crypto/test/Makefile
@@ -76,7 +76,7 @@ release_spec:
release_tests_spec: $(TEST_TARGET)
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) crypto.spec $(RELTEST_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) crypto.spec crypto.cover $(RELTEST_FILES) $(RELSYSDIR)
chmod -R u+w $(RELSYSDIR)
release_docs_spec:
diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl
index d117e7cc3d..a7a2c25467 100644
--- a/lib/crypto/test/blowfish_SUITE.erl
+++ b/lib/crypto/test/blowfish_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
@@ -23,7 +23,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("test_server_line.hrl").
-define(TIMEOUT, 120000). % 2 min
@@ -45,8 +45,12 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- crypto:start(),
- Config.
+ case catch crypto:start() of
+ ok ->
+ Config;
+ _Else ->
+ {skip,"Could not start crypto!"}
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
@@ -100,15 +104,20 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test Blowfish functionality"];
-
-all(suite) ->
- [ecb,
- cbc,
- cfb64,
- ofb64
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+[ecb, cbc, cfb64, ofb64].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases start here.
%%--------------------------------------------------------------------
diff --git a/lib/crypto/test/crypto.cover b/lib/crypto/test/crypto.cover
new file mode 100644
index 0000000000..61ee372ec5
--- /dev/null
+++ b/lib/crypto/test/crypto.cover
@@ -0,0 +1,2 @@
+{incl_app,crypto,details}.
+
diff --git a/lib/crypto/test/crypto.spec b/lib/crypto/test/crypto.spec
index 7ba5696189..cc09970cb3 100644
--- a/lib/crypto/test/crypto.spec
+++ b/lib/crypto/test/crypto.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../crypto_test"}}.
-
+{suites,"../crypto_test",all}.
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 06b284d50d..fe8f8e69a0 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. 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
@@ -18,12 +18,11 @@
%%
-module(crypto_SUITE).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
info/1,
link_test/1,
md5/1,
@@ -44,6 +43,7 @@
aes_cfb/1,
aes_cbc/1,
aes_cbc_iter/1,
+ aes_ctr/1,
mod_exp_test/1,
rand_uniform_test/1,
rsa_verify_test/1,
@@ -61,48 +61,41 @@
-export([hexstr2bin/1]).
-all(suite) ->
- [link_test,
- {conf,info,[md5,
- md5_update,
- md4,
- md4_update,
- md5_mac,
- md5_mac_io,
- sha,
- sha_update,
-%% sha256,
-%% sha256_update,
-%% sha512,
-%% sha512_update,
- des_cbc,
- aes_cfb,
- aes_cbc,
- aes_cbc_iter,
- des_cbc_iter,
- des_ecb,
- rand_uniform_test,
- rsa_verify_test,
- dsa_verify_test,
- rsa_sign_test,
- dsa_sign_test,
- rsa_encrypt_decrypt,
- dh,
- exor_test,
- rc4_test,
- rc4_stream_test,
- mod_exp_test,
- blowfish_cfb64,
- smp],
- cleanup}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [link_test, md5, md5_update, md4, md4_update, md5_mac,
+ md5_mac_io, sha, sha_update,
+ %% sha256, sha256_update, sha512,sha512_update,
+ des_cbc, aes_cfb, aes_cbc,
+ aes_cbc_iter, aes_ctr, des_cbc_iter, des_ecb, rand_uniform_test,
+ rsa_verify_test, dsa_verify_test, rsa_sign_test,
+ dsa_sign_test, rsa_encrypt_decrypt, dh, exor_test,
+ rc4_test, rc4_stream_test, mod_exp_test, blowfish_cfb64,
+ smp].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_testcase(_Name,Config) ->
io:format("init_per_testcase\n"),
?line crypto:start(),
Config.
-fin_per_testcase(_Name,Config) ->
- io:format("fin_per_testcase\n"),
+end_per_testcase(_Name,Config) ->
+ io:format("end_per_testcase\n"),
?line crypto:stop(),
Config.
@@ -619,6 +612,65 @@ aes_cbc_decrypt_iter(Key,IVec,Data, Acc) ->
aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>).
+aes_ctr(doc) -> "CTR";
+aes_ctr(Config) when is_list(Config) ->
+ %% Sample data from NIST Spec.Publ. 800-38A
+ %% F.5.1 CTR-AES128.Encrypt
+ Key128 = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
+ Samples128 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ "6bc1bee22e409f96e93d7e117393172a", % Plaintext
+ "874d6191b620e3261bef6864990db6ce"},% Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "9806f66b7970fdff8617187bb9fffdff"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "5ae4df3edbd5d35e5b4f09020db03eab"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "1e031dda2fbe03d1792170a0f3009cee"}],
+ lists:foreach(fun(S) -> aes_ctr_do(Key128,S) end, Samples128),
+
+ %% F.5.3 CTR-AES192.Encrypt
+ Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
+ Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ "6bc1bee22e409f96e93d7e117393172a", % Plaintext
+ "1abc932417521ca24f2b0459fe7e6e0b"},% Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "090339ec0aa6faefd5ccc2c6f4ce8e94"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "1e36b26bd1ebc670d1bd1d665620abf7"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "4f78a7f6d29809585a97daec58c6b050"}],
+ lists:foreach(fun(S) -> aes_ctr_do(Key192,S) end, Samples192),
+
+ %% F.5.5 CTR-AES256.Encrypt
+ Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
+ Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ "6bc1bee22e409f96e93d7e117393172a", % Plaintext
+ "601ec313775789a5b7a7f504bbf3d228"},% Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "f443e3ca4d62b59aca84e990cacaf5c5"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "2b0930daa23de94ce87017ba2d84988d"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "dfc9c58db67aada613c2dd08457941a6"}],
+ lists:foreach(fun(S) -> aes_ctr_do(Key256,S) end, Samples256).
+
+
+aes_ctr_do(Key,{IVec, Plain, Cipher}) ->
+ ?line I = hexstr2bin(IVec),
+ ?line P = hexstr2bin(Plain),
+ ?line C = crypto:aes_ctr_encrypt(Key, I, P),
+ ?line m(C, hexstr2bin(Cipher)),
+ ?line m(P, crypto:aes_ctr_decrypt(Key, I, C)).
+
%%
%%
mod_exp_test(doc) ->
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index e3549f0c50..e2d6fd0b37 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 2.0.1
+CRYPTO_VSN = 2.0.2.1