Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5a729ed
Whitespace fix.
defuse Oct 16, 2015
9451325
Refactors, and changes the protcol a bit:
defuse Oct 16, 2015
e7008c0
Fix silly mistakes to make the tests pass.
defuse Oct 16, 2015
6da7367
Remove debug echos I accidentally left in.
defuse Oct 16, 2015
0202401
Add backwards compatibility attack prevention to File.
defuse Oct 16, 2015
3d84dbc
Move the runtime tests into their own file.
defuse Oct 16, 2015
a2521bc
Fix documentation of get*Config() methods.
defuse Oct 16, 2015
aa6a5d4
Fix method documentation.
defuse Oct 16, 2015
9074411
SECURITY CRITICAL: Fix CTR mode nonce incrementor.
defuse Oct 16, 2015
ace418e
Make incrementCounter more robust, improve tests.
defuse Oct 17, 2015
5551dba
Move legacy test to PHPUnit.
defuse Oct 17, 2015
5e832aa
Remove the empty output test (no longer checking accurately)
defuse Oct 17, 2015
ff87a53
Fix bug uncovered by testing with mbstring.func_overload=7
defuse Oct 17, 2015
5c15b10
Run tests properly.
defuse Oct 17, 2015
bbcc1ae
Move annoying files into an 'other/' directory.
defuse Oct 17, 2015
ee6abfd
Put proper credit to Scott in phpunit.sh
defuse Oct 17, 2015
7fca4ae
Make all exceptions use consistent names and namespacing.
defuse Oct 17, 2015
b310ac9
Test that our nonce format is the same as OpenSSL's
defuse Oct 17, 2015
7647408
Fix file handle leak.
defuse Oct 17, 2015
26a1067
Fix documentation now that we use CTR mode.
defuse Oct 17, 2015
3b41509
Get rid of the terrible ExceptionHandler hack.
defuse Oct 17, 2015
aa6810a
Switch to AES-256.
defuse Oct 17, 2015
533ad7d
Get older PHPUnit on older versions of PHP.
defuse Oct 17, 2015
82a7599
Fix syntax to parse on older versions of PHP.
defuse Oct 17, 2015
26db090
Fix bug by baking 'sha256' in the mac-the-mac comparison.
defuse Oct 17, 2015
2986ab1
Fix bug caused by moving createNewRandomKey() to Crypto.
defuse Oct 17, 2015
9b9a732
Don't allow Travis-CI tests of PHP 7.0 to fail.
defuse Oct 17, 2015
0211202
Add a 'Key' "firewall" to prevent use of insecurely-generated keys.
defuse Oct 17, 2015
6e72941
SECURITY CRITICAL: Fix bug where bad version header could cause inval…
defuse Oct 17, 2015
56dd2d2
Turn RangeExceptions into our exceptions upon hex decoding failure.
defuse Oct 17, 2015
fec7f5f
Add test for backwards compatibility attacks.
defuse Oct 17, 2015
4691ab2
Add more invalid version number tests.
defuse Oct 17, 2015
6f99c97
Use an object for config instead of an array.
defuse Oct 17, 2015
35c618a
Use HEADER_VERSION_SIZE instead of magic number 4.
defuse Oct 19, 2015
6c1d4bc
Make Key not use an error-prone array for config options.
defuse Oct 19, 2015
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
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ sudo: false

matrix:
fast_finish: true
allow_failures:
- php: "7.0"

script: ./test.sh
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ This is a class for doing symmetric encryption in PHP. **Requires PHP 5.4 or new
Implementation
--------------

Messages are encrypted with AES-128 in CBC mode and are authenticated with
HMAC-SHA256 (Encrypt-then-Mac). PKCS7 padding is used to pad the message to
a multiple of the block size. HKDF is used to split the user-provided key into
Messages are encrypted with AES-128 in CTR mode and are authenticated with
HMAC-SHA256 (Encrypt-then-Mac). HKDF is used to split the user-provided key into
two keys: one for encryption, and the other for authentication. It is
implemented using the `openssl_` and `hash_hmac` functions.

