aboutsummaryrefslogtreecommitdiff
path: root/src/device.rs
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-02-19 22:09:04 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-02-19 23:24:50 +0100
commit1e127de5173e3b8fb62efc79f97651ca22694441 (patch)
tree968e3746893d764341d7902beb5656c37a7f8ddd /src/device.rs
parentdbae67d6fbb1f8a310b8de820fcda34c31eed39f (diff)
downloadntw-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.rs16
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(())
}