Skip to content

Commit

Permalink
hash, feat: support keccak256.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed May 7, 2022
1 parent e66a392 commit fa6a44a
Show file tree
Hide file tree
Showing 11 changed files with 785 additions and 48 deletions.
47 changes: 44 additions & 3 deletions fibjs/include/ifs/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class hash_base : public object_base {
C_SHA384 = 5,
C_SHA512 = 6,
C_RIPEMD160 = 7,
C_SM3 = 8
C_SM3 = 8,
C_KECCAK256 = 9
};

public:
Expand All @@ -46,6 +47,7 @@ class hash_base : public object_base {
static result_t ripemd160(Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t sm3(Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t sm3(PKey_base* pubKey, exlib::string id, Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t keccak256(Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t hmac(int32_t algo, Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t hmac_md5(Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t hmac_sha1(Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);
Expand All @@ -56,6 +58,7 @@ class hash_base : public object_base {
static result_t hmac_ripemd160(Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t hmac_sm3(Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t hmac_sm3(PKey_base* pubKey, exlib::string id, Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);
static result_t hmac_keccak256(Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal);

public:
static void s__new(const v8::FunctionCallbackInfo<v8::Value>& args)
Expand All @@ -78,6 +81,7 @@ class hash_base : public object_base {
static void s_static_sha512(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_ripemd160(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_sm3(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_keccak256(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_hmac(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_hmac_md5(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_hmac_sha1(const v8::FunctionCallbackInfo<v8::Value>& args);
Expand All @@ -87,6 +91,7 @@ class hash_base : public object_base {
static void s_static_hmac_sha512(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_hmac_ripemd160(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_hmac_sm3(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_static_hmac_keccak256(const v8::FunctionCallbackInfo<v8::Value>& args);
};
}

Expand All @@ -107,6 +112,7 @@ inline ClassInfo& hash_base::class_info()
{ "sha512", s_static_sha512, true, false },
{ "ripemd160", s_static_ripemd160, true, false },
{ "sm3", s_static_sm3, true, false },
{ "keccak256", s_static_keccak256, true, false },
{ "hmac", s_static_hmac, true, false },
{ "hmac_md5", s_static_hmac_md5, true, false },
{ "hmac_sha1", s_static_hmac_sha1, true, false },
Expand All @@ -115,7 +121,8 @@ inline ClassInfo& hash_base::class_info()
{ "hmac_sha384", s_static_hmac_sha384, true, false },
{ "hmac_sha512", s_static_hmac_sha512, true, false },
{ "hmac_ripemd160", s_static_hmac_ripemd160, true, false },
{ "hmac_sm3", s_static_hmac_sm3, true, false }
{ "hmac_sm3", s_static_hmac_sm3, true, false },
{ "hmac_keccak256", s_static_hmac_keccak256, true, false }
};

static ClassData::ClassConst s_const[] = {
Expand All @@ -126,7 +133,8 @@ inline ClassInfo& hash_base::class_info()
{ "SHA384", C_SHA384 },
{ "SHA512", C_SHA512 },
{ "RIPEMD160", C_RIPEMD160 },
{ "SM3", C_SM3 }
{ "SM3", C_SM3 },
{ "KECCAK256", C_KECCAK256 }
};

static ClassData s_cd = {
Expand Down Expand Up @@ -292,6 +300,22 @@ inline void hash_base::s_static_sm3(const v8::FunctionCallbackInfo<v8::Value>& a
METHOD_RETURN();
}

inline void hash_base::s_static_keccak256(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<Digest_base> vr;

METHOD_NAME("hash.keccak256");
METHOD_ENTER();

METHOD_OVER(1, 0);

OPT_ARG(obj_ptr<Buffer_base>, 0, NULL);

hr = keccak256(v0, vr);

METHOD_RETURN();
}

inline void hash_base::s_static_hmac(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<Digest_base> vr;
Expand Down Expand Up @@ -454,4 +478,21 @@ inline void hash_base::s_static_hmac_sm3(const v8::FunctionCallbackInfo<v8::Valu

METHOD_RETURN();
}

inline void hash_base::s_static_hmac_keccak256(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<Digest_base> vr;

METHOD_NAME("hash.hmac_keccak256");
METHOD_ENTER();

METHOD_OVER(2, 1);

ARG(obj_ptr<Buffer_base>, 0);
OPT_ARG(obj_ptr<Buffer_base>, 1, NULL);

hr = hmac_keccak256(v0, v1, vr);

METHOD_RETURN();
}
}
25 changes: 12 additions & 13 deletions fibjs/src/crypto/Digest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "Buffer.h"
#include "encoding.h"
#include <string.h>
#include "mbedtls/src/md_wrap.h"
#include "mbedtls/error.h"
#include "md_api.h"

namespace fibjs {

Expand All @@ -22,8 +25,8 @@ Digest::Digest(mbedtls_md_type_t algo)
m_iAlgo = algo;

mbedtls_md_init(&m_ctx);
mbedtls_md_setup(&m_ctx, mbedtls_md_info_from_type(algo), 0);
mbedtls_md_starts(&m_ctx);
_md_setup(&m_ctx, algo, 0);
_md_starts(&m_ctx);
}

Digest::Digest(mbedtls_md_type_t algo, const char* key, int32_t sz)
Expand All @@ -32,8 +35,8 @@ Digest::Digest(mbedtls_md_type_t algo, const char* key, int32_t sz)
m_iAlgo = algo;

mbedtls_md_init(&m_ctx);
mbedtls_md_setup(&m_ctx, mbedtls_md_info_from_type(algo), 1);
mbedtls_md_hmac_starts(&m_ctx, (unsigned char*)key, sz);
_md_setup(&m_ctx, algo, 1);
_md_hmac_starts(&m_ctx, (unsigned char*)key, sz);
}

Digest::~Digest()
Expand All @@ -49,12 +52,8 @@ result_t Digest::update(Buffer_base* data, obj_ptr<Digest_base>& retVal)
exlib::string str;
data->toString(str);

if (m_bMac)
mbedtls_md_hmac_update(&m_ctx, (const unsigned char*)str.c_str(),
(int32_t)str.length());
else
mbedtls_md_update(&m_ctx, (const unsigned char*)str.c_str(),
(int32_t)str.length());
_md_update(&m_ctx, (const unsigned char*)str.c_str(),
(int32_t)str.length());

retVal = this;

Expand All @@ -70,12 +69,12 @@ result_t Digest::digest(obj_ptr<Buffer_base>& retVal)
strBuf.resize(mbedtls_md_get_size(m_ctx.md_info));

if (m_bMac)
mbedtls_md_hmac_finish(&m_ctx, (unsigned char*)strBuf.c_buffer());
_md_hmac_finish(&m_ctx, (unsigned char*)strBuf.c_buffer());
else
mbedtls_md_finish(&m_ctx, (unsigned char*)strBuf.c_buffer());
_md_finish(&m_ctx, (unsigned char*)strBuf.c_buffer());

m_iAlgo = -1;
mbedtls_md_hmac_reset(&m_ctx);
_md_hmac_reset(&m_ctx);

retVal = new Buffer(strBuf);
return 0;
Expand Down
64 changes: 40 additions & 24 deletions fibjs/src/crypto/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,35 @@
#include <string.h>
#include <mbedtls/mbedtls/pkcs5.h>
#include "PKey_impl.h"
#include "md_api.h"

namespace fibjs {

DECLARE_MODULE(crypto);

mbedtls_md_type_t _md_type_from_string(const char* md_name)
{
if (!qstrcmp(md_name, "KECCAK256"))
return MBEDTLS_MD_KECCAK256;

const mbedtls_md_info_t* mi = mbedtls_md_info_from_string(md_name);
if (!mi)
return MBEDTLS_MD_NONE;

return mbedtls_md_get_type(mi);
}

result_t crypto_base::createHash(exlib::string algo, obj_ptr<Digest_base>& retVal)
{
algo.toupper();
if (algo == "RMD160")
algo = "RIPEMD160";

const mbedtls_md_info_t* mi = mbedtls_md_info_from_string(algo.c_str());
if (!mi)
mbedtls_md_type_t algo_id = _md_type_from_string(algo.c_str());
if (algo_id == MBEDTLS_MD_NONE)
return CHECK_ERROR(CALL_E_INVALIDARG);

retVal = new Digest(mbedtls_md_get_type(mi));
retVal = new Digest(algo_id);

return 0;
}
Expand All @@ -48,11 +61,11 @@ result_t crypto_base::createHmac(exlib::string algo, Buffer_base* key,
if (algo == "RMD160")
algo = "RIPEMD160";

const mbedtls_md_info_t* mi = mbedtls_md_info_from_string(algo.c_str());
if (!mi)
mbedtls_md_type_t algo_id = _md_type_from_string(algo.c_str());
if (algo_id == MBEDTLS_MD_NONE)
return CHECK_ERROR(CALL_E_INVALIDARG);

return hash_base::hmac(mbedtls_md_get_type(mi), key, NULL, retVal);
return hash_base::hmac(algo_id, key, NULL, retVal);
}

result_t crypto_base::loadCert(exlib::string filename, obj_ptr<X509Cert_base>& retVal)
Expand Down Expand Up @@ -327,33 +340,33 @@ inline int pkcs5_pbkdf1(mbedtls_md_context_t* ctx, const unsigned char* password
return (MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA);

while (key_length) {
if ((ret = mbedtls_md_starts(ctx)) != 0)
if ((ret = _md_starts(ctx)) != 0)
return (ret);

if (!bFirst)
if ((ret = mbedtls_md_update(ctx, md1, md_size)) != 0)
if ((ret = _md_update(ctx, md1, md_size)) != 0)
return (ret);
bFirst = false;

if ((ret = mbedtls_md_update(ctx, password, plen)) != 0)
if ((ret = _md_update(ctx, password, plen)) != 0)
return (ret);

if ((ret = mbedtls_md_update(ctx, salt, slen)) != 0)
if ((ret = _md_update(ctx, salt, slen)) != 0)
return (ret);

if ((ret = mbedtls_md_finish(ctx, work)) != 0)
if ((ret = _md_finish(ctx, work)) != 0)
return (ret);

memcpy(md1, work, md_size);

for (i = 1; i < iteration_count; i++) {
if ((ret = mbedtls_md_starts(ctx)) != 0)
if ((ret = _md_starts(ctx)) != 0)
return (ret);

if ((ret = mbedtls_md_update(ctx, md1, md_size)) != 0)
if ((ret = _md_update(ctx, md1, md_size)) != 0)
return (ret);

if ((ret = mbedtls_md_finish(ctx, work)) != 0)
if ((ret = _md_finish(ctx, work)) != 0)
return (ret);

memcpy(md1, work, md_size);
Expand Down Expand Up @@ -390,7 +403,7 @@ result_t crypto_base::pbkdf1(Buffer_base* password, Buffer_base* salt, int32_t i
str_key.resize(size);

mbedtls_md_context_t ctx;
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type((mbedtls_md_type_t)algo), 1);
_md_setup(&ctx, (mbedtls_md_type_t)algo, 1);
pkcs5_pbkdf1(&ctx, (const unsigned char*)str_pass.c_str(), str_pass.length(),
(const unsigned char*)str_salt.c_str(), str_salt.length(),
iterations, size, (unsigned char*)str_key.c_buffer());
Expand All @@ -412,11 +425,11 @@ result_t crypto_base::pbkdf1(Buffer_base* password, Buffer_base* salt, int32_t i
return CHECK_ERROR(CALL_E_NOSYNC);

algoName.toupper();
const mbedtls_md_info_t* mi = mbedtls_md_info_from_string(algoName.c_str());
if (!mi)
mbedtls_md_type_t algo_id = _md_type_from_string(algoName.c_str());
if (algo_id == MBEDTLS_MD_NONE)
return CHECK_ERROR(CALL_E_INVALIDARG);

return pbkdf1(password, salt, iterations, size, mbedtls_md_get_type(mi), retVal, ac);
return pbkdf1(password, salt, iterations, size, algo_id, retVal, ac);
}

result_t crypto_base::pbkdf2(Buffer_base* password, Buffer_base* salt, int32_t iterations,
Expand All @@ -440,7 +453,7 @@ result_t crypto_base::pbkdf2(Buffer_base* password, Buffer_base* salt, int32_t i
str_key.resize(size);

mbedtls_md_context_t ctx;
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type((mbedtls_md_type_t)algo), 1);
_md_setup(&ctx, (mbedtls_md_type_t)algo, 1);
mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char*)str_pass.c_str(), str_pass.length(),
(const unsigned char*)str_salt.c_str(), str_salt.length(),
iterations, size, (unsigned char*)str_key.c_buffer());
Expand All @@ -462,11 +475,11 @@ result_t crypto_base::pbkdf2(Buffer_base* password, Buffer_base* salt, int32_t i
return CHECK_ERROR(CALL_E_NOSYNC);

algoName.toupper();
const mbedtls_md_info_t* mi = mbedtls_md_info_from_string(algoName.c_str());
if (!mi)
mbedtls_md_type_t algo_id = _md_type_from_string(algoName.c_str());
if (algo_id == MBEDTLS_MD_NONE)
return CHECK_ERROR(CALL_E_INVALIDARG);

return pbkdf2(password, salt, iterations, size, mbedtls_md_get_type(mi), retVal, ac);
return pbkdf2(password, salt, iterations, size, algo_id, retVal, ac);
}

obj_ptr<NArray> g_hashes;
Expand All @@ -476,8 +489,6 @@ class init_hashes {
{
g_hashes = new NArray();

g_hashes->append("md2");
g_hashes->append("md4");
g_hashes->append("md5");
g_hashes->append("sha1");
g_hashes->append("sha224");
Expand All @@ -486,11 +497,16 @@ class init_hashes {
g_hashes->append("sha512");
g_hashes->append("ripemd160");
g_hashes->append("sm3");
g_hashes->append("keccak256");
g_hashes->append("md5_hmac");
g_hashes->append("sha1_hmac");
g_hashes->append("sha224_hmac");
g_hashes->append("sha256_hmac");
g_hashes->append("sha384_hmac");
g_hashes->append("sha512_hmac");
g_hashes->append("ripemd160_hmac");
g_hashes->append("sm3_hmac");
g_hashes->append("keccak256_hmac");
}

} s_init_hashes;
Expand Down
14 changes: 12 additions & 2 deletions fibjs/src/crypto/hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ DECLARE_MODULE(hash);
result_t hash_base::digest(int32_t algo, Buffer_base* data,
obj_ptr<Digest_base>& retVal)
{
if (algo < hash_base::C_MD5 || algo > hash_base::C_SM3)
if (algo < hash_base::C_MD5 || algo > hash_base::C_KECCAK256)
return CHECK_ERROR(CALL_E_INVALIDARG);

retVal = new Digest((mbedtls_md_type_t)algo);
Expand Down Expand Up @@ -64,10 +64,15 @@ result_t hash_base::ripemd160(Buffer_base* data, obj_ptr<Digest_base>& retVal)
return digest(hash_base::C_RIPEMD160, data, retVal);
}

result_t hash_base::keccak256(Buffer_base* data, obj_ptr<Digest_base>& retVal)
{
return digest(hash_base::C_KECCAK256, data, retVal);
}

result_t hash_base::hmac(int32_t algo, Buffer_base* key, Buffer_base* data,
obj_ptr<Digest_base>& retVal)
{
if (algo < hash_base::C_MD5 || algo > hash_base::C_SM3)
if (algo < hash_base::C_MD5 || algo > hash_base::C_KECCAK256)
return CHECK_ERROR(CALL_E_INVALIDARG);

exlib::string strBuf;
Expand Down Expand Up @@ -118,4 +123,9 @@ result_t hash_base::hmac_ripemd160(Buffer_base* key, Buffer_base* data, obj_ptr<
return hmac(hash_base::C_RIPEMD160, key, data, retVal);
}

result_t hash_base::hmac_keccak256(Buffer_base* key, Buffer_base* data, obj_ptr<Digest_base>& retVal)
{
return hmac(hash_base::C_KECCAK256, key, data, retVal);
}

} /* namespace fibjs */
Loading

0 comments on commit fa6a44a

Please sign in to comment.