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); }
protected virtual byte[] GetPersonalizationArray(SinglecastKey sckey, SpanContainer spanContainer) { byte[] senderNonce = null; if (spanContainer.SpanState == SpanStates.ReceiversNonce) { senderNonce = GetRandomData(); // Generate sender nonce. spanContainer.InstantiateWithSenderNonce(senderNonce, sckey.Personalization); } return(senderNonce); }
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 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); }