private static void QueuePayload(ZWaveNode node, SecutiryPayload payload) { var nodeSecurityData = GetSecurityData(node); lock (nodeSecurityData.SecurePayload) { nodeSecurityData.SecurePayload.Add(payload); if (nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds > 10000) { nodeSecurityData.IsWaitingForNonce = false; } if (!nodeSecurityData.IsWaitingForNonce) { RequestNonce(node); } } }
public static void SendMessage(ZWaveNode node, byte[] message) { int length = message[5]; Utility.DebugLog(DebugMessageType.Information, "In sendMsg - SecurityHandler"); if (message.Length < 7) { Utility.DebugLog(DebugMessageType.Information, "Message too short"); } if (message[3] != 0x13) { Utility.DebugLog(DebugMessageType.Information, "Invalid Message type"); } if (length > 28) { SecutiryPayload t_payload = new SecutiryPayload(); t_payload.length = 28; t_payload.part = 1; byte[] t_message = new byte[t_payload.length]; System.Array.Copy(message, 6, t_message, 0, t_payload.length); t_payload.message = t_message; QueuePayload(node, t_payload); SecutiryPayload t_payload2 = new SecutiryPayload(); t_payload2.length = length - 28; t_payload2.part = 2; byte[] t_message2 = new byte[t_payload.length]; System.Array.Copy(message, 34, t_message2, 0, t_payload2.length); t_payload2.message = t_message2; QueuePayload(node, t_payload2); } else { SecutiryPayload t_payload = new SecutiryPayload(); t_payload.length = length; t_payload.part = 0; byte[] t_message = new byte[t_payload.length]; System.Array.Copy(message, 6, t_message, 0, t_payload.length); t_payload.message = t_message; QueuePayload(node, t_payload); } }
// IN the mesage to be Encrypted // OUT - true - message processed and sent - proceed to next one // - false - we need to wait for the nonce report to come private static bool EncryptMessage(ZWaveNode node, byte[] message) { SecurityData nodeSecurityData = GetSecurityData(node); Utility.DebugLog(DebugMessageType.Information, "In EncryptMessage - secure_payload [" + nodeSecurityData.SecurePayload.Count + "] - " + nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds); // if we get true we need to wait for the new Nonce // if we get false we need to proceed // if (sendRequestNonce()) // return false; if (nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds > 10000) { return(false); } SecutiryPayload payload = null; lock (nodeSecurityData.SecurePayload) { if (nodeSecurityData.SecurePayload.Count > 0) { payload = nodeSecurityData.SecurePayload.First(); nodeSecurityData.SecurePayload.Remove(payload); } } if (payload != null) { int len = payload.length + 20; byte[] t_message = new byte[len]; int i = 0; t_message[i] = (byte)CommandClass.Security; i++; t_message[i] = (byte)SecurityCommand.MessageEncap; byte[] initializationVector = new byte[16]; for (int a = 0; a < 8; a++) { initializationVector[a] = (byte)0xAA; i++; t_message[i] = initializationVector[a]; } Array.Copy(nodeSecurityData.DeviceCurrentNonce, 0, initializationVector, 8, 8); int sequence = 0; if (payload.part == 1) { ++nodeSecurityData.SequenceCounter; sequence = nodeSecurityData.SequenceCounter & (byte)0x0f; sequence |= (byte)0x10; } else if (payload.part == 2) { ++nodeSecurityData.SequenceCounter; sequence = nodeSecurityData.SequenceCounter & (byte)0x0f; sequence |= (byte)0x30; } byte[] plaintextmsg = new byte[payload.length + 1]; plaintextmsg[0] = (byte)sequence; for (int a = 0; a < payload.length; a++) { plaintextmsg[a + 1] = payload.message[a]; } byte[] encryptedPayload = new byte[30]; encryptedPayload = AesWork.EncryptOfbMessage(nodeSecurityData.EncryptionKey, initializationVector, plaintextmsg); Utility.DebugLog(DebugMessageType.Information, "authKey " + BitConverter.ToString(nodeSecurityData.AuthorizationKey)); Utility.DebugLog(DebugMessageType.Information, "EncryptKey " + BitConverter.ToString(nodeSecurityData.EncryptionKey)); Utility.DebugLog(DebugMessageType.Information, "Input Packet: " + BitConverter.ToString(plaintextmsg)); Utility.DebugLog(DebugMessageType.Information, "IV " + BitConverter.ToString(initializationVector)); Utility.DebugLog(DebugMessageType.Information, "encryptedPayload " + BitConverter.ToString(encryptedPayload)); for (int a = 0; a < payload.length + 1; ++a) { i++; t_message[i] = encryptedPayload[a]; } i++; t_message[i] = nodeSecurityData.DeviceCurrentNonce[0]; //GenerateAuthentication int start = 1; byte[] mac = GenerateAuthentication(nodeSecurityData.AuthorizationKey, t_message, start, t_message.Length + 2 - start - 1, 0x01, node.Id, initializationVector); for (int a = 0; a < 8; ++a) { i++; t_message[i] = mac[a]; } node.SendDataRequest(t_message); Utility.DebugLog(DebugMessageType.Information, "In EncryptMessage - message sent"); if ((nodeSecurityData.IsNetworkKeySet == false) && payload.message[0] == (byte)CommandClass.Security && payload.message[1] == (byte)SecurityCommand.NetworkKeySet) { nodeSecurityData.IsNetworkKeySet = true; nodeSecurityData.IsAddingNode = false; } return(true); } return(true); }
private static void QueuePayload(ZWaveNode node, SecutiryPayload payload) { var nodeSecurityData = GetSecurityData(node); lock (nodeSecurityData.SecurePayload) { nodeSecurityData.SecurePayload.Add(payload); if (nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds > 10000) nodeSecurityData.IsWaitingForNonce = false; if (!nodeSecurityData.IsWaitingForNonce) { RequestNonce(node); } } }