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);
            }
        }
Beispiel #2
0
        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);
 }
Beispiel #4
0
        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);
 }
Beispiel #6
0
 public void BlockUpdate(byte[] input, int inOff, int len)
 {
     cipher.ProcessAadBytes(input, inOff, len);
 }
Beispiel #7
0
        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");
            }
        }
Beispiel #8
0
        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);
            }
        }