protected virtual byte[] GetMacArray(byte senderNodeId, byte receiverNodeId, byte[] IV, byte cmdId, byte[] payload) { byte[] header = new byte[20]; Array.Copy(IV, 0, header, 0, IV.Length); header[16] = cmdId; header[17] = senderNodeId; header[18] = receiverNodeId; header[19] = (byte)payload.Length; return(SecurityS0Utils.MakeAuthTag(AesEngine, _authKey, header, payload)); }
public static byte[] DecryptPayload(byte[] externalNonce, byte[] internalNonce, byte[] securityKey, byte[] message) { ZWaveAES AES = new ZWaveAES(); byte[] _authKey = new byte[16]; byte[] _encKey = new byte[16]; SecurityS0Utils.LoadKeys(AES, securityKey, out _authKey, out _encKey); byte[] _IV = new byte[16]; Array.Copy(internalNonce, 0, _IV, 0, internalNonce.Length); Array.Copy(externalNonce, 0, _IV, 8, externalNonce.Length); SecurityS0Utils.Decrypt(AES, _encKey, _IV, ref message); return(message); }
public static byte[] EncryptCommand(byte property, byte[] command, byte senderNodeId, byte receiverNodeId, byte[] internalNonce, byte[] externalNonce, byte[] networkKey, bool isWithNonceGet) { byte[] _authKey = new byte[16]; byte[] _encKey = new byte[16]; COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION.Tproperties1 prop = property; COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION ret = new COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION(); ret.initializationVectorByte = internalNonce; byte[] payload = new byte[command.Length + 1]; payload[0] = prop; Array.Copy(command, 0, payload, 1, command.Length); byte[] IV = new byte[16]; Array.Copy(internalNonce, 0, IV, 0, 8); Array.Copy(externalNonce, 0, IV, 8, 8); ZWaveAES _aesEngine = new ZWaveAES(); SecurityS0Utils.LoadKeys(_aesEngine, networkKey, out _authKey, out _encKey); SecurityS0Utils.Encrypt(_aesEngine, _encKey, IV, ref payload); ret.properties1 = payload[0]; if (payload.Length > 0) { ret.commandByte = new List <byte>(); for (int i = 1; i < payload.Length; i++) { ret.commandByte.Add(payload[i]); } } ret.receiversNonceIdentifier = externalNonce[0]; byte[] header = new byte[20]; Array.Copy(IV, 0, header, 0, IV.Length); header[16] = COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION.ID; if (isWithNonceGet) { header[16] = COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION_NONCE_GET.ID; } else { header[16] = COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION.ID; } header[17] = senderNodeId; header[18] = receiverNodeId; header[19] = (byte)payload.Length; ret.messageAuthenticationCodeByte = SecurityS0Utils.MakeAuthTag(_aesEngine, _authKey, header, payload); return(ret); }
public byte[] Encrypt(byte property, byte[] command, byte senderNodeId, byte receiverNodeId, byte[] externalNonce1) { COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION ret = new COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION(); COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION.Tproperties1 prop = property; byte[] payload = new byte[command.Length + 1]; payload[0] = GetPropertyByte(property); Array.Copy(command, 0, payload, 1, command.Length); var internalNonce = GetInternalNonceArray(senderNodeId, receiverNodeId); ret.initializationVectorByte = internalNonce; var externalNonce = GetExternalNonceArray(externalNonce1); if (internalNonce != null && internalNonce.Length == 8 && externalNonce != null && externalNonce.Length == 8) { byte[] IV = new byte[16]; Array.Copy(internalNonce, 0, IV, 0, 8); Array.Copy(externalNonce, 0, IV, 8, 8); SecurityS0Utils.Encrypt(AesEngine, _encKey, IV, ref payload); ret.properties1 = payload[0]; if (payload.Length > 0) { ret.commandByte = new List <byte>(); for (int i = 1; i < payload.Length; i++) { ret.commandByte.Add(payload[i]); } } ret.receiversNonceIdentifier = GetNonceIdByte(externalNonce); byte cmdId; if (prop.sequenced > 0 && prop.secondFrame == 0) { cmdId = COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION_NONCE_GET.ID; } else { cmdId = COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION.ID; } ret.messageAuthenticationCodeByte = GetMacArray(senderNodeId, receiverNodeId, IV, cmdId, payload); } return(ret); }
private byte[] Decrypt(COMMAND_CLASS_SECURITY.SECURITY_MESSAGE_ENCAPSULATION cmd, byte cmdId, byte senderNodeId, byte receivedNodeId, out byte decryptedProperties) { decryptedProperties = 0; byte[] ret = null; byte[] internalNonce = NonceS0Storage.Find(new OrdinalPeerNodeId(senderNodeId, receivedNodeId), cmd.receiversNonceIdentifier); if (internalNonce != null) { byte[] IV = new byte[16]; Array.Copy(cmd.initializationVectorByte.ToArray(), 0, IV, 0, 8); Array.Copy(internalNonce, 0, IV, 8, 8); int len = 1; if (cmd.commandByte != null) { len += cmd.commandByte.Count; } byte[] payload = new byte[len]; payload[0] = cmd.properties1; for (int i = 0; i < len - 1; i++) { payload[i + 1] = cmd.commandByte[i]; } byte[] header = new byte[20]; Array.Copy(IV, 0, header, 0, IV.Length); header[16] = cmdId; header[17] = senderNodeId; header[18] = receivedNodeId; header[19] = (byte)payload.Length; if (SecurityS0Utils.VerifyAuthTag(AesEngine, _authKey, header, payload, cmd.messageAuthenticationCodeByte.ToArray())) { SecurityS0Utils.Decrypt(AesEngine, _encKey, IV, ref payload); ret = new byte[payload.Length - 1]; // exclude properties Array.Copy(payload, 1, ret, 0, ret.Length); decryptedProperties = payload[0]; } else { "^{0} <<|<< {1} {2}"._DLOG(0, "N/D", internalNonce.GetHex()); } } else { "^{0} <<|<< {1} {2}"._DLOG(0, "N/D", "N/Nonce"); } return(ret); }
public void OnNetworkKeyS0Changed(byte[] networkKey) { SecurityS0Utils.LoadKeys(AesEngine, networkKey, out _authKey, out _encKey); }