Bladeren bron

add: 添加流式hash接口

doudou 2 jaren geleden
bovenliggende
commit
3a31e94aac
3 gewijzigde bestanden met toevoegingen van 148 en 0 verwijderingen
  1. 50 0
      components/crypto/luat_crypto_mbedtls.c
  2. 11 0
      luat/include/luat_crypto.h
  3. 87 0
      luat/modules/luat_lib_crypto.c

+ 50 - 0
components/crypto/luat_crypto_mbedtls.c

@@ -257,6 +257,56 @@ int luat_crypto_md_file(const char* md, void* out_ptr, const char* key, size_t k
     return ret;
 }
 
+int luat_crypto_md_stream_init(const char* md, const char* key, luat_crypt_stream_t *stream) {
+    const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
+    if (info == NULL) {
+        return -1;
+    }
+    stream->ctx = luat_heap_malloc(sizeof(mbedtls_md_context_t));
+    mbedtls_md_init(stream->ctx);
+    mbedtls_md_setup(stream->ctx, info, stream->key_len > 0 ? 1 : 0);
+    if (stream->key_len > 0){
+        mbedtls_md_hmac_starts(stream->ctx, (const unsigned char*)key, stream->key_len);
+    }
+    else {
+        mbedtls_md_starts(stream->ctx);
+    }
+    return 0;
+}
+
+int luat_crypto_md_stream_update(const char* str, size_t str_size, luat_crypt_stream_t *stream) {
+    if (stream->key_len > 0){
+        mbedtls_md_hmac_update(stream->ctx, (const unsigned char*)str, str_size);
+    }
+    else {
+        mbedtls_md_update(stream->ctx, str, str_size);
+    }
+    return 0;
+}
+
+int luat_crypto_md_stream_finish(void* out_ptr, luat_crypt_stream_t *stream) {
+    int ret = 0;
+
+    if (stream->key_len > 0) {
+        ret = mbedtls_md_hmac_finish(stream->ctx, out_ptr);
+    }
+    else {
+        ret = mbedtls_md_finish(stream->ctx, out_ptr);
+    }
+    if (ret == 0) {
+        unsigned char size = mbedtls_md_get_size(stream->ctx->md_info);
+        mbedtls_md_free(stream->ctx);
+        luat_heap_free(stream->ctx);
+        stream->ctx = NULL;
+        return size;
+    }
+    mbedtls_md_free(stream->ctx);
+    luat_heap_free(stream->ctx);
+    stream->ctx = NULL;
+    LLOGI("md finish ret %d", ret);
+    return ret;
+}
+
 int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr) {
     return luat_crypto_md("MD5", str, str_size, out_ptr, NULL, 0);
 }

+ 11 - 0
luat/include/luat_crypto.h

@@ -1,6 +1,7 @@
 #ifndef LUAT_CRYPTO_H
 #define LUAT_CRYPTO_H
 #include "luat_base.h"
+#include "mbedtls/md.h"
 
 #define LUAT_CRYPTO_AES_ECB 1
 #define LUAT_CRYPTO_AES_CBC 2
@@ -12,6 +13,12 @@
 #define LUAT_CRYPTO_AES_PAD_5 2
 #define LUAT_CRYPTO_AES_PAD_7 3
 
+typedef struct
+{
+    size_t key_len;
+	mbedtls_md_context_t *ctx;
+}luat_crypt_stream_t;
+
 int luat_crypto_trng(char* buff, size_t len);
 
 int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr);
@@ -31,4 +38,8 @@ int luat_crypto_cipher_suites(const char** list, size_t* len);
 
 int luat_crypto_md(const char* md, const char* str, size_t str_size, void* out_ptr, const char* key, size_t key_len);
 int luat_crypto_md_file(const char* md, void* out_ptr, const char* key, size_t key_len, const char* path);
+
+int luat_crypto_md_stream_init(const char* md, const char* key, luat_crypt_stream_t *stream);
+int luat_crypto_md_stream_update(const char* str, size_t str_size, luat_crypt_stream_t *stream);
+int luat_crypto_md_stream_finish(void* out_ptr, luat_crypt_stream_t *stream);
 #endif

+ 87 - 0
luat/modules/luat_lib_crypto.c

@@ -13,8 +13,10 @@
 #include "luat_str.h"
 #include <time.h>
 #include "luat_zbuff.h"
+#include "mbedtls/md.h"
 
 #define LUAT_LOG_TAG "crypto"
+#define LUAT_CRYPTO_TYPE "crypto"
 #include "luat_log.h"
 
 static const unsigned char hexchars[] = "0123456789ABCDEF";
