From b0d1500b73b8d90de9ce989e7c0efab3ee0968a9 Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Thu, 1 Dec 2016 15:24:49 +0100 Subject: [PATCH] Add Lua shim providing SHA1 and SHA256 Signed-off-by: Tobias Ulmer --- generic/lsha.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 generic/lsha.c diff --git a/generic/lsha.c b/generic/lsha.c new file mode 100644 index 0000000..1fa8f7c --- /dev/null +++ b/generic/lsha.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2016 emlix GmbH, see file AUTHORS + * + * This file is part of e2factory, the emlix embedded build system. + * For more information see http://www.e2factory.org + * + * e2factory is a registered trademark of emlix GmbH. + * + * e2factory is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +#include "sha1.h" +#include "sha2.h" + +#define TYPE_SHA1 "SHA1_CTX" +#define TYPE_SHA256 "SHA256_CTX" + +int +lsha1_init(lua_State *L) +{ + SHA1_CTX *ctx = lua_newuserdata(L, sizeof(SHA1_CTX)); + luaL_newmetatable(L, TYPE_SHA1); + lua_setmetatable(L, 1); + SHA1Init(ctx); + return 1; +} + +int +lsha1_update(lua_State *L) +{ + SHA1_CTX *ctx; + const char* data; + size_t sz; + + luaL_checktype(L, 1, LUA_TUSERDATA); + ctx = luaL_checkudata(L, 1, TYPE_SHA1); + luaL_checktype(L, 2, LUA_TSTRING); + /* guard luaL_checklstring against number */ + data = luaL_checklstring(L, 2, &sz); + if (sz > UINT_MAX) + return luaL_error(L, "sha1_update: data exceeds UINT_MAX"); + SHA1Update(ctx, (unsigned char *)data, sz); + return 0; +} + +int +lsha1_final(lua_State *L) +{ + SHA1_CTX *ctx; + unsigned char digest[20]; + const char *hexdigits = "0123456789abcdef"; + char strdigest[40+1]; + int i, j; + + luaL_checktype(L, 1, LUA_TUSERDATA); + ctx = luaL_checkudata(L, 1, TYPE_SHA1); + + SHA1Final(digest, ctx); + + for (i = 0, j = 0; i < 20; i++) { + strdigest[j++] = hexdigits[(digest[i] & 0xf0) >> 4]; + strdigest[j++] = hexdigits[digest[i] & 0x0f]; + } + strdigest[j] = '\0'; + + lua_pushstring(L, strdigest); + return 1; +} + +int +lsha256_init(lua_State *L) +{ + SHA256_CTX *ctx = lua_newuserdata(L, sizeof(SHA256_CTX)); + luaL_newmetatable(L, TYPE_SHA256); + lua_setmetatable(L, 1); + + SHA256_Init(ctx); + return 1; +} + +int +lsha256_update(lua_State *L) +{ + SHA256_CTX *ctx; + const char* data; + size_t sz; + + luaL_checktype(L, 1, LUA_TUSERDATA); + ctx = luaL_checkudata(L, 1, TYPE_SHA256); + luaL_checktype(L, 2, LUA_TSTRING); + /* guard luaL_checklstring against number */ + data = luaL_checklstring(L, 2, &sz); + SHA256_Update(ctx, (const u_int8_t *)data, sz); + return 0; +} + +int +lsha256_final(lua_State *L) +{ + SHA256_CTX *ctx; + char digest[SHA256_DIGEST_STRING_LENGTH]; + + luaL_checktype(L, 1, LUA_TUSERDATA); + ctx = luaL_checkudata(L, 1, TYPE_SHA256); + + SHA256_End(ctx, digest); + lua_pushstring(L, digest); + return 1; +} + +static luaL_reg lib[] = { + { "sha1_init", lsha1_init }, + { "sha1_update", lsha1_update }, + { "sha1_final", lsha1_final }, + { "sha256_init", lsha256_init }, + { "sha256_update", lsha256_update }, + { "sha256_final", lsha256_final }, + { NULL, NULL } +}; + +int +luaopen_lsha(lua_State *L) +{ + luaL_Reg *next; + + lua_newtable(L); + for (next = lib; next->name != NULL; next++) { + lua_pushcfunction(L, next->func); + lua_setfield(L, -2, next->name); + } + + return 1; +} -- 2.39.5