1<?php 2 3/* 4 * The RandomLib library for securely generating random numbers and strings in PHP 5 * 6 * @author Anthony Ferrara <ircmaxell@ircmaxell.com> 7 * @copyright 2011 The Authors 8 * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 * @version Build @@version@@ 10 */ 11 12/** 13 * The Mcrypt abstract mixer class 14 * 15 * PHP version 5.3 16 * 17 * @category PHPCryptLib 18 * @package Random 19 * @subpackage Mixer 20 * 21 * @author Anthony Ferrara <ircmaxell@ircmaxell.com> 22 * @copyright 2013 The Authors 23 * @license http://www.opensource.org/licenses/mit-license.html MIT License 24 * 25 * @version Build @@version@@ 26 */ 27namespace RandomLib; 28 29/** 30 * The mcrypt abstract mixer class 31 * 32 * @category PHPCryptLib 33 * @package Random 34 * @subpackage Mixer 35 * 36 * @author Anthony Ferrara <ircmaxell@ircmaxell.com> 37 * @author Chris Smith <chris@cs278.org> 38 */ 39abstract class AbstractMcryptMixer extends AbstractMixer 40{ 41 /** 42 * mcrypt module resource 43 * 44 * @var resource 45 */ 46 private $mcrypt; 47 48 /** 49 * Block size of cipher 50 * 51 * @var int 52 */ 53 private $blockSize; 54 55 /** 56 * Cipher initialization vector 57 * 58 * @var string 59 */ 60 private $initv; 61 62 /** 63 * {@inheritdoc} 64 */ 65 public static function test() 66 { 67 return extension_loaded('mcrypt'); 68 } 69 70 /** 71 * Construct mcrypt mixer 72 */ 73 public function __construct() 74 { 75 $this->mcrypt = mcrypt_module_open($this->getCipher(), '', MCRYPT_MODE_ECB, ''); 76 $this->blockSize = mcrypt_enc_get_block_size($this->mcrypt); 77 $this->initv = str_repeat(chr(0), mcrypt_enc_get_iv_size($this->mcrypt)); 78 } 79 80 /** 81 * Performs cleanup 82 */ 83 public function __destruct() 84 { 85 if ($this->mcrypt) { 86 mcrypt_module_close($this->mcrypt); 87 } 88 } 89 90 /** 91 * Fetch the cipher for mcrypt. 92 * 93 * @return string 94 */ 95 abstract protected function getCipher(); 96 97 /** 98 * {@inheritdoc} 99 */ 100 protected function getPartSize() 101 { 102 return $this->blockSize; 103 } 104 105 /** 106 * {@inheritdoc} 107 */ 108 protected function mixParts1($part1, $part2) 109 { 110 return $this->encryptBlock($part1, $part2); 111 } 112 113 /** 114 * {@inheritdoc} 115 */ 116 protected function mixParts2($part1, $part2) 117 { 118 return $this->decryptBlock($part2, $part1); 119 } 120 121 /** 122 * Encrypts a block using the suppied key 123 * 124 * @param string $input Plaintext to encrypt 125 * @param string $key Encryption key 126 * 127 * @return string Resulting ciphertext 128 */ 129 private function encryptBlock($input, $key) 130 { 131 if (!$input && !$key) { 132 return ''; 133 } 134 135 $this->prepareCipher($key); 136 $result = mcrypt_generic($this->mcrypt, $input); 137 mcrypt_generic_deinit($this->mcrypt); 138 139 return $result; 140 } 141 142 /** 143 * Derypts a block using the suppied key 144 * 145 * @param string $input Ciphertext to decrypt 146 * @param string $key Encryption key 147 * 148 * @return string Resulting plaintext 149 */ 150 private function decryptBlock($input, $key) 151 { 152 if (!$input && !$key) { 153 return ''; 154 } 155 156 $this->prepareCipher($key); 157 $result = mdecrypt_generic($this->mcrypt, $input); 158 mcrypt_generic_deinit($this->mcrypt); 159 160 return $result; 161 } 162 163 /** 164 * Sets up the mcrypt module 165 * 166 * @param string $key 167 * 168 * @return void 169 */ 170 private function prepareCipher($key) 171 { 172 if (0 !== mcrypt_generic_init($this->mcrypt, $key, $this->initv)) { 173 throw new \RuntimeException('Failed to prepare mcrypt module'); 174 } 175 } 176} 177