private void Network_S2SchemeSettingsChanged(SecuritySchemes scheme, bool isEnabled) { if (SecuritySchemeSet.ALLS2.Contains(scheme)) { var nodeIds = _nodesMask.Where(id => id != Network.NodeId && Network.HasSecurityScheme(id, scheme)).ToList(); var selfNodeId = Network.NodeId; foreach (var id in nodeIds) { var key = new InvariantPeerNodeId(selfNodeId, id); if (ScKeys.ContainsKey(key)) { if ((int)scheme >= (int)ScKeys[key].SecurityScheme) { ScKeys.Remove(key); } } } if (MpanTable != null) { var groups = MpanTable.SelectGroupIds(selfNodeId).Where( groupId => { var container = MpanTable.GetContainer(new NodeGroupId(selfNodeId, groupId)); if (container != null) { return(container.ReceiverGroupHandle.Intersect(nodeIds).Any()); } return(false); }); foreach (var groupId in groups) { var peerGroupId = new NodeGroupId(selfNodeId, groupId); McKeys.Remove(peerGroupId); } } } }
private void FireNetworkKeyS2Changed(InvariantPeerNodeId peerNodeId, byte[] networkKey, SecuritySchemes securityScheme) { var mpanKey = new byte[SecurityS2Utils.KEY_SIZE]; var ccmKey = new byte[SecurityS2Utils.KEY_SIZE]; var personalization = new byte[SecurityS2Utils.PERSONALIZATION_SIZE]; if (securityScheme == SecuritySchemes.S2_TEMP) { SecurityS2Utils.TempKeyExpand(networkKey, ccmKey, personalization, mpanKey); } else { SecurityS2Utils.NetworkKeyExpand(networkKey, ccmKey, personalization, mpanKey); } switch (peerNodeId.NodeId2) { case 0: for (int ii = 0; ii <= ushort.MaxValue; ii++) { var index = new InvariantPeerNodeId(ii); if (ScKeys.ContainsKey(index) && !ScKeys[index].CcmKey.SequenceEqual(ccmKey) && ScKeys[index].SecurityScheme == securityScheme) { ScKeys[index].CcmKey = ccmKey; ScKeys[index].Personalization = personalization; if (SpanTable.GetSpanState(index) != SpanStates.ReceiversNonce) { SpanTable.SetNonceFree(index); } } } for (int i = 0; i <= ushort.MaxValue; i++) { var index = new NodeGroupId(i); if (McKeys.ContainsKey(index) && !McKeys[index].CcmKey.SequenceEqual(ccmKey) && McKeys[index].SecurityScheme == securityScheme) { MpanTable.RemoveRecord(index); } } break; case 0xFF: for (int ii = 0; ii <= ushort.MaxValue; ii++) { var i = new InvariantPeerNodeId(ii); if (ScKeys.ContainsKey(i)) { ScKeys[i].CcmKey = ccmKey; ScKeys[i].Personalization = personalization; ScKeys[i].SecurityScheme = securityScheme; } } MpanTable.ClearMpanTable(); SpanTable.ClearNonceTable(); break; default: if (ScKeys.ContainsKey(peerNodeId)) { ScKeys[peerNodeId].CcmKey = ccmKey; ScKeys[peerNodeId].Personalization = personalization; ScKeys[peerNodeId].SecurityScheme = securityScheme; } else { ScKeys.Add(peerNodeId, new SinglecastKey { CcmKey = ccmKey, Personalization = personalization, SecurityScheme = securityScheme }); } if (SpanTable.GetSpanState(peerNodeId) != SpanStates.ReceiversNonce) { SpanTable.SetNonceFree(peerNodeId); } break; } if (IsInclusion && securityScheme == SecuritySchemes.S2_TEMP) { IsTempKeyActivatedOnInclusion = true; } if (NetworkKeyS2Changed != null) { NetworkKeyS2Changed(peerNodeId, networkKey, securityScheme, IsInclusion); } if (peerNodeId.NodeId2 == 0) { for (int ii = 0; ii <= ushort.MaxValue; ii++) { var index = new InvariantPeerNodeId(ii); // TODO S2 if (_scKeys.ContainsKey(index) && !_scKeys[index].CcmKey.SequenceEqual(ccmKey) && _scKeys[index].SecurityScheme == securityScheme) { RetransmissionTableS2.Clear(); } } } else if (peerNodeId.NodeId2 == 0xFF) { RetransmissionTableS2.Clear(); } else { if (RetransmissionTableS2.ContainsKey(peerNodeId)) { RetransmissionTableS2.Remove(peerNodeId); } } }