diff --git a/app/include/user_modules.h b/app/include/user_modules.h index d8ddc654..e0d0b40c 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -31,6 +31,7 @@ #define LUA_USE_MODULES_U8G #define LUA_USE_MODULES_WS2812 #define LUA_USE_MODULES_CJSON +#define LUA_USE_MODULES_CRYPTO #endif /* LUA_USE_MODULES */ #endif /* __USER_MODULES_H__ */ diff --git a/app/modules/crypto.c b/app/modules/crypto.c new file mode 100644 index 00000000..f8c89697 --- /dev/null +++ b/app/modules/crypto.c @@ -0,0 +1,90 @@ +// Module for cryptography + +//#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +#include "platform.h" +#include "auxmods.h" +#include "lrotable.h" + +#include "c_types.h" +#include "c_stdlib.h" + +#include "user_interface.h" + +/** + * hash = crypto.sha1(input) + * + * Calculates raw SHA1 hash of input string. + * Input is arbitrary string, output is raw 20-byte hash as string. + */ +static int crypto_sha1( lua_State* L ) +{ + // We only need a data buffer large enough to match SHA1_CTX in the rom. + // I *think* this is a 92-byte netbsd struct. + uint8_t ctx[100]; + uint8_t digest[20]; + // Read the string from lua (with length) + int len; + const char* msg = luaL_checklstring(L, 1, &len); + // Use the SHA* functions in the rom + SHA1Init(ctx); + SHA1Update(ctx, msg, len); + SHA1Final(digest, ctx); + + // Push the result as a lua string + lua_pushlstring(L, digest, 20); + return 1; +} + +static const char* bytes64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +/** + * encoded = crypto.base64_encode(raw) + * + * Encodes raw binary string as base64 string. + */ +static int crypto_base64_encode( lua_State* L ) +{ + int len; + const char* msg = luaL_checklstring(L, 1, &len); + int blen = (len + 2) / 3 * 4; + char* out = (char*)c_malloc(blen); + int j = 0, i; + for (i = 0; i < len; i += 3) { + int a = msg[i]; + int b = (i + 1 < len) ? msg[i + 1] : 0; + int c = (i + 2 < len) ? msg[i + 2] : 0; + out[j++] = bytes64[a >> 2]; + out[j++] = bytes64[((a & 3) << 4) | (b >> 4)]; + out[j++] = (i + 1 < len) ? bytes64[((b & 15) << 2) | (c >> 6)] : 61; + out[j++] = (i + 2 < len) ? bytes64[(c & 63)] : 61; + } + lua_pushlstring(L, out, j); + c_free(out); + return 1; +} + +// Module function map +#define MIN_OPT_LEVEL 2 +#include "lrodefs.h" +const LUA_REG_TYPE crypto_map[] = +{ + { LSTRKEY( "sha1" ), LFUNCVAL( crypto_sha1 ) }, + { LSTRKEY( "base64Encode" ), LFUNCVAL( crypto_base64_encode ) }, +#if LUA_OPTIMIZE_MEMORY > 0 + +#endif + { LNILKEY, LNILVAL } +}; + +LUALIB_API int luaopen_crypto( lua_State *L ) +{ +#if LUA_OPTIMIZE_MEMORY > 0 + return 0; +#else // #if LUA_OPTIMIZE_MEMORY > 0 + luaL_register( L, AUXLIB_CRYPTO, crypto_map ); + // Add constants + + return 1; +#endif // #if LUA_OPTIMIZE_MEMORY > 0 +} diff --git a/app/modules/modules.h b/app/modules/modules.h index fddc45cc..a823d360 100644 --- a/app/modules/modules.h +++ b/app/modules/modules.h @@ -149,6 +149,14 @@ #define ROM_MODULES_CJSON #endif +#if defined(LUA_USE_MODULES_CRYPTO) +#define MODULES_CRYPTO "crypto" +#define ROM_MODULES_CRYPTO \ + _ROM(MODULES_CRYPTO, luaopen_crypto, crypto_map) +#else +#define ROM_MODULES_CRYPTO +#endif + #define LUA_MODULES_ROM \ ROM_MODULES_GPIO \ ROM_MODULES_PWM \ @@ -167,7 +175,8 @@ ROM_MODULES_OW \ ROM_MODULES_BIT \ ROM_MODULES_WS2812 \ - ROM_MODULES_CJSON + ROM_MODULES_CJSON \ + ROM_MODULES_CRYPTO #endif