internal static AesEncryptedResult Encrypt(byte[] key, byte[]?aad, byte[] requestData) { try { byte[] iv = Util.GetSecretBytes(12); var cipher = new GcmBlockCipher(new AesEngine()); cipher.Init(true, new AeadParameters(new KeyParameter(key), TAG_LENGTH_BITS, iv)); if (aad != null) { cipher.ProcessAadBytes(aad, 0, aad.Length); } byte[] cipherText1 = new byte[cipher.GetUpdateOutputSize(requestData.Length)]; cipher.ProcessBytes(requestData, 0, requestData.Length, cipherText1, 0); byte[] cipherText2 = new byte[cipher.GetOutputSize(0)]; cipher.DoFinal(cipherText2, 0); byte[] cipherText = ByteUtil.combine(cipherText1, cipherText2); byte[][] parts = ByteUtil.split(cipherText, cipherText.Length - TAG_LENGTH_BYTES, TAG_LENGTH_BYTES); return(new AesEncryptedResult(iv, parts[0], parts[1], aad)); } catch (Exception ex) { throw new InvalidOperationException(null, ex); } }
public void aesGcmRevTest() { byte[] encrypted = { 0x0D, 0xB6, 0x59, 0xB3, 0x0B, 0x7A, 0x91, 0x5C, 0x46, 0x9F, 0x01, 0x01, 0x83, 0x63, 0x1F, 0x20, 0xCB, 0x28, 0xD2, 0x6D, 0xD0, 0x5E, 0xC9, 0xB5, 0x2F, 0x6E }; byte[] authData = { 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; var MacBitSize = 96; //byte[] iv = getIv(connection.serverSysTitle, connection.serverInvocationCounter); byte[] iv = Security.getIv(new byte[] { 0x48, 0x58, 0x45, 0x03, 0x37, 0x4A, 0x1B, 0x08 }, 15582); //byte[] iv = { 0x48, 0x58, 0x45, 0x03, 0x37, 0x4A, 0x1B, 0x08, 0x00, 0x00, 0x3C, 0xDE }; lock (cipherLocker) { using (var cipherStream = new MemoryStream(encrypted)) using (var cipherReader = new BinaryReader(cipherStream)) { var cipher = new GcmBlockCipher(new AesEngine()); cipher.Init(false, new AeadParameters(new KeyParameter(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), MacBitSize, iv)); var cipherText = cipherReader.ReadBytes(encrypted.Length); var plainText = new byte[cipher.GetOutputSize(cipherText.Length)]; var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0); cipher.ProcessAadBytes(authData, 0, authData.Length); cipher.DoFinal(plainText, len); var aux = plainText; CollectionAssert.AreEqual(new byte[] { 8, 0, 6, 95, 31, 4, 0, 0, 0, 31, 1, 0, 0, 7 }, plainText); } } }
public static byte[] aesGcmReverse(byte[] encrypted, byte[] authData, CosemParameters parameters, CosemConnection connection) { try { byte[] iv = getIv(connection.serverSysTitle, connection.serverInvocationCounter); lock (cipherLocker) { using (var cipherStream = new MemoryStream(encrypted)) using (var cipherReader = new BinaryReader(cipherStream)) { var cipher = new GcmBlockCipher(new AesEngine()); cipher.Init(false, new AeadParameters(new KeyParameter(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), MacBitSize, iv)); var cipherText = cipherReader.ReadBytes(encrypted.Length); var plainText = new byte[cipher.GetOutputSize(cipherText.Length)]; var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0); cipher.ProcessAadBytes(authData, 0, authData.Length); cipher.DoFinal(plainText, len); return(plainText); } } } catch (InvalidKeyException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } //catch (InvalidAlgorithmParameterException e) catch (InvalidParameterException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } //catch (IllegalBlockSizeException e) catch (CryptographicException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } //catch (AEADBadTagException) //{ // throw new DlmsException(DlmsException.DlmsExceptionReason.SECURITY_FAIL); //} //catch (BadPaddingException e) //{ // Console.WriteLine(e.ToString()); // Console.Write(e.StackTrace); //} throw new DlmsException(DlmsException.DlmsExceptionReason.INTERNAL_ERROR); }
public void aesGcmTest() { byte[] data = { 8, 0, 6, 95, 31, 4, 0, 0, 0, 31, 1, 0, 0, 7 }; byte[] authData = { 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; var MacBitSize = 96; byte[] iv = Security.getIv(new byte[] { 0x48, 0x58, 0x45, 0x03, 0x37, 0x4A, 0x1B, 0x08 }, 15582); lock (cipherLocker) { var cipher = new GcmBlockCipher(new AesEngine()); cipher.Init(true, new AeadParameters(new KeyParameter(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), MacBitSize, iv)); var cipherText = new byte[cipher.GetOutputSize(data.Length)]; var len = cipher.ProcessBytes(data, 0, data.Length, cipherText, 0); cipher.ProcessAadBytes(authData, 0, authData.Length); cipher.DoFinal(cipherText, len); byte[] expected = { 0x0D, 0xB6, 0x59, 0xB3, 0x0B, 0x7A, 0x91, 0x5C, 0x46, 0x9F, 0x01, 0x01, 0x83, 0x63, 0x1F, 0x20, 0xCB, 0x28, 0xD2, 0x6D, 0xD0, 0x5E, 0xC9, 0xB5, 0x2F, 0x6E }; CollectionAssert.AreEqual(expected, cipherText); } }
public static byte[] aesGcm(byte[] data, byte[] authData, CosemParameters parameters, int ivCounter) { try { byte[] iv = getIv(parameters.systemTitle, ivCounter); lock (cipherLocker) { var cipher = new GcmBlockCipher(new AesEngine()); cipher.Init(true, new AeadParameters(new KeyParameter(parameters.ek), MacBitSize, iv)); var cipherText = new byte[cipher.GetOutputSize(data.Length)]; var len = cipher.ProcessBytes(data, 0, data.Length, cipherText, 0); cipher.ProcessAadBytes(authData, 0, authData.Length); cipher.DoFinal(cipherText, len); return(cipherText); } } catch (InvalidKeyException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } catch (InvalidParameterException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } catch (CryptographicException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } //catch (AEADBadTagException) //{ // throw new DlmsException(DlmsException.DlmsExceptionReason.SECURITY_FAIL); //} //catch (BadPaddingException e) //{ // Console.WriteLine(e.ToString()); // Console.Write(e.StackTrace); //} throw new DlmsException(DlmsException.DlmsExceptionReason.INTERNAL_ERROR); }
public void BlockUpdate(byte[] input, int inOff, int len) { cipher.ProcessAadBytes(input, inOff, len); }
private void RandomTest(SecureRandom srng, IGcmMultiplier m) { int kLength = 16 + 8 * srng.Next(3); byte[] K = new byte[kLength]; srng.NextBytes(K); int pLength = srng.Next(65536); byte[] P = new byte[pLength]; srng.NextBytes(P); int aLength = srng.Next(256); byte[] A = new byte[aLength]; srng.NextBytes(A); int saLength = srng.Next(256); byte[] SA = new byte[saLength]; srng.NextBytes(SA); int ivLength = 1 + srng.Next(256); byte[] IV = new byte[ivLength]; srng.NextBytes(IV); AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A); GcmBlockCipher cipher = InitCipher(m, true, parameters); byte[] C = new byte[cipher.GetOutputSize(P.Length)]; int predicted = cipher.GetUpdateOutputSize(P.Length); int split = srng.Next(SA.Length + 1); cipher.ProcessAadBytes(SA, 0, split); int len = cipher.ProcessBytes(P, 0, P.Length, C, 0); cipher.ProcessAadBytes(SA, split, SA.Length - split); if (predicted != len) { Fail("encryption reported incorrect update length in randomised test"); } len += cipher.DoFinal(C, len); if (C.Length != len) { Fail("encryption reported incorrect length in randomised test"); } byte[] encT = cipher.GetMac(); byte[] tail = new byte[C.Length - P.Length]; Array.Copy(C, P.Length, tail, 0, tail.Length); if (!AreEqual(encT, tail)) { Fail("stream contained wrong mac in randomised test"); } cipher.Init(false, parameters); byte[] decP = new byte[cipher.GetOutputSize(C.Length)]; predicted = cipher.GetUpdateOutputSize(C.Length); split = srng.Next(SA.Length + 1); cipher.ProcessAadBytes(SA, 0, split); len = cipher.ProcessBytes(C, 0, C.Length, decP, 0); cipher.ProcessAadBytes(SA, split, SA.Length - split); if (predicted != len) { Fail("decryption reported incorrect update length in randomised test"); } len += cipher.DoFinal(decP, len); if (!AreEqual(P, decP)) { Fail("incorrect decrypt in randomised test"); } byte[] decT = cipher.GetMac(); if (!AreEqual(encT, decT)) { Fail("decryption produced different mac from encryption"); } // // key reuse test // cipher.Init(false, AeadTestUtilities.ReuseKey(parameters)); decP = new byte[cipher.GetOutputSize(C.Length)]; split = NextInt(srng, SA.Length + 1); cipher.ProcessAadBytes(SA, 0, split); len = cipher.ProcessBytes(C, 0, C.Length, decP, 0); cipher.ProcessAadBytes(SA, split, SA.Length - split); len += cipher.DoFinal(decP, len); if (!AreEqual(P, decP)) { Fail("incorrect decrypt in randomised test"); } decT = cipher.GetMac(); if (!AreEqual(encT, decT)) { Fail("decryption produced different mac from encryption"); } }
private void CheckTestCase( GcmBlockCipher encCipher, GcmBlockCipher decCipher, string testName, byte[] SA, byte[] P, byte[] C, byte[] T) { byte[] enc = new byte[encCipher.GetOutputSize(P.Length)]; if (SA != null) { encCipher.ProcessAadBytes(SA, 0, SA.Length); } int len = encCipher.ProcessBytes(P, 0, P.Length, enc, 0); len += encCipher.DoFinal(enc, len); if (enc.Length != len) { // Console.WriteLine("" + enc.Length + "/" + len); Fail("encryption reported incorrect length: " + testName); } byte[] mac = encCipher.GetMac(); byte[] data = new byte[P.Length]; Array.Copy(enc, data, data.Length); byte[] tail = new byte[enc.Length - P.Length]; Array.Copy(enc, P.Length, tail, 0, tail.Length); if (!AreEqual(C, data)) { Fail("incorrect encrypt in: " + testName); } if (!AreEqual(T, mac)) { Fail("GetMac() returned wrong mac in: " + testName); } if (!AreEqual(T, tail)) { Fail("stream contained wrong mac in: " + testName); } byte[] dec = new byte[decCipher.GetOutputSize(enc.Length)]; if (SA != null) { decCipher.ProcessAadBytes(SA, 0, SA.Length); } len = decCipher.ProcessBytes(enc, 0, enc.Length, dec, 0); len += decCipher.DoFinal(dec, len); mac = decCipher.GetMac(); data = new byte[C.Length]; Array.Copy(dec, data, data.Length); if (!AreEqual(P, data)) { Fail("incorrect decrypt in: " + testName); } }