summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/openssl.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/src/openssl.c b/src/openssl.c
index 624f6d5..1d15f7c 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -55,6 +55,10 @@
55 55
56#include <dlfcn.h> /* dladdr(3) dlopen(3) */ 56#include <dlfcn.h> /* dladdr(3) dlopen(3) */
57 57
58#if __APPLE__
59#include <mach/mach_time.h> /* mach_absolute_time() */
60#endif
61
58#include <openssl/err.h> 62#include <openssl/err.h>
59#include <openssl/bn.h> 63#include <openssl/bn.h>
60#include <openssl/asn1.h> 64#include <openssl/asn1.h>
@@ -3980,6 +3984,15 @@ int luaopen__openssl_cipher(lua_State *L) {
3980 * 3984 *
3981 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 3985 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3982 3986
3987struct randL_state {
3988 pid_t pid;
3989}; /* struct randL_state */
3990
3991static struct randL_state *randL_getstate(lua_State *L) {
3992 return lua_touserdata(L, lua_upvalueindex(1));
3993} /* randL_getstate() */
3994
3995
3983#ifndef HAVE_RANDOM_UUID 3996#ifndef HAVE_RANDOM_UUID
3984#define HAVE_RANDOM_UUID (defined __linux) /* RANDOM_UUID is an enum, not macro */ 3997#define HAVE_RANDOM_UUID (defined __linux) /* RANDOM_UUID is an enum, not macro */
3985#endif 3998#endif
@@ -3992,7 +4005,7 @@ int luaopen__openssl_cipher(lua_State *L) {
3992#define HAVE_KERN_ARND (defined KERN_ARND) 4005#define HAVE_KERN_ARND (defined KERN_ARND)
3993#endif 4006#endif
3994 4007
3995static int stir(unsigned rqstd) { 4008static int randL_stir(struct randL_state *st, unsigned rqstd) {
3996 unsigned count = 0; 4009 unsigned count = 0;
3997 int error; 4010 int error;
3998 unsigned char data[256]; 4011 unsigned char data[256];
@@ -4054,6 +4067,8 @@ static int stir(unsigned rqstd) {
4054 close(fd); 4067 close(fd);
4055 } 4068 }
4056 4069
4070 st->pid = getpid();
4071
4057 return 0; 4072 return 0;
4058syserr: 4073syserr:
4059 error = errno; 4074 error = errno;
@@ -4064,22 +4079,47 @@ error:;
4064 struct rusage ru; 4079 struct rusage ru;
4065 struct utsname un; 4080 struct utsname un;
4066 uintptr_t aslr; 4081 uintptr_t aslr;
4082#if defined __APPLE__
4083 uint64_t mt;
4084#elif defined __sun
4085 struct timespec mt;
4086#endif
4067 } junk; 4087 } junk;
4068 4088
4069 gettimeofday(&junk.tv, NULL); 4089 gettimeofday(&junk.tv, NULL);
4070 junk.pid = getpid(); 4090 junk.pid = getpid();
4071 getrusage(RUSAGE_SELF, &junk.ru); 4091 getrusage(RUSAGE_SELF, &junk.ru);
4072 uname(&junk.un); 4092 uname(&junk.un);
4073 junk.aslr = (uintptr_t)&strcpy ^ (uintptr_t)&stir; 4093 junk.aslr = (uintptr_t)&strcpy ^ (uintptr_t)&randL_stir;
4094#if defined __APPLE__
4095 junk.mt = mach_absolute_time();
4096#elif defined __sun
4097 /*
4098 * NOTE: Linux requires -lrt for clock_gettime, and in any event
4099 * already has RANDOM_UUID. The BSDs have KERN_URND and KERN_ARND.
4100 * Just do this for Solaris to keep things simple. We've already
4101 * crossed the line of what can be reasonably accomplished on
4102 * unreasonable platforms.
4103 */
4104 clock_gettime(CLOCK_MONOTONIC, &junk.mt);
4105#endif
4074 4106
4075 RAND_add(&junk, sizeof junk, 0.1); 4107 RAND_add(&junk, sizeof junk, 0.1);
4076 4108
4109 st->pid = getpid();
4110
4077 return error; 4111 return error;
4078} /* stir() */ 4112} /* randL_stir() */
4113
4114
4115static void randL_checkpid(struct randL_state *st) {
4116 if (st->pid != getpid())
4117 (void)randL_stir(st, 16);
4118} /* randL_checkpid() */
4079 4119
4080 4120
4081static int rand_stir(lua_State *L) { 4121static int rand_stir(lua_State *L) {
4082 int error = stir(luaL_optunsigned(L, 1, 16)); 4122 int error = randL_stir(randL_getstate(L), luaL_optunsigned(L, 1, 16));
4083 4123
4084 if (error) { 4124 if (error) {
4085 lua_pushboolean(L, 0); 4125 lua_pushboolean(L, 0);
@@ -4116,6 +4156,8 @@ static int rand_bytes(lua_State *L) {
4116 luaL_Buffer B; 4156 luaL_Buffer B;
4117 int count = 0, n; 4157 int count = 0, n;
4118 4158
4159 randL_checkpid(randL_getstate(L));
4160
4119 luaL_buffinit(L, &B); 4161 luaL_buffinit(L, &B);
4120 4162
4121 while (count < size) { 4163 while (count < size) {
@@ -4219,6 +4261,8 @@ static unsigned long long rand_llu(lua_State *L) {
4219static int rand_uniform(lua_State *L) { 4261static int rand_uniform(lua_State *L) {
4220 unsigned long long r; 4262 unsigned long long r;
4221 4263
4264 randL_checkpid(randL_getstate(L));
4265
4222 if (lua_isnoneornil(L, 1)) { 4266 if (lua_isnoneornil(L, 1)) {
4223 r = rand_llu(L); 4267 r = rand_llu(L);
4224 } else { 4268 } else {
@@ -4261,9 +4305,14 @@ static const luaL_Reg rand_globals[] = {
4261}; 4305};
4262 4306
4263int luaopen__openssl_rand(lua_State *L) { 4307int luaopen__openssl_rand(lua_State *L) {
4308 struct randL_state *st;
4309
4264 initall(L); 4310 initall(L);
4265 4311
4266 luaL_newlib(L, rand_globals); 4312 luaL_newlibtable(L, rand_globals);
4313 st = lua_newuserdata(L, sizeof *st);
4314 memset(st, 0, sizeof *st);
4315 luaL_setfuncs(L, rand_globals, 1);
4267 4316
4268 return 1; 4317 return 1;
4269} /* luaopen__openssl_rand() */ 4318} /* luaopen__openssl_rand() */