Created
December 9, 2024 16:52
-
-
Save johnd0e/135e03b4d3f1044bb94a4c563d84507a to your computer and use it in GitHub Desktop.
LuaJIT module: HMAC functions from OpenSSL (w/o LuaResty)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local ffi = require "ffi" | |
local ffi_new = ffi.new | |
local ffi_str = ffi.string | |
local ffi_gc = ffi.gc | |
local setmetatable = setmetatable | |
local _M = { _VERSION = '0.06' } --Source: https://github.com/jkeys089/lua-resty-hmac | |
local mt = { __index = _M } | |
local crypto = ffi.load("libcrypto-3.dll") | |
ffi.cdef [[ | |
typedef struct engine_st ENGINE; | |
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; | |
typedef struct hmac_ctx_st HMAC_CTX; | |
//OpenSSL 1.1 | |
HMAC_CTX *HMAC_CTX_new(void); | |
void HMAC_CTX_free(HMAC_CTX *ctx); | |
typedef struct evp_md_ctx_st EVP_MD_CTX; | |
typedef struct evp_md_st EVP_MD; | |
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); | |
int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); | |
int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); | |
const EVP_MD *EVP_md5(void); | |
const EVP_MD *EVP_sha1(void); | |
const EVP_MD *EVP_sha256(void); | |
const EVP_MD *EVP_sha384(void); | |
const EVP_MD *EVP_sha512(void); | |
]] | |
local hashes = { | |
MD5 = crypto.EVP_md5(), | |
SHA1 = crypto.EVP_sha1(), | |
SHA256 = crypto.EVP_sha256(), | |
SHA384 = crypto.EVP_sha384(), | |
SHA512 = crypto.EVP_sha512() | |
} | |
_M.ALGOS = hashes | |
function _M.new(self, key, hash_algo) | |
local ctx = crypto.HMAC_CTX_new() | |
local _hash_algo = hash_algo or hashes.MD5 | |
if crypto.HMAC_Init_ex(ctx, key, #key, _hash_algo, nil) == 0 then | |
return nil | |
end | |
ffi_gc(ctx, crypto.HMAC_CTX_free) | |
return setmetatable({ _ctx = ctx }, mt) | |
end | |
function _M.update(self, s) | |
return crypto.HMAC_Update(self._ctx, s, #s) == 1 | |
end | |
local function to_hex (s) | |
local hex = {} | |
for i=1,#s do | |
hex[i] = string.format("%02x", string.byte(string.sub(s,i,i))) | |
end | |
return table.concat(hex) | |
end | |
local buf = ffi_new("unsigned char[64]") | |
local res_len = ffi_new("unsigned int[1]") | |
function _M.final(self, s, hex_output) | |
if s ~= nil then | |
if crypto.HMAC_Update(self._ctx, s, #s) == 0 then | |
return nil | |
end | |
end | |
if crypto.HMAC_Final(self._ctx, buf, res_len) == 1 then | |
if hex_output == true then | |
return to_hex(ffi_str(buf, res_len[0])) | |
end | |
return ffi_str(buf, res_len[0]) | |
end | |
return nil | |
end | |
function _M.reset(self) | |
return crypto.HMAC_Init_ex(self._ctx, nil, 0, nil, nil) == 1 | |
end | |
return _M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment