Skip to content

Commit 85b9006

Browse files
committed
- rename macros - use openssl RAND_bytes - CS
1 parent cfed1f7 commit 85b9006

File tree

4 files changed

+60
-55
lines changed

4 files changed

+60
-55
lines changed

ext/openssl/openssl_pwhash.c

Lines changed: 55 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -31,51 +31,52 @@
3131
#include <openssl/core_names.h>
3232
#include <openssl/kdf.h>
3333
#include <openssl/thread.h>
34+
#include <openssl/rand.h>
3435

35-
#define MEMLIMIT_MIN 8u
36-
#define MEMLIMIT_MAX UINT32_MAX
37-
#define OPSLIMIT_MIN 1u
38-
#define OPSLIMIT_MAX UINT32_MAX
39-
#define THREADS_MIN 1u
40-
#define THREADS_MAX UINT32_MAX
36+
#define PHP_OPENSSL_MEMLIMIT_MIN 8u
37+
#define PHP_OPENSSL_MEMLIMIT_MAX UINT32_MAX
38+
#define PHP_OPENSSL_ITERLIMIT_MIN 1u
39+
#define PHP_OPENSSL_ITERLIMIT_MAX UINT32_MAX
40+
#define PHP_OPENSSL_THREADS_MIN 1u
41+
#define PHP_OPENSSL_THREADS_MAX UINT32_MAX
4142

42-
#define ARGON_VERSION 0x13
43+
#define PHP_OPENSSL_ARGON_VERSION 0x13
4344

44-
#define SALT_SIZE 16
45-
#define HASH_SIZE 32
46-
#define DIGEST_SIZE 128
45+
#define PHP_OPENSSL_SALT_SIZE 16
46+
#define PHP_OPENSSL_HASH_SIZE 32
47+
#define PHP_OPENSSL_DIGEST_SIZE 128
4748

