From d05745816634d82a14bb8abb9c322c8b63be098f Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 14 Oct 2018 10:21:29 +0200 Subject: [PATCH 1/5] ext/sodium: Avoid shifts wider than 32 bits on size_t values Backport from PECL libsodium-php 2.0.10 --- ext/sodium/libsodium.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index e168aad105d..08ac0f9ab21 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -3405,7 +3405,8 @@ PHP_FUNCTION(sodium_pad) for (j = 0U; j <= xpadded_len; j++) { ZSTR_VAL(padded)[j] = unpadded[i]; k -= st; - st = (~(((((k >> 48) | (k >> 32) | (k >> 16) | k) & 0xffff) - 1U) >> 16)) & 1U; + st = (size_t) (~(((( (((uint64_t) k) >> 48) | (((uint64_t) k) >> 32) | + (k >> 16) | k) & 0xffff) - 1U) >> 16)) & 1U; i += st; } #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6) From 15ba7df2245ac177a965346e7ec96a4ab3300839 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 14 Oct 2018 10:32:48 +0200 Subject: [PATCH 2/5] ext/sodium: Use a correct max output size for base64 decoding Also handle the case where the function is not available in test. Backport from PECL libsodium-php 2.0.12 --- ext/sodium/libsodium.c | 2 +- ext/sodium/tests/utils.phpt | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 08ac0f9ab21..a5f892fb7a3 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -2780,7 +2780,7 @@ PHP_FUNCTION(sodium_base642bin) "invalid base64 variant identifier", 0); return; } - bin_len = b64_len / 4U * 3U; + bin_len = b64_len / 4U * 3U + 1U; bin = zend_string_alloc(bin_len, 0); if (sodium_base642bin((unsigned char *) ZSTR_VAL(bin), bin_len, b64, b64_len, diff --git a/ext/sodium/tests/utils.phpt b/ext/sodium/tests/utils.phpt index ff380ff78ca..4f99f75671a 100644 --- a/ext/sodium/tests/utils.phpt +++ b/ext/sodium/tests/utils.phpt @@ -86,6 +86,12 @@ if (defined('SODIUM_BASE64_VARIANT_ORIGINAL')) { } catch (Exception $e) { var_dump('base64("O") case passed'); } + var_dump(sodium_base642bin('YWJjZA', SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING)); +} else { + var_dump('base64("O1R") case passed'); + var_dump('base64("O1") case passed'); + var_dump('base64("O") case passed'); + var_dump('abcd'); } ?> @@ -107,3 +113,4 @@ bool(true) string(25) "base64("O1R") case passed" string(24) "base64("O1") case passed" string(23) "base64("O") case passed" +string(4) "abcd" From bf48d0c475c0c1312fbf763d221d94e87cf480d0 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 14 Oct 2018 10:37:37 +0200 Subject: [PATCH 3/5] ext/sodium: Fix sodium_pad() with blocksize >= 256 Backport from PECL libsodium-php 2.0.12 --- ext/sodium/libsodium.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index a5f892fb7a3..5462700f6c4 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -3424,7 +3424,8 @@ PHP_FUNCTION(sodium_pad) tail = &ZSTR_VAL(padded)[xpadded_len]; mask = 0U; for (i = 0; i < blocksize; i++) { - barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> 8); + barrier_mask = (unsigned char) + (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT)); tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask); mask |= barrier_mask; } From 82a93c17943c510b0bf33904429d47fbb74d9fc2 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 14 Oct 2018 10:43:21 +0200 Subject: [PATCH 4/5] ext/sodium: sodium_pad(): do not copy any bytes if the string is empty Spotted by San Zhang, thanks! Backport from PECL libsodium-php 2.0.13 --- ext/sodium/libsodium.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 5462700f6c4..b6a49254980 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -3402,12 +3402,17 @@ PHP_FUNCTION(sodium_pad) st = 1U; i = 0U; k = unpadded_len; - for (j = 0U; j <= xpadded_len; j++) { - ZSTR_VAL(padded)[j] = unpadded[i]; - k -= st; - st = (size_t) (~(((( (((uint64_t) k) >> 48) | (((uint64_t) k) >> 32) | - (k >> 16) | k) & 0xffff) - 1U) >> 16)) & 1U; - i += st; + if (unpadded_len > 0) { + st = 1U; + i = 0U; + k = unpadded_len; + for (j = 0U; j <= xpadded_len; j++) { + ZSTR_VAL(padded)[j] = unpadded[i]; + k -= st; + st = (size_t) (~(((( (((uint64_t) k) >> 48) | (((uint64_t) k) >> 32) | + (k >> 16) | k) & 0xffff) - 1U) >> 16)) & 1U; + i += st; + } } #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6) if (sodium_pad(NULL, (unsigned char *) ZSTR_VAL(padded), unpadded_len, From 5d70165f632d8857f2e75975d5857fa29a68f3fc Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 14 Oct 2018 10:58:02 +0200 Subject: [PATCH 5/5] [ci skip] Update NEWS --- NEWS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS b/NEWS index 2c8ef3b33cf..034976bff94 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,14 @@ PHP NEWS . Fixed bug #66430 (ReflectionFunction::invoke does not invoke closure with object scope). (Nikita) +- Sodium: + . Some base64 outputs were truncated; this is not the case any more. + (jedisct1) + . block sizes >= 256 bytes are now supposed by sodium_pad() even + when an old version of libsodium has been installed. (jedisct1) + . Fixed bug #77008 (sodium_pad() could read (but not return nor write) + uninitialized memory when trying to pad an empty input). (jedisct1) + - Standard: . Fixed bug #76965 (INI_SCANNER_RAW doesn't strip trailing whitespace). (Pierrick)