Skip to content

High strength mixer using mcrypt #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions lib/RandomLib/AbstractMcryptMixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php
/**
* The Mcrypt abstract mixer class
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/

namespace RandomLib;

/**
* The mcrypt abstract mixer class
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
*/
abstract class AbstractMcryptMixer extends AbstractMixer {
/**
* mcrypt module resource
*
* @var resource
*/
private $mcrypt;

/**
* Block size of cipher
*
* @var int
*/
private $blockSize;

/**
* Cipher initialization vector
*
* @var string
*/
private $initv;

/**
* {@inheritdoc}
*/
public static function test() {
return extension_loaded('mcrypt');
}

/**
* Construct mcrypt mixer
*/
public function __construct() {
$this->mcrypt = mcrypt_module_open($this->getCipher(), '', MCRYPT_MODE_ECB, '');
$this->blockSize = mcrypt_enc_get_block_size($this->mcrypt);
$this->initv = str_repeat(chr(0), mcrypt_enc_get_iv_size($this->mcrypt));
}

/**
* Performs cleanup
*/
public function __destruct() {
if ($this->mcrypt) {
mcrypt_module_close($this->mcrypt);
}
}

/**
* Fetch the cipher for mcrypt.
*
* @return string
*/
abstract protected function getCipher();

/**
* {@inheritdoc}
*/
protected function getPartSize() {
return $this->blockSize;
}


/**
* {@inheritdoc}
*/
protected function mixParts1($part1, $part2) {
return $this->encryptBlock($part1, $part2);
}


/**
* {@inheritdoc}
*/
protected function mixParts2($part1, $part2) {
return $this->decryptBlock($part2, $part1);
}

/**
* Encrypts a block using the suppied key
*
* @param string $input Plaintext to encrypt
* @param string $key Encryption key
* @return string Resulting ciphertext
*/
private function encryptBlock($input, $key) {
if (!$input && !$key) {
return '';
}

$this->prepareCipher($key);
$result = mcrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);

return $result;
}

/**
* Derypts a block using the suppied key
*
* @param string $input Ciphertext to decrypt
* @param string $key Encryption key
* @return string Resulting plaintext
*/
private function decryptBlock($input, $key) {
if (!$input && !$key) {
return '';
}

$this->prepareCipher($key);
$result = mdecrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);

return $result;
}

/**
* Sets up the mcrypt module
*
* @param string $key
* @return void
*/
private function prepareCipher($key) {
if (0 !== mcrypt_generic_init($this->mcrypt, $key, $this->initv)) {
throw new \RuntimeException('Failed to prepare mcrypt module');
}
}
}
44 changes: 44 additions & 0 deletions lib/RandomLib/Mixer/McryptRijndael128.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/

namespace RandomLib\Mixer;

use RandomLib\AbstractMcryptMixer;
use SecurityLib\Strength;

/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
*/
class McryptRijndael128 extends AbstractMcryptMixer {
/**
* {@inheritdoc}
*/
public static function getStrength() {
return new Strength(Strength::HIGH);
}

/**
* {@inheritdoc}
*/
protected function getCipher() {
return 'rijndael-128';
}
}
54 changes: 54 additions & 0 deletions test/Unit/RandomLib/Mixer/McryptRijndael128Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace RandomLib\Mixer;

use SecurityLib\Strength;

class McryptRijndael128Test extends \PHPUnit_Framework_TestCase {

public static function provideMix() {
$data = array(
array(array(), ''),
array(array('', ''), ''),
array(array('a'), '61'),
array(array('a', 'b'), '6a'),
array(array('aa', 'ba'), '688d'),
array(array('ab', 'bb'), 'f8bc'),
array(array('aa', 'bb'), 'a0f3'),
array(array('aa', 'bb', 'cc'), '87c3'),
array(array('aabbcc', 'bbccdd', 'ccddee'), '7cf2273e46c7'),
);
return $data;
}

protected function setUp() {
if (!extension_loaded('mcrypt')) {
$this->markTestSkipped('mcrypt extension is not available');
}
}

public function testConstructWithoutArgument() {
$hash = new McryptRijndael128;
$this->assertTrue($hash instanceof \RandomLib\Mixer);
}

public function testGetStrength() {
$strength = new Strength(Strength::HIGH);
$actual = McryptRijndael128::getStrength();
$this->assertEquals($actual, $strength);
}

public function testTest() {
$actual = McryptRijndael128::test();
$this->assertTrue($actual);
}

/**
* @dataProvider provideMix
*/
public function testMix($parts, $result) {
$mixer = new McryptRijndael128;
$actual = $mixer->mix($parts);
$this->assertEquals($result, bin2hex($actual));
}
}