Example #1
0
        static private byte[] EncryptAesGcm(Command command, Security security, UInt32 FrameCounter, byte[] systemTitle, byte[] BlockCipherKey, byte[] AuthenticationKey, byte[] plainText, CountType type, out byte[] countTag)
        {
            countTag = null;
            List <byte> data = new List <byte>();

            if (type == CountType.Packet)
            {
                data.Add((byte)security);
            }
            byte[] tmp = BitConverter.GetBytes(FrameCounter).Reverse().ToArray();
            byte[] aad = GetAuthenticatedData(security, AuthenticationKey, plainText);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(security, true, BlockCipherKey, aad, GetNonse(FrameCounter, systemTitle), null);

            // Encrypt the secret message
            if (security != Security.Authentication)
            {
                gcm.Write(plainText);
            }
            byte[] ciphertext = gcm.FlushFinalBlock();
            if (security == Security.Authentication)
            {
                if (type == CountType.Packet)
                {
                    data.AddRange(tmp);
                }
                if ((type & CountType.Data) != 0)
                {
                    data.AddRange(plainText);
                }
                if ((type & CountType.Tag) != 0)
                {
                    countTag = gcm.GetTag();
                    data.AddRange(countTag);
                }
            }
            else if (security == Security.Encryption)
            {
                data.AddRange(tmp);
                data.AddRange(ciphertext);
            }
            else if (security == Security.AuthenticationEncryption)
            {
                if (type == CountType.Packet)
                {
                    data.AddRange(tmp);
                }
                if ((type & CountType.Data) != 0)
                {
                    data.AddRange(ciphertext);
                }
                if ((type & CountType.Tag) != 0)
                {
                    countTag = gcm.GetTag();
                    data.AddRange(countTag);
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("security");
            }
            if (type == CountType.Packet)
            {
                Gurux.DLMS.Internal.GXCommon.SetObjectCount(data.Count, data, 0);
                data.Insert(0, (byte)command);
            }
            return(data.ToArray());
        }
Example #2
0
        /// <summary>
        /// Decrypt data.
        /// </summary>
        /// <param name="cryptedText">Crypted data.</param>
        /// <param name="systemTitle"></param>
        /// <param name="BlockCipherKey"></param>
        /// <param name="AuthenticationKey"></param>
        /// <returns></returns>
        public static byte[] DecryptAesGcm(byte[] cryptedText, byte[] systemTitle, byte[] blockCipherKey, byte[] authenticationKey)
        {
            if (cryptedText == null || cryptedText.Length < 2)
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int     pos = 0;
            Command cmd = (Command)cryptedText[pos++];

            if (!(cmd == Command.GloGetRequest ||
                  cmd == Command.GloGetResponse ||
                  cmd == Command.GloSetRequest ||
                  cmd == Command.GloSetResponse ||
                  cmd == Command.GloMethodRequest ||
                  cmd == Command.GloMethodResponse))
            {
                throw new ArgumentOutOfRangeException("cryptedData");
            }
            int      len      = Gurux.DLMS.Internal.GXCommon.GetObjectCount(cryptedText, ref pos);
            Security security = (Security)cryptedText[pos++];

            byte[] FrameCounterData = new byte[4];
            FrameCounterData[3] = cryptedText[pos++];
            FrameCounterData[2] = cryptedText[pos++];
            FrameCounterData[1] = cryptedText[pos++];
            FrameCounterData[0] = cryptedText[pos++];
            UInt32 frameCounter = BitConverter.ToUInt32(FrameCounterData, 0);

            byte[] tag = new byte[12];
            byte[] encryptedData;
            int    length;

            if (security == Security.Authentication)
            {
                length        = cryptedText.Length - pos - 12;
                encryptedData = new byte[length];
                Array.Copy(cryptedText, pos, encryptedData, 0, length);
                pos += length;
                Array.Copy(cryptedText, pos, tag, 0, 12);
                //Check tag.
                byte[] countTag;
                EncryptAesGcm(Command.None, security, frameCounter, systemTitle,
                              blockCipherKey, authenticationKey, encryptedData, CountType.Packet, out countTag);
                if (!GXDLMSChipperingStream.TagsEquals(tag, countTag))
                {
                    throw new GXDLMSException("Decrypt failed. Invalid tag.");
                }
                return(encryptedData);
            }
            byte[] ciphertext = null;
            if (security == Security.Encryption)
            {
                length     = cryptedText.Length - pos;
                ciphertext = new byte[length];
                Array.Copy(cryptedText, pos, ciphertext, 0, ciphertext.Length);
                pos += ciphertext.Length;
            }
            else if (security == Security.AuthenticationEncryption)
            {
                length     = cryptedText.Length - pos - 12;
                ciphertext = new byte[length];
                Array.Copy(cryptedText, pos, ciphertext, 0, ciphertext.Length);
                pos += ciphertext.Length;
                Array.Copy(cryptedText, pos, tag, 0, 12);
                pos += tag.Length;
            }
            byte[] aad = GetAuthenticatedData(security, authenticationKey, cryptedText);
            GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(security, false, blockCipherKey, aad, GetNonse(frameCounter, systemTitle), tag);

            gcm.Write(ciphertext);
            return(gcm.FlushFinalBlock());
        }
Example #3
0
 static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secret)
 {
     if (auth == Authentication.High)
     {
         byte[] p = new byte[challenge.Length + 15];
         byte[] s = new byte[16];
         byte[] x = new byte[16];
         int i;
         if (secret.Length < 16)
         {                   
             challenge.CopyTo(p, 0);
             secret.CopyTo(s, 0);
             for (i = 0; i < p.Length; i += 16)
             {
                 Buffer.BlockCopy(p, i, x, 0, 16);
                 GXAes128.Encrypt(x, s);
                 x.CopyTo(p, i);
             }
             return p;
         }
         throw new ArgumentException("Chipher failed. Invalid secret.");               
     }
     if (auth == Authentication.HighMD5)
     {
         using (MD5 md5Hash = MD5.Create())
         {
             byte[] tmp = new byte[challenge.Length + secret.Length];
             challenge.CopyTo(tmp, 0);
             secret.CopyTo(tmp, challenge.Length);
             tmp = md5Hash.ComputeHash(tmp);
             return tmp;
         }
     }
     if (auth == Authentication.HighSHA1)
     {
         using (SHA1 sha = new SHA1CryptoServiceProvider())
         {
             byte[] tmp = new byte[challenge.Length + secret.Length];
             challenge.CopyTo(tmp, 0);
             secret.CopyTo(tmp, challenge.Length);
             tmp = sha.ComputeHash(tmp);
             return tmp;
         }
     }
     if (auth == Authentication.HighGMAC)
     {
         GXDLMSChipperingStream tmp = new GXDLMSChipperingStream(Security.Authentication, true, challenge, challenge, null, null);
         tmp.Write(challenge);
         return tmp.FlushFinalBlock();
     }
     return challenge;
 }
 static private byte[] EncryptAesGcm(Command command, Security security, UInt32 FrameCounter, byte[] systemTitle, byte[] BlockCipherKey, byte[] AuthenticationKey, byte[] plainText, CountType type, out byte[] countTag)
 {
     countTag = null;
     List<byte> data = new List<byte>();
     if (type == CountType.Packet)
     {
         data.Add((byte)security);
     }
     byte[] tmp = BitConverter.GetBytes(FrameCounter).Reverse().ToArray();
     byte[] aad = GetAuthenticatedData(security, AuthenticationKey, plainText);
     GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(security, true, BlockCipherKey, aad, GetNonse(FrameCounter, systemTitle), null);
     // Encrypt the secret message
     if (security != Security.Authentication)
     {                
         gcm.Write(plainText);
     }
     byte[] ciphertext = gcm.FlushFinalBlock();
     if (security == Security.Authentication)
     {
         if (type == CountType.Packet)
         {
             data.AddRange(tmp);
         }
         if ((type & CountType.Data) != 0)
         {
             data.AddRange(plainText);
         }
         if ((type & CountType.Tag) != 0)
         {
             countTag = gcm.GetTag();
             data.AddRange(countTag);                    
         }
     }
     else if (security == Security.Encryption)
     {
         data.AddRange(tmp);
         data.AddRange(ciphertext);
     }
     else if (security == Security.AuthenticationEncryption)
     {
         if (type == CountType.Packet)
         {
             data.AddRange(tmp);
         }
         if ((type & CountType.Data) != 0)
         {
             data.AddRange(ciphertext);
         }
         if ((type & CountType.Tag) != 0)
         {
             countTag = gcm.GetTag();
             data.AddRange(countTag);
         }
     }
     else
     {
         throw new ArgumentOutOfRangeException("security");
     }
     if (type == CountType.Packet)
     {
         Gurux.DLMS.Internal.GXCommon.SetObjectCount(data.Count, data, 0);
         data.Insert(0, (byte)command);
     }
     return data.ToArray();        
 }
 /// <summary>
 /// Decrypt data.
 /// </summary>
 /// <param name="cryptedText">Crypted data.</param>
 /// <param name="systemTitle"></param>
 /// <param name="BlockCipherKey"></param>
 /// <param name="AuthenticationKey"></param>
 /// <returns></returns>
 public static byte[] DecryptAesGcm(byte[] cryptedText, byte[] systemTitle, byte[] blockCipherKey, byte[] authenticationKey)
 {
     if (cryptedText == null || cryptedText.Length < 2)
     {
         throw new ArgumentOutOfRangeException("cryptedData");
     }
     int pos = 0;
     Command cmd = (Command) cryptedText[pos++];
     if (!(cmd == Command.GloGetRequest ||
         cmd == Command.GloGetResponse ||
         cmd == Command.GloSetRequest ||
         cmd == Command.GloSetResponse ||
         cmd == Command.GloMethodRequest ||
         cmd == Command.GloMethodResponse))
     {
         throw new ArgumentOutOfRangeException("cryptedData");
     }
     int len = Gurux.DLMS.Internal.GXCommon.GetObjectCount(cryptedText, ref pos);
     Security security = (Security)cryptedText[pos++];
     byte[] FrameCounterData = new byte[4];
     FrameCounterData[3] = cryptedText[pos++];
     FrameCounterData[2] = cryptedText[pos++];
     FrameCounterData[1] = cryptedText[pos++];
     FrameCounterData[0] = cryptedText[pos++];
     UInt32 frameCounter = BitConverter.ToUInt32(FrameCounterData, 0);
     byte[] tag = new byte[12];
     byte[] encryptedData;
     int length;
     if (security == Security.Authentication)
     {
         length = cryptedText.Length - pos - 12;
         encryptedData = new byte[length];
         Array.Copy(cryptedText, pos, encryptedData, 0, length);
         pos += length;
         Array.Copy(cryptedText, pos, tag, 0, 12);
         //Check tag.
         byte[] countTag;
         EncryptAesGcm(Command.None, security, frameCounter, systemTitle,
             blockCipherKey, authenticationKey, encryptedData, CountType.Packet, out countTag);
         if (!GXDLMSChipperingStream.TagsEquals(tag, countTag))
         {
             throw new GXDLMSException("Decrypt failed. Invalid tag.");
         }
         return encryptedData;
     }
     byte[] ciphertext = null;
     if (security == Security.Encryption)
     {
         length = cryptedText.Length - pos;
         ciphertext = new byte[length];
         Array.Copy(cryptedText, pos, ciphertext, 0, ciphertext.Length);
         pos += ciphertext.Length;
     }
     else if (security == Security.AuthenticationEncryption)
     {
         length = cryptedText.Length - pos - 12;
         ciphertext = new byte[length];
         Array.Copy(cryptedText, pos, ciphertext, 0, ciphertext.Length);
         pos += ciphertext.Length;
         Array.Copy(cryptedText, pos, tag, 0, 12);
         pos += tag.Length;                
     }            
     byte[] aad = GetAuthenticatedData(security, authenticationKey, cryptedText);
     GXDLMSChipperingStream gcm = new GXDLMSChipperingStream(security, false, blockCipherKey, aad, GetNonse(frameCounter, systemTitle), tag);
     gcm.Write(ciphertext);
     return gcm.FlushFinalBlock();            
 }
