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 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 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); }