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()); }
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(); }
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; }