Example #6
0
 static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secret)
 {
     if (auth == Authentication.High)
     {
         byte[] p = new byte[challenge.Length];
         byte[] s;
         if (secret.Length < 16)
         {
             s = new byte[16];
         }
         else
         {
             s = new byte[secret.Length];
         }
         challenge.CopyTo(p, 0);
         secret.CopyTo(s, 0);
         GXAes128.Encrypt(s, p);
         return s;
     }
     if (auth == Authentication.HighMD5)
     {
         using (MD5 md5Hash = MD5.Create())
         {
             byte[] tmp = new byte[challenge.Length + secret.Length];
             challenge.CopyTo(tmp, 0);
             secret.CopyTo(tmp, challenge.Length);
             tmp = md5Hash.ComputeHash(tmp);
             return tmp;
         }
     }
     if (auth == Authentication.HighSHA1)
     {
         using (SHA1 sha = new SHA1CryptoServiceProvider())
         {
             byte[] tmp = new byte[challenge.Length + secret.Length];
             challenge.CopyTo(tmp, 0);
             secret.CopyTo(tmp, challenge.Length);
             tmp = sha.ComputeHash(tmp);
             return tmp;
         }
     }
     if (auth == Authentication.HighGMAC)
     {
         GXDLMSChipperingStream tmp = new GXDLMSChipperingStream(Security.Authentication, true, challenge, challenge, null, null);
         tmp.Write(challenge);
         return tmp.FlushFinalBlock();
     }
     return challenge;
 }