From 3881407ea8444c280d9659f40e6c169a1e10310d Mon Sep 17 00:00:00 2001 From: Michael Loftis Date: Tue, 18 Dec 2012 15:08:46 -0700 Subject: add ripemd160 support to crypto add ripemd160 message digest support to the crypto app, includes some test cases. --- lib/crypto/c_src/crypto.c | 56 ++++++++++++++++++++++++++++++++++++++++ lib/crypto/src/crypto.erl | 16 ++++++++++++ lib/crypto/test/crypto_SUITE.erl | 32 +++++++++++++++++++++-- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 72c9e5b8e8..b08e570dba 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -139,6 +140,10 @@ static ERL_NIF_TERM md5(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM md5_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM md5_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM md5_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM ripemd160(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM ripemd160_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM ripemd160_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM ripemd160_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM sha_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM sha_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -246,6 +251,10 @@ static ErlNifFunc nif_funcs[] = { {"md5_init", 0, md5_init}, {"md5_update", 2, md5_update}, {"md5_final", 1, md5_final}, + {"ripemd160", 1, ripemd160}, + {"ripemd160_init", 0, ripemd160_init}, + {"ripemd160_update", 2, ripemd160_update}, + {"ripemd160_final", 1, ripemd160_final}, {"sha", 1, sha}, {"sha_init", 0, sha_init}, {"sha_update", 2, sha_update}, @@ -600,6 +609,53 @@ static ERL_NIF_TERM md5_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ return ret; } +static ERL_NIF_TERM ripemd160(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data) */ + ErlNifBinary ibin; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) { + return enif_make_badarg(env); + } + RIPEMD160((unsigned char *) ibin.data, ibin.size, + enif_make_new_binary(env,RIPEMD160_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM ripemd160_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* () */ + ERL_NIF_TERM ret; + RIPEMD160_Init((RIPEMD160_CTX *) enif_make_new_binary(env, RIPEMD160_CTX_LEN, &ret)); + return ret; +} +static ERL_NIF_TERM ripemd160_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ + RIPEMD160_CTX* new_ctx; + ErlNifBinary ctx_bin, data_bin; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) + || ctx_bin.size != RIPEMD160_CTX_LEN + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { + return enif_make_badarg(env); + } + new_ctx = (RIPEMD160_CTX*) enif_make_new_binary(env,RIPEMD160_CTX_LEN, &ret); + memcpy(new_ctx, ctx_bin.data, RIPEMD160_CTX_LEN); + RIPEMD160_Update(new_ctx, data_bin.data, data_bin.size); + return ret; +} +static ERL_NIF_TERM ripemd160_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context) */ + ErlNifBinary ctx_bin; + RIPEMD160_CTX ctx_clone; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != RIPEMD160_CTX_LEN) { + return enif_make_badarg(env); + } + memcpy(&ctx_clone, ctx_bin.data, RIPEMD160_CTX_LEN); /* writable */ + RIPEMD160_Final(enif_make_new_binary(env, RIPEMD160_LEN, &ret), &ctx_clone); + return ret; +} + + static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Data) */ ErlNifBinary ibin; diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 461558a79e..69fecf4a11 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -25,6 +25,7 @@ -export([hash/2, hash_init/1, hash_update/2, hash_final/1]). -export([md4/1, md4_init/0, md4_update/2, md4_final/1]). -export([md5/1, md5_init/0, md5_update/2, md5_final/1]). +-export([ripemd160/1, ripemd160_init/0, ripemd160_update/2, ripemd160_final/1]). -export([sha/1, sha_init/0, sha_update/2, sha_final/1]). -export([sha224/1, sha224_init/0, sha224_update/2, sha224_final/1]). -export([sha256/1, sha256_init/0, sha256_update/2, sha256_final/1]). @@ -70,6 +71,7 @@ -define(FUNC_LIST, [md4, md4_init, md4_update, md4_final, md5, md5_init, md5_update, md5_final, + ripemd160, ripemd160_init, ripemd160_update, ripemd160_final, sha, sha_init, sha_update, sha_final, sha224, sha224_init, sha224_update, sha224_final, sha256, sha256_init, sha256_update, sha256_final, @@ -262,6 +264,20 @@ md4_init() -> ?nif_stub. md4_update(_Context, _Data) -> ?nif_stub. md4_final(_Context) -> ?nif_stub. +%% +%% RIPEMD160 +%% + +-spec ripemd160(iodata()) -> binary(). +-spec ripemd160_init() -> binary(). +-spec ripemd160_update(binary(), iodata()) -> binary(). +-spec ripemd160_final(binary()) -> binary(). + +ripemd160(_Data) -> ?nif_stub. +ripemd160_init() -> ?nif_stub. +ripemd160_update(_Context, _Data) -> ?nif_stub. +ripemd160_final(_Context) -> ?nif_stub. + %% %% SHA %% diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 8965ab6b94..829d867d8c 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -39,6 +39,8 @@ hmac_update_md5_io/1, hmac_update_md5_n/1, hmac_rfc4231/1, + ripemd160/1, + ripemd160_update/1, sha256/1, sha256_update/1, sha512/1, @@ -86,7 +88,7 @@ groups() -> [{info, [sequence],[info, {group, rest}]}, {rest, [], [md5, md5_update, md4, md4_update, md5_mac, - md5_mac_io, sha, sha_update, + md5_mac_io, ripemd160, ripemd160_update, sha, sha_update, sha256, sha256_update, sha512, sha512_update, hmac_update_sha, hmac_update_sha_n, hmac_update_sha256, hmac_update_sha512, hmac_update_md5_n, hmac_update_md5_io, hmac_update_md5, @@ -719,7 +721,33 @@ hmac_update_md5_n(Config) when is_list(Config) -> ?line Mac = crypto:hmac_final_n(Ctx3, 12), ?line Exp = crypto:md5_mac_96(Key, lists:flatten([Data, Data2])), ?line m(Exp, Mac). - +%% +%% +ripemd160(doc) -> + ["Generate RIPEMD160 message digests and check the result."]; +ripemd160(suite) -> + []; +ripemd160(Config) when is_list(Config) -> + ?line m(crypto:ripemd160("abc"), + hexstr2bin("8EB208F7E05D987A9B044A8E98C6B087F15A0BFC")), + ?line m(crypto:ripemd160("abcdbcdecdefdefgefghfghighijhijkijkljklmklm" + "nlmnomnopnopq"), + hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")). + + +%% +%% +ripemd160_update(doc) -> + ["Generate RIPEMD160 message digests by using ripemd160_init," + "ripemd160_update, and ripemd160_final and check the result."]; +ripemd160_update(suite) -> + []; +ripemd160_update(Config) when is_list(Config) -> + ?line Ctx = crypto:ripemd160_init(), + ?line Ctx1 = crypto:ripemd160_update(Ctx, "abcdbcdecdefdefgefghfghighi"), + ?line Ctx2 = crypto:ripemd160_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"), + ?line m(crypto:ripemd160_final(Ctx2), + hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")). %% %% -- cgit v1.2.3 From e84023379df3f0a66aae31f64880629b6035e2a8 Mon Sep 17 00:00:00 2001 From: Michael Loftis Date: Wed, 19 Dec 2012 10:35:19 -0700 Subject: fix missing defines for RIPEMD160_CTX_LEN and RIPEMD160_LEN A couple of #defines were missed in my previous patch. --- lib/crypto/c_src/crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index b08e570dba..e77e5fb8f0 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -335,6 +335,8 @@ ERL_NIF_INIT(crypto,nif_funcs,load,NULL,upgrade,unload) #define MD5_LEN_96 12 #define MD4_CTX_LEN (sizeof(MD4_CTX)) #define MD4_LEN 16 +#define RIPEMD160_CTX_LEN (sizeof(RIPEMD160_CTX)) +#define RIPEMD160_LEN 20 #define SHA_CTX_LEN (sizeof(SHA_CTX)) #define SHA_LEN 20 #define SHA_LEN_96 12 -- cgit v1.2.3 From f33c0a7aaf5c051c6328451c3ebfd9936273be90 Mon Sep 17 00:00:00 2001 From: Michael Loftis Date: Fri, 21 Dec 2012 11:17:40 -0700 Subject: fix ripemd160 to use hash_init family and add documentation this patch removes the exports for ripemd160 from the previous patches and incorporates those functions into the hash_init family. documentation is also added. --- lib/crypto/doc/src/crypto.xml | 4 +-- lib/crypto/src/crypto.erl | 69 ++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 35 deletions(-) mode change 100644 => 100755 lib/crypto/doc/src/crypto.xml diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml old mode 100644 new mode 100755 index 3e533158c8..61e80d7d5f --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -265,7 +265,7 @@ Mpint() = >]]> hash(Type, Data) -> Digest - Type = md4 | md5 | sha | sha224 | sha256 | sha384 | sha512 + Type = md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 Data = iodata() Digest = binary() @@ -279,7 +279,7 @@ Mpint() = >]]> hash_init(Type) -> Context - Type = md4 | md5 | sha | sha224 | sha256 | sha384 | sha512 + Type = md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512

Initializes the context for streaming hash operations. Type determines diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 69fecf4a11..f25d63fe3b 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -25,7 +25,6 @@ -export([hash/2, hash_init/1, hash_update/2, hash_final/1]). -export([md4/1, md4_init/0, md4_update/2, md4_final/1]). -export([md5/1, md5_init/0, md5_update/2, md5_final/1]). --export([ripemd160/1, ripemd160_init/0, ripemd160_update/2, ripemd160_final/1]). -export([sha/1, sha_init/0, sha_update/2, sha_final/1]). -export([sha224/1, sha224_init/0, sha224_update/2, sha224_final/1]). -export([sha256/1, sha256_init/0, sha256_update/2, sha256_final/1]). @@ -71,7 +70,6 @@ -define(FUNC_LIST, [md4, md4_init, md4_update, md4_final, md5, md5_init, md5_update, md5_final, - ripemd160, ripemd160_init, ripemd160_update, ripemd160_final, sha, sha_init, sha_update, sha_final, sha224, sha224_init, sha224_update, sha224_final, sha256, sha256_init, sha256_update, sha256_final, @@ -199,43 +197,48 @@ version() -> ?CRYPTO_VSN. %% -spec hash(_, iodata()) -> binary(). -hash(md5, Data) -> md5(Data); -hash(md4, Data) -> md4(Data); -hash(sha, Data) -> sha(Data); -hash(sha224, Data) -> sha224(Data); -hash(sha256, Data) -> sha256(Data); -hash(sha384, Data) -> sha384(Data); -hash(sha512, Data) -> sha512(Data). - --spec hash_init('md5'|'md4'|'sha'|'sha224'|'sha256'|'sha384'|'sha512') -> any(). - -hash_init(md5) -> {md5, md5_init()}; -hash_init(md4) -> {md4, md4_init()}; -hash_init(sha) -> {sha, sha_init()}; -hash_init(sha224) -> {sha224, sha224_init()}; -hash_init(sha256) -> {sha256, sha256_init()}; -hash_init(sha384) -> {sha384, sha384_init()}; -hash_init(sha512) -> {sha512, sha512_init()}. +hash(md5, Data) -> md5(Data); +hash(md4, Data) -> md4(Data); +hash(sha, Data) -> sha(Data); +hash(ripemd160, Data) -> ripemd160(Data); +hash(sha224, Data) -> sha224(Data); +hash(sha256, Data) -> sha256(Data); +hash(sha384, Data) -> sha384(Data); +hash(sha512, Data) -> sha512(Data). + +-spec hash_init('md5'|'md4'|'ripemd160'| + 'sha'|'sha224'|'sha256'|'sha384'|'sha512') -> any(). + +hash_init(md5) -> {md5, md5_init()}; +hash_init(md4) -> {md4, md4_init()}; +hash_init(sha) -> {sha, sha_init()}; +hash_init(ripemd160) -> {ripemd160, ripemd160_init()}; +hash_init(sha224) -> {sha224, sha224_init()}; +hash_init(sha256) -> {sha256, sha256_init()}; +hash_init(sha384) -> {sha384, sha384_init()}; +hash_init(sha512) -> {sha512, sha512_init()}. -spec hash_update(_, iodata()) -> any(). -hash_update({md5,Context}, Data) -> {md5, md5_update(Context,Data)}; -hash_update({md4,Context}, Data) -> {md4, md4_update(Context,Data)}; -hash_update({sha,Context}, Data) -> {sha, sha_update(Context,Data)}; -hash_update({sha224,Context}, Data) -> {sha224, sha224_update(Context,Data)}; -hash_update({sha256,Context}, Data) -> {sha256, sha256_update(Context,Data)}; -hash_update({sha384,Context}, Data) -> {sha384, sha384_update(Context,Data)}; -hash_update({sha512,Context}, Data) -> {sha512, sha512_update(Context,Data)}. +hash_update({md5,Context}, Data) -> {md5, md5_update(Context,Data)}; +hash_update({md4,Context}, Data) -> {md4, md4_update(Context,Data)}; +hash_update({sha,Context}, Data) -> {sha, sha_update(Context,Data)}; +hash_update({ripemd160,Context}, Data) -> {ripemd160, ripemd160_update(Context,Data)}; +hash_update({sha224,Context}, Data) -> {sha224, sha224_update(Context,Data)}; +hash_update({sha256,Context}, Data) -> {sha256, sha256_update(Context,Data)}; +hash_update({sha384,Context}, Data) -> {sha384, sha384_update(Context,Data)}; +hash_update({sha512,Context}, Data) -> {sha512, sha512_update(Context,Data)}. -spec hash_final(_) -> binary(). -hash_final({md5,Context}) -> md5_final(Context); -hash_final({md4,Context}) -> md4_final(Context); -hash_final({sha,Context}) -> sha_final(Context); -hash_final({sha224,Context}) -> sha224_final(Context); -hash_final({sha256,Context}) -> sha256_final(Context); -hash_final({sha384,Context}) -> sha384_final(Context); -hash_final({sha512,Context}) -> sha512_final(Context). +hash_final({md5,Context}) -> md5_final(Context); +hash_final({md4,Context}) -> md4_final(Context); +hash_final({sha,Context}) -> sha_final(Context); +hash_final({ripemd160,Context}) -> ripemd160_final(Context); +hash_final({sha224,Context}) -> sha224_final(Context); +hash_final({sha256,Context}) -> sha256_final(Context); +hash_final({sha384,Context}) -> sha384_final(Context); +hash_final({sha512,Context}) -> sha512_final(Context). %% %% MD5 -- cgit v1.2.3 From 1ba013ffcc5efd75869088161f33a09305653fb9 Mon Sep 17 00:00:00 2001 From: Michael Loftis Date: Fri, 21 Dec 2012 11:21:52 -0700 Subject: fix crypto ripemd160 tests to use hash_init family this updates the previous patch adding tests for the ripemd160 functions to use the hash and hash_init family instead of calling directly. --- lib/crypto/test/crypto_SUITE.erl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 829d867d8c..019f5f9d83 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -728,9 +728,9 @@ ripemd160(doc) -> ripemd160(suite) -> []; ripemd160(Config) when is_list(Config) -> - ?line m(crypto:ripemd160("abc"), + ?line m(crypto:hash(ripemd160,"abc"), hexstr2bin("8EB208F7E05D987A9B044A8E98C6B087F15A0BFC")), - ?line m(crypto:ripemd160("abcdbcdecdefdefgefghfghighijhijkijkljklmklm" + ?line m(crypto:hash(ripemd160,"abcdbcdecdefdefgefghfghighijhijkijkljklmklm" "nlmnomnopnopq"), hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")). @@ -743,10 +743,10 @@ ripemd160_update(doc) -> ripemd160_update(suite) -> []; ripemd160_update(Config) when is_list(Config) -> - ?line Ctx = crypto:ripemd160_init(), - ?line Ctx1 = crypto:ripemd160_update(Ctx, "abcdbcdecdefdefgefghfghighi"), - ?line Ctx2 = crypto:ripemd160_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"), - ?line m(crypto:ripemd160_final(Ctx2), + ?line Ctx = crypto:hash_init(ripemd160), + ?line Ctx1 = crypto:hash_update(Ctx, "abcdbcdecdefdefgefghfghighi"), + ?line Ctx2 = crypto:hash_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"), + ?line m(crypto:hash_final(Ctx2), hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")). %% -- cgit v1.2.3