markTestSkipped( 'AES-GCM decryption is only supported in PHP 7.1 or greater' ); } parent::set_up(); } /** * @dataProvider cartesianJoinInputKeySizeProvider * * @param StreamInterface $plainText * @param int $keySize */ public function testStreamOutputSameAsOpenSSL( StreamInterface $plainText, $keySize ) { if (version_compare(PHP_VERSION, '7.1', '<')) { $this->markTestSkipped( 'AES-GCM decryption is only supported in PHP 7.1 or greater' ); return; } $plainText->rewind(); $key = 'foo'; $iv = random_bytes(openssl_cipher_iv_length('aes-256-gcm')); $additionalData = json_encode(['foo' => 'bar']); $tag = null; $encryptingStream = new AesGcmEncryptingStream( $plainText, $key, $iv, $additionalData, 16, $keySize ); $this->assertSame( (string) $encryptingStream, openssl_encrypt( (string) $plainText, "aes-{$keySize}-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag, $additionalData, 16 ) ); $this->assertSame($iv, $encryptingStream->getCurrentIv()); $this->assertSame($tag, $encryptingStream->getTag()); } /** * @dataProvider encryptDataProvider */ public function testCorrectlyEncryptsData( $plaintext, $key, $iv, $aad, $keySize, $expectedCipher, $expectedTag ) { $stream = new AesGcmEncryptingStream( Psr7\Utils::streamFor(hex2bin($plaintext)), hex2bin($key), hex2bin($iv), hex2bin($aad), 16, $keySize ); $this->assertEquals( $expectedCipher, strtoupper(bin2hex($stream->createStream()->getContents())) ); $this->assertEquals( $expectedTag, strtoupper(bin2hex($stream->getTag())) ); } public function encryptDataProvider() { // [[ $plaintext, $key, $iv, $aad, $keySize, $expectedCipher, $expectedTag ]] return [ [ '', 'DA2FDB0CED551AEB723D8AC1A267CEF3', 'A5F5160B7B0B025757ACCDAA', '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 128, '', '7AD0758C4FA9B8660AA0687B3E7BD517' ], [ '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', '4194935CF4524DF93D62FEDBC818D8AC', '0C5A8F5AF7F6064C0130EE64', '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 128, '3F4CC9A7451717E5E939D294A1362B32C274D06411188DAD76AEE3EE4DA46483EA4C1AF38B9B74D7AD2FD8E310CF82', 'AD563FD10E1EFA3F26753F46E09DB3A0' ], [ '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 'AD03EE2FD6048DB7158CEC55D3D760BC', '1B813A16DDCB7F08D26E2541', '', 128, 'ADD161BE957AE9EC3CEE6600C77FF81D64A80242A510A9D5AD872096C79073B61E8237FAA7D63A3301EA58EC11332C', '01944370EC28601ADC989DE05A794AEB' ], [ '', '20142E898CD2FD980FBF34DE6BC85C14DA7D57BD28F4AA5CF1728AB64E843142', 'FB7B4A824E82DAA6C8BC1251', '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 256, '', '81C0E42BB195E262CB3B3A74A0DAE1C8' ], [ '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 'D211F278A44EAB666B1021F4B4F60BA6B74464FA9CB7B134934D7891E1479169', '6B5CD3705A733C1AD943D58A', '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 256, '4C25ABD66D3A1BCCE794ACAAF4CEFDF6D2552F4A82C50A98CB15B4812FF557ABE564A9CEFF15F32DCF5A5AA7894888', '03EDE71EC952E65AE7B4B85CFEC7D304' ], [ '167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D', 'CFE8BFE61B89AF53D2BECE744D27B78C9E4D74D028CE88ED10A422285B1201C9', '5F08EFBFB7BF5BA365D9EB1D', '', 256, '0A7E82F1E5C76C69679671EEAEE455936F2C4FCCD9DDF1FAA27075E2040644938920C5D16C69E4D93375487B9A80D4', '04347D0C5B0E0DE89E033D04D0493DCA' ], ]; } public function testStreamLegacyPHP() { if (version_compare(PHP_VERSION, '7.1', '>=')) { $this->markTestSkipped( 'Test is unnecessary on PHP 7.1 and newer' ); return; } $knownAnswerTest = [ 'KEY' => "foo\0\0\0\0\0\0\0\0\0\0\0\0\0", 'KeySize' => 128, 'TagLength' => 16, 'CT' => hex2bin('cbb92a00adfaa91fbee308603a1c21b87f12c30246dc01097b0f000dc1a2f872748bd6b41a37a2d7d89b9cfd'), 'PT' => hex2bin('546865207261696e20696e20537061696e2066616c6c73206d61696e6c79206f6e2074686520706c61696e2e'), 'IV' => hex2bin('43a29bcfb3322d134a4ef364'), 'AAD' => json_encode(['foo' => 'bar']), 'Tag' => hex2bin('cba38431a0c28712778de8e8c6ec4594') ]; $stream = new AesGcmEncryptingStream( Psr7\Utils::streamFor($knownAnswerTest['PT']), $knownAnswerTest['KEY'], $knownAnswerTest['IV'], $knownAnswerTest['AAD'], $knownAnswerTest['TagLength'], $knownAnswerTest['KeySize'] ); $cipherText = (string) $stream; $tag = $stream->getTag(); $this->assertSame($cipherText, $knownAnswerTest['CT']); $this->assertSame($tag, $knownAnswerTest['Tag']); } public function testIsNotWritable() { $decryptingStream = new AesGcmEncryptingStream( Psr7\Utils::streamFor(''), 'key', random_bytes(openssl_cipher_iv_length('aes-256-gcm')) ); $this->assertFalse($decryptingStream->isWritable()); } }