Annotate

util-src/crand.c @ 7826:7702ce682427

util.crand: Raise hard errors
author Kim Alvefur <zash@zash.se>
date Fri, 20 Jan 2017 12:23:55 +0100
parent 7825:1dfa5847d49e
child 7829:1fb477d19fdd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 /* Prosody IM
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 -- Copyright (C) 2008-2016 Matthew Wild
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 -- Copyright (C) 2008-2016 Waqas Hussain
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 -- Copyright (C) 2016 Kim Alvefur
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5 --
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 -- This project is MIT/X11 licensed. Please see the
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 -- COPYING file in the source package for more information.
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 --
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 */
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 /*
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 * crand.c
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 * C PRNG interface
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 */
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
15
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 #include "lualib.h"
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 #include "lauxlib.h"
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 #include <string.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 #include <errno.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 #if defined(WITH_GETRANDOM)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 #include <unistd.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 #include <sys/syscall.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 #include <linux/random.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 #ifndef SYS_getrandom
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 #error getrandom() requires Linux 3.17 or later
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 #endif
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 /* Was this not supposed to be a function? */
7824
56552733742e util.crand: Let Lua handle allocation, freeing and error handling for buffer
Kim Alvefur <zash@zash.se>
parents: 7823
diff changeset
32 int getrandom(void *buf, size_t len, int flags) {
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 return syscall(SYS_getrandom, buf, len, flags);
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 }
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 #elif defined(WITH_ARC4RANDOM)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 #include <stdlib.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 #elif defined(WITH_OPENSSL)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 #include <openssl/rand.h>
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
40 #else
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 #error util.crand compiled without a random source
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42 #endif
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 int Lrandom(lua_State *L) {
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 int ret = 0;
7823
9b66ada1487c util.crand: Switch to luaL_checkinteger since checkint is deprecated in Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 7818
diff changeset
46 size_t len = (size_t)luaL_checkinteger(L, 1);
7824
56552733742e util.crand: Let Lua handle allocation, freeing and error handling for buffer
Kim Alvefur <zash@zash.se>
parents: 7823
diff changeset
47 void *buf = lua_newuserdata(L, len);
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 #if defined(WITH_GETRANDOM)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 ret = getrandom(buf, len, 0);
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 if(ret < 0) {
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 lua_pushstring(L, strerror(errno));
7826
7702ce682427 util.crand: Raise hard errors
Kim Alvefur <zash@zash.se>
parents: 7825
diff changeset
54 return lua_error(L);
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 }
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 #elif defined(WITH_ARC4RANDOM)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 arc4random_buf(buf, len);
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 ret = len;
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 #elif defined(WITH_OPENSSL)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 ret = RAND_bytes(buf, len);
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 if(ret == 1) {
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 ret = len;
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 } else {
7826
7702ce682427 util.crand: Raise hard errors
Kim Alvefur <zash@zash.se>
parents: 7825
diff changeset
66 lua_pushstring(L, "RAND_bytes() failed");
7702ce682427 util.crand: Raise hard errors
Kim Alvefur <zash@zash.se>
parents: 7825
diff changeset
67 return lua_error(L);
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 }
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 #endif
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71
7824
56552733742e util.crand: Let Lua handle allocation, freeing and error handling for buffer
Kim Alvefur <zash@zash.se>
parents: 7823
diff changeset
72 lua_pushlstring(L, buf, ret);
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 return 1;
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 }
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 int luaopen_util_crand(lua_State *L) {
7818
54669df178c2 util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents: 7439
diff changeset
77 #if (LUA_VERSION_NUM > 501)
54669df178c2 util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents: 7439
diff changeset
78 luaL_checkversion(L);
54669df178c2 util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents: 7439
diff changeset
79 #endif
7187
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 lua_newtable(L);
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 lua_pushcfunction(L, Lrandom);
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 lua_setfield(L, -2, "bytes");
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 #if defined(WITH_GETRANDOM)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 lua_pushstring(L, "Linux");
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 #elif defined(WITH_ARC4RANDOM)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
87 lua_pushstring(L, "arc4random()");
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 #elif defined(WITH_OPENSSL)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 lua_pushstring(L, "OpenSSL");
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 #endif
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
91 lua_setfield(L, -2, "_source");
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
92
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
93 #if defined(WITH_OPENSSL) && defined(_WIN32)
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
94 /* Do we need to seed this on Windows? */
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
95 #endif
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
96
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97 return 1;
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
98 }
3d2c2f0809ee util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG
Kim Alvefur <zash@zash.se>
parents:
diff changeset
99