Finish the operation. Does not append mac tag to the cipher text. Mac tag does NOT get verified in decryption mode.
Process additional authenticated data.
Process a block of bytes from in putting the result into out.
Reset the cipher. After resetting the cipher is in the same state as it was after the last init (if there was one).
Initialize the underlying cipher.
underlying BlockCipher
Test with test vectors from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf
section 2.2.1
1 t { 2 import dcrypt.blockcipher.aes; 3 4 alias const(ubyte)[] octets; 5 6 octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; 7 octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits 8 9 GCM!AES gcm; 10 gcm.start(true, key, iv); 11 12 ubyte[48] output; 13 ubyte[] oBuf = output; 14 size_t outLen; 15 16 gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); 17 18 outLen = gcm.processBytes(cast(octets)x"08000F101112131415161718191A1B1C", oBuf).length; 19 oBuf = oBuf[outLen..$]; 20 outLen = gcm.processBytes(cast(octets)x"1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A", oBuf).length; 21 oBuf = oBuf[outLen..$]; 22 23 outLen = gcm.processBytes(cast(octets)x"0002", oBuf).length; 24 oBuf = oBuf[outLen..$]; 25 26 gcm.processAADBytes(cast(octets)x"B2C2846512153524C0895E81"); 27 ubyte[16] mac; 28 outLen = gcm.finish(mac, oBuf); 29 // import std.stdio; 30 // writefln("%(%x%)", output); 31 assert(output == cast(octets)x"701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D"); 32 assert(mac == cast(octets)x"4F8D55E7D3F06FD5A13C0C29B9D5B880"
test decryption test vectors from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf
section 2.2.1
1 t { 2 import dcrypt.blockcipher.aes; 3 4 alias const(ubyte)[] octets; 5 6 octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; 7 octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits 8 9 GCM!AES gcm; 10 gcm.start(false, key, iv); 11 12 ubyte[48] output; 13 ubyte[] oBuf = output; 14 size_t outLen; 15 16 gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); 17 18 // add ciphertext 19 outLen = gcm.processBytes(cast(octets) 20 x"701AFA1CC039C0D765128A665DAB6924 21 3899BF7318CCDC81C9931DA17FBE8EDD 22 7D17CB8B4C26FC81E3284F2B7FBA713D", oBuf).length; 23 oBuf = oBuf[outLen..$]; 24 25 gcm.processAADBytes(cast(octets)x"B2C2846512153524C0895E81"); 26 ubyte[16] mac; 27 outLen = gcm.finish(mac, oBuf); 28 // import std.stdio; 29 // writefln("%(%.2x%)", output); 30 31 assert(output == 32 x"08000F101112131415161718191A1B1 33 C1D1E1F202122232425262728292A2B 34 2C2D2E2F303132333435363738393A0002"); 35 36 assert(mac == x"4F8D55E7D3F06FD5A13C0C29B9D5B880"
Test decryption with modified cipher data. An exception should be thrown beacause of wrong token.
test vectors from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf
section 2.2.1
1 t { 2 import dcrypt.blockcipher.aes; 3 4 alias const(ubyte)[] octets; 5 6 octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; 7 octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits 8 9 GCM!AES gcm; 10 gcm.start(false, key, iv); 11 12 ubyte[48] output; 13 ubyte[] oBuf = output[]; 14 size_t outLen; 15 16 gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); 17 18 // add ciphertext 19 outLen = gcm.processBytes(cast(octets) 20 x"701AFA1CC039C0D765128A665DAB6924 21 3899BF7318CCDC81C9931DA17FBE8EDD 22 7D17CB8B4C26FC81E3284F2B7FBA713D", oBuf).length; // 880 has been changed do EEF 23 oBuf = oBuf[outLen..$]; 24 25 gcm.processAADBytes(cast(octets)x"B2C2846512153524C0895E81"); 26 ubyte[16] mac; 27 outLen = gcm.finish(mac, oBuf); 28 assert(mac != x"4F8D55E7D3F06FD5A13C0C29B9D5BEEF"
Test decryption with altered AAD. An exception should be thrown beacause of wrong token.
test vectors from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf
section 2.2.1
1 t { 2 import dcrypt.blockcipher.aes; 3 4 alias const(ubyte)[] octets; 5 6 octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; 7 octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits 8 9 GCM!AES gcm; 10 gcm.start(false, key, iv); 11 12 ubyte[48] output; 13 ubyte[] oBuf = output; 14 size_t outLen; 15 16 gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); 17 18 // add ciphertext 19 outLen = gcm.processBytes(cast(octets) 20 x"701AFA1CC039C0D765128A665DAB6924 21 3899BF7318CCDC81C9931DA17FBE8EDD 22 7D17CB8B4C26FC81E3284F2B7FBA713D", oBuf).length; 23 oBuf = oBuf[outLen..$]; 24 25 gcm.processAADBytes(cast(octets)x"B2C2846512153524C089beef"); // changed 5E81 to beef 26 ubyte[16] mac; 27 gcm.finish(mac, oBuf); 28 assert(mac != x"4F8D55E7D3F06FD5A13C0C29B9D5B880"); 29 // verify that an InvalidCipherTextException is thrown 30 // bool exception = false; 31 // try { 32 // outLen = gcm.finish(oBuf); 33 // } catch (InvalidCipherTextException e) { 34 // exception = true; 35 // } 36 // assert(exception, "AAD has been altered but no exception has been thrown!"
test GCM with different MAC sizes
1 t { 2 3 import dcrypt.blockcipher.aes; 4 5 string[] keys = [ 6 x"00000000000000000000000000000000", 7 x"00000000000000000000000000000000", 8 x"00000000000000000000000000000000", 9 x"00000000000000000000000000000000", 10 x"00000000000000000000000000000000", 11 x"00000000000000000000000000000000", 12 x"00000000000000000000000000000000", 13 x"00000000000000000000000000000000", 14 x"00000000000000000000000000000000", 15 x"00000000000000000000000000000000", 16 x"00000000000000000000000000000000", 17 x"00000000000000000000000000000000", 18 x"00000000000000000000000000000000", 19 ]; 20 string[] ivs = [ 21 x"00", 22 x"00000000", 23 x"00000000000000", 24 x"00000000000000000000", 25 x"00000000000000000000000000", 26 x"00000000000000000000000000000000", 27 x"00000000000000000000000000000000000000", 28 x"00000000000000000000000000000000000000000000", 29 x"00000000000000000000000000000000000000000000000000", 30 x"00000000000000000000000000000000000000000000000000000000", 31 x"00000000000000000000000000000000000000000000000000000000000000", 32 x"00000000000000000000000000000000000000000000000000000000000000000000", 33 x"00000000000000000000000000000000000000000000000000000000000000000000000000", 34 ]; 35 string[] aads = [ 36 x"", 37 x"00000000000000", 38 x"0000000000000000000000000000", 39 x"000000000000000000000000000000000000000000", 40 x"00000000000000000000000000000000000000000000000000000000", 41 x"0000000000000000000000000000000000000000000000000000000000000000000000", 42 x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 43 x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 44 x"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 45 x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 46 x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 47 x"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 48 x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 49 ]; 50 string[] plains = [ 51 x"", 52 x"0000000000", 53 x"00000000000000000000", 54 x"000000000000000000000000000000", 55 x"0000000000000000000000000000000000000000", 56 x"00000000000000000000000000000000000000000000000000", 57 x"000000000000000000000000000000000000000000000000000000000000", 58 x"0000000000000000000000000000000000000000000000000000000000000000000000", 59 x"00000000000000000000000000000000000000000000000000000000000000000000000000000000", 60 x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 61 x"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 62 x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 63 x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 64 ]; 65 string[] ciphers = [ 66 x"3c2fa7a9", 67 x"078bb038e6b2353f0e05", 68 x"d6a480d4dec719bd36a60efde3aaf1f8", 69 x"e37dd3785cc7017f206df18d831e37cfe63f9e057a23", 70 x"3fe95bef64662ddcf19a96cc584d2146499320eef8d518bb5e7e49a7", 71 x"a3b22b8449afafbcd6c09f2cfa9de2be938f8bbf235863d0cefb4075046c9a4d351e", 72 x"a0912f3bde077afa3f21725fbcae1c9c2e00b28b6eb462745e9b65a026cc4ba84d13b408b7061fe1", 73 x"535b0d13cbb1012df5402f748cea5304d52db1e4b997317a54c2296b95e0300c6692f911625bfe617d16b63a237b", 74 x"547096f9d7a83ba8d128467baac4a9d861ebd51cc2dfff111915cd0b4260b7dc49c8d8723eb15429024ac21eed99ca1338844092", 75 x"95e67a9eade034290efa90e33f51710f02f3aba4c32873545891924aa52dcc092695e983b529b60e7b13aee5f7d6de278c77410e216d0fdbd7e1", 76 x"0957e69831df479e8cf7b214e1cef4d3e7a2716e8179deaf8061383f35eeabd017080c3d7972b98009a38b5842a2a08a9123412338e16de05a72b76849629b48", 77 x"07052b0f8b95c9491ae43bac6693802384688e9dd19d9ce295b4ab550163a2bb4b0dd905012a56094e895ea7a5857f8100af40b4adb6452d0b8e78e709c5c9f1d432b5f59317", 78 x"e0902e27a95867acaa788920ac71b2f2a61863bdc40ee869bea53470edf02fc71800465c550a58ba69220c67243899d756cf0a5ac4fda582fc6e9d2f8498a0e73e0e809bfb8d86ab5fdf066c", 79 ]; 80 uint[] macSizes = [ 81 32, 82 40, 83 48, 84 56, 85 64, 86 72, 87 80, 88 88, 89 96, 90 104, 91 112, 92 120, 93 128, 94 ]; 95 96 AEADCipherTest( 97 new GCMEngine(new AESEngine), 98 keys, 99 ivs, 100 plains, 101 aads, 102 ciphers, 103 macSizes)
usage of OOP API: auto aes_gcm = new AEADCipherWrapper!(GCM!AES)();