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.
13 * Lua library for sha1, sha256 and md5 hashes
20 typedef unsigned __int32 uint32_t;
27 #include <openssl/sha.h>
28 #include <openssl/md5.h>
30 #define HMAC_IPAD 0x36363636
31 #define HMAC_OPAD 0x5c5c5c5c
33 const char *hex_tab = "0123456789abcdef";
34 void toHex(const unsigned char *in, int length, unsigned char *out) {
36 for (i = 0; i < length; i++) {
37 out[i*2] = hex_tab[(in[i] >> 4) & 0xF];
38 out[i*2+1] = hex_tab[(in[i]) & 0xF];
42 #define MAKE_HASH_FUNCTION(myFunc, func, size) \
43 static int myFunc(lua_State *L) { \
45 const char *s = luaL_checklstring(L, 1, &len); \
46 int hex_out = lua_toboolean(L, 2); \
47 unsigned char hash[size], result[size*2]; \
48 func((const unsigned char*)s, len, hash); \
50 toHex(hash, size, result); \
51 lua_pushlstring(L, (char*)result, size*2); \
53 lua_pushlstring(L, (char*)hash, size);\
58 MAKE_HASH_FUNCTION(Lsha1, SHA1, SHA_DIGEST_LENGTH)
59 MAKE_HASH_FUNCTION(Lsha224, SHA224, SHA224_DIGEST_LENGTH)
60 MAKE_HASH_FUNCTION(Lsha256, SHA256, SHA256_DIGEST_LENGTH)
61 MAKE_HASH_FUNCTION(Lsha384, SHA384, SHA384_DIGEST_LENGTH)
62 MAKE_HASH_FUNCTION(Lsha512, SHA512, SHA512_DIGEST_LENGTH)
63 MAKE_HASH_FUNCTION(Lmd5, MD5, MD5_DIGEST_LENGTH)
67 int (*Update)(void*, const void *, size_t);
68 int (*Final)(unsigned char*, void*);
73 static void hmac(struct hash_desc *desc, const char *key, size_t key_len,
74 const char *msg, size_t msg_len, unsigned char *result)
77 unsigned char bytes[64];
78 uint32_t quadbytes[16];
82 char hashedKey[64]; /* Maximum used digest length */
83 union xory k_ipad, k_opad;
86 desc->Init(desc->ctx);
87 desc->Update(desc->ctx, key, key_len);
88 desc->Final(hashedKey, desc->ctx);
89 key = (const char*)hashedKey;
90 key_len = desc->digestLength;
93 memcpy(k_ipad.bytes, key, key_len);
94 memset(k_ipad.bytes + key_len, 0, 64 - key_len);
95 memcpy(k_opad.bytes, k_ipad.bytes, 64);
97 for (i = 0; i < 16; i++) {
98 k_ipad.quadbytes[i] ^= HMAC_IPAD;
99 k_opad.quadbytes[i] ^= HMAC_OPAD;
102 desc->Init(desc->ctx);
103 desc->Update(desc->ctx, k_ipad.bytes, 64);
104 desc->Init(desc->ctxo);
105 desc->Update(desc->ctxo, k_opad.bytes, 64);
106 desc->Update(desc->ctx, msg, msg_len);
107 desc->Final(result, desc->ctx);
108 desc->Update(desc->ctxo, result, desc->digestLength);
109 desc->Final(result, desc->ctxo);
112 #define MAKE_HMAC_FUNCTION(myFunc, func, size, type) \
113 static int myFunc(lua_State *L) { \
115 unsigned char hash[size], result[2*size]; \
116 size_t key_len, msg_len; \
117 const char *key = luaL_checklstring(L, 1, &key_len); \
118 const char *msg = luaL_checklstring(L, 2, &msg_len); \
119 const int hex_out = lua_toboolean(L, 3); \
120 struct hash_desc desc; \
121 desc.Init = (int (*)(void*))func##_Init; \
122 desc.Update = (int (*)(void*, const void *, size_t))func##_Update; \
123 desc.Final = (int (*)(unsigned char*, void*))func##_Final; \
124 desc.digestLength = size; \
127 hmac(&desc, key, key_len, msg, msg_len, hash); \
129 toHex(hash, size, result); \
130 lua_pushlstring(L, (char*)result, size*2); \
132 lua_pushlstring(L, (char*)hash, size); \
137 MAKE_HMAC_FUNCTION(Lhmac_sha1, SHA1, SHA_DIGEST_LENGTH, SHA_CTX)
138 MAKE_HMAC_FUNCTION(Lhmac_sha256, SHA256, SHA256_DIGEST_LENGTH, SHA256_CTX)
139 MAKE_HMAC_FUNCTION(Lhmac_sha512, SHA512, SHA512_DIGEST_LENGTH, SHA512_CTX)
140 MAKE_HMAC_FUNCTION(Lhmac_md5, MD5, MD5_DIGEST_LENGTH, MD5_CTX)
142 static int LscramHi(lua_State *L) {
144 unsigned char bytes[SHA_DIGEST_LENGTH];
145 uint32_t quadbytes[SHA_DIGEST_LENGTH/4];
149 unsigned char Ust[SHA_DIGEST_LENGTH];
152 size_t str_len, salt_len;
153 struct hash_desc desc;
154 const char *str = luaL_checklstring(L, 1, &str_len);
155 const char *salt = luaL_checklstring(L, 2, &salt_len);
157 const int iter = luaL_checkinteger(L, 3);
159 desc.Init = (int (*)(void*))SHA1_Init;
160 desc.Update = (int (*)(void*, const void *, size_t))SHA1_Update;
161 desc.Final = (int (*)(unsigned char*, void*))SHA1_Final;
162 desc.digestLength = SHA_DIGEST_LENGTH;
166 salt2 = malloc(salt_len + 4);
168 luaL_error(L, "Out of memory in scramHi");
169 memcpy(salt2, salt, salt_len);
170 memcpy(salt2 + salt_len, "\0\0\0\1", 4);
171 hmac(&desc, str, str_len, salt2, salt_len + 4, Ust);
174 memcpy(res.bytes, Ust, sizeof(res));
175 for (i = 1; i < iter; i++) {
177 hmac(&desc, str, str_len, (char*)Ust, sizeof(Ust), Und.bytes);
178 for (j = 0; j < SHA_DIGEST_LENGTH/4; j++)
179 res.quadbytes[j] ^= Und.quadbytes[j];
180 memcpy(Ust, Und.bytes, sizeof(Ust));
183 lua_pushlstring(L, (char*)res.bytes, SHA_DIGEST_LENGTH);
188 static const luaL_Reg Reg[] =
191 { "sha224", Lsha224 },
192 { "sha256", Lsha256 },
193 { "sha384", Lsha384 },
194 { "sha512", Lsha512 },
196 { "hmac_sha1", Lhmac_sha1 },
197 { "hmac_sha256", Lhmac_sha256 },
198 { "hmac_sha512", Lhmac_sha512 },
199 { "hmac_md5", Lhmac_md5 },
200 { "scram_Hi_sha1", LscramHi },
204 LUALIB_API int luaopen_util_hashes(lua_State *L)
206 luaL_register(L, "hashes", Reg);
207 lua_pushliteral(L, "version"); /** version */
208 lua_pushliteral(L, "-3.14");