From a861a3a93d89a50ce58e1ab1abef1eb501f97483 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 1 Mar 2014 23:51:03 +0100 Subject: Abort on invalid key size Previously an incorrectly sized key was either silently padded with NUL bytes or truncated. Especially the silent nature of this behavior makes it extremely easy to use weak encryption. A common mistake - which has also been extensively made in our tests - is to use a password instead of a key. Incorrectly sized keys will now be rejected. --- ext/mcrypt/mcrypt.c | 32 +++++------- ext/mcrypt/tests/bug46010.phpt | 13 ++--- ext/mcrypt/tests/mcrypt_cbc.phpt | 3 +- ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt | 18 ++++--- ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt | 18 ++++--- ext/mcrypt/tests/mcrypt_cbc_variation2.phpt | 60 ++++++++++++++-------- ext/mcrypt/tests/mcrypt_cbc_variation3.phpt | 2 +- ext/mcrypt/tests/mcrypt_cbc_variation4.phpt | 2 +- ext/mcrypt/tests/mcrypt_cbc_variation5.phpt | 2 +- ext/mcrypt/tests/mcrypt_cfb.phpt | 2 +- ext/mcrypt/tests/mcrypt_decrypt.phpt | 2 +- ext/mcrypt/tests/mcrypt_decrypt_3des_cbc.phpt | 18 ++++--- ext/mcrypt/tests/mcrypt_decrypt_3des_ecb.phpt | 22 ++++---- ext/mcrypt/tests/mcrypt_decrypt_variation2.phpt | 60 ++++++++++++++-------- ext/mcrypt/tests/mcrypt_decrypt_variation3.phpt | 2 +- ext/mcrypt/tests/mcrypt_decrypt_variation5.phpt | 2 +- ext/mcrypt/tests/mcrypt_ecb.phpt | 2 +- ext/mcrypt/tests/mcrypt_ecb_3des_decrypt.phpt | 20 +++++--- ext/mcrypt/tests/mcrypt_ecb_3des_encrypt.phpt | 14 +++-- ext/mcrypt/tests/mcrypt_ecb_variation2.phpt | 60 ++++++++++++++-------- ext/mcrypt/tests/mcrypt_ecb_variation3.phpt | 2 +- ext/mcrypt/tests/mcrypt_ecb_variation4.phpt | 2 +- ext/mcrypt/tests/mcrypt_ecb_variation5.phpt | 2 +- ext/mcrypt/tests/mcrypt_encrypt_3des_cbc.phpt | 16 +++--- ext/mcrypt/tests/mcrypt_encrypt_3des_ecb.phpt | 20 +++++--- ext/mcrypt/tests/mcrypt_encrypt_variation2.phpt | 60 ++++++++++++++-------- ext/mcrypt/tests/mcrypt_encrypt_variation3.phpt | 2 +- ext/mcrypt/tests/mcrypt_encrypt_variation5.phpt | 2 +- ext/mcrypt/tests/mcrypt_ofb.phpt | 2 +- ext/mcrypt/tests/mcrypt_rijndael128_128BitKey.phpt | 26 +++++++--- ext/mcrypt/tests/mcrypt_rijndael128_256BitKey.phpt | 28 ++++++---- 31 files changed, 322 insertions(+), 194 deletions(-) (limited to 'ext') diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c index 889dce397f..d3dc5c2040 100644 --- a/ext/mcrypt/mcrypt.c +++ b/ext/mcrypt/mcrypt.c @@ -1169,7 +1169,7 @@ static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, cons { char *cipher_dir_string; char *module_dir_string; - int block_size, max_key_length, use_key_length, i, count, iv_size; + int block_size, use_key_length, i, count, iv_size; unsigned long int data_size; int *key_length_sizes; char *key_s = NULL, *iv_s; @@ -1184,33 +1184,27 @@ static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, cons RETURN_FALSE; } /* Checking for key-length */ - max_key_length = mcrypt_enc_get_key_size(td); - if (key_len > max_key_length) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size of key is too large for this algorithm"); - } key_length_sizes = mcrypt_enc_get_supported_key_sizes(td, &count); if (count == 0 && key_length_sizes == NULL) { /* all lengths 1 - k_l_s = OK */ use_key_length = key_len; key_s = emalloc(use_key_length); memset(key_s, 0, use_key_length); memcpy(key_s, key, use_key_length); - } else if (count == 1) { /* only m_k_l = OK */ - key_s = emalloc(key_length_sizes[0]); - memset(key_s, 0, key_length_sizes[0]); - memcpy(key_s, key, MIN(key_len, key_length_sizes[0])); - use_key_length = key_length_sizes[0]; - } else { /* dertermine smallest supported key > length of requested key */ - use_key_length = max_key_length; /* start with max key length */ + } else { for (i = 0; i < count; i++) { - if (key_length_sizes[i] >= key_len && - key_length_sizes[i] < use_key_length) - { - use_key_length = key_length_sizes[i]; + if (key_length_sizes[i] == key_len) { + use_key_length = key_len; + key_s = emalloc(use_key_length); + memcpy(key_s, key, use_key_length); + break; } } - key_s = emalloc(use_key_length); - memset(key_s, 0, use_key_length); - memcpy(key_s, key, MIN(key_len, use_key_length)); + + if (!key_s) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key of length %d not supported by this algorithm", key_len); + mcrypt_free(key_length_sizes); + RETURN_FALSE; + } } mcrypt_free (key_length_sizes); diff --git a/ext/mcrypt/tests/bug46010.phpt b/ext/mcrypt/tests/bug46010.phpt index ddb691e362..1f0fe40a3d 100644 --- a/ext/mcrypt/tests/bug46010.phpt +++ b/ext/mcrypt/tests/bug46010.phpt @@ -5,12 +5,13 @@ Bug #46010 (warnings incorrectly generated for iv in ecb mode) --FILE-- --EXPECTF-- -string(16) "372eeb4a524b8d31" -string(16) "372eeb4a524b8d31" -string(16) "372eeb4a524b8d31" +string(16) "f7a2ce11d4002294" +string(16) "f7a2ce11d4002294" +string(16) "f7a2ce11d4002294" diff --git a/ext/mcrypt/tests/mcrypt_cbc.phpt b/ext/mcrypt/tests/mcrypt_cbc.phpt index fb74df9322..cf723e3803 100644 --- a/ext/mcrypt/tests/mcrypt_cbc.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc.phpt @@ -4,7 +4,7 @@ mcrypt_cbc --FILE-- --EXPECTF-- Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d diff --git a/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt b/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt index f65123bc42..775c153643 100644 --- a/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt @@ -21,7 +21,7 @@ $cipher = MCRYPT_TRIPLEDES; $data = b"This is the secret message which must be encrypted"; $mode = MCRYPT_DECRYPT; -// tripledes uses keys upto 192 bits (24 bytes) +// tripledes uses keys with exactly 192 bits (24 bytes) $keys = array( b'12345678', b'12345678901234567890', @@ -54,7 +54,7 @@ for ($i = 0; $i < sizeof($keys); $i++) { special_var_dump(mcrypt_cbc($cipher, $keys[$i], base64_decode($data1[$i]), $mode, $iv)); } -$key = b'1234567890123456'; +$key = b'123456789012345678901234'; echo "\n--- testing different iv lengths\n"; for ($i = 0; $i < sizeof($ivs); $i++) { echo "\niv length=".strlen($ivs[$i])."\n"; @@ -74,12 +74,16 @@ function special_var_dump($str) { key length=8 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -string(32) "736563726574206d6573736167650000" + +Warning: mcrypt_cbc(): Key of length 8 not supported by this algorithm in %s on line %d +string(0) "" key length=20 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -string(32) "736563726574206d6573736167650000" + +Warning: mcrypt_cbc(): Key of length 20 not supported by this algorithm in %s on line %d +string(0) "" key length=24 @@ -90,8 +94,8 @@ key length=26 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -Warning: mcrypt_cbc(): Size of key is too large for this algorithm in %s on line %d -string(32) "736563726574206d6573736167650000" +Warning: mcrypt_cbc(): Key of length 26 not supported by this algorithm in %s on line %d +string(0) "" --- testing different iv lengths @@ -105,7 +109,7 @@ string(0) "" iv length=8 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -string(32) "736563726574206d6573736167650000" +string(32) "659ec947f4dc3a3b9c50de744598d3c8" iv length=9 diff --git a/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt b/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt index 962d4091a2..2e8dd5fd50 100644 --- a/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt @@ -21,7 +21,7 @@ $cipher = MCRYPT_TRIPLEDES; $data = b"This is the secret message which must be encrypted"; $mode = MCRYPT_ENCRYPT; -// tripledes uses keys upto 192 bits (24 bytes) +// tripledes uses keys with exactly 192 bits (24 bytes) $keys = array( b'12345678', b'12345678901234567890', @@ -41,7 +41,7 @@ foreach ($keys as $key) { var_dump(bin2hex(mcrypt_cbc($cipher, $key, $data, $mode, $iv))); } -$key = b'1234567890123456'; +$key = b'123456789012345678901234'; echo "\n--- testing different iv lengths\n"; foreach ($ivs as $iv) { echo "\niv length=".strlen($iv)."\n"; @@ -57,12 +57,16 @@ foreach ($ivs as $iv) { key length=8 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -string(112) "082b437d039d09418e20dc9de1dafa7ed6da5c6335b78950968441da1faf40c1f886e04da8ca177b80b376811e138c1bf51cb48dae2e7939" + +Warning: mcrypt_cbc(): Key of length 8 not supported by this algorithm in %s on line %d +string(0) "" key length=20 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -string(112) "0627351e0f8a082bf7981ae2c700a43fd3d44b270ac67b00fded1c5796eea935be0fef2a23da0b3f5e243929e62ac957bf0bf463aa90fc4f" + +Warning: mcrypt_cbc(): Key of length 20 not supported by this algorithm in %s on line %d +string(0) "" key length=24 @@ -73,8 +77,8 @@ key length=26 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -Warning: mcrypt_cbc(): Size of key is too large for this algorithm in %s on line %d -string(112) "b85e21072239d60c63a80e7c9ae493cb741a1cd407e52f451c5f43a0d103f55a7b62617eb2e44213c2d44462d388bc0b8f119384b12c84ac" +Warning: mcrypt_cbc(): Key of length 26 not supported by this algorithm in %s on line %d +string(0) "" --- testing different iv lengths @@ -88,7 +92,7 @@ string(0) "" iv length=8 Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d -string(112) "bac347506bf092c5557c4363c301745d78f047028e2953e84fd66b30aeb6005812dadbe8baa871b83278341599b0c448ddaaa52b5a378ce5" +string(112) "b85e21072239d60c63a80e7c9ae493cb741a1cd407e52f451c5f43a0d103f55a7b62617eb2e44213c2d44462d388bc0b8f119384b12c84ac" iv length=9 diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt index 3d2a061472..6a1624127b 100644 --- a/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt @@ -125,39 +125,48 @@ fclose($fp); --int 0-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "bc27b3a4e33b531d5983fc7df693cd09" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --int 1-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "bc27b3a4e33b531d5983fc7df693cd09" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --int 12345-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "d109b7973383127002474ae731c4b3a8" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --int -12345-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "3e82a931cedb03a38b91a637ff8c9f9e" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --float 10.5-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "de71833586c1d7132a289960ebeeca7a" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --float -10.5-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "7d0489dd2e99ae910ecc015573f3dd16" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --float 12.3456789000e10-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "978055b42c0506a8947e3c3c8d994baf" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --float -12.3456789000e10-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "4aa84ba400c2b8ef467d4d98372b4f4e" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --float .5-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "e731dc5059b84e0c8774ac490f77d6e6" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --empty array-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) @@ -181,39 +190,48 @@ string(0) "" --uppercase NULL-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --lowercase null-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --lowercase true-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "bc27b3a4e33b531d5983fc7df693cd09" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --lowercase false-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --uppercase TRUE-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "bc27b3a4e33b531d5983fc7df693cd09" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --uppercase FALSE-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --empty string DQ-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --empty string SQ-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --instance of classWithToString-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "19420fa26f561ee82ed84abbcd2d284b" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --instance of classWithoutToString-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) @@ -222,11 +240,13 @@ string(0) "" --undefined var-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --unset var-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) -string(32) "be722a5ffc361d721fbcab1eacc6acf5" +Error: 2 - mcrypt_cbc(): Key of length %d not supported by this algorithm, %s(%d) +string(0) "" --resource-- Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d) diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt index 9a1464b112..f9098a4221 100644 --- a/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt @@ -27,7 +27,7 @@ set_error_handler('test_error_handler'); // Initialise function arguments not being substituted (if any) $cipher = MCRYPT_TRIPLEDES; -$key = b'string_val'; +$key = b"string_val\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; $mode = MCRYPT_ENCRYPT; $iv = b'01234567'; diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt index a3dd29ba41..a13e4ffb7c 100644 --- a/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt @@ -27,7 +27,7 @@ set_error_handler('test_error_handler'); // Initialise function arguments not being substituted (if any) $cipher = MCRYPT_TRIPLEDES; -$key = b'string_val'; +$key = b"string_val\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; $data = b'string_val'; $iv = b'01234567'; diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt index d3a6d9c12d..24d518d096 100644 --- a/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt +++ b/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt @@ -27,7 +27,7 @@ set_error_handler('test_error_handler'); // Initialise function arguments not being substituted (if any) $cipher = MCRYPT_TRIPLEDES; -$key = b'string_val'; +$key = b"string_val\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; $data = b'string_val'; $mode = MCRYPT_ENCRYPT; diff --git a/ext/mcrypt/tests/mcrypt_cfb.phpt b/ext/mcrypt/tests/mcrypt_cfb.phpt index 1c7b9c12ff..a82ea46d11 100644 --- a/ext/mcrypt/tests/mcrypt_cfb.phpt +++ b/ext/mcrypt/tests/mcrypt_cfb.phpt @@ -4,7 +4,7 @@ mcrypt_cfb --FILE-- --FILE-- --FILE-- --FILE--