summaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_noise.cpp
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2015-08-06 08:57:13 +0200
committerkwolekr <kwolekr@minetest.net>2015-11-08 15:57:15 -0500
commitad5ac39d8d1a8b8f6f0fe077e20bac914ddc624b (patch)
tree6d30b2687f6c0ed60c22e626be9c31ba64a8efd7 /src/script/lua_api/l_noise.cpp
parentd506d567075914b138ca869981f2e45ce503ee5d (diff)
downloadminetest-ad5ac39d8d1a8b8f6f0fe077e20bac914ddc624b.tar.gz
minetest-ad5ac39d8d1a8b8f6f0fe077e20bac914ddc624b.tar.bz2
minetest-ad5ac39d8d1a8b8f6f0fe077e20bac914ddc624b.zip
Add LuaSecureRandom
Diffstat (limited to 'src/script/lua_api/l_noise.cpp')
-rw-r--r--src/script/lua_api/l_noise.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp
index 6dcffa31c..04dc6048f 100644
--- a/src/script/lua_api/l_noise.cpp
+++ b/src/script/lua_api/l_noise.cpp
@@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_converter.h"
#include "common/c_content.h"
#include "log.h"
+#include "porting.h"
+#include "util/numeric.h"
///////////////////////////////////////
/*
@@ -600,3 +602,116 @@ const luaL_reg LuaPcgRandom::methods[] = {
luamethod(LuaPcgRandom, rand_normal_dist),
{0,0}
};
+
+///////////////////////////////////////
+/*
+ LuaSecureRandom
+*/
+
+bool LuaSecureRandom::fillRandBuf()
+{
+ return porting::secure_rand_fill_buf(m_rand_buf, RAND_BUF_SIZE);
+}
+
+int LuaSecureRandom::l_next_bytes(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaSecureRandom *o = checkobject(L, 1);
+ u32 count = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : 1;
+
+ // Limit count
+ count = MYMIN(RAND_BUF_SIZE, count);
+
+ // Find out whether we can pass directly from our array, or have to do some gluing
+ size_t count_remaining = RAND_BUF_SIZE - o->m_rand_idx;
+ if (count_remaining >= count) {
+ lua_pushlstring(L, o->m_rand_buf + o->m_rand_idx, count);
+ o->m_rand_idx += count;
+ } else {
+ char output_buf[RAND_BUF_SIZE];
+
+ // Copy over with what we have left from our current buffer
+ memcpy(output_buf, o->m_rand_buf + o->m_rand_idx, count_remaining);
+
+ // Refill buffer and copy over the remainder of what was requested
+ o->fillRandBuf();
+ memcpy(output_buf + count_remaining, o->m_rand_buf, count - count_remaining);
+
+ // Update index
+ o->m_rand_idx = count - count_remaining;
+
+ lua_pushlstring(L, output_buf, count);
+ }
+
+ return 1;
+}
+
+
+int LuaSecureRandom::create_object(lua_State *L)
+{
+ LuaSecureRandom *o = new LuaSecureRandom();
+
+ // Fail and return nil if we can't securely fill the buffer
+ if (!o->fillRandBuf()) {
+ delete o;
+ return 0;
+ }
+
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int LuaSecureRandom::gc_object(lua_State *L)
+{
+ LuaSecureRandom *o = *(LuaSecureRandom **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+
+LuaSecureRandom *LuaSecureRandom::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+ return *(LuaSecureRandom **)ud;
+}
+
+
+void LuaSecureRandom::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1);
+
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
+
+ lua_register(L, className, create_object);
+}
+
+const char LuaSecureRandom::className[] = "SecureRandom";
+const luaL_reg LuaSecureRandom::methods[] = {
+ luamethod(LuaSecureRandom, next_bytes),
+ {0,0}
+};