2 -- Copyright (C) 2009-2010 Matthew Wild
3 -- Copyright (C) 2009-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
12 * Lua library for sha1, sha256 and md5 hashes
19 typedef unsigned __int32
uint32_t;
26 #include <openssl/sha.h>
27 #include <openssl/md5.h>
28 #include <openssl/hmac.h>
29 #include <openssl/evp.h>
31 #if (LUA_VERSION_NUM == 501)
32 #define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R)
35 #define HMAC_IPAD 0x36363636
36 #define HMAC_OPAD 0x5c5c5c5c
38 const char *hex_tab
= "0123456789abcdef";
39 void toHex(const unsigned char *in
, int length
, unsigned char *out
) {
42 for(i
= 0; i
< length
; i
++) {
43 out
[i
* 2] = hex_tab
[(in
[i
] >> 4) & 0xF];
44 out
[i
* 2 + 1] = hex_tab
[(in
[i
]) & 0xF];
48 #define MAKE_HASH_FUNCTION(myFunc, func, size) \
49 static int myFunc(lua_State *L) { \
51 const char *s = luaL_checklstring(L, 1, &len); \
52 int hex_out = lua_toboolean(L, 2); \
53 unsigned char hash[size], result[size*2]; \
54 func((const unsigned char*)s, len, hash); \
56 toHex(hash, size, result); \
57 lua_pushlstring(L, (char*)result, size*2); \
59 lua_pushlstring(L, (char*)hash, size);\
64 MAKE_HASH_FUNCTION(Lsha1
, SHA1
, SHA_DIGEST_LENGTH
)
65 MAKE_HASH_FUNCTION(Lsha224
, SHA224
, SHA224_DIGEST_LENGTH
)
66 MAKE_HASH_FUNCTION(Lsha256
, SHA256
, SHA256_DIGEST_LENGTH
)
67 MAKE_HASH_FUNCTION(Lsha384
, SHA384
, SHA384_DIGEST_LENGTH
)
68 MAKE_HASH_FUNCTION(Lsha512
, SHA512
, SHA512_DIGEST_LENGTH
)
69 MAKE_HASH_FUNCTION(Lmd5
, MD5
, MD5_DIGEST_LENGTH
)
73 int (*Update
)(void *, const void *, size_t);
74 int (*Final
)(unsigned char *, void *);
79 #define MAKE_HMAC_FUNCTION(myFunc, evp, size, type) \
80 static int myFunc(lua_State *L) { \
81 unsigned char hash[size], result[2*size]; \
82 size_t key_len, msg_len; \
83 unsigned int out_len; \
84 const char *key = luaL_checklstring(L, 1, &key_len); \
85 const char *msg = luaL_checklstring(L, 2, &msg_len); \
86 const int hex_out = lua_toboolean(L, 3); \
87 HMAC(evp(), key, key_len, (const unsigned char*)msg, msg_len, (unsigned char*)hash, &out_len); \
89 toHex(hash, out_len, result); \
90 lua_pushlstring(L, (char*)result, out_len*2); \
92 lua_pushlstring(L, (char*)hash, out_len); \
97 MAKE_HMAC_FUNCTION(Lhmac_sha1
, EVP_sha1
, SHA_DIGEST_LENGTH
, SHA_CTX
)
98 MAKE_HMAC_FUNCTION(Lhmac_sha256
, EVP_sha256
, SHA256_DIGEST_LENGTH
, SHA256_CTX
)
99 MAKE_HMAC_FUNCTION(Lhmac_sha512
, EVP_sha512
, SHA512_DIGEST_LENGTH
, SHA512_CTX
)
100 MAKE_HMAC_FUNCTION(Lhmac_md5
, EVP_md5
, MD5_DIGEST_LENGTH
, MD5_CTX
)
102 static int Lpbkdf2_sha1(lua_State
*L
) {
103 unsigned char out
[SHA_DIGEST_LENGTH
];
105 size_t pass_len
, salt_len
;
106 const char *pass
= luaL_checklstring(L
, 1, &pass_len
);
107 const unsigned char *salt
= (unsigned char *)luaL_checklstring(L
, 2, &salt_len
);
108 const int iter
= luaL_checkinteger(L
, 3);
110 if(PKCS5_PBKDF2_HMAC(pass
, pass_len
, salt
, salt_len
, iter
, EVP_sha1(), SHA_DIGEST_LENGTH
, out
) == 0) {
111 return luaL_error(L
, "PKCS5_PBKDF2_HMAC() failed");
114 lua_pushlstring(L
, (char *)out
, SHA_DIGEST_LENGTH
);
120 static int Lpbkdf2_sha256(lua_State
*L
) {
121 unsigned char out
[SHA256_DIGEST_LENGTH
];
123 size_t pass_len
, salt_len
;
124 const char *pass
= luaL_checklstring(L
, 1, &pass_len
);
125 const unsigned char *salt
= (unsigned char *)luaL_checklstring(L
, 2, &salt_len
);
126 const int iter
= luaL_checkinteger(L
, 3);
128 if(PKCS5_PBKDF2_HMAC(pass
, pass_len
, salt
, salt_len
, iter
, EVP_sha256(), SHA256_DIGEST_LENGTH
, out
) == 0) {
129 return luaL_error(L
, "PKCS5_PBKDF2_HMAC() failed");
132 lua_pushlstring(L
, (char *)out
, SHA_DIGEST_LENGTH
);
136 static const luaL_Reg Reg
[] = {
138 { "sha224", Lsha224
},
139 { "sha256", Lsha256
},
140 { "sha384", Lsha384
},
141 { "sha512", Lsha512
},
143 { "hmac_sha1", Lhmac_sha1
},
144 { "hmac_sha256", Lhmac_sha256
},
145 { "hmac_sha512", Lhmac_sha512
},
146 { "hmac_md5", Lhmac_md5
},
147 { "scram_Hi_sha1", Lpbkdf2_sha1
}, /* COMPAT */
148 { "pbkdf2_hmac_sha1", Lpbkdf2_sha1
},
149 { "pbkdf2_hmac_sha256", Lpbkdf2_sha256
},
153 LUALIB_API
int luaopen_util_hashes(lua_State
*L
) {
154 #if (LUA_VERSION_NUM > 501)
155 luaL_checkversion(L
);
158 luaL_setfuncs(L
, Reg
, 0);
159 lua_pushliteral(L
, "-3.14");
160 lua_setfield(L
, -2, "version");