public static bool DecrementMpan(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.DecrementMpanState(); return(true); } return(false); }
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 bool HasActiveKeyForNode(InvariantPeerNodeId peerNodeId) //{ // return ScKeys.ContainsKey(peerNodeId); //} //public SecuritySchemes GetActiveSecuritySchemeForNode(InvariantPeerNodeId peerNodeId) //{ // return ScKeys[peerNodeId].SecurityScheme; //} //public SecuritySchemes GetActiveSecuritySchemeForGroup(NodeGroupId peerGroupId) //{ // return McKeys[peerGroupId].SecurityScheme; //} //public bool HasActiveKeyForGroupId(byte groupId, byte ownerId) //{ // return McKeys.ContainsKey(new NodeGroupId(ownerId, groupId)); //} public bool CheckMpanMosForOwnerNode(MpanTable mpanTable, byte ownerNodeId) { var groupIds = mpanTable.SelectGroupIds(ownerNodeId); bool isMos = false; foreach (var groupId in groupIds) { var nodeGroupId = new NodeGroupId(ownerNodeId, groupId); if (mpanTable.IsRecordInMOSState(nodeGroupId)) { // If found several goups leave the first one and remove another. if (!isMos) { isMos = true; } else { mpanTable.RemoveRecord(nodeGroupId); } } } return(isMos); }