diff options
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/c_src/crypto.c | 47 | ||||
-rw-r--r-- | lib/crypto/doc/src/crypto.xml | 30 | ||||
-rw-r--r-- | lib/crypto/doc/src/crypto_app.xml | 2 | ||||
-rw-r--r-- | lib/crypto/doc/src/notes.xml | 30 | ||||
-rw-r--r-- | lib/crypto/doc/src/release_notes.xml | 2 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 12 | ||||
-rw-r--r-- | lib/crypto/test/Makefile | 2 | ||||
-rw-r--r-- | lib/crypto/test/blowfish_SUITE.erl | 35 | ||||
-rw-r--r-- | lib/crypto/test/crypto.cover | 2 | ||||
-rw-r--r-- | lib/crypto/test/crypto.spec | 3 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 134 | ||||
-rw-r--r-- | lib/crypto/vsn.mk | 2 |
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 e728875027..f4689a23df 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 -f -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 |