Expand Down
2 changes: 0 additions & 2 deletions autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,3 @@
require $file;
}
});

$crypto_exception_handler_object_dont_touch_me = new \Defuse\Crypto\ExceptionHandler;
26 changes: 13 additions & 13 deletions doc/02-Crypto.php.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Symmetric Key Encryption

At a glance:

* **Cipher and Mode**: `AES-128-CBC`
* **Padding**: `PKCS#7`
* **Cipher and Mode**: `AES-256-CTR`
* **Padding**: None (CTR mode doesn't pad)
* **Authentication**: `HMAC-SHA-256`
* **Construction**: `Encrypt then MAC`
* **Algorithm Backend**: `ext/openssl`
Expand Down Expand Up @@ -37,9 +37,9 @@ try {
// \Defuse\Crypto\Crypto\binToHex()
// \Defuse\Crypto\Crypto\hexToBin()
//
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely create a key');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely create a key');
}
```
Expand All @@ -51,9 +51,9 @@ Encrypting a Message
$message = 'ATTACK AT DAWN';
try {
$ciphertext = \Defuse\Crypto\Crypto::Encrypt($message, $key);
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform encryption');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform encryption');
}
```
Expand All @@ -64,16 +64,16 @@ Decrypting a Message
```php
try {
$decrypted = self::Decrypt($ciphertext, $key);
} catch (\Defuse\Crypto\Exception\InvalidCiphertext $ex) { // VERY IMPORTANT
} catch (\Defuse\Crypto\Exception\InvalidCiphertextException $ex) { // VERY IMPORTANT
// Either:
// 1. The ciphertext was modified by the attacker,
// 2. The key is wrong, or
// 3. $ciphertext is not a valid ciphertext or was corrupted.
// Assume the worst.
die('DANGER! DANGER! The ciphertext has been tampered with!');
} catch (CryptoTestFailedException $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform decryption');
} catch (CannotPerformOperationException $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform decryption');
}
```
Expand All @@ -86,16 +86,16 @@ Decrypting a Message Encrypted with version 1 of this Library
```php
try {
$decrypted = self::legacyDecrypt($ciphertext, $key);
} catch (\Defuse\Crypto\Exception\InvalidCiphertext $ex) { // VERY IMPORTANT
} catch (\Defuse\Crypto\Exception\InvalidCiphertextException $ex) { // VERY IMPORTANT
// Either:
// 1. The ciphertext was modified by the attacker,
// 2. The key is wrong, or
// 3. $ciphertext is not a valid ciphertext or was corrupted.
// Assume the worst.
die('DANGER! DANGER! The ciphertext has been tampered with!');
} catch (CryptoTestFailedException $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform decryption');
} catch (CannotPerformOperationException $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform decryption');
}
```
```
24 changes: 12 additions & 12 deletions doc/03-File.php.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Symmetric Key File Encryption

At a glance:

* **Cipher and Mode**: `AES-128-CTR`
* **Cipher and Mode**: `AES-256-CTR`
* **Padding**: None (CTR mode doesn't pad)
* **Authentication**: `HMAC-SHA-256`
* **Construction**: `Encrypt then MAC`
Expand Down Expand Up @@ -37,9 +37,9 @@ try {
// \Defuse\Crypto\File\binToHex()
// \Defuse\Crypto\File\hexToBin()
//
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely create a key');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely create a key');
}
```
Expand All @@ -62,9 +62,9 @@ try {
$outputFilename,
$key
);
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform encryption');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform encryption');
}
```
Expand All @@ -87,9 +87,9 @@ try {
$outputFilename,
$key
);
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform decryption');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform decryption');
}
```
Expand All @@ -108,9 +108,9 @@ $oFile = \fopen('image2.enc.jpg', 'wb');

