protected byte[] EncryptSinglecastCommandInternal(SinglecastKey sckey, SpanTable spanTable, byte senderNodeId, byte receiverNodeId, byte[] homeId, byte[] plainData, Extensions extentions, SubstituteSettings substituteSettings) { Extensions ext = extentions ?? new Extensions(); InvariantPeerNodeId peerNodeId = new InvariantPeerNodeId(senderNodeId, receiverNodeId); var spanContainer = spanTable.GetContainer(peerNodeId); var spanExtension = GetPersonalizationArray(sckey, spanContainer); if (spanExtension != null) { ext.AddSpanExtension(spanExtension); } spanContainer.NextNonce(); spanTable.UpdateTxSequenceNumber(peerNodeId); var iv = GetPropertyIV(spanContainer.Span); var sequenceNumber = GetPropertySequenceNo(spanContainer.TxSequenceNumber); var reserved = GetPropertyReserved(0); FillExtensions(ext, true); byte[] encryptedData = EncryptS2(sckey.CcmKey, sequenceNumber, plainData, senderNodeId, receiverNodeId, homeId, iv, reserved, ext); if (plainData != null && encryptedData != null) { SaveDataForRetransmission(peerNodeId, plainData, substituteSettings, sckey.SecurityScheme); } return(encryptedData); }
public byte[] GenerateNonceReport(SpanTable spanTable, InvariantPeerNodeId peerNodeId, byte txSequenceNumber, byte rxSequenceNumber, bool isSos, bool isMos) { byte[] receiverNonce = GetRandomData(); if (isSos) { if (spanTable.CheckNonceExists(peerNodeId)) { spanTable.SetNonceFree(peerNodeId); } spanTable.Add(peerNodeId, receiverNonce, txSequenceNumber, rxSequenceNumber); } var nonceReportCmd = new COMMAND_CLASS_SECURITY_2.SECURITY_2_NONCE_REPORT { sequenceNumber = txSequenceNumber, properties1 = new COMMAND_CLASS_SECURITY_2.SECURITY_2_NONCE_REPORT.Tproperties1 { sos = (byte)(isSos ? 1 : 0), mos = (byte)(isMos ? 1 : 0) }, receiversEntropyInput = receiverNonce }; return(nonceReportCmd); }
public bool CheckNonceExists(InvariantPeerNodeId peerNodeId) { lock (_synchObject) { return(_table.ContainsKey(peerNodeId) && _table[peerNodeId].SpanState != SpanStates.None); } }
public SpanStates GetSpanState(InvariantPeerNodeId peerNodeId) { lock (_synchObject) { if (_table.ContainsKey(peerNodeId) && _table[peerNodeId].SpanState != SpanStates.None) { return(_table[peerNodeId].SpanState); } return(SpanStates.None); } }
public static byte[] EncryptPayload(byte senderId, byte receiverId, byte[] homeId, byte sequenceNumber, byte[] receiverNonce, byte[] senderNonce, byte[] networkKey, byte[] textToEncrypt, int generationCount, bool isRealKey) { var ret = new COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION { sequenceNumber = sequenceNumber }; InvariantPeerNodeId peerNodeId = new InvariantPeerNodeId(0); var mpanKey = new byte[SecurityS2Utils.KEY_SIZE]; var ccmKey = new byte[SecurityS2Utils.KEY_SIZE]; var personalization = new byte[SecurityS2Utils.PERSONALIZATION_SIZE]; if (isRealKey) { SecurityS2Utils.NetworkKeyExpand(networkKey, ccmKey, personalization, mpanKey); } else { SecurityS2Utils.TempKeyExpand(networkKey, ccmKey, personalization, mpanKey); } SpanTable spanTable = new SpanTable(); spanTable.Add(peerNodeId, receiverNonce, 0, 0); SpanContainer spanContainer = spanTable.GetContainer(peerNodeId); spanContainer.InstantiateWithSenderNonce(senderNonce, personalization); for (int i = 0; i < generationCount; i++) { spanContainer.NextNonce(); } AAD aad = new AAD { SenderNodeId = senderId, ReceiverNodeId = receiverId, HomeId = homeId, PayloadLength = (ushort)(textToEncrypt.Length + SecurityS2Utils.AUTH_DATA_HEADER_LENGTH), SequenceNumber = sequenceNumber }; aad.PayloadLength += (ushort)((byte[])ret).Length; var cipherData = SecurityS2Utils.CcmEncryptAndAuth(ccmKey, spanContainer.Span, aad, textToEncrypt); if (cipherData != null && cipherData.Length > 0) { ret.ccmCiphertextObject = new List <byte>(cipherData); } else { ret = null; } return(ret); }
//public void UpdateRxSequenceNumber(InvariantPeerNodeId peerNodeId, byte rxSequenceNumber) //{ // lock (_synchObject) // { // if (_table.ContainsKey(peerNodeId)) // { // _table[peerNodeId].RxSequenceNumber = rxSequenceNumber; // } // } //} public byte GetRxSequenceNumber(InvariantPeerNodeId peerNodeId) { byte ret = 0; lock (_synchObject) { if (_table.ContainsKey(peerNodeId)) { ret = _table[peerNodeId].RxSequenceNumber; } } return(ret); }
public bool SetNonceFree(InvariantPeerNodeId peerNodeId) { bool ret = false; lock (_synchObject) { if (_table.ContainsKey(peerNodeId)) { ret = true; _table[peerNodeId].SetNonceFree(); } } return(ret); }
private void BackupTxSequenceNumber(InvariantPeerNodeId peerNodeId) { if (_table.ContainsKey(peerNodeId)) { if (_txSequenceNumberTable.ContainsKey(peerNodeId)) { _txSequenceNumberTable[peerNodeId] = _table[peerNodeId].TxSequenceNumber; } else { _txSequenceNumberTable.Add(peerNodeId, _table[peerNodeId].TxSequenceNumber); } } }
public byte[] EncryptSinglecastCommand(SinglecastKey sckey, SpanTable spanTable, byte senderNodeId, byte receiverNodeId, byte[] homeId, byte[] plainData, Extensions extentions, SubstituteSettings substituteSettings) { byte[] encryptedData = null; InvariantPeerNodeId peerNodeId = new InvariantPeerNodeId(senderNodeId, receiverNodeId); var spanContainer = spanTable.GetContainer(peerNodeId); if (spanContainer != null) { encryptedData = EncryptSinglecastCommandInternal(sckey, spanTable, senderNodeId, receiverNodeId, homeId, plainData, extentions, substituteSettings); } else { } return(encryptedData); }
public byte UpdateTxSequenceNumber(InvariantPeerNodeId peerNodeId) { byte ret = 0; lock (_synchObject) { if (_table.ContainsKey(peerNodeId)) { _table[peerNodeId].TxSequenceNumber++; ret = _table[peerNodeId].TxSequenceNumber; } BackupTxSequenceNumber(peerNodeId); } return(ret); }
/// <summary> /// Remove if exists and adds new nonce with Receiver state to table. /// </summary> /// <param name="peerNodeId">Sender node id</param> /// <param name="receiverNonce">16 bytes receiver nonce</param> public void AddOrReplace(InvariantPeerNodeId peerNodeId, byte[] receiverNonce, byte txSequenceNumber, byte rxSequenceNumber) { lock (_synchObject) { if (_table.ContainsKey(peerNodeId)) { _table[peerNodeId].SetReceiversNonceState(receiverNonce); _table[peerNodeId].RxSequenceNumber = rxSequenceNumber; } else { _table.Add(peerNodeId, new SpanContainer(receiverNonce, txSequenceNumber, rxSequenceNumber)); } BackupTxSequenceNumber(peerNodeId); } }
public bool IsValidRxSequenceNumber(InvariantPeerNodeId peerNodeId, byte rxSequenceNumber) { bool ret = false; lock (_synchObject) { if (_table.ContainsKey(peerNodeId)) { ret = _table[peerNodeId].RxSequenceNumber != rxSequenceNumber; } else { ret = true; } } return(ret); }
public byte GetTxSequenceNumber(InvariantPeerNodeId peerNodeId) { byte ret = 0; lock (_synchObject) { if (_table.ContainsKey(peerNodeId)) { ret = _table[peerNodeId].TxSequenceNumber; } else if (_txSequenceNumberTable.ContainsKey(peerNodeId)) { ret = ++_txSequenceNumberTable[peerNodeId]; } else { ret = 0x55; _txSequenceNumberTable.Add(peerNodeId, ret); } } return(ret); }
/// <summary> /// Adds new nonce with Receiver state to table /// </summary> /// <param name="peerNodeId">Sender node id</param> /// <param name="receiverNonce">16 bytes receiver nonce</param> /// <param name="sequenceNumber">Sequence number</param> public void Add(InvariantPeerNodeId peerNodeId, byte[] receiverNonce, byte txSequenceNumber, byte rxSequenceNumber) { lock (_synchObject) { if (!_table.ContainsKey(peerNodeId)) { _table.Add(peerNodeId, new SpanContainer(receiverNonce, txSequenceNumber, rxSequenceNumber)); } else if (_table.ContainsKey(peerNodeId) && _table[peerNodeId].SpanState == SpanStates.None) { _table[peerNodeId].SetReceiversNonceState(receiverNonce); _table[peerNodeId].TxSequenceNumber = txSequenceNumber; _table[peerNodeId].RxSequenceNumber = rxSequenceNumber; } else { throw new InvalidOperationException("Nonce with specified peerNodeId already exists"); } BackupTxSequenceNumber(peerNodeId); } }
protected virtual void SaveDataForRetransmission(InvariantPeerNodeId peerNodeId, byte[] plainData, SubstituteSettings substituteSettings, SecuritySchemes scheme) { }
public static bool DecryptSinglecastFrame( SpanContainer spanContainer, SinglecastKey singlecastKey, byte sourceNodeId, byte destNodeId, 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; bool isDecryptSucceeded = false; InvariantPeerNodeId peerNodeId = new InvariantPeerNodeId(destNodeId, sourceNodeId); extensionsList = cmd.vg1; if (spanContainer != null && singlecastKey != null) { spanContainer.RxSequenceNumber = cmd.sequenceNumber; if (spanContainer.SpanState == SpanStates.ReceiversNonce) { #region SpanStates.ReceiversNonce // Establish nonce synchronization. byte[] senderEntropyInput = null; if (cmd.properties1.extension == 1) { foreach (var extData in cmd.vg1) { if (extData.properties1.type == (byte)ExtensionTypes.Span && extData.extensionLength == 18 && extData.extension.Count == 16) { senderEntropyInput = extData.extension.ToArray(); break; } } } if (senderEntropyInput != null) { var receiverEntropyInput = spanContainer.ReceiversNonce; spanContainer.InstantiateWithSenderNonce(senderEntropyInput, singlecastKey.Personalization); byte[] plainData; spanContainer.NextNonce(); isDecryptSucceeded = DecryptS2(singlecastKey.CcmKey, spanContainer.Span, sourceNodeId, destNodeId, homeId, cmd, out plainData, out encryptedExtensionsList); if (isDecryptSucceeded) { 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 { extensions = new Extensions { ExtensionsList = extensionsList ?? new List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1>(), EncryptedExtensionsList = new List <COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION.TVG1>() }; spanContainer.SetReceiversNonceState(); } } #endregion } else if (spanContainer.SpanState == SpanStates.Span) { #region SpanStates.Span // Check nonce synchronization. int attemptsCount = 5; byte[] plainData = null; while (!isDecryptSucceeded && attemptsCount > 0) { spanContainer.NextNonce(); attemptsCount--; if (spanContainer != null) { isDecryptSucceeded = DecryptS2(singlecastKey.CcmKey, spanContainer.Span, sourceNodeId, destNodeId, homeId, cmd, out plainData, out encryptedExtensionsList); } } if (isDecryptSucceeded) { 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; } #endregion } else { throw new InvalidOperationException("Unexpected nonce state"); } } return(ret); }
public static byte[] DecryptPayload(byte senderId, byte receiverId, byte[] homeId, byte sequenceNumber, byte[] receiverNonce, byte[] senderNonce, byte[] networkKey, int generationCount, bool isRealKey, byte[] fullMessageS2, out int currentGenerationCount) { byte[] ret = null; currentGenerationCount = 0; if (fullMessageS2 != null && fullMessageS2.Length > 2) { var msgEncap = (COMMAND_CLASS_SECURITY_2.SECURITY_2_MESSAGE_ENCAPSULATION)fullMessageS2; var peerNodeId = new InvariantPeerNodeId(0); var mpanKey = new byte[SecurityS2Utils.KEY_SIZE]; var ccmKey = new byte[SecurityS2Utils.KEY_SIZE]; var personalization = new byte[SecurityS2Utils.PERSONALIZATION_SIZE]; if (isRealKey) { SecurityS2Utils.NetworkKeyExpand(networkKey, ccmKey, personalization, mpanKey); } else { SecurityS2Utils.TempKeyExpand(networkKey, ccmKey, personalization, mpanKey); } SpanTable spanTable = new SpanTable(); spanTable.Add(peerNodeId, receiverNonce, 0, 0); SpanContainer spanContainer = spanTable.GetContainer(peerNodeId); spanContainer.InstantiateWithSenderNonce(senderNonce, personalization); var messageLength = (ushort)fullMessageS2.Length; AAD aad = new AAD { SenderNodeId = senderId, ReceiverNodeId = receiverId, HomeId = homeId, PayloadLength = messageLength, SequenceNumber = sequenceNumber, StatusByte = msgEncap.properties1 }; if (msgEncap.properties1.extension == 1) { var dataList = new List <byte>(); foreach (var vg1 in msgEncap.vg1) { dataList.AddRange(new byte[] { vg1.extensionLength, vg1.properties1 }); dataList.AddRange(vg1.extension); } aad.ExtensionData = dataList.ToArray(); } for (int i = 0; i < generationCount; i++) { spanContainer.NextNonce(); ret = SecurityS2Utils.CcmDecryptAndAuth(ccmKey, spanContainer.Span, aad, msgEncap.ccmCiphertextObject.ToArray()); if (ret != null && ret.Length > 0) { currentGenerationCount = i + 1; break; } } } return(ret); }