Exemple #1
0
 public static void LoadKeys(ZWaveAES aesEngine, byte[] networkKey, out byte[] authKey, out byte[] encKey)
 {
     authKey = new byte[16];
     encKey  = new byte[16];
     byte[] pattern = ZWaveAES.RepeatByte16(0x55);
     aesEngine.AES_ECB(networkKey, pattern, authKey); // K_A = AES(K_N,pattern)
     pattern = ZWaveAES.RepeatByte16(0xAA);
     aesEngine.AES_ECB(networkKey, pattern, encKey);  // K_E = AES(K_N,pattern)
 }
Exemple #2
0
        /// <summary>
        /// Called: When fresh input from hardware RNG is needed
        /// Task: Update the PRNG with data from hardware RNG
        /// Global vars: prngState[0..15]   Modify
        /// Temp data: byt k[16], h[16], temp[16], i, j
        /// </summary>
        public void PRNGUpdate(byte[] randomResult)
        {
            byte[] hwData;
            // 1.a. Collect 256 bit (32 byte) data from hw generator
            hwData = GetHWRNG(32, randomResult);

            // 1.b.
            for (int i = 0; i < hwData.Length; i++)
            {
                if (i < 16)
                {
                    K1[i] = hwData[i];
                }
                else
                {
                    K2[i - 16] = hwData[i];
                }
            }
            H0 = new byte[] { 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5 };

            // 1.c.
            AESEngine.AES_ECB(K1, H0, H1);
            for (int i = 0; i < H1.Length; i++)
            {
                H1[i] ^= H0[i];
            }

            // 1.d.
            AESEngine.AES_ECB(K2, H1, H2);
            for (int i = 0; i < H2.Length; i++)
            {
                H2[i] ^= H1[i];
            }

            // 2.
            byte[] S = new byte[16];
            for (int i = 0; i < innerState.Length; i++)
            {
                S[i] = (byte)(innerState[i] ^ H2[i]);
            }

            // 3 + 4.
            byte[] ISGen = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 };
            innerState = new byte[16];
            AESEngine.AES_ECB(S, ISGen, innerState);
        }
Exemple #3
0
        /// <summary>
        /// Decrypts the payload.
        /// </summary>
        /// <param name="networkKey">The network key.</param>
        /// <param name="encryptedPayload">The encrypted payload.</param>
        /// <param name="IV">The IV.</param>
        /// <returns></returns>
        public byte[] DecryptPayload(byte[] networkKey, byte[] encryptedPayload, byte[] IV)
        {
            try
            {
                /////////////////////////////
                //byte[] authKey = new byte[16];
                byte[] encKey = new byte[16];

                //byte[] pattern = ZWaveAES.RepeatByte16(0x55);
                //AES.AES_ECB(authData.Key, pattern, authKey); // K_A = AES(K_N,pattern)
                byte[] pattern = ZWaveAES.RepeatByte16(0xAA);
                Engine.AES_ECB(networkKey, pattern, encKey); // K_E = AES(K_N,pattern)
                /////////////////////////////
                byte[] output     = new byte[0];
                byte[] encPayload = new byte[0];

                if (encryptedPayload.Length < 16)
                {
                    output     = ExpandEmptyArray(16);
                    encPayload = ExpandEmptyArray(16);
                }
                else
                {
                    output     = ExpandEmptyArray(encryptedPayload.Length);
                    encPayload = ExpandEmptyArray(encryptedPayload.Length);
                }

                for (int i = 0; i < encryptedPayload.Length; i++)
                {
                    encPayload[i] = encryptedPayload[i];
                }

                Engine.AES_OFB(encKey, IV, encPayload, true);

                byte[] decryptedPayload = new byte[encryptedPayload.Length];
                for (int i = 0; i < encryptedPayload.Length; i++)
                {
                    if (i < encPayload.Length)
                    {
                        decryptedPayload[i] = encPayload[i];
                    }
                }
                return(decryptedPayload);
            }
            catch (Exception ex)
            {
                throw new ApplicationException("SecurityException", ex);
            }
        }
Exemple #4
0
        /// <summary>
        /// Authenticates the specified network key.
        /// </summary>
        /// <param name="networkKey">The network key.</param>
        /// <param name="noncesPayload">The nonces payload.</param>
        /// <param name="framePayload">The frame payload.</param>
        /// <param name="commandClassKey">The command class key.</param>
        /// <param name="sourceId">The source id.</param>
        /// <param name="destId">The dest id.</param>
        /// <returns></returns>
        public AuthData Authenticate(byte[] networkKey, byte[] noncesPayload, byte[] framePayload, byte commandClassKey, byte sourceId, byte destId)
        {
            try
            {
                AuthData authData = new AuthData(networkKey);
                if (noncesPayload.Length > 9 &&
                    framePayload.Length > framePayload.Length - 9 &&
                    framePayload.Length > 19)
                {
                    authData.Nonces = new byte[] { noncesPayload[2],
                                                   noncesPayload[3],
                                                   noncesPayload[4],
                                                   noncesPayload[5],
                                                   noncesPayload[6],
                                                   noncesPayload[7],
                                                   noncesPayload[8],
                                                   noncesPayload[9] };

                    authData.RI = framePayload[framePayload.Length - 9];

                    authData.MAC = new byte[] { framePayload[framePayload.Length - 8],
                                                framePayload[framePayload.Length - 7],
                                                framePayload[framePayload.Length - 6],
                                                framePayload[framePayload.Length - 5],
                                                framePayload[framePayload.Length - 4],
                                                framePayload[framePayload.Length - 3],
                                                framePayload[framePayload.Length - 2],
                                                framePayload[framePayload.Length - 1] };

                    authData.IV = new byte[] { framePayload[2],
                                               framePayload[3],
                                               framePayload[4],
                                               framePayload[5],
                                               framePayload[6],
                                               framePayload[7],
                                               framePayload[8],
                                               framePayload[9] };

                    authData.EncryptedPayload = new byte[framePayload.Length - 19];
                    int index = 0;
                    for (int i = 10; i < framePayload.Length - 9; i++)
                    {
                        authData.EncryptedPayload[index] = framePayload[i];
                        index++;
                    }
                    ZWaveAES AES     = new ZWaveAES();
                    byte[]   tempMAC = new byte[16];
                    byte[]   authKey = new byte[16];
                    byte[]   encKey  = new byte[16];

                    byte[] pattern = ZWaveAES.RepeatByte16(0x55);
                    AES.AES_ECB(authData.Key, pattern, authKey); // K_A = AES(K_N,pattern)
                    pattern = ZWaveAES.RepeatByte16(0xAA);
                    AES.AES_ECB(authData.Key, pattern, encKey);  // K_E = AES(K_N,pattern)


                    authData.SecurityAuthData = new ZWaveSecurityAuthData(authData.IV, authData.Nonces, commandClassKey, sourceId, destId, (byte)authData.EncryptedPayload.Length);

                    AES.AES_CBCMAC(authKey,
                                   authData.SecurityAuthData.ToByteArray(),
                                   authData.EncryptedPayload, tempMAC);

                    authData.IsValid = true;
                    for (int i = 0; i < 8; i++)
                    {
                        if (tempMAC[i] != authData.MAC[i])
                        {
                            authData.IsValid = false;
                            break;
                        }
                    }
                }
                return(authData);
            }
            catch (Exception ex)
            {
                throw new ApplicationException("SecurityException", ex);
            }
        }