try {
\Defuse\Crypto\File::encryptResource($iFile, $oFile, $key);
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform encryption');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform encryption');
}
```
Expand All @@ -129,9 +129,9 @@ $oFile = \fopen('image2.dec.jpg', 'wb');

try {
\Defuse\Crypto\File::decryptResource($iFile, $oFile, $key);
} catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) {
} catch (\Defuse\Crypto\Exception\CryptoTestFailedException $ex) {
die('Cannot safely perform decryption');
} catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) {
} catch (\Defuse\Crypto\Exception\CannotPerformOperationException $ex) {
die('Cannot safely perform decryption');
}
```
```
2 changes: 1 addition & 1 deletion benchmark.php → other/benchmark.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
use \Defuse\Crypto\Crypto;

require_once'autoload.php';
require_once 'autoload.php';

function showResults($type, $start, $end, $count)
{
Expand Down
File renamed without changes.
149 changes: 149 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php
namespace Defuse\Crypto;

use \Defuse\Crypto\Exception as Ex;
use \Defuse\Crypto\Core;

class Config
{
private $cipher_method;
private $block_byte_size;
private $key_byte_size;
private $salt_byte_size;
private $mac_byte_size;
private $hash_function_name;
private $encryption_info_string;
private $authentication_info_string;

public function __construct($config_array)
{
$expected_keys = array(
"cipher_method",
"block_byte_size",
"key_byte_size",
"salt_byte_size",
"mac_byte_size",
"hash_function_name",
"encryption_info_string",
"authentication_info_string"
);
if (sort($expected_keys) !== true) {
throw Ex\CannotPerformOperationException(
"sort() failed."
);
}

$actual_keys = array_keys($config_array);
if (sort($actual_keys) !== true) {
throw Ex\CannotPerformOperationException(
"sort() failed."
);
}

if ($expected_keys !== $actual_keys) {
throw new Ex\CannotPerformOperationException(
"Trying to instantiate a bad configuration."
);
}

$this->cipher_method = $config_array["cipher_method"];
$this->block_byte_size = $config_array["block_byte_size"];
$this->key_byte_size = $config_array["key_byte_size"];
$this->salt_byte_size = $config_array["salt_byte_size"];
$this->mac_byte_size = $config_array["mac_byte_size"];
$this->hash_function_name = $config_array["hash_function_name"];
$this->encryption_info_string = $config_array["encryption_info_string"];
$this->authentication_info_string = $config_array["authentication_info_string"];

Core::ensureFunctionExists('openssl_get_cipher_methods');
if (\in_array($this->cipher_method, \openssl_get_cipher_methods()) === false) {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid OpenSSL cipher method."
);
}

if (!\is_int($this->block_byte_size) || $this->block_byte_size <= 0) {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid block byte size."
);
}

if (!\is_int($this->key_byte_size) || $this->key_byte_size <= 0) {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid key byte size."
);
}

if ($this->salt_byte_size !== false) {
if (!is_int($this->salt_byte_size) || $this->salt_byte_size <= 0) {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid salt byte size."
);
}
}

if (!\is_int($this->mac_byte_size) || $this->mac_byte_size <= 0) {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid MAC byte size."
);
}

if (\in_array($this->hash_function_name, \hash_algos()) === false) {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid hash function name."
);
}

if (!\is_string($this->encryption_info_string) || $this->encryption_info_string === "") {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid encryption info string."
);
}

if (!\is_string($this->authentication_info_string) || $this->authentication_info_string === "") {
throw new Ex\CannotPerformOperationException(
"Configuration contains an invalid authentication info string."
);
}
}

public function cipherMethod()
{
return $this->cipher_method;
}

public function blockByteSize()
{
return $this->block_byte_size;
}

public function keyByteSize()
{
return $this->key_byte_size;
}

public function saltByteSize()
{
return $this->salt_byte_size;
}

public function macByteSize()
{
return $this->mac_byte_size;
}

public function hashFunctionName()
{
return $this->hash_function_name;
}

public function encryptionInfoString()
{
return $this->encryption_info_string;
}

public function authenticationInfoString()
{
return $this->authentication_info_string;
}
}
Loading