public static bool DecryptMulticastFrame(MpanTable mpanTable, MulticastKey multicastKey, NodeGroupId nodeGroupId, byte[] homeId, COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION cmd, out byte[] data, out Extensions extensions) { List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1> encryptedExtensionsList = new List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1>(); List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1> extensionsList = new List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1>(); extensions = null; data = null; bool ret = false; extensionsList = cmd.vg1; if (mpanTable.CheckMpanExists(nodeGroupId) && !mpanTable.IsRecordInMOSState(nodeGroupId)) { // Backup mpan. byte seqNo = mpanTable[nodeGroupId].SequenceNumber; byte[] mpanBackup = new byte[mpanTable[nodeGroupId].MpanState.Length]; Array.Copy(mpanTable[nodeGroupId].MpanState, mpanBackup, mpanTable[nodeGroupId].MpanState.Length); // Try to decrypt. bool decryptSucceeded = false; int attempts = 0; byte[] plainData = null; while (!decryptSucceeded && attempts < MaxMpanIterations) { var mpan = new byte[16]; if (IncrementMpan(mpanTable, multicastKey, nodeGroupId, mpan)) { decryptSucceeded = DecryptS2(multicastKey.CcmKey, mpan, nodeGroupId.NodeId, nodeGroupId.GroupId, homeId, cmd, out plainData, out encryptedExtensionsList); } attempts++; } if (decryptSucceeded) { extensions = new Extensions { ExtensionsList = extensionsList ?? new List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1>(), EncryptedExtensionsList = encryptedExtensionsList ?? new List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1>() }; ret = true; data = plainData; } else { var restoredMpanContainer = mpanTable.AddOrReplace(nodeGroupId, seqNo, null, mpanBackup); } } return(ret); }
public static bool IncrementMpan(MpanTable mpanTable, MulticastKey multicastKey, NodeGroupId nodeGroupId, byte[] outMpan) { if (mpanTable.CheckMpanExists(nodeGroupId) && !mpanTable.IsRecordInMOSState(nodeGroupId)) { var container = mpanTable[nodeGroupId]; SecurityS2Utils.Aes128EcbEncrypt(container.MpanState, multicastKey.MpanKey, outMpan); container.IncrementMpanState(); container.UpdateSequenceNumber(); return(true); } return(false); }