Ruby  3.1.0dev(2021-09-10revisionb76ad15ed0da636161de0243c547ee1e6fc95681)
ossl_rand.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4  *
5  * All rights reserved.
6  *
7  * This program is licensed under the same licence as Ruby.
8  * (See the file 'LICENCE'.)
9  */
10 #include "ossl.h"
11 
14 
15 /*
16  * call-seq:
17  * seed(str) -> str
18  *
19  * ::seed is equivalent to ::add where _entropy_ is length of _str_.
20  */
21 static VALUE
22 ossl_rand_seed(VALUE self, VALUE str)
23 {
25  RAND_seed(RSTRING_PTR(str), RSTRING_LENINT(str));
26 
27  return str;
28 }
29 
30 /*
31  * call-seq:
32  * add(str, entropy) -> self
33  *
34  * Mixes the bytes from _str_ into the Pseudo Random Number Generator(PRNG)
35  * state.
36  *
37  * Thus, if the data from _str_ are unpredictable to an adversary, this
38  * increases the uncertainty about the state and makes the PRNG output less
39  * predictable.
40  *
41  * The _entropy_ argument is (the lower bound of) an estimate of how much
42  * randomness is contained in _str_, measured in bytes.
43  *
44  * === Example
45  *
46  * pid = $$
47  * now = Time.now
48  * ary = [now.to_i, now.nsec, 1000, pid]
49  * OpenSSL::Random.add(ary.join, 0.0)
50  * OpenSSL::Random.seed(ary.join)
51  */
52 static VALUE
53 ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
54 {
56  RAND_add(RSTRING_PTR(str), RSTRING_LENINT(str), NUM2DBL(entropy));
57 
58  return self;
59 }
60 
61 /*
62  * call-seq:
63  * load_random_file(filename) -> true
64  *
65  * Reads bytes from _filename_ and adds them to the PRNG.
66  */
67 static VALUE
68 ossl_rand_load_file(VALUE self, VALUE filename)
69 {
70  if(!RAND_load_file(StringValueCStr(filename), -1)) {
72  }
73  return Qtrue;
74 }
75 
76 /*
77  * call-seq:
78  * write_random_file(filename) -> true
79  *
80  * Writes a number of random generated bytes (currently 1024) to _filename_
81  * which can be used to initialize the PRNG by calling ::load_random_file in a
82  * later session.
83  */
84 static VALUE
85 ossl_rand_write_file(VALUE self, VALUE filename)
86 {
87  if (RAND_write_file(StringValueCStr(filename)) == -1) {
89  }
90  return Qtrue;
91 }
92 
93 /*
94  * call-seq:
95  * random_bytes(length) -> string
96  *
97  * Generates a String with _length_ number of cryptographically strong
98  * pseudo-random bytes.
99  *
100  * === Example
101  *
102  * OpenSSL::Random.random_bytes(12)
103  * #=> "..."
104  */
105 static VALUE
106 ossl_rand_bytes(VALUE self, VALUE len)
107 {
108  VALUE str;
109  int n = NUM2INT(len);
110  int ret;
111 
112  str = rb_str_new(0, n);
113  ret = RAND_bytes((unsigned char *)RSTRING_PTR(str), n);
114  if (ret == 0) {
115  ossl_raise(eRandomError, "RAND_bytes");
116  } else if (ret == -1) {
117  ossl_raise(eRandomError, "RAND_bytes is not supported");
118  }
119 
120  return str;
121 }
122 
123 #ifdef HAVE_RAND_EGD
124 /*
125  * call-seq:
126  * egd(filename) -> true
127  *
128  * Same as ::egd_bytes but queries 255 bytes by default.
129  */
130 static VALUE
131 ossl_rand_egd(VALUE self, VALUE filename)
132 {
133  if (RAND_egd(StringValueCStr(filename)) == -1) {
135  }
136  return Qtrue;
137 }
138 
139 /*
140  * call-seq:
141  * egd_bytes(filename, length) -> true
142  *
143  * Queries the entropy gathering daemon EGD on socket path given by _filename_.
144  *
145  * Fetches _length_ number of bytes and uses ::add to seed the OpenSSL built-in
146  * PRNG.
147  */
148 static VALUE
149 ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
150 {
151  int n = NUM2INT(len);
152 
153  if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
155  }
156  return Qtrue;
157 }
158 #endif /* HAVE_RAND_EGD */
159 
160 /*
161  * call-seq:
162  * status? => true | false
163  *
164  * Return +true+ if the PRNG has been seeded with enough data, +false+ otherwise.
165  */
166 static VALUE
167 ossl_rand_status(VALUE self)
168 {
169  return RAND_status() ? Qtrue : Qfalse;
170 }
171 
172 /*
173  * INIT
174  */
175 void
177 {
178 #if 0
179  mOSSL = rb_define_module("OpenSSL");
181 #endif
182 
183  mRandom = rb_define_module_under(mOSSL, "Random");
184 
186 
187  rb_define_module_function(mRandom, "seed", ossl_rand_seed, 1);
188  rb_define_module_function(mRandom, "random_add", ossl_rand_add, 2);
189  rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1);
190  rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
191  rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
192 #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
193  rb_define_alias(rb_singleton_class(mRandom), "pseudo_bytes", "random_bytes");
194 #endif
195 #ifdef HAVE_RAND_EGD
196  rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);
197  rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
198 #endif /* HAVE_RAND_EGD */
199  rb_define_module_function(mRandom, "status?", ossl_rand_status, 0);
200 }
StringValue
#define StringValue(v)
Definition: rstring.h:50
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:914
eRandomError
VALUE eRandomError
Definition: ossl_rand.c:13
NUM2DBL
#define NUM2DBL
Definition: double.h:27
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:887
Init_ossl_rand
void Init_ossl_rand(void)
Definition: ossl_rand.c:176
ossl.h
NUM2INT
#define NUM2INT
Definition: int.h:44
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:2050
rb_str_new
#define rb_str_new(str, len)
Definition: string.h:213
mOSSL
VALUE mOSSL
Definition: ossl.c:237
Qfalse
#define Qfalse
Definition: special_consts.h:50
len
uint8_t len
Definition: escape.c:17
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:299
mRandom
VALUE mRandom
Definition: ossl_rand.c:12
NULL
#define NULL
Definition: regenc.h:69
Qtrue
#define Qtrue
Definition: special_consts.h:52
VALUE
unsigned long VALUE
Definition: value.h:38
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
ret
return ret
Definition: memory.h:232
rb_singleton_class
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1975
eOSSLError
VALUE eOSSLError
Definition: ossl.c:242
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:809
StringValueCStr
#define StringValueCStr(v)
Definition: rstring.h:52
rb_define_module_function
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
Definition: cxxanyargs.hpp:674
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:1090