2013-01-03 16:47:40 +00:00
< ? php
/**
2014-02-15 18:57:49 +00:00
* @ author Andreas Fischer < bantu @ phpbb . com >
2014-12-09 23:02:44 +00:00
* @ copyright 2013 Andreas Fischer
2014-02-15 18:57:49 +00:00
* @ license http :// www . opensource . org / licenses / mit - license . html MIT License
2013-01-03 16:47:40 +00:00
*/
2014-08-14 15:47:26 +00:00
require_once 'Crypt/AES.php' ;
abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
2013-01-03 16:47:40 +00:00
{
2014-11-29 13:39:21 +00:00
protected $engine ;
2014-10-15 22:59:48 +00:00
2014-12-13 19:47:37 +00:00
private function _checkEngine ( $aes )
2014-02-15 18:57:49 +00:00
{
2014-11-29 13:39:21 +00:00
if ( $aes -> getEngine () != $this -> engine ) {
$engine = 'internal' ;
switch ( $this -> engine ) {
2014-12-13 20:42:58 +00:00
case CRYPT_ENGINE_OPENSSL :
2014-11-29 13:39:21 +00:00
$engine = 'OpenSSL' ;
break ;
2014-12-13 20:42:58 +00:00
case CRYPT_ENGINE_MCRYPT :
2014-11-29 13:39:21 +00:00
$engine = 'mcrypt' ;
}
self :: markTestSkipped ( 'Unable to initialize ' . $engine . ' engine' );
}
2014-08-14 15:03:01 +00:00
}
/**
* Produces all combinations of test values .
*
* @ return array
*/
public function continuousBufferCombos ()
{
$modes = array (
'CRYPT_AES_MODE_CTR' ,
'CRYPT_AES_MODE_OFB' ,
'CRYPT_AES_MODE_CFB' ,
);
$plaintexts = array (
'' ,
'12345678901234567' , // https://github.com/phpseclib/phpseclib/issues/39
" \xDE \xAD \xBE \xAF " ,
':-):-):-):-):-):-)' , // https://github.com/phpseclib/phpseclib/pull/43
);
$ivs = array (
'' ,
'test123' ,
);
$keys = array (
'' ,
':-8' , // https://github.com/phpseclib/phpseclib/pull/43
'FOOBARZ' ,
);
$result = array ();
// @codingStandardsIgnoreStart
2014-08-14 15:59:37 +00:00
foreach ( $modes as $mode )
foreach ( $plaintexts as $plaintext )
foreach ( $ivs as $iv )
foreach ( $keys as $key )
2014-08-14 15:03:01 +00:00
$result [] = array ( $mode , $plaintext , $iv , $key );
// @codingStandardsIgnoreEnd
return $result ;
2014-02-15 18:57:49 +00:00
}
2013-01-03 16:47:40 +00:00
2014-08-14 15:03:01 +00:00
/**
* @ dataProvider continuousBufferCombos
*/
public function testEncryptDecryptWithContinuousBuffer ( $mode , $plaintext , $iv , $key )
2014-02-15 18:57:49 +00:00
{
2014-08-14 15:03:01 +00:00
$aes = new Crypt_AES ( constant ( $mode ));
2014-11-29 13:39:21 +00:00
$aes -> setPreferredEngine ( $this -> engine );
2014-08-14 15:03:01 +00:00
$aes -> enableContinuousBuffer ();
$aes -> setIV ( $iv );
$aes -> setKey ( $key );
2014-12-13 19:47:37 +00:00
$this -> _checkEngine ( $aes );
2014-11-29 13:39:21 +00:00
2014-08-14 15:03:01 +00:00
$actual = '' ;
for ( $i = 0 , $strlen = strlen ( $plaintext ); $i < $strlen ; ++ $i ) {
$actual .= $aes -> decrypt ( $aes -> encrypt ( $plaintext [ $i ]));
2014-02-15 18:57:49 +00:00
}
2014-08-14 15:03:01 +00:00
$this -> assertEquals ( $plaintext , $actual );
}
2014-08-14 15:06:25 +00:00
/**
* @ group github451
*/
2014-08-14 15:03:01 +00:00
public function testKeyPaddingRijndael ()
{
// this test case is from the following URL:
// https://web.archive.org/web/20070209120224/http://fp.gladman.plus.com/cryptography_technology/rijndael/aesdvec.zip
$aes = new Crypt_Rijndael ();
2014-11-29 13:39:21 +00:00
$aes -> setPreferredEngine ( $this -> engine );
2014-08-14 15:03:01 +00:00
$aes -> disablePadding ();
$aes -> setKey ( pack ( 'H*' , '2b7e151628aed2a6abf7158809cf4f3c762e7160' )); // 160-bit key. Valid in Rijndael.
2014-12-13 19:47:37 +00:00
//$this->_checkEngine($aes); // should only work in internal mode
2014-08-14 15:03:01 +00:00
$ciphertext = $aes -> encrypt ( pack ( 'H*' , '3243f6a8885a308d313198a2e0370734' ));
$this -> assertEquals ( $ciphertext , pack ( 'H*' , '231d844639b31b412211cfe93712b880' ));
}
2014-08-14 15:06:25 +00:00
/**
* @ group github451
*/
2014-08-14 15:03:01 +00:00
public function testKeyPaddingAES ()
{
// same as the above - just with a different ciphertext
$aes = new Crypt_AES ();
2014-11-29 13:39:21 +00:00
$aes -> setPreferredEngine ( $this -> engine );
2014-08-14 15:03:01 +00:00
$aes -> disablePadding ();
$aes -> setKey ( pack ( 'H*' , '2b7e151628aed2a6abf7158809cf4f3c762e7160' )); // 160-bit key. AES should null pad to 192-bits
2014-12-13 19:47:37 +00:00
$this -> _checkEngine ( $aes );
2014-08-14 15:03:01 +00:00
$ciphertext = $aes -> encrypt ( pack ( 'H*' , '3243f6a8885a308d313198a2e0370734' ));
$this -> assertEquals ( $ciphertext , pack ( 'H*' , 'c109292b173f841b88e0ee49f13db8c0' ));
2014-02-15 18:57:49 +00:00
}
2014-11-29 13:39:21 +00:00
/**
* Produces all combinations of test values .
*
* @ return array
*/
public function continuousBufferBatteryCombos ()
{
$modes = array (
'CRYPT_MODE_CTR' ,
'CRYPT_MODE_OFB' ,
'CRYPT_MODE_CFB' ,
);
$combos = array (
2014-12-20 17:14:08 +00:00
array ( 16 ),
array ( 17 ),
array ( 1 , 16 ),
array ( 3 , 6 , 7 ), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation)
2014-11-29 13:39:21 +00:00
array ( 15 , 4 ), // (15 to test openssl_encrypt call and buffer creation and 4 to test something that spans multpile bloc
array ( 3 , 6 , 10 , 16 ), // this is why the strlen check in the buffer-only code was needed
array ( 16 , 16 ), // two full size blocks
array ( 3 , 6 , 7 , 16 ), // partial block + full size block
array ( 16 , 3 , 6 , 7 ),
// a few others just for fun
array ( 32 , 32 ),
array ( 31 , 31 ),
array ( 17 , 17 ),
array ( 99 , 99 )
);
$result = array ();
// @codingStandardsIgnoreStart
foreach ( $modes as $mode )
foreach ( $combos as $combo )
foreach ( array ( 'encrypt' , 'decrypt' ) as $op )
$result [] = array ( $op , $mode , $combo );
// @codingStandardsIgnoreEnd
return $result ;
}
/**
* @ dataProvider continuousBufferBatteryCombos
*/
public function testContinuousBufferBattery ( $op , $mode , $test )
{
$iv = str_repeat ( 'x' , 16 );
$key = str_repeat ( 'a' , 16 );
$aes = new Crypt_AES ( constant ( $mode ));
$aes -> setPreferredEngine ( $this -> engine );
$aes -> setKey ( $key );
$aes -> setIV ( $iv );
2014-12-13 19:47:37 +00:00
$this -> _checkEngine ( $aes );
2014-11-29 13:39:21 +00:00
$str = '' ;
$result = '' ;
foreach ( $test as $len ) {
$temp = str_repeat ( 'd' , $len );
$str .= $temp ;
}
$c1 = $aes -> $op ( $str );
$aes = new Crypt_AES ( constant ( $mode ));
$aes -> setPreferredEngine ( $this -> engine );
$aes -> enableContinuousBuffer ();
$aes -> setKey ( $key );
$aes -> setIV ( $iv );
2014-12-13 19:47:37 +00:00
$this -> _checkEngine ( $aes );
2014-11-29 13:39:21 +00:00
foreach ( $test as $len ) {
$temp = str_repeat ( 'd' , $len );
$output = $aes -> $op ( $temp );
$result .= $output ;
}
$c2 = $result ;
2015-01-01 05:02:22 +00:00
$this -> assertSame ( bin2hex ( $c1 ), bin2hex ( $c2 ));
2014-11-29 13:39:21 +00:00
}
2014-12-31 21:00:54 +00:00
/**
* @ dataProvider continuousBufferBatteryCombos
*/
// pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled
public function testNonContinuousBufferBattery ( $op , $mode , $test )
{
2014-12-31 21:15:15 +00:00
if ( count ( $test ) == 1 ) {
return ;
}
2014-12-31 21:00:54 +00:00
$iv = str_repeat ( 'x' , 16 );
$key = str_repeat ( 'a' , 16 );
$aes = new Crypt_AES ( constant ( $mode ));
$aes -> setPreferredEngine ( $this -> engine );
$aes -> setKey ( $key );
$aes -> setIV ( $iv );
$this -> _checkEngine ( $aes );
$str = '' ;
$result = '' ;
foreach ( $test as $len ) {
$temp = str_repeat ( 'd' , $len );
$str .= $temp ;
}
$c1 = $aes -> $op ( $str );
$aes = new Crypt_AES ( constant ( $mode ));
$aes -> setPreferredEngine ( $this -> engine );
$aes -> setKey ( $key );
$aes -> setIV ( $iv );
$this -> _checkEngine ( $aes );
foreach ( $test as $len ) {
$temp = str_repeat ( 'd' , $len );
$output = $aes -> $op ( $temp );
$result .= $output ;
}
$c2 = $result ;
2015-01-01 05:02:22 +00:00
$this -> assertNotSame ( bin2hex ( $c1 ), bin2hex ( $c2 ));
2014-12-31 21:00:54 +00:00
}
2015-01-02 05:56:01 +00:00
// from http://csrc.nist.gov/groups/STM/cavp/documents/aes/AESAVS.pdf#page=16
public function testGFSBox128 ()
{
$aes = new Crypt_AES ();
$aes -> setKey ( pack ( 'H*' , '00000000000000000000000000000000' ));
$aes -> setIV ( pack ( 'H*' , '00000000000000000000000000000000' ));
$aes -> setPreferredEngine ( $this -> engine );
$this -> _checkEngine ( $aes );
2015-01-08 03:14:02 +00:00
$result = bin2hex ( $aes -> encrypt ( 'f34481ec3cc627bacd5dc3fb08f273e6' ));
2015-01-02 05:56:01 +00:00
$this -> assertSame ( $result , '0336763e966d92595a567cc9ce537f5e' );
$result = $aes -> encrypt ( '9798c4640bad75c7c3227db910174e72' );
$this -> assertSame ( $result , 'a9a1631bf4996954ebc093957b234589' );
$result = $aes -> encrypt ( '96ab5c2ff612d9dfaae8c31f30c42168' );
$this -> assertSame ( $result , 'ff4f8391a6a40ca5b25d23bedd44a597' );
$result = $aes -> encrypt ( '6a118a874519e64e9963798a503f1d35' );
$this -> assertSame ( $result , 'dc43be40be0e53712f7e2bf5ca707209' );
$result = $aes -> encrypt ( 'cb9fceec81286ca3e989bd979b0cb284' );
$this -> assertSame ( $result , '92beedab1895a94faa69b632e5cc47ce' );
$result = $aes -> encrypt ( 'b26aeb1874e47ca8358ff22378f09144' );
$this -> assertSame ( $result , '459264f4798f6a78bacb89c15ed3d601' );
$result = $aes -> encrypt ( '58c8e00b2631686d54eab84b91f0aca1' );
$this -> assertSame ( $result , '08a4e2efec8a8e3312ca7460b9040bbf' );
}
public function testGFSBox192 ()
{
$aes = new Crypt_AES ();
$aes -> setKey ( pack ( 'H*' , '000000000000000000000000000000000000000000000000' ));
$aes -> setIV ( pack ( 'H*' , '00000000000000000000000000000000' ));
$aes -> setPreferredEngine ( $this -> engine );
$this -> _checkEngine ( $aes );
2015-01-08 03:14:02 +00:00
$result = bin2hex ( $aes -> encrypt ( '1b077a6af4b7f98229de786d7516b639' ));
2015-01-02 05:56:01 +00:00
$this -> assertSame ( $result , '275cfc0413d8ccb70513c3859b1d0f72' );
$result = $aes -> encrypt ( '9c2d8842e5f48f57648205d39a239af1' );
$this -> assertSame ( $result , 'c9b8135ff1b5adc413dfd053b21bd96d' );
$result = $aes -> encrypt ( 'bff52510095f518ecca60af4205444bb' );
$this -> assertSame ( $result , '4a3650c3371ce2eb35e389a171427440' );
$result = $aes -> encrypt ( '51719783d3185a535bd75adc65071ce1' );
$this -> assertSame ( $result , '4f354592ff7c8847d2d0870ca9481b7c' );
$result = $aes -> encrypt ( '26aa49dcfe7629a8901a69a9914e6dfd' );
$this -> assertSame ( $result , 'd5e08bf9a182e857cf40b3a36ee248cc' );
$result = $aes -> encrypt ( '941a4773058224e1ef66d10e0a6ee782' );
$this -> assertSame ( $result , '067cd9d3749207791841562507fa9626' );
}
public function testGFSBox256 ()
{
$aes = new Crypt_AES ();
$aes -> setKey ( pack ( 'H*' , '00000000000000000000000000000000' . '00000000000000000000000000000000' ));
$aes -> setIV ( pack ( 'H*' , '00000000000000000000000000000000' ));
$aes -> setPreferredEngine ( $this -> engine );
$this -> _checkEngine ( $aes );
2015-01-08 03:14:02 +00:00
$result = bin2hex ( $aes -> encrypt ( '014730f80ac625fe84f026c60bfd547d' ));
2015-01-02 05:56:01 +00:00
$this -> assertSame ( $result , '5c9d844ed46f9885085e5d6a4f94c7d7' );
$result = $aes -> encrypt ( '0b24af36193ce4665f2825d7b4749c98' );
$this -> assertSame ( $result , 'a9ff75bd7cf6613d3731c77c3b6d0c04' );
$result = $aes -> encrypt ( '761c1fe41a18acf20d241650611d90f1' );
$this -> assertSame ( $result , '623a52fcea5d443e48d9181ab32c7421' );
$result = $aes -> encrypt ( '8a560769d605868ad80d819bdba03771' );
$this -> assertSame ( $result , '38f2c7ae10612415d27ca190d27da8b4' );
$result = $aes -> encrypt ( '91fbef2d15a97816060bee1feaa49afe' );
$this -> assertSame ( $result , '1bc704f1bce135ceb810341b216d7abe' );
}
2014-12-13 19:47:37 +00:00
}