summaryrefslogtreecommitdiff
path: root/ext/mcrypt/mcrypt.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2014-03-01 23:51:03 +0100
committerNikita Popov <nikic@php.net>2014-03-05 15:32:32 +0100
commita861a3a93d89a50ce58e1ab1abef1eb501f97483 (patch)
tree88f2cff036668095d35e3491281406874a1c0fc8 /ext/mcrypt/mcrypt.c
parent25d801f97ec3f4bcac8977efd50f843eba9b19e1 (diff)
downloadphp-git-a861a3a93d89a50ce58e1ab1abef1eb501f97483.tar.gz
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.
Diffstat (limited to 'ext/mcrypt/mcrypt.c')
-rw-r--r--ext/mcrypt/mcrypt.c32
1 files changed, 13 insertions, 19 deletions
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);