mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Introduction of timing attack safe bcmp implementation.
Nothing new but to refactor usage b/w hash and password extensions but using volatile pointers to be a bit safer, allowing to expand its usage eventually.
This commit is contained in:
parent
8aa7e203ed
commit
bfe6f9e66a
@ -1616,7 +1616,7 @@ PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \
|
||||
php_ini_builder.c \
|
||||
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
|
||||
strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \
|
||||
network.c php_open_temporary_file.c php_odbc_utils.c \
|
||||
network.c php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c \
|
||||
output.c getopt.c php_syslog.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
|
||||
|
||||
PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no)
|
||||
|
@ -1111,9 +1111,7 @@ PHP_FUNCTION(hash_pbkdf2)
|
||||
PHP_FUNCTION(hash_equals)
|
||||
{
|
||||
zval *known_zval, *user_zval;
|
||||
char *known_str, *user_str;
|
||||
int result = 0;
|
||||
size_t j;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &known_zval, &user_zval) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
@ -1130,17 +1128,8 @@ PHP_FUNCTION(hash_equals)
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (Z_STRLEN_P(known_zval) != Z_STRLEN_P(user_zval)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
known_str = Z_STRVAL_P(known_zval);
|
||||
user_str = Z_STRVAL_P(user_zval);
|
||||
|
||||
/* This is security sensitive code. Do not optimize this for speed. */
|
||||
for (j = 0; j < Z_STRLEN_P(known_zval); j++) {
|
||||
result |= known_str[j] ^ user_str[j];
|
||||
}
|
||||
result = php_safe_bcmp(Z_STR_P(known_zval), Z_STR_P(user_zval));
|
||||
|
||||
RETURN_BOOL(0 == result);
|
||||
}
|
||||
|
@ -152,7 +152,6 @@ static bool php_password_bcrypt_needs_rehash(const zend_string *hash, zend_array
|
||||
}
|
||||
|
||||
static bool php_password_bcrypt_verify(const zend_string *password, const zend_string *hash) {
|
||||
size_t i;
|
||||
int status = 0;
|
||||
zend_string *ret = php_crypt(ZSTR_VAL(password), (int)ZSTR_LEN(password), ZSTR_VAL(hash), (int)ZSTR_LEN(hash), 1);
|
||||
|
||||
@ -160,7 +159,7 @@ static bool php_password_bcrypt_verify(const zend_string *password, const zend_s
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ZSTR_LEN(ret) != ZSTR_LEN(hash) || ZSTR_LEN(hash) < 13) {
|
||||
if (ZSTR_LEN(hash) < 13) {
|
||||
zend_string_free(ret);
|
||||
return 0;
|
||||
}
|
||||
@ -169,9 +168,7 @@ static bool php_password_bcrypt_verify(const zend_string *password, const zend_s
|
||||
* resistance towards timing attacks. This is a constant time
|
||||
* equality check that will always check every byte of both
|
||||
* values. */
|
||||
for (i = 0; i < ZSTR_LEN(hash); i++) {
|
||||
status |= (ZSTR_VAL(ret)[i] ^ ZSTR_VAL(hash)[i]);
|
||||
}
|
||||
status = php_safe_bcmp(ret, hash);
|
||||
|
||||
zend_string_free(ret);
|
||||
return status == 0;
|
||||
|
@ -179,6 +179,10 @@ END_EXTERN_C()
|
||||
#define explicit_bzero php_explicit_bzero
|
||||
#endif
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
PHPAPI int php_safe_bcmp(const zend_string *a, const zend_string *b);
|
||||
END_EXTERN_C()
|
||||
|
||||
#ifndef HAVE_STRTOK_R
|
||||
BEGIN_EXTERN_C()
|
||||
char *strtok_r(char *s, const char *delim, char **last);
|
||||
|
43
main/safe_bcmp.c
Normal file
43
main/safe_bcmp.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: David Carlier <devnexen@gmail.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "php.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Returns 0 if both inputs match, 1 if they don't.
|
||||
* Returns -1 early if inputs do not have the same lengths.
|
||||
*
|
||||
*/
|
||||
PHPAPI int php_safe_bcmp(const zend_string *a, const zend_string *b)
|
||||
{
|
||||
const volatile unsigned char *ua = (const volatile unsigned char *)ZSTR_VAL(a);
|
||||
const volatile unsigned char *ub = (const volatile unsigned char *)ZSTR_VAL(b);
|
||||
size_t i = 0;
|
||||
int r = 0;
|
||||
|
||||
if (ZSTR_LEN(a) != ZSTR_LEN(b)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i < ZSTR_LEN(a)) {
|
||||
r |= ua[i] ^ ub[i];
|
||||
++i;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
@ -265,7 +265,7 @@ ADD_SOURCES("main", "main.c snprintf.c spprintf.c getopt.c fopen_wrappers.c \
|
||||
php_scandir.c php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
|
||||
strlcat.c reentrancy.c php_variables.c php_ticks.c network.c \
|
||||
php_open_temporary_file.c output.c internal_functions.c \
|
||||
php_syslog.c php_odbc_utils.c");
|
||||
php_syslog.c php_odbc_utils.c safe_bcmp.c");
|
||||
ADD_FLAG("CFLAGS_BD_MAIN", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
|
||||
if (VS_TOOLSET && VCVERS >= 1914) {
|
||||
ADD_FLAG("CFLAGS_BD_MAIN", "/d2FuncCache1");
|
||||
|
Loading…
Reference in New Issue
Block a user