From b95490c1657756d53f80002b59971b925d099ab5 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 25 Dec 2022 21:12:23 -0500 Subject: [PATCH] enc use wipe to fallback to unset if sodium not installed. Fixed size name issues with vars be called bit when their bytes. --- src/classes/services/encryption.php | 70 +++++++++++++++-------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/classes/services/encryption.php b/src/classes/services/encryption.php index 3b0a97a..6beab48 100644 --- a/src/classes/services/encryption.php +++ b/src/classes/services/encryption.php @@ -19,14 +19,14 @@ final class encryption { const iterations = 81952; // should be over 80K. The number of internal iterations to perform for the derivation. const length = 64; // The length of the output string. If raw_output is TRUE this corresponds to the byte-length of the derived key, if raw_output is FALSE this corresponds to twice the byte-length of the derived key (as every byte of the key is returned as two hexits). const raw = true; // When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits. - const key_bits = 32; // 256 bit encryption key + const key_bytes = 32; // 32 bytes = 256 bits, 64 bytes = 512 bits, 16 bytes = 128 bits encryption key private $random_engine; private $binary = false; private $url_encode = false; private $method = 'AES-256-CBC'; private $default_hash = 'sha256'; // should be sha256 or higher - private $_iterations = self::iterations, $_length=self::length, $_raw=self::raw, $_key_bits=self::key_bits; + private $_iterations = self::iterations, $_length=self::length, $_raw=self::raw, $_key_bytes=self::key_bytes; public function __construct() { $this->random_engine = new \tts\random_engine(); @@ -65,38 +65,38 @@ final class encryption { * like encrypted sessions. Where as, good, normal, * and paranoid are for cookies, DB storage, etc... */ - case 'lighting': // 0.0001 Seconds - $this->set_loops(3); // Very very fast + case 'lighting': // 0.0006 Seconds + $this->set_loops(98); // Very very fast $this->set_length(64); - $this->set_key_bits(16); + $this->set_key_bytes(16); $this->method = 'AES-128-CBC'; $this->default_hash = 'sha256'; return true; case 'blaze': // 0.0109 Seconds $this->set_loops(1843); $this->set_length(64); - $this->set_key_bits(32); + $this->set_key_bytes(32); $this->method = 'AES-128-CBC'; $this->default_hash = 'sha256'; return true; case 'quick': // 0.0167 Seconds $this->set_loops(2843); $this->set_length(64); - $this->set_key_bits(32); + $this->set_key_bytes(32); $this->method = 'AES-192-CBC'; $this->default_hash = 'sha256'; return true; case 'good': // 0.0732 Seconds $this->set_loops(11952); $this->set_length(64); - $this->set_key_bits(32); + $this->set_key_bytes(32); // 32B or 256b, standard key size $this->method = 'AES-256-CBC'; $this->default_hash = 'sha256'; return true; case 'normal': // 0.4901 Seconds $this->set_loops(81952); // slow $this->set_length(64); - $this->set_key_bits(32); + $this->set_key_bytes(32); $this->method = 'AES-256-CBC'; $this->default_hash = 'sha256'; return true; @@ -105,8 +105,8 @@ final class encryption { case 'high': case 'slow-secure': // Very slow $this->set_loops(82952); - $this->set_length(128); - $this->set_key_bits(64); + $this->set_length(128); // extended length to make it work + $this->set_key_bytes(64); // extended key size for 512 hash $this->method = 'AES-256-CBC'; $this->default_hash = 'sha512'; return true; @@ -126,8 +126,8 @@ final class encryption { $this->_raw = $output_raw; } - public function set_key_bits(int $key_bits=self::key_bits): void { - $this->_key_bits = $key_bits; + public function set_key_bytes(int $key_bytes=self::key_bytes): void { + $this->_key_bytes = $key_bytes; } public function list_ssl_methods(): array { @@ -224,8 +224,8 @@ final class encryption { $iv = $this->random_engine->get_bytes($ivsize); // Requires PHP 7 // Encryption key generated by PBKDF2 (since PHP 5.5) $keys = hash_pbkdf2($this->default_hash, $key, $iv, $this->_iterations, $this->_length, $this->_raw); - $encKey = substr($keys, 0, $this->_key_bits); // X bit encryption key - $hmacKey = substr($keys, $this->_key_bits); // X bit hmac key + $encKey = substr($keys, 0, $this->_key_bytes); // X bit encryption key + $hmacKey = substr($keys, $this->_key_bytes); // X bit hmac key $ciphertext = openssl_encrypt( $text, $this->method, @@ -233,11 +233,11 @@ final class encryption { OPENSSL_RAW_DATA, $iv ); - sodium_memzero($text); - sodium_memzero($key); - sodium_memzero($encKey); + \bs_tts\common::wipe($text); + \bs_tts\common::wipe($key); + \bs_tts\common::wipe($encKey); $hmac = hash_hmac($this->default_hash, $iv . $ciphertext, $hmacKey); - sodium_memzero($hmacKey); + \bs_tts\common::wipe($hmacKey); if (! $this->binary) { return (! $this->url_encode) ? base64_encode($hmac . $iv . $ciphertext) : \tts\misc::base64url_encode($hmac . $iv . $ciphertext); } else { @@ -264,9 +264,9 @@ final class encryption { $ciphertext = substr($text, $ivsize + $this->_length); // Generate the encryption and hmac keys $keys = hash_pbkdf2($this->default_hash, $key, $iv, $this->_iterations, $this->_length, $this->_raw); - $encKey = substr($keys, 0, $this->_key_bits); // X bit encryption key - $hmacNew = hash_hmac($this->default_hash, $iv . $ciphertext, substr($keys, $this->_key_bits)); - if (! hash_equals($hmac, $hmacNew)) { // to prevent timing attacks + $encKey = substr($keys, 0, $this->_key_bytes); // X bit encryption key + $hmacNew = hash_hmac($this->default_hash, $iv . $ciphertext, substr($keys, $this->_key_bytes)); + if (! hash_equals($hmac, $hmacNew)) { // to prevent timing attacks/Verify MSG Auth return false; // Note: hash_equals() requires PHP5.6+ } $ret = openssl_decrypt( @@ -276,10 +276,10 @@ final class encryption { OPENSSL_RAW_DATA, $iv ); - sodium_memzero($ciphertext); - sodium_memzero($key); - sodium_memzero($encKey); - sodium_memzero($keys); + \bs_tts\common::wipe($ciphertext); + \bs_tts\common::wipe($key); + \bs_tts\common::wipe($encKey); + \bs_tts\common::wipe($keys); return $ret; } @@ -303,7 +303,7 @@ final class encryption { } $ret = bin2hex(pack('H*', $key)); - sodium_memzero($key); + \bs_tts\common::wipe($key); return $ret; } @@ -317,7 +317,7 @@ final class encryption { } /** - * Also, this requires SSL connection to the database. + * This FN requires SSL connection to the database. * So, the KEY does not get exposed!!!! */ public function mysql_aes_encode(string $data, string $key, bool $bind = true) { @@ -325,14 +325,18 @@ final class encryption { $safe_key = addslashes($key); $parm = ($bind) ? ":{$safe_text}" : "'{$safe_text}'"; $ret = "HEX(AES_ENCRYPT($parm},'{$safe_key}'))"; - sodium_memzero($key); - sodium_memzero($safe_key); - sodium_memzero($data); - sodium_memzero($safe_text); - sodium_memzero($parm); + \bs_tts\common::wipe($key); + \bs_tts\common::wipe($safe_key); + \bs_tts\common::wipe($data); + \bs_tts\common::wipe($safe_text); + \bs_tts\common::wipe($parm); return $ret; } + /** + * This FN requires SSL connection to the database. + * So, the KEY does not get exposed!!!! + */ public function mysql_aes_decode(string $field_name, string $key, bool $add_as = false) { $safe_field = addslashes($field_name); $safe_key = addslashes($key);