public static byte[] MakeAuthTag(ZWaveAES aesEngine, byte[] authKey, byte[] header, byte[] payload) { byte[] tempMAC = new byte[16]; aesEngine.AES_CBCMAC(authKey, header, payload, tempMAC); byte[] temp8bitMAC = new byte[8]; for (int i = 0; i < 8; i++) { temp8bitMAC[i] = tempMAC[i]; } //Tools._writeDebugDiagnosticMessage("****MAKE - AK:" + Tools.GetHex(authKey, "", false) + " header:" + Tools.GetHex(header, "", false) + " payload:" + Tools.GetHex(payload, "", false) + " code:" + Tools.GetHex(tempMAC, "", false)); return(temp8bitMAC); }
public static bool VerifyAuthTag(ZWaveAES aesEngine, byte[] authKey, byte[] header, byte[] payload, byte[] remoteMAC) { // Calculate actual MAC byte[] localMAC = new byte[16]; aesEngine.AES_CBCMAC(authKey, header, payload, localMAC); byte[] local8bitMAC = new byte[8]; for (int i = 0; i < 8; i++) { local8bitMAC[i] = localMAC[i]; } bool ret = Tools.ByteArrayEquals(local8bitMAC, remoteMAC); //Tools._writeDebugDiagnosticMessage("****VERF - AK:" + Tools.GetHex(authKey, "", false) + " header:" + Tools.GetHex(header, "", false) + " payload:" + Tools.GetHex(payload, "", false) + " code:" + Tools.GetHex(localMAC, "", false) + " remote:" + Tools.GetHex(remoteMAC, "", false)); return(ret); }
/// <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); } }