diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2019-02-19 22:09:04 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2019-02-19 23:24:50 +0100 |
commit | 1e127de5173e3b8fb62efc79f97651ca22694441 (patch) | |
tree | 968e3746893d764341d7902beb5656c37a7f8ddd /src/device.rs | |
parent | dbae67d6fbb1f8a310b8de820fcda34c31eed39f (diff) | |
download | ntw-1e127de5173e3b8fb62efc79f97651ca22694441.tar.gz ntw-1e127de5173e3b8fb62efc79f97651ca22694441.tar.bz2 |
Validate CRC of incoming data
The data sent with Set_Report requests contains a CRC which we so far
ignored. This patch adds a Crc struct that uses the CRC peripheral to
calculate the CRC for some data and uses it to validate the CRC of the
received data.
Diffstat (limited to 'src/device.rs')
-rw-r--r-- | src/device.rs | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/device.rs b/src/device.rs index 0df14ae..fc119d5 100644 --- a/src/device.rs +++ b/src/device.rs @@ -7,6 +7,7 @@ use usb_device::bus::{UsbBus, UsbBusAllocator}; use usb_device::device::{UsbDevice, UsbDeviceBuilder, UsbVidPid}; use crate::commands::{CommandId, COMMAND_LEN}; +use crate::crc::Crc; use crate::hid::{HidDevice, Protocol, ReportType, Subclass}; use crate::util::TryFrom; @@ -85,14 +86,18 @@ impl Response { } pub struct Nitrokey { + crc: Crc, request: Option<Request>, + request_crc: u32, buf: [u8; REPORT_LEN], } impl Nitrokey { - pub fn new() -> Self { + pub fn new(crc: Crc) -> Self { Nitrokey { + crc, request: None, + request_crc: 0, buf: [0; REPORT_LEN], } } @@ -118,12 +123,15 @@ impl HidDevice for Nitrokey { if let Some(ref request) = self.request { let mut response = Response::new(DeviceStatus::Ok, request.command_id, request.crc); - response.command_status = + response.command_status = if self.request_crc == request.crc { if let Ok(command_id) = CommandId::try_from(request.command_id) { command_id.execute(&request.data, &mut response.data) } else { CommandStatus::UnknownCommand - }; + } + } else { + CommandStatus::WrongCrc + }; // TODO: calculate actual CRC response.crc = 1; // libnitrokey accepts any non-zero value @@ -146,6 +154,8 @@ impl HidDevice for Nitrokey { } else { let (request, len) = ssmarshal::deserialize(data).map_err(|_| ())?; assert!(len == REPORT_LEN); + // the last four bytes are ignored as they contain the CRC + self.request_crc = self.crc.get(&data[..REPORT_LEN - 4]); self.request = Some(request); Ok(()) } |