48-
static inline int get_options(zend_array *options, uint32_t *memlimit, uint32_t *opslimit, uint32_t *threads)
49+
static inline zend_result get_options(zend_array *options, uint32_t *memlimit, uint32_t *iterlimit, uint32_t *threads)
4950
{
5051
zval *opt;
5152

52-
*opslimit = PHP_OPENSSL_PWHASH_OPSLIMIT;
53-
*memlimit = PHP_OPENSSL_PWHASH_MEMLIMIT;
54-
*threads = PHP_OPENSSL_PWHASH_THREADS;
53+
*iterlimit = PHP_OPENSSL_PWHASH_ITERLIMIT;
54+
*memlimit = PHP_OPENSSL_PWHASH_MEMLIMIT;
55+
*threads = PHP_OPENSSL_PWHASH_THREADS;
5556

5657
if (!options) {
5758
return SUCCESS;
5859
}
5960
if ((opt = zend_hash_str_find(options, "memory_cost", strlen("memory_cost")))) {
6061
zend_long smemlimit = zval_get_long(opt);
6162

62-
if ((smemlimit < 0) || (smemlimit < MEMLIMIT_MIN) || (smemlimit > (MEMLIMIT_MAX))) {
63+
if ((smemlimit < 0) || (smemlimit < PHP_OPENSSL_MEMLIMIT_MIN) || (smemlimit > (PHP_OPENSSL_MEMLIMIT_MAX))) {
6364
zend_value_error("Memory cost is outside of allowed memory range");
6465
return FAILURE;
6566
}
6667
*memlimit = smemlimit;
6768
}
6869
if ((opt = zend_hash_str_find(options, "time_cost", strlen("time_cost")))) {
69-
zend_long sopslimit = zval_get_long(opt);
70-
if ((sopslimit < OPSLIMIT_MIN) || (sopslimit > OPSLIMIT_MAX)) {
70+
zend_long siterlimit = zval_get_long(opt);
71+
if ((siterlimit < PHP_OPENSSL_ITERLIMIT_MIN) || (siterlimit > PHP_OPENSSL_ITERLIMIT_MAX)) {
7172
zend_value_error("Time cost is outside of allowed time range");
7273
return FAILURE;
7374
}
74-
*opslimit = sopslimit;
75+
*iterlimit = siterlimit;
7576
}
7677
if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && (zval_get_long(opt) != 1)) {
7778
zend_long sthreads = zval_get_long(opt);
78-
if ((sthreads < THREADS_MIN) || (sthreads > THREADS_MAX)) {
79+
if ((sthreads < PHP_OPENSSL_THREADS_MIN) || (sthreads > PHP_OPENSSL_THREADS_MAX)) {
7980
zend_value_error("Invalid number of threads");
8081
return FAILURE;
8182
}
@@ -86,19 +87,22 @@ static inline int get_options(zend_array *options, uint32_t *memlimit, uint32_t
8687

8788
static bool php_openssl_argon2_compute_hash(
8889
const char *algo,
89-
uint32_t version, uint32_t memlimit, uint32_t opslimit, uint32_t threads,
90+
uint32_t version, uint32_t memlimit, uint32_t iterlimit, uint32_t threads,
9091
const char *pass, size_t pass_len,
9192
const unsigned char *salt, size_t salt_len,
9293
unsigned char *hash, size_t hash_len)
9394
{
9495
OSSL_PARAM params[7], *p = params;
96+
OSSL_LIB_CTX *ctx = NULL;
9597
EVP_KDF *kdf = NULL;
9698
EVP_KDF_CTX *kctx = NULL;
9799
bool ret = false;
98100

99-
100101
if (threads > 1) {
101-
if (OSSL_set_max_threads(NULL, threads) != 1) {
102+
if ((ctx = OSSL_LIB_CTX_new()) == NULL) {
103+
goto fail;
104+
}
105+
if (OSSL_set_max_threads(ctx, threads) != 1) {
102106
goto fail;
103107
}
104108
}
@@ -108,76 +112,77 @@ static bool php_openssl_argon2_compute_hash(
108112
*p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_LANES,
109113
&threads);
110114
*p++= OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ITER,
111-
&opslimit);
115+
&iterlimit);
112116
*p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST,
113117
&memlimit);
114118
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
115119
(void *)salt, salt_len);
116120
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
117121
(void *)pass, pass_len);
118-
*p++ = OSSL_PARAM_construct_end();
122+
*p++ = OSSL_PARAM_construct_end();
119123

120-
if ((kdf = EVP_KDF_fetch(NULL, algo, NULL)) == NULL) {
124+
if ((kdf = EVP_KDF_fetch(ctx, algo, NULL)) == NULL) {
121125
goto fail;
122126
}
123127
if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) {
124128
goto fail;
125129
}
126-
if (EVP_KDF_derive(kctx, hash, hash_len, params) != 1) {
130+
if (EVP_KDF_derive(kctx, hash, hash_len, params) != 1) {
127131
zend_value_error("Unexpected failure hashing password");
128132
goto fail;
129133
}
130134

131135
ret = true;
132136

133137
fail:
134-
EVP_KDF_free(kdf);
135-
EVP_KDF_CTX_free(kctx);
138+
EVP_KDF_free(kdf);
139+
EVP_KDF_CTX_free(kctx);
136140

137141
if (threads > 1) {
138-
OSSL_set_max_threads(NULL, 0);
142+
OSSL_set_max_threads(ctx, 0);
143+
OSSL_LIB_CTX_free(ctx);
139144
}
140145
return ret;
141146
}
142147

143148
static zend_string *php_openssl_argon2_hash(const zend_string *password, zend_array *options, const char *algo)
144149
{
145-
uint32_t opslimit, memlimit, threads, version = ARGON_VERSION;
150+
uint32_t iterlimit, memlimit, threads, version = PHP_OPENSSL_ARGON_VERSION;
146151
zend_string *digest = NULL, *salt64 = NULL, *hash64 = NULL;
147-
unsigned char hash[HASH_SIZE+1], salt[SALT_SIZE+1];
152+
unsigned char hash[PHP_OPENSSL_HASH_SIZE+1], salt[PHP_OPENSSL_SALT_SIZE+1];
148153

149154
if ((ZSTR_LEN(password) >= UINT32_MAX)) {
150155
zend_value_error("Password is too long");
151156
return NULL;
152157
}
153-
if (get_options(options, &memlimit, &opslimit, &threads) == FAILURE) {
158+
if (get_options(options, &memlimit, &iterlimit, &threads) == FAILURE) {
154159
return NULL;
155160
}
156-
if (FAILURE == php_random_bytes_throw(salt, SALT_SIZE)) {
161+
if (RAND_bytes(salt, PHP_OPENSSL_SALT_SIZE) <= 0) {
157162
return NULL;
158163
}
159164

160-
if (!php_openssl_argon2_compute_hash(algo, version, memlimit, opslimit, threads,
161-
ZSTR_VAL(password), ZSTR_LEN(password), salt, SALT_SIZE, hash, HASH_SIZE)) {
165+
if (!php_openssl_argon2_compute_hash(algo, version, memlimit, iterlimit, threads,
166+
ZSTR_VAL(password), ZSTR_LEN(password), salt, PHP_OPENSSL_SALT_SIZE, hash, PHP_OPENSSL_HASH_SIZE)) {
162167
return NULL;
163168
}
164169

165-
hash64 = php_base64_encode_ex(hash, HASH_SIZE, PHP_BASE64_NO_PADDING);
170+
hash64 = php_base64_encode_ex(hash, PHP_OPENSSL_HASH_SIZE, PHP_BASE64_NO_PADDING);
166171

167-
salt64 = php_base64_encode_ex(salt, SALT_SIZE, PHP_BASE64_NO_PADDING);
172+
salt64 = php_base64_encode_ex(salt, PHP_OPENSSL_SALT_SIZE, PHP_BASE64_NO_PADDING);
168173

169-
digest = zend_string_alloc(DIGEST_SIZE, 0);
174+
digest = zend_string_alloc(PHP_OPENSSL_DIGEST_SIZE, 0);
170175
ZSTR_LEN(digest) = snprintf(ZSTR_VAL(digest), ZSTR_LEN(digest), "$%s$v=%d$m=%u,t=%u,p=%u$%s$%s",
171-
algo, version, memlimit, opslimit, threads, ZSTR_VAL(salt64), ZSTR_VAL(hash64));
176+
algo, version, memlimit, iterlimit, threads, ZSTR_VAL(salt64), ZSTR_VAL(hash64));
172177

173178
zend_string_release(salt64);
174179
zend_string_release(hash64);
175180

176-
return digest;
181+
return digest;
177182
}
178183

179184
static int php_openssl_argon2_extract(
180-
const zend_string *digest, uint32_t *version, uint32_t *memlimit, uint32_t *opslimit,
185+
const zend_string *digest, uint32_t *version, uint32_t *memlimit, uint32_t *iterlimit,
181186
uint32_t *threads, zend_string **salt, zend_string **hash)
182187
{
183188
const char *p;
@@ -195,7 +200,7 @@ static int php_openssl_argon2_extract(
195200
return FAILURE;
196201
}
197202
if (sscanf(p, "v=%" PRIu32 "$m=%" PRIu32 ",t=%" PRIu32 ",p=%" PRIu32,
198-
version, memlimit, opslimit, threads) != 4) {
203+
version, memlimit, iterlimit, threads) != 4) {
199204
return FAILURE;
200205
}
201206
if (salt && hash) {
@@ -226,19 +231,19 @@ static int php_openssl_argon2_extract(
226231

227232
static bool php_openssl_argon2_verify(const zend_string *password, const zend_string *digest, const char *algo)
228233
{
229-
uint32_t version, opslimit, memlimit, threads;
234+
uint32_t version, iterlimit, memlimit, threads;
230235
zend_string *salt, *hash, *new;
231236
bool ret = false;
232237

233238
if ((ZSTR_LEN(password) >= UINT32_MAX) || (ZSTR_LEN(digest) >= UINT32_MAX)) {
234239
return false;
235240
}
236-
if (FAILURE == php_openssl_argon2_extract(digest, &version, &memlimit, &opslimit, &threads, &salt, &hash)) {
241+
if (FAILURE == php_openssl_argon2_extract(digest, &version, &memlimit, &iterlimit, &threads, &salt, &hash)) {
237242
return false;
238243
}
239244

240245
new = zend_string_alloc(ZSTR_LEN(hash), 0);
241-
if (php_openssl_argon2_compute_hash(algo, version, memlimit, opslimit, threads,
246+
if (php_openssl_argon2_compute_hash(algo, version, memlimit, iterlimit, threads,
242247
ZSTR_VAL(password), ZSTR_LEN(password), (unsigned char *)ZSTR_VAL(salt),
243248
ZSTR_LEN(salt), (unsigned char *)ZSTR_VAL(new), ZSTR_LEN(new))) {
244249
ret = (php_safe_bcmp(hash, new) == 0);
@@ -263,19 +268,19 @@ static bool php_openssl_argon2id_verify(const zend_string *password, const zend_
263268

264269
static bool php_openssl_argon2_needs_rehash(const zend_string *hash, zend_array *options)
265270
{
266-
uint32_t version, opslimit, memlimit, threads;
267-
uint32_t new_version = ARGON_VERSION, new_opslimit, new_memlimit, new_threads;
271+
uint32_t version, iterlimit, memlimit, threads;
272+
uint32_t new_version = PHP_OPENSSL_ARGON_VERSION, new_iterlimit, new_memlimit, new_threads;
268273

269-
if (FAILURE == get_options(options, &new_memlimit, &new_opslimit, &new_threads)) {
274+
if (FAILURE == get_options(options, &new_memlimit, &new_iterlimit, &new_threads)) {
270275
return true;
271276
}
272-
if (FAILURE == php_openssl_argon2_extract(hash, &version, &memlimit, &opslimit, &threads, NULL, NULL)) {
277+
if (FAILURE == php_openssl_argon2_extract(hash, &version, &memlimit, &iterlimit, &threads, NULL, NULL)) {
273278
return true;
274279
}
275280

276281
// Algo already checked in pasword_needs_rehash implementation
277282
return (version != new_version) ||
278-
(opslimit != new_opslimit) ||
283+
(iterlimit != new_iterlimit) ||
279284
(memlimit != new_memlimit) ||
280285
(threads != new_threads);
281286
}

ext/openssl/openssl_pwhash.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
const PASSWORD_ARGON2_DEFAULT_MEMORY_COST = UNKNOWN;
1919
/**
2020
* @var int
21-
* @cvalue PHP_OPENSSL_PWHASH_OPSLIMIT
21+
* @cvalue PHP_OPENSSL_PWHASH_ITERLIMIT
2222
*/
2323
const PASSWORD_ARGON2_DEFAULT_TIME_COST = UNKNOWN;
2424
/**

ext/openssl/openssl_pwhash_arginfo.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/openssl/php_openssl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ static inline php_openssl_certificate_object *php_openssl_certificate_from_obj(z
172172
#define PHP_OPENSSL_PWHASH_MEMLIMIT (64 << 10)
173173
#endif
174174
#if defined(PHP_PASSWORD_ARGON2_TIME_COST)
175-
#define PHP_OPENSSL_PWHASH_OPSLIMIT PHP_PASSWORD_ARGON2_TIME_COST
175+
#define PHP_OPENSSL_PWHASH_ITERLIMIT PHP_PASSWORD_ARGON2_TIME_COST
176176
#else
177-
#define PHP_OPENSSL_PWHASH_OPSLIMIT 4
177+
#define PHP_OPENSSL_PWHASH_ITERLIMIT 4
178178
#endif
179179
#if defined(PHP_PASSWORD_ARGON2_THREADS)
180180
#define PHP_OPENSSL_PWHASH_THREADS PHP_PASSWORD_ARGON2_THREADS

0 commit comments

Comments
 (0)