summaryrefslogtreecommitdiffstats
path: root/system/libraries
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2014-02-06 04:01:48 +0100
committerAndrey Andreev <narf@devilix.net>2014-02-06 04:01:48 +0100
commite8088d693d6bd8b08c1cdc397bbdebd7067844a5 (patch)
treeb6722a2add4b1370e5eddc1324c5fd7ad36bfcc4 /system/libraries
parent7c5544817de29222aa2d79ac7445122d57ad62c6 (diff)
CI_Encryption: CAST-128/CAST5 and RC4/ARCFour compatibility
Diffstat (limited to 'system/libraries')
-rw-r--r--system/libraries/Encryption.php65
1 files changed, 50 insertions, 15 deletions
diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php
index f5950ee46..583ddac3b 100644
--- a/system/libraries/Encryption.php
+++ b/system/libraries/Encryption.php
@@ -367,11 +367,21 @@ class CI_Encryption {
}
elseif ( ! isset($params['iv']))
{
- $params['iv'] = ($iv_size = mcrypt_enc_get_iv_size($params['handle']))
+ // The greater-than-1 comparison is mostly a work-around for a bug,
+ // where 1 is returned for ARCFour instead of 0.
+ $params['iv'] = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM)
: NULL;
}
+ // CAST-128 compatibility (http://tools.ietf.org/rfc/rfc2144.txt)
+ //
+ // RFC2144 says that keys shorter than 16 bytes are to be padded with
+ // zero bytes to 16 bytes, but (surprise) MCrypt doesn't do that.
+ if ($params['cipher'] === 'cast-128' && ($kl = strlen($params['key'])) < 16)
+ {
+ $params['key'] .= str_repeat("\x0", 16 - $kl);
+ }
if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0)
{
@@ -541,7 +551,9 @@ class CI_Encryption {
}
elseif ( ! isset($params['iv']))
{
- if ($iv_size = mcrypt_enc_get_iv_size($params['handle']))
+ // The greater-than-1 comparison is mostly a work-around for a bug,
+ // where 1 is returned for ARCFour instead of 0.
+ if (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
{
if (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB')
{
@@ -560,6 +572,15 @@ class CI_Encryption {
}
}
+ // CAST-128 compatibility (http://tools.ietf.org/rfc/rfc2144.txt)
+ //
+ // RFC2144 says that keys shorter than 16 bytes are to be padded with
+ // zero bytes to 16 bytes, but (surprise) MCrypt doesn't do that.
+ if ($params['cipher'] === 'cast-128' && ($kl = strlen($params['key'])) < 16)
+ {
+ $params['key'] .= str_repeat("\x0", 16 - $kl);
+ }
+
if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0)
{
if ($params['handle'] !== $this->_handle)
@@ -760,35 +781,49 @@ class CI_Encryption {
'aes-256' => 'rijndael-128',
'des3-ede3' => 'tripledes',
'bf' => 'blowfish',
+ 'cast5' => 'cast-128',
+ 'rc4' => 'arcfour',
+ 'rc4-40' => 'arcfour'
),
'openssl' => array(
'rijndael-128' => 'aes-128',
'tripledes' => 'des-ede3',
- 'blowfish' => 'bf'
+ 'blowfish' => 'bf',
+ 'cast-128' => 'cast5',
+ 'arcfour' => 'rc4-40',
+ 'rc4' => 'rc4-40'
)
);
// Notes:
//
+ // - Rijndael-128 is, at the same time all three of AES-128,
+ // AES-192 and AES-256. The only difference between them is
+ // the key size. Rijndael-192, Rijndael-256 on the other hand
+ // also have different block sizes and are NOT AES-compatible.
+ //
// - Blowfish is said to be supporting key sizes between
// 4 and 56 bytes, but it appears that between MCrypt and
// OpenSSL, only those of 16 and more bytes are compatible.
+ // Also, don't know what MCrypt's 'blowfish-compat' is.
//
- // Other seemingly matching ciphers between MCrypt, OpenSSL:
+ // - CAST-128/CAST5 produces a longer cipher when encrypted via
+ // OpenSSL, but (strangely enough) can be decrypted by either
+ // extension anyway.
+ // Also, RFC2144 says that the cipher supports key sizes
+ // between 5 and 16 bytes by the implementation actually
+ // zero-padding them to 16 bytes, but MCrypt doesn't do that.
//
- // - DES is compatible, but doesn't need an alias
- // - CAST-128/CAST5 is NOT compatible
- // mcrypt: 'cast-128'
- // openssl: 'cast5'
- // - RC2 is NOT compatible
- // mcrypt: 'rc2'
- // openssl: 'rc2', 'rc2-40', 'rc2-64'
+ // - RC4 (ARCFour) has a strange implementation under OpenSSL.
+ // Its 'rc4-40' cipher method seems to work flawlessly, yet
+ // there's another one, 'rc4' that only works with a 16-byte key.
//
- // To avoid any other confusion due to a popular (but incorrect)
- // belief, it should also be noted that Rijndael-192/256 are NOT
- // the same ciphers as AES-192/256 like Rijndael-128 and AES-256 is.
+ // - DES is compatible, but doesn't need an alias.
+ //
+ // Other seemingly matching ciphers between MCrypt, OpenSSL:
//
- // All compatibility tests were done in CBC mode.
+ // - RC2 is NOT compatible and only an obscure forum post
+ // confirms that it is MCrypt's fault.
}
if (isset($dictionary[$this->_driver][$cipher]))