From 1e127de5173e3b8fb62efc79f97651ca22694441 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 19 Feb 2019 22:09:04 +0000 Subject: 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. --- src/device.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/device.rs') 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_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(()) } -- cgit v1.2.1