Esempio n. 1
0
        private static byte[] DecryptMessage(ZWaveNode node, byte[] message, int start)
        {
            SecurityData nodeSecurityData = GetSecurityData(node);

            Utility.DebugLog(DebugMessageType.Information, "In DecryptMessage - SecurityHandler");
            if (nodeSecurityData.ControllerNonceTimer.ElapsedMilliseconds > 10000)
            {
                Utility.DebugLog(DebugMessageType.Information, "Received the nonce  too late'" + nodeSecurityData.ControllerNonceTimer.ElapsedMilliseconds + "' > 10000");
                return(null);
            }

            //            Utility.DebugLog(DebugMessageType.Information, "Message to be decrypted: " + BitConverter.ToString(message));

            // Get IV from inbound packet
            byte[] iv = new byte[16];
            Array.Copy(message, start + 1, iv, 0, 8);
            byte[] currentNonce = nodeSecurityData.GetControllerCurrentNonce(true);

            if (currentNonce == null)
            {
                Utility.DebugLog(DebugMessageType.Information, "currentNonce null");
                return(null);
            }

            Utility.DebugLog(DebugMessageType.Information, "currentNonce NOT null");

            Array.Copy(currentNonce, 0, iv, 8, 8);

            int _length = message.Length;
            int encryptedpackagesize = _length - 11 - 8; //19 + 11 + 8

            byte[] encryptedpacket = new byte[encryptedpackagesize];


            Array.Copy(message, 8 + start + 1, encryptedpacket, 0, encryptedpackagesize);

            byte[] decryptedpacket = AesWork.EncryptOfbMessage(nodeSecurityData.EncryptionKey, iv, encryptedpacket);
            Utility.DebugLog(DebugMessageType.Information, "Message          " + BitConverter.ToString(message));
            Utility.DebugLog(DebugMessageType.Information, "IV               " + BitConverter.ToString(iv));
            //Utility.DebugLog(DebugMessageType.Information, "Encrypted Packet " + BitConverter.ToString(encryptedpacket));
            Utility.DebugLog(DebugMessageType.Information, "Decrypted Packet " + BitConverter.ToString(decryptedpacket));

            byte[] mac = GenerateAuthentication(nodeSecurityData.AuthorizationKey, message, start, _length, node.Id, 0x01, iv);

            byte[] e_mac = new byte[8];
            Array.Copy(message, start + 8 + encryptedpackagesize + 2, e_mac, 0, 8);
            if (!Enumerable.SequenceEqual(mac, e_mac))
            {
                Utility.DebugLog(DebugMessageType.Information, "Computed mac " + BitConverter.ToString(mac) + " does not match the provider mac " + BitConverter.ToString(e_mac) + ". Dropping.");
                if (nodeSecurityData.SecurePayload.Count > 1)
                {
                    RequestNonce(node);
                }
                return(null);
            }

            /*
             * if (decryptedpacket[1] == (byte)CommandClass.Security && 1 == 0)
             * {
             *  byte[] msg = new byte[decryptedpacket.Length - 1];
             *  Array.Copy(decryptedpacket, 1, msg, 0, msg.Length);
             *
             *  Utility.DebugLog(DebugMessageType.Information, "Processing Internally: " + BitConverter.ToString(msg));
             *
             * }
             * else
             * {
             */
            byte[] msg = new byte[decryptedpacket.Length - 2 + 8];
            Array.Clear(msg, 0, 7);
            Array.Copy(decryptedpacket, 1, msg, 7, msg.Length - 7);

            msg[6] = (byte)(msg.Length - 7);

            Utility.DebugLog(DebugMessageType.Information, "Forwarding: " + BitConverter.ToString(msg));

            /* send to the Command Class for Proecssing */
            Utility.DebugLog(DebugMessageType.Information, "Received External Command Class: " + BitConverter.ToString(new byte[] { decryptedpacket[1] }));
//                node.MessageRequestHandler(node.pController, msg);
            Utility.DebugLog(DebugMessageType.Information, "In DecryptMessage - Finished");

            return(msg);
        }
Esempio n. 2
0
        private static byte[] GenerateAuthentication(byte[] authorizationKey, byte[] data, int start, int length, byte sendingNode, byte receivingNode, byte[] iv)
        {
            // data should stat at 4
            byte[] buffer  = new byte[256];
            byte[] tmpauth = new byte[16];
            int    ib      = 0;

            buffer[ib] = data[start + 0];
            ib++;
            buffer[ib] = sendingNode;
            ib++;
            buffer[ib] = receivingNode;
            ib++;
            buffer[ib] = (byte)(length - 19);
            Array.Copy(data, start + 9, buffer, 4, buffer[3]);

            byte[] buff = new byte[length - 19 + 4];
            Array.Copy(buffer, buff, length - 19 + 4);
            //            Utility.DebugLog(DebugMessageType.Information, "Raw Auth (minus IV)" + BitConverter.ToString(buff));

            tmpauth = AesWork.EncryptEcbMessage(authorizationKey, iv);

            byte[] encpck = new byte[16];
            Array.Clear(encpck, 0, 16);

            int block = 0;

            for (int i = 0; i < buff.Length; i++)
            {
                encpck[block] = buff[i];
                block++;

                if (block == 16)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        tmpauth[j] = (byte)(encpck[j] ^ tmpauth[j]);
                        encpck[j]  = 0;
                    }
                    block   = 0;
                    tmpauth = AesWork.EncryptEcbMessage(authorizationKey, tmpauth);
                }
            }

            /* any left over data that isn't a full block size*/
            if (block > 0)
            {
                for (int i = 0; i < 16; i++)
                {
                    tmpauth[i] = (byte)(encpck[i] ^ tmpauth[i]);
                }
                tmpauth = AesWork.EncryptEcbMessage(authorizationKey, tmpauth);
            }

            byte[] auth = new byte[8];
            Array.Copy(tmpauth, auth, 8);

            //            Utility.DebugLog(DebugMessageType.Information, "Computed Auth " + BitConverter.ToString(auth));

            return(auth);
        }
Esempio n. 3
0
        // 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);
        }