From c161b7d6fe142231346cc1844e6e27c0ab7718c1 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 16 Sep 2022 15:53:42 +0200 Subject: 2022-09-16 14:41:00 --- source/luametatex/source/luarest/lmtaeslib.c | 115 +++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 source/luametatex/source/luarest/lmtaeslib.c (limited to 'source/luametatex/source/luarest/lmtaeslib.c') diff --git a/source/luametatex/source/luarest/lmtaeslib.c b/source/luametatex/source/luarest/lmtaeslib.c new file mode 100644 index 000000000..5dbd3556a --- /dev/null +++ b/source/luametatex/source/luarest/lmtaeslib.c @@ -0,0 +1,115 @@ +/* + See license.txt in the root of this project. +*/ + +# include "luametatex.h" + +# include + +// 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; +} -- cgit v1.2.3