Created
May 18, 2013 09:24
-
-
Save siddontang/5603849 to your computer and use it in GitHub Desktop.
openresty string hmac implementation
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 sha512 = require "resty.sha512" | |
local aes = require "resty.aes" | |
local ffi_new = ffi.new | |
local ffi_str = ffi.string | |
local C = ffi.C | |
local setmetatable = setmetatable | |
local error = error | |
module(...) | |
_VERSION = '0.01' | |
local mt = { __index = _M } | |
ffi.cdef[[ | |
typedef struct HMACstate_st | |
{ | |
SHA512_CTX shactx; | |
unsigned char k_opad[128]; | |
} HMAC_CTX; | |
void HMAC_CTX_init(HMAC_CTX *ctx); | |
int HMAC_Init_ex(HMAC_CTX *ctx, const void* key, int key_len, const EVP_MD *md, ENGINE *imple); | |
int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len); | |
int HMAC_Final(HMAC_CTX *ct, unsigned char *md, unsigned int *len); | |
void HMAC_CTX_cleanup(HMAC_CTX *ctx); | |
]] | |
--[[ | |
Support openssl version >= 1.0.0 | |
HMAC_Init_ex(), HMAC_Update() and HMAC_Final() did not return values in versions of OpenSSL before 1.0.0. You may change ffi hmac definition if your version is below 1.0.0. | |
--]] | |
local ctx_ptr_type = ffi.typeof("HMAC_CTX[1]") | |
hash = { | |
md5 = C.EVP_md5(), | |
sha1 = C.EVP_sha1(), | |
sha224 = C.EVP_sha224(), | |
sha256 = C.EVP_sha256(), | |
sha384 = C.EVP_sha384(), | |
sha512 = C.EVP_sha512() | |
} | |
local buf = ffi_new("unsigned char[64]") | |
function new(self, key, _hash) | |
local ctx = ffi_new(ctx_ptr_type) | |
C.HMAC_CTX_init(ctx) | |
local md = _hash or hash.md5 | |
if C.HMAC_Init_ex(ctx, key, #key, md, nil) == 0 then | |
return nil | |
end | |
return setmetatable({ _ctx = ctx }, mt) | |
end | |
function update(self, s) | |
return C.HMAC_Update(self._ctx, s, #s) == 1 | |
end | |
function final(self) | |
local out_len = ffi_new("unsigned int[1]") | |
if C.HMAC_Final(self._ctx, buf, out_len) == 1 then | |
return ffi_str(buf, out_len[0]) | |
end | |
return nil | |
end | |
function reset(self) | |
C.HMAC_Init_ex(self._ctx, nil, 0, nil, nil) | |
end | |
function cleanup(self) | |
C.HMAC_CTX_cleanup(self._ctx) | |
end | |
local class_mt = { | |
-- to prevent use of casual module global variables | |
__newindex = function (table, key, val) | |
error('attempt to write to undeclared variable "' .. key .. '"') | |
end | |
} | |
setmetatable(_M, class_mt) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very Useful!