1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
See license.txt in the root of this project.
*/
# include "luametatex.h"
# include <utilcrypt.h>
// AES_HAS_IV AES_INLINE_IV AES_CONTINUE AES_NULL_PADDING
static const uint8_t nulliv[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
typedef size_t aes_coder (
const void *input,
size_t length,
void *output,
const void *key,
size_t keylength,
const void *iv,
int flags
);
/* data key [block] [inline] [padding] */ /* key : 16 24 32 */
/* random_bytes is taken from pplib */
static int aeslib_aux_code(lua_State *L, aes_coder code) {
size_t inputlength = 0;
const char *input = lua_tolstring(L, 1, &inputlength);
if (inputlength) {
size_t keylength = 0;
const char *key = lua_tolstring(L, 2, &keylength);
if (keylength == 16 || keylength == 24 || keylength == 32) {
luaL_Buffer buffer;
/* always */
int flags = 0;
/* the same length as input plus optional 16 from iv */
char *output = NULL;
size_t outputlength = 0;
/* this is optional, iv get copied in aes */
const uint8_t *iv = NULL;
switch (lua_type(L, 3)) {
case LUA_TSTRING:
{
size_t ivlength = 0;
iv = (const uint8_t *) lua_tolstring(L, 3, &ivlength);
if (ivlength != 16) {
iv = nulliv;
}
break;
}
case LUA_TBOOLEAN:
if (lua_toboolean(L, 3)) {
uint8_t randiv[16];
random_bytes(randiv, 16);
iv = (const uint8_t *) randiv;
break;
}
// fall through
default:
iv = nulliv;
}
if (lua_toboolean(L, 4)) {
flags |= AES_INLINE_IV;
}
if (! lua_toboolean(L, 5)) {
flags |= AES_NULL_PADDING;
}
/* always multiples of 16 and we might have the iv too */
output = luaL_buffinitsize(L, &buffer, inputlength + 32);
outputlength = code(input, inputlength, output, key, keylength, iv, flags);
if (outputlength) {
luaL_pushresultsize(&buffer, outputlength);
return 1;
}
} else {
luaL_error(L, "aeslib: key of length 16, 24 or 32 expected");
}
}
lua_pushnil(L);
return 1;
}
static int aeslib_encode(lua_State *L) {
return aeslib_aux_code(L, &aes_encode_data);
}
static int aeslib_decode(lua_State *L) {
return aeslib_aux_code(L, &aes_decode_data);
}
static int aeslib_random(lua_State *L) {
uint8_t iv[32];
int n = (int) luaL_optinteger(L, 1, 16);
if (n > 32) {
n = 32;
}
random_bytes(iv, n);
lua_pushlstring(L, (const char *) iv, n);
return 1;
}
static struct luaL_Reg aeslib_function_list[] = {
/*tex We started out with this: */
{ "encode", aeslib_encode },
{ "decode", aeslib_decode },
{ "random", aeslib_random },
{ NULL, NULL },
};
int luaopen_aes(lua_State *L) {
lua_newtable(L);
luaL_setfuncs(L, aeslib_function_list, 0);
return 1;
}
|