Finish the operation by either appending or verifying the MAC at the end of the data.
Write the MAC of the processed data to buf
return the size of the output buffer required for a processBytes plus a doFinal with an input of len bytes.
return the size of the output buffer required for a processBytes an input of len bytes.
Add a sequence of bytes to the associated data check.
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).
init cipher, H, Y0, E0
Test OOP API with test vectors from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf
section 2.2.1
t { import dcrypt.crypto.engines.aes; alias const(ubyte)[] octets; octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits auto gcm = new GCMCipher(new AESEngine); gcm.start(true, key, iv); ubyte[] output = new ubyte[64]; ubyte[] oBuf = output; size_t outLen; gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); outLen = gcm.processBytes(cast(octets)x"08000F101112131415161718191A1B1C", oBuf); oBuf = oBuf[outLen..$]; outLen = gcm.processBytes(cast(octets)x"1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A", oBuf); oBuf = oBuf[outLen..$]; outLen = gcm.processBytes(cast(octets)x"0002", oBuf); oBuf = oBuf[outLen..$]; gcm.processAADBytes(cast(octets)x"B2C2846512153524C0895E81"); outLen = gcm.doFinal(oBuf); assert(output == cast(octets)x"701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880"
test decryption test vectors from http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf
section 2.2.1
t { import dcrypt.crypto.engines.aes; alias const(ubyte)[] octets; octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits GCM!AES gcm; gcm.start(false, key, iv); ubyte[] output = new ubyte[48]; ubyte[] oBuf = output; size_t outLen; gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); // add ciphertext outLen = gcm.processBytes(cast(octets) x"701AFA1CC039C0D765128A665DAB6924 3899BF7318CCDC81C9931DA17FBE8EDD 7D17CB8B4C26FC81E3284F2B7FBA713D 4F8D55E7D3F06FD5A13C0C29B9D5B880", oBuf); oBuf = oBuf[outLen..$]; gcm.processAADBytes(cast(octets)x"B2C2846512153524C0895E81"); outLen = gcm.doFinal(oBuf); assert(output == cast(octets) x"08000F101112131415161718191A1B1 C1D1E1F202122232425262728292A2B 2C2D2E2F303132333435363738393A0002"
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
t { import dcrypt.crypto.engines.aes; alias const(ubyte)[] octets; octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits GCM!AES gcm; gcm.start(false, key, iv); ubyte[] output = new ubyte[48]; ubyte[] oBuf = output; size_t outLen; gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); // add ciphertext outLen = gcm.processBytes(cast(octets) x"701AFA1CC039C0D765128A665DAB6924 3899BF7318CCDC81C9931DA17FBE8EDD 7D17CB8B4C26FC81E3284F2B7FBA713D 4F8D55E7D3F06FD5A13C0C29B9D5BEEF", oBuf); // 880 has been changed do EEF oBuf = oBuf[outLen..$]; gcm.processAADBytes(cast(octets)x"B2C2846512153524C0895E81"); // verify that an InvalidCipherTextException is thrown bool exception = false; try { outLen = gcm.doFinal(oBuf); } catch (InvalidCipherTextException e) { exception = true; } assert(exception, "Ciphertext has been altered but no exception has been thrown!"
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
t { import dcrypt.crypto.engines.aes; alias const(ubyte)[] octets; octets key = cast(octets)x"AD7A2BD03EAC835A6F620FDCB506B345"; octets iv = cast(octets)x"12153524C0895E81B2C28465"; // 96 bits GCM!AES gcm; gcm.start(false, key, iv); ubyte[] output = new ubyte[48]; ubyte[] oBuf = output; size_t outLen; gcm.processAADBytes(cast(octets)x"D609B1F056637A0D46DF998D88E52E00"); // add ciphertext outLen = gcm.processBytes(cast(octets) x"701AFA1CC039C0D765128A665DAB6924 3899BF7318CCDC81C9931DA17FBE8EDD 7D17CB8B4C26FC81E3284F2B7FBA713D 4F8D55E7D3F06FD5A13C0C29B9D5B880", oBuf); oBuf = oBuf[outLen..$]; gcm.processAADBytes(cast(octets)x"B2C2846512153524C089beef"); // changed 5E81 to beef // verify that an InvalidCipherTextException is thrown bool exception = false; try { outLen = gcm.doFinal(oBuf); } catch (InvalidCipherTextException e) { exception = true; } assert(exception, "AAD has been altered but no exception has been thrown!"
test GCM with different MAC sizes
1 t { 2 3 import dcrypt.crypto.engines.aes; 4 5 string[] keys = [ 6 "00000000000000000000000000000000", 7 "00000000000000000000000000000000", 8 "00000000000000000000000000000000", 9 "00000000000000000000000000000000", 10 "00000000000000000000000000000000", 11 "00000000000000000000000000000000", 12 "00000000000000000000000000000000", 13 "00000000000000000000000000000000", 14 "00000000000000000000000000000000", 15 "00000000000000000000000000000000", 16 "00000000000000000000000000000000", 17 "00000000000000000000000000000000", 18 "00000000000000000000000000000000", 19 ]; 20 string[] ivs = [ 21 "00", 22 "00000000", 23 "00000000000000", 24 "00000000000000000000", 25 "00000000000000000000000000", 26 "00000000000000000000000000000000", 27 "00000000000000000000000000000000000000", 28 "00000000000000000000000000000000000000000000", 29 "00000000000000000000000000000000000000000000000000", 30 "00000000000000000000000000000000000000000000000000000000", 31 "00000000000000000000000000000000000000000000000000000000000000", 32 "00000000000000000000000000000000000000000000000000000000000000000000", 33 "00000000000000000000000000000000000000000000000000000000000000000000000000", 34 ]; 35 string[] aads = [ 36 "", 37 "00000000000000", 38 "0000000000000000000000000000", 39 "000000000000000000000000000000000000000000", 40 "00000000000000000000000000000000000000000000000000000000", 41 "0000000000000000000000000000000000000000000000000000000000000000000000", 42 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 43 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 44 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 45 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 46 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 47 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 48 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 49 ]; 50 string[] plains = [ 51 "", 52 "0000000000", 53 "00000000000000000000", 54 "000000000000000000000000000000", 55 "0000000000000000000000000000000000000000", 56 "00000000000000000000000000000000000000000000000000", 57 "000000000000000000000000000000000000000000000000000000000000", 58 "0000000000000000000000000000000000000000000000000000000000000000000000", 59 "00000000000000000000000000000000000000000000000000000000000000000000000000000000", 60 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 61 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 62 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 63 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 64 ]; 65 string[] ciphers = [ 66 "3c2fa7a9", 67 "078bb038e6b2353f0e05", 68 "d6a480d4dec719bd36a60efde3aaf1f8", 69 "e37dd3785cc7017f206df18d831e37cfe63f9e057a23", 70 "3fe95bef64662ddcf19a96cc584d2146499320eef8d518bb5e7e49a7", 71 "a3b22b8449afafbcd6c09f2cfa9de2be938f8bbf235863d0cefb4075046c9a4d351e", 72 "a0912f3bde077afa3f21725fbcae1c9c2e00b28b6eb462745e9b65a026cc4ba84d13b408b7061fe1", 73 "535b0d13cbb1012df5402f748cea5304d52db1e4b997317a54c2296b95e0300c6692f911625bfe617d16b63a237b", 74 "547096f9d7a83ba8d128467baac4a9d861ebd51cc2dfff111915cd0b4260b7dc49c8d8723eb15429024ac21eed99ca1338844092", 75 "95e67a9eade034290efa90e33f51710f02f3aba4c32873545891924aa52dcc092695e983b529b60e7b13aee5f7d6de278c77410e216d0fdbd7e1", 76 "0957e69831df479e8cf7b214e1cef4d3e7a2716e8179deaf8061383f35eeabd017080c3d7972b98009a38b5842a2a08a9123412338e16de05a72b76849629b48", 77 "07052b0f8b95c9491ae43bac6693802384688e9dd19d9ce295b4ab550163a2bb4b0dd905012a56094e895ea7a5857f8100af40b4adb6452d0b8e78e709c5c9f1d432b5f59317", 78 "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 GCMCipher(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)();