32 #define MAKE_HASH_FUNCTION(myFunc, func, size) \ |
35 #define MAKE_HASH_FUNCTION(myFunc, func, size) \ |
33 static int myFunc(lua_State *L) { \ |
36 static int myFunc(lua_State *L) { \ |
34 size_t len; \ |
37 size_t len; \ |
35 const char *s = luaL_checklstring(L, 1, &len); \ |
38 const char *s = luaL_checklstring(L, 1, &len); \ |
36 int hex_out = lua_toboolean(L, 2); \ |
39 int hex_out = lua_toboolean(L, 2); \ |
37 char hash[size]; \ |
40 unsigned char hash[size], result[size*2]; \ |
38 char result[size*2]; \ |
41 func((const unsigned char*)s, len, hash); \ |
39 func((const unsigned char*)s, len, (unsigned char*)hash); \ |
|
40 if (hex_out) { \ |
42 if (hex_out) { \ |
41 toHex(hash, size, result); \ |
43 toHex(hash, size, result); \ |
42 lua_pushlstring(L, result, size*2); \ |
44 lua_pushlstring(L, (char*)result, size*2); \ |
43 } else { \ |
45 } else { \ |
44 lua_pushlstring(L, hash, size);\ |
46 lua_pushlstring(L, (char*)hash, size);\ |
45 } \ |
47 } \ |
46 return 1; \ |
48 return 1; \ |
47 } |
49 } |
48 |
50 |
49 MAKE_HASH_FUNCTION(Lsha1, SHA1, SHA_DIGEST_LENGTH) |
51 MAKE_HASH_FUNCTION(Lsha1, SHA1, SHA_DIGEST_LENGTH) |
51 MAKE_HASH_FUNCTION(Lsha256, SHA256, SHA256_DIGEST_LENGTH) |
53 MAKE_HASH_FUNCTION(Lsha256, SHA256, SHA256_DIGEST_LENGTH) |
52 MAKE_HASH_FUNCTION(Lsha384, SHA384, SHA384_DIGEST_LENGTH) |
54 MAKE_HASH_FUNCTION(Lsha384, SHA384, SHA384_DIGEST_LENGTH) |
53 MAKE_HASH_FUNCTION(Lsha512, SHA512, SHA512_DIGEST_LENGTH) |
55 MAKE_HASH_FUNCTION(Lsha512, SHA512, SHA512_DIGEST_LENGTH) |
54 MAKE_HASH_FUNCTION(Lmd5, MD5, MD5_DIGEST_LENGTH) |
56 MAKE_HASH_FUNCTION(Lmd5, MD5, MD5_DIGEST_LENGTH) |
55 |
57 |
|
58 struct hash_desc { |
|
59 int (*Init)(void*); |
|
60 int (*Update)(void*, const void *, size_t); |
|
61 int (*Final)(unsigned char*, void*); |
|
62 size_t digestLength; |
|
63 void *ctx, *ctxo; |
|
64 }; |
|
65 |
|
66 static void hmac(struct hash_desc *desc, const char *key, size_t key_len, |
|
67 const char *msg, size_t msg_len, unsigned char *result) |
|
68 { |
|
69 union xory { |
|
70 unsigned char bytes[64]; |
|
71 uint32_t quadbytes[16]; |
|
72 }; |
|
73 |
|
74 int i; |
|
75 char hashedKey[64]; /* Maximum used digest length */ |
|
76 union xory k_ipad, k_opad; |
|
77 |
|
78 if (key_len > 64) { |
|
79 desc->Init(desc->ctx); |
|
80 desc->Update(desc->ctx, key, key_len); |
|
81 desc->Final(desc->ctx, hashedKey); |
|
82 key = (const char*)hashedKey; |
|
83 key_len = desc->digestLength; |
|
84 } |
|
85 |
|
86 memcpy(k_ipad.bytes, key, key_len); |
|
87 memset(k_ipad.bytes + key_len, 0, 64 - key_len); |
|
88 memcpy(k_opad.bytes, k_ipad.bytes, 64); |
|
89 |
|
90 for (i = 0; i < 16; i++) { |
|
91 k_ipad.quadbytes[i] ^= HMAC_IPAD; |
|
92 k_opad.quadbytes[i] ^= HMAC_OPAD; |
|
93 } |
|
94 |
|
95 desc->Init(desc->ctx); |
|
96 desc->Update(desc->ctx, k_ipad.bytes, 64); |
|
97 desc->Init(desc->ctxo); |
|
98 desc->Update(desc->ctxo, k_opad.bytes, 64); |
|
99 desc->Update(desc->ctx, msg, msg_len); |
|
100 desc->Final(result, desc->ctx); |
|
101 desc->Update(desc->ctxo, result, desc->digestLength); |
|
102 desc->Final(result, desc->ctxo); |
|
103 } |
|
104 |
|
105 #define MAKE_HMAC_FUNCTION(myFunc, func, size, type) \ |
|
106 static int myFunc(lua_State *L) { \ |
|
107 type ctx, ctxo; \ |
|
108 unsigned char hash[size], result[2*size]; \ |
|
109 size_t key_len, msg_len; \ |
|
110 const char *key = luaL_checklstring(L, 1, &key_len); \ |
|
111 const char *msg = luaL_checklstring(L, 2, &msg_len); \ |
|
112 const int hex_out = lua_toboolean(L, 3); \ |
|
113 struct hash_desc desc; \ |
|
114 desc.Init = (int (*)(void*))func##_Init; \ |
|
115 desc.Update = (int (*)(void*, const void *, size_t))func##_Update; \ |
|
116 desc.Final = (int (*)(unsigned char*, void*))func##_Final; \ |
|
117 desc.digestLength = size; \ |
|
118 desc.ctx = &ctx; \ |
|
119 desc.ctxo = &ctxo; \ |
|
120 hmac(&desc, key, key_len, msg, msg_len, hash); \ |
|
121 if (hex_out) { \ |
|
122 toHex(hash, size, result); \ |
|
123 lua_pushlstring(L, (char*)result, size*2); \ |
|
124 } else { \ |
|
125 lua_pushlstring(L, (char*)hash, size); \ |
|
126 } \ |
|
127 return 1; \ |
|
128 } |
|
129 |
|
130 MAKE_HMAC_FUNCTION(Lhmac_sha1, SHA1, SHA_DIGEST_LENGTH, SHA_CTX) |
|
131 MAKE_HMAC_FUNCTION(Lhmac_sha256, SHA256, SHA256_DIGEST_LENGTH, SHA256_CTX) |
|
132 MAKE_HMAC_FUNCTION(Lhmac_sha512, SHA512, SHA512_DIGEST_LENGTH, SHA512_CTX) |
|
133 MAKE_HMAC_FUNCTION(Lhmac_md5, MD5, MD5_DIGEST_LENGTH, MD5_CTX) |
|
134 |
56 static const luaL_Reg Reg[] = |
135 static const luaL_Reg Reg[] = |
57 { |
136 { |
58 { "sha1", Lsha1 }, |
137 { "sha1", Lsha1 }, |
59 { "sha224", Lsha224 }, |
138 { "sha224", Lsha224 }, |
60 { "sha256", Lsha256 }, |
139 { "sha256", Lsha256 }, |
61 { "sha384", Lsha384 }, |
140 { "sha384", Lsha384 }, |
62 { "sha512", Lsha512 }, |
141 { "sha512", Lsha512 }, |
63 { "md5", Lmd5 }, |
142 { "md5", Lmd5 }, |
64 { NULL, NULL } |
143 { "hmac_sha1", Lhmac_sha1 }, |
|
144 { "hmac_sha256", Lhmac_sha256 }, |
|
145 { "hmac_sha512", Lhmac_sha512 }, |
|
146 { "hmac_md5", Lhmac_md5 }, |
|
147 { NULL, NULL } |
65 }; |
148 }; |
66 |
149 |
67 LUALIB_API int luaopen_util_hashes(lua_State *L) |
150 LUALIB_API int luaopen_util_hashes(lua_State *L) |
68 { |
151 { |
69 luaL_register(L, "hashes", Reg); |
152 luaL_register(L, "hashes", Reg); |