aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto')
-rw-r--r--lib/crypto/c_src/crypto.c58
-rwxr-xr-x[-rw-r--r--]lib/crypto/doc/src/crypto.xml4
-rw-r--r--lib/crypto/src/crypto.erl81
-rw-r--r--lib/crypto/test/crypto_SUITE.erl32
4 files changed, 140 insertions, 35 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 72c9e5b8e8..e77e5fb8f0 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -44,6 +44,7 @@
#include <openssl/md5.h>
#include <openssl/md4.h>
#include <openssl/sha.h>
+#include <openssl/ripemd.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
#include <openssl/rc4.h>
@@ -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},
@@ -326,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
@@ -600,6 +611,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/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 5e2a7acb97..14c77c873f 100644..100755
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -265,7 +265,7 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<name>hash(Type, Data) -> Digest</name>
<fsummary></fsummary>
<type>
- <v>Type = md4 | md5 | sha | sha224 | sha256 | sha384 | sha512</v>
+ <v>Type = md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512</v>
<v>Data = iodata()</v>
<v>Digest = binary()</v>
</type>
@@ -279,7 +279,7 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<name>hash_init(Type) -> Context</name>
<fsummary></fsummary>
<type>
- <v>Type = md4 | md5 | sha | sha224 | sha256 | sha384 | sha512</v>
+ <v>Type = md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512</v>
</type>
<desc>
<p>Initializes the context for streaming hash operations. <c>Type</c> determines
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 5e7f1a948a..aa89f6cc61 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -197,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
@@ -263,6 +268,20 @@ 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
%%
-spec sha(iodata()) -> binary().
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 027881957c..142f06677a 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -40,6 +40,8 @@
hmac_update_md5_n/1,
hmac_rfc2202/1,
hmac_rfc4231/1,
+ ripemd160/1,
+ ripemd160_update/1,
sha256/1,
sha256_update/1,
sha512/1,
@@ -87,7 +89,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,
@@ -973,7 +975,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:hash(ripemd160,"abc"),
+ hexstr2bin("8EB208F7E05D987A9B044A8E98C6B087F15A0BFC")),
+ ?line m(crypto:hash(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: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")).
%%
%%