-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtomcrypt_rng.c
167 lines (142 loc) · 4.85 KB
/
tomcrypt_rng.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 2017 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: François Poirotte <[email protected]> |
+----------------------------------------------------------------------+
*/
#include <tomcrypt.h>
#include "php_tomcrypt_rng.h"
#ifdef LTC_CHACHA20_PRNG
#define PHP_TOMCRYPT_DESC_PRNG_CHACHA20 &chacha20_prng_desc
#else
#define PHP_TOMCRYPT_DESC_PRNG_CHACHA20 NULL
#endif
#ifdef LTC_FORTUNA
#define PHP_TOMCRYPT_DESC_PRNG_FORTUNA &fortuna_desc
#else
#define PHP_TOMCRYPT_DESC_PRNG_FORTUNA NULL
#endif
#ifdef LTC_RC4
#define PHP_TOMCRYPT_DESC_PRNG_RC4 &rc4_desc
#else
#define PHP_TOMCRYPT_DESC_PRNG_RC4 NULL
#endif
#ifdef LTC_SPRNG
#define PHP_TOMCRYPT_DESC_PRNG_SECURE &sprng_desc
#else
#define PHP_TOMCRYPT_DESC_PRNG_SECURE NULL
#endif
#ifdef LTC_SOBER128
#define PHP_TOMCRYPT_DESC_PRNG_SOBER128 &sober128_desc
#else
#define PHP_TOMCRYPT_DESC_PRNG_SOBER128 NULL
#endif
#ifdef LTC_YARROW
#define PHP_TOMCRYPT_DESC_PRNG_YARROW &yarrow_desc
#else
#define PHP_TOMCRYPT_DESC_PRNG_YARROW NULL
#endif
#define TOMCRYPT_DEFINE_RNG(rng) { \
.php_const = "TOMCRYPT_RNG_" # rng, \
.php_value = PHP_TOMCRYPT_RNG_ ## rng, \
.desc = PHP_TOMCRYPT_DESC_PRNG_ ## rng \
}
static struct {
const char *php_const;
const char *php_value;
const struct ltc_prng_descriptor *desc;
prng_state state;
} php_tomcrypt_rngs[] = {
TOMCRYPT_DEFINE_RNG(CHACHA20),
TOMCRYPT_DEFINE_RNG(FORTUNA),
TOMCRYPT_DEFINE_RNG(RC4),
TOMCRYPT_DEFINE_RNG(SECURE),
TOMCRYPT_DEFINE_RNG(SOBER128),
TOMCRYPT_DEFINE_RNG(YARROW),
{ NULL }
};
int init_prngs(int module_number TSRMLS_DC)
{
unsigned short i;
for (i = 0; php_tomcrypt_rngs[i].php_const != NULL; i++) {
PLTC_REGISTER_STRING_CONSTANT(php_tomcrypt_rngs[i].php_const,
(char *) php_tomcrypt_rngs[i].php_value, CONST_PERSISTENT | CONST_CS);
if (php_tomcrypt_rngs[i].desc == NULL) {
continue;
}
if (register_prng(php_tomcrypt_rngs[i].desc) == -1 ||
rng_make_prng(128, find_prng(php_tomcrypt_rngs[i].desc->name), &php_tomcrypt_rngs[i].state, NULL) == -1) {
return -1;
}
}
return 0;
}
int deinit_prngs(void)
{
unsigned short i;
for (i = 0; php_tomcrypt_rngs[i].php_const != NULL; i++) {
if (php_tomcrypt_rngs[i].desc != NULL) {
php_tomcrypt_rngs[i].desc->done(&php_tomcrypt_rngs[i].state);
}
}
return 0;
}
/* {{{ proto array tomcrypt_list_rngs()
List all available (Pseudo-)Random Number Generators (PRNGs) */
PHP_FUNCTION(tomcrypt_list_rngs)
{
int i, j = 0;
array_init(return_value);
for (i = 0; php_tomcrypt_rngs[i].php_const != NULL; i++) {
if (php_tomcrypt_rngs[i].desc != NULL) {
pltc_add_index_string(return_value, j++, php_tomcrypt_rngs[i].php_value, 1);
}
}
}
/* }}} */
/* {{{ proto string tomcrypt_rng_get_bytes(int size, string rng = TOMCRYPT_RNG_SECURE)
Get some random bytes from the (Pseudo-)RNG */
PHP_FUNCTION(tomcrypt_rng_get_bytes)
{
char sprng[] = PHP_TOMCRYPT_RNG_SECURE;
char *rng = sprng;
pltc_size rng_len = sizeof(PHP_TOMCRYPT_RNG_SECURE);
int i, err;
pltc_long size;
unsigned char *buffer;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &size, &rng, &rng_len) == FAILURE) {
return;
}
if (size <= 0) {
TOMCRYPT_G(last_error) = CRYPT_INVALID_ARG;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid size (%d)", size);
RETURN_FALSE;
}
for (i = 0; php_tomcrypt_rngs[i].php_const != NULL; i++) {
if (strncmp(php_tomcrypt_rngs[i].php_value, rng, rng_len) || php_tomcrypt_rngs[i].desc == NULL) {
continue;
}
if ((err = php_tomcrypt_rngs[i].desc->ready(&php_tomcrypt_rngs[i].state)) != CRYPT_OK) {
TOMCRYPT_G(last_error) = err;
RETURN_FALSE;
}
buffer = emalloc(size + 1);
size = (int) php_tomcrypt_rngs[i].desc->read(buffer, size, &php_tomcrypt_rngs[i].state);
buffer[size] = '\0';
PLTC_RETURN_STRINGL(buffer, size, 0);
}
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown RNG: %s", rng);
RETURN_FALSE;
}
/* }}} */