com php-src: Make bin2hex() and hex2bin() timing safe: ext/standard/string.c
| From: | Anatol Belski | Date: | Tue, 04 Aug 2015 20:07:13 +0000 |
| Subject: | com php-src: Make bin2hex() and hex2bin() timing safe: ext/standard/string.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-88641@lists.php.net to get a copy of this message | ||
Commit: ad4d139f29c1710290f53b81a8673f00f37d7e7a
Author: Bob Weinand <bobwei9@hotmail.com> Tue, 4 Aug 2015 22:07:13 +0200
Parents: 668ecaa606b3203311b3329fcbd49b59f715e1e4
Branches: PHP-7.0.0
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=ad4d139f29c1710290f53b81a8673f00f37d7e7a
Log:
Make bin2hex() and hex2bin() timing safe
Changed paths:
M ext/standard/string.c
Diff:
diff --git a/ext/standard/string.c b/ext/standard/string.c
index a39105e..9c1031e 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -117,8 +117,16 @@ void register_string_constants(INIT_FUNC_ARGS)
int php_tag_find(char *tag, size_t len, const char *set);
+#ifdef PHP_WIN32
+# define SET_ALIGNED(alignment, decl) __declspec(align(alignment)) decl
+#elif HAVE_ATTRIBUTE_ALIGNED
+# define SET_ALIGNED(alignment, decl) decl __attribute__ ((__aligned__ (alignment)))
+#else
+# define SET_ALIGNED(alignment, decl) decl
+#endif
+
/* this is read-only, so it's ok */
-static char hexconvtab[] = "0123456789abcdef";
+SET_ALIGNED(16, static char hexconvtab[]) = "0123456789abcdef";
/* localeconv mutex */
#ifdef ZTS
@@ -155,25 +163,22 @@ static zend_string *php_hex2bin(const unsigned char *old, const size_t oldlen)
for (i = j = 0; i < target_length; i++) {
unsigned char c = old[j++];
+ unsigned char l = c & ~0x20;
+ int is_letter = ((unsigned int) ((l - 'A') ^ (l - 'F' - 1))) >> (8 *
sizeof(unsigned int) - 1);
unsigned char d;
- if (c >= '0' && c <= '9') {
- d = (c - '0') << 4;
- } else if (c >= 'a' && c <= 'f') {
- d = (c - 'a' + 10) << 4;
- } else if (c >= 'A' && c <= 'F') {
- d = (c - 'A' + 10) << 4;
+ /* basically (c >= '0' && c <= '9') || (l >= 'A'
&& l <= 'F') */
+ if (EXPECTED((((c ^ '0') - 10) >> (8 * sizeof(unsigned int) - 1)) | is_letter)) {
+ d = (l - 0x10 - 0x27 * is_letter) << 4;
} else {
zend_string_free(str);
return NULL;
}
c = old[j++];
- if (c >= '0' && c <= '9') {
- d |= c - '0';
- } else if (c >= 'a' && c <= 'f') {
- d |= c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- d |= c - 'A' + 10;
+ l = c & ~0x20;
+ is_letter = ((unsigned int) ((l - 'A') ^ (l - 'F' - 1))) >> (8 *
sizeof(unsigned int) - 1);
+ if (EXPECTED((((c ^ '0') - 10) >> (8 * sizeof(unsigned int) - 1)) | is_letter)) {
+ d |= l - 0x10 - 0x27 * is_letter;
} else {
zend_string_free(str);
return NULL;