@@ -662,6 +664,86 @@ static int l_crypto_md(lua_State *L) {
     return 1;
 }
 
+/*
+创建流式hash用的stream
+@api crypto.hash_stream_init()
+@string hash类型, 大写字母, 例如 "MD5" "SHA1" "SHA256"
+@string hmac值,可选
+@return userdata 成功返回一个数据结构,否则返回nil
+@usage
+-- 无hmac的hash stream
+log.info("md5", crypto.hash_stream_init("MD5"))
+log.info("sha1", crypto.hash_stream_init("SHA1"))
+log.info("sha256", crypto.hash_stream_init("SHA256"))
+
+-- 带hmac的hash stream
+log.info("hmac_md5", crypto.hash_stream_init("MD5", "123456"))
+log.info("hmac_sha1", crypto.hash_stream_init("SHA1", "123456"))
+log.info("hmac_sha256", crypto.hash_stream_init("SHA256", "123456"))
+local stream = crypto.hash_stream_init()
+*/
+static int l_crypt_hash_stream_init(lua_State *L) {
+    luat_crypt_stream_t *stream = (luat_crypt_stream_t *)lua_newuserdata(L, sizeof(luat_crypt_stream_t));
+    if(stream == NULL) {
+        lua_pushnil(L);
+    } else {
+        memset(stream, 0x00, sizeof(luat_crypt_stream_t));
+        const char* key = NULL;
+        const char* md = luaL_checkstring(L, 1);
+        if(lua_type(L, 2) == LUA_TSTRING) {
+            key = luaL_checklstring(L, 2, &(stream->key_len));
+        }
+        int ret = luat_crypto_md_stream_init(md, key, stream);
+        if (ret < 0) {
+            lua_pushnil(L);
+        } else {
+            luaL_setmetatable(L, LUAT_CRYPTO_TYPE);
+        }
+    }
+    return 1;
+}
+
+/*
+流式hash更新数据
+@api crypto.hash_stream_update(stream, data)
+@userdata crypto.hash_stream_init()创建的stream, 必选
+@string 待计算的数据,必选
+@return 无
+@usage
+crypto.hash_stream_update(stream, "OK")
+*/
+static int l_crypt_hash_stream_update(lua_State *L) {
+    luat_crypt_stream_t *stream = (luat_crypt_stream_t *)luaL_checkudata(L, 1, LUAT_CRYPTO_TYPE);
+    const char *data = NULL;
+    size_t data_len = 0;
+    data = luaL_checklstring(L, 2, &data_len);
+    luat_crypto_md_stream_update(data, data_len ,stream);
+    return 0;
+}
+
+/*
+获取流式hash校验值并释放创建的stream
+@api crypto.l_crypt_hash_stream_finish(stream)
+@userdata crypto.hash_stream_init()创建的stream,必选
+@return string 成功返回计算得出的流式hash值的hex字符串,失败无返回
+@usage
+local hashResult = crypto.hash_stream_finish(stream)
+*/
+static int l_crypt_hash_stream_finish(lua_State *L) {
+    luat_crypt_stream_t *stream = (luat_crypt_stream_t *)luaL_checkudata(L, 1, LUAT_CRYPTO_TYPE);
+    char buff[128] = {0};
+    char output[64];
+    int ret = luat_crypto_md_stream_finish(output, stream);
+    LLOGD("finish result %d", ret);
+    if (ret < 1) {
+        return 0;
+    }
+    fixhex(output, buff, ret);
+    lua_pushlstring(L, buff, ret * 2);
+    return 1;
+}
+
+
 /*
 计算checksum校验和
 @api crypto.checksum(data, mode)
@@ -725,12 +807,17 @@ static const rotable_Reg_t reg_crypto[] =
     { "md_file",        ROREG_FUNC(l_crypto_md_file)},
     { "md",             ROREG_FUNC(l_crypto_md)},
     { "checksum",       ROREG_FUNC(l_crypt_checksum)},
+    { "hash_stream_init",ROREG_FUNC(l_crypt_hash_stream_init)},
+    { "hash_stream_update",ROREG_FUNC(l_crypt_hash_stream_update)},
+    { "hash_stream_finish",ROREG_FUNC(l_crypt_hash_stream_finish)},
 
 	{ NULL,             ROREG_INT(0) }
 };
 
 LUAMOD_API int luaopen_crypto( lua_State *L ) {
     luat_newlib2(L, reg_crypto);
+    luaL_newmetatable(L, LUAT_CRYPTO_TYPE);
+    lua_pop(L, 1);
     return 1;
 }