Merge pull request #1 from trussed-dev/nitrokey-upstreaming

Upstream changes from the Nitrokey firmware repository
This commit is contained in:
Robin Krahl
2023-01-25 11:25:38 +01:00
committed by GitHub
7 changed files with 49 additions and 35 deletions
+8 -4
View File
@@ -66,7 +66,7 @@ where
}
pub fn did_start_processing(&mut self) -> Status {
if self.pipe.did_started_processing() {
if self.pipe.did_start_processing() {
// We should send a wait extension later
Status::ReceivedData(1_000.milliseconds())
} else {
@@ -137,15 +137,19 @@ where
packet.resize_default(packet.capacity()).unwrap();
let result = self.read.read(&mut packet);
result.map(|count| {
packet.resize_default(count).unwrap();
assert!(count <= packet.len());
packet.truncate(count);
packet
})
};
// should we return an error message
// if the raw packet is invalid?
if let Ok(packet) = maybe_packet {
self.pipe.handle_packet(packet);
match maybe_packet {
Ok(packet) => self.pipe.handle_packet(packet),
Err(_err) => {
error!("Failed to read packet: {:?}", _err);
}
}
}
+3 -1
View File
@@ -4,6 +4,8 @@ pub const PACKET_SIZE: usize = 512;
#[cfg(not(feature = "highspeed-usb"))]
pub const PACKET_SIZE: usize = 64;
pub const CCID_HEADER_LEN: usize = 10;
pub const CLASS_CCID: u8 = 0x0B;
pub const SUBCLASS_NONE: u8 = 0x0;
@@ -39,7 +41,7 @@ pub const MAX_IFSD: [u8; 4] = [0xfe, 0x00, 0x00, 0x00];
// "The value shall be between 261 + 10 and 65544 + 10
// dwMaxCCIDMsgLen 3072
pub const MAX_MSG_LENGTH: usize = 3072;
pub const MAX_MSG_LENGTH_LE: [u8; 4] = [0x00, 0x0C, 0x00, 0x00];
pub const MAX_MSG_LENGTH_LE: [u8; 4] = (MAX_MSG_LENGTH as u32).to_le_bytes();
pub const NUM_SLOTS: u8 = 1;
pub const MAX_BUSY_SLOTS: u8 = 1;
+7 -2
View File
@@ -1,7 +1,12 @@
#![no_std]
//! https://www.usb.org/sites/default/files/DWG_Smart-Card_CCID_Rev110.pdf
//! https://www.usb.org/sites/default/files/DWG_Smart-Card_USB-ICC_ICCD_rev10.pdf
//! CCID descriptor and USB CCID class implementation.
//!
//! This crate implements CCID communication to a USB host, and sends the resulting APDUs to an [Interchange](https://docs.rs/interchange)
//!
//! [CCID Specification for Integrated Circuit(s) Cards Interface Devices](https://www.usb.org/sites/default/files/DWG_Smart-Card_CCID_Rev110.pdf)
//!
//! [CCID SpecificationUSB Integrated Circuit(s) Card Devices](https://www.usb.org/sites/default/files/DWG_Smart-Card_USB-ICC_ICCD_rev10.pdf)
#[macro_use]
extern crate delog;
+17 -16
View File
@@ -12,6 +12,9 @@ use crate::{
use usb_device::class_prelude::*;
// Const assertion
const _: [(); 0 - !{ MAX_MSG_LENGTH >= PACKET_SIZE } as usize] = [];
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum State {
Idle,
@@ -65,8 +68,6 @@ where
request_pipe: Requester<I>,
card_issuers_data: Option<&[u8]>,
) -> Self {
// assert!(MAX_MSG_LENGTH >= PACKET_SIZE);
Self {
write,
seq: 0,
@@ -144,18 +145,18 @@ where
// when certificates are transmitted, because PIV somehow uses short APDUs
// only (can we fix this), so 255B is the maximum)
if !self.receiving_long {
if packet.len() < 10 {
if packet.len() < CCID_HEADER_LEN {
panic!("unexpected short packet");
}
self.ext_packet.clear();
// TODO check
self.ext_packet.extend_from_slice(&packet).unwrap();
let pl = packet.packet_len();
if pl > 54 {
let pl = packet.data_len();
if pl > PACKET_SIZE - CCID_HEADER_LEN {
self.receiving_long = true;
self.in_chain = 1;
self.long_packet_missing = pl - 54;
self.long_packet_missing = pl - PACKET_SIZE - CCID_HEADER_LEN;
self.packet_len = pl;
return;
} else {
@@ -303,7 +304,7 @@ where
if self.state == State::Processing {
// Need to send a wait extension request.
let mut packet = RawPacket::new();
packet.resize_default(10).ok();
packet.resize_default(CCID_HEADER_LEN).ok();
packet[0] = 0x80;
packet[6] = self.seq;
@@ -322,7 +323,7 @@ where
}
/// Turns false on read. Intended for checking to see if a wait extension request needs to be started.
pub fn did_started_processing(&mut self) -> bool {
pub fn did_start_processing(&mut self) -> bool {
if self.started_processing {
self.started_processing = false;
true
@@ -342,7 +343,7 @@ where
#[inline(never)]
pub fn poll_app(&mut self) {
if let State::Processing = self.state {
if State::Processing == self.state {
// info!("processing, checking for response, interchange state {:?}",
// self.interchange.state()).ok();
@@ -361,13 +362,14 @@ where
}
if self.outbox.is_some() {
panic!();
panic!("Full outbox");
}
// if let Some(message) = self.interchange.response() {
let message: &mut Vec<u8, N> = unsafe { (*self.interchange.interchange.get()).rp_mut() };
let Some(message) = self.interchange.response() else {
panic!("No response while priming outbox");
};
let chunk_size = core::cmp::min(PACKET_SIZE - 10, message.len() - self.sent);
let chunk_size = core::cmp::min(PACKET_SIZE - CCID_HEADER_LEN, message.len() - self.sent);
let chunk = &message[self.sent..][..chunk_size];
self.sent += chunk_size;
let more = self.sent < message.len();
@@ -398,7 +400,6 @@ where
// fast-lane response attempt
self.maybe_send_packet();
// }
}
fn send_empty_datablock(&mut self, chain: Chain) {
@@ -408,7 +409,7 @@ where
fn send_slot_status_ok(&mut self) {
let mut packet = RawPacket::new();
packet.resize_default(10).ok();
packet.resize_default(CCID_HEADER_LEN).ok();
packet[0] = 0x81;
packet[6] = self.seq;
self.send_packet_assuming_possible(packet);
@@ -416,7 +417,7 @@ where
fn send_slot_status_error(&mut self, error: Error) {
let mut packet = RawPacket::new();
packet.resize_default(10).ok();
packet.resize_default(CCID_HEADER_LEN).ok();
packet[0] = 0x6c;
packet[6] = self.seq;
packet[7] = 1 << 6;
-1
View File
@@ -2,7 +2,6 @@ use embedded_time::duration::Milliseconds;
// pub mod apdu;
pub mod packet;
pub mod tlv;
// pub type MessageBuffer = apdu_dispatch::interchanges::Data;
+14 -10
View File
@@ -1,4 +1,4 @@
use core::convert::TryInto;
use core::convert::{TryFrom, TryInto};
use crate::constants::*;
@@ -6,11 +6,11 @@ pub type RawPacket = heapless::Vec<u8, PACKET_SIZE>;
pub type ExtPacket = heapless::Vec<u8, MAX_MSG_LENGTH>;
pub trait RawPacketExt {
fn packet_len(&self) -> usize;
fn data_len(&self) -> usize;
}
impl RawPacketExt for RawPacket {
fn packet_len(&self) -> usize {
fn data_len(&self) -> usize {
u32::from_le_bytes(self[1..5].try_into().unwrap()) as usize
}
}
@@ -45,9 +45,9 @@ pub trait PacketWithData: Packet {
fn data(&self) -> &[u8] {
// let len = u32::from_le_bytes(self[1..5].try_into().unwrap()) as usize;
let declared_len = u32::from_le_bytes(self[1..5].try_into().unwrap()) as usize;
let len = core::cmp::min(MAX_MSG_LENGTH - 10, declared_len);
let len = core::cmp::min(MAX_MSG_LENGTH - CCID_HEADER_LEN, declared_len);
// hprintln!("delcared = {}, len = {}", declared_len, len).ok();
&self[10..][..len]
&self[CCID_HEADER_LEN..][..len]
}
}
@@ -76,7 +76,7 @@ pub struct DataBlock<'a> {
impl<'a> DataBlock<'a> {
pub fn new(seq: u8, chain: Chain, data: &'a [u8]) -> Self {
assert!(data.len() + 10 <= PACKET_SIZE);
assert!(data.len() + CCID_HEADER_LEN <= PACKET_SIZE);
Self { seq, chain, data }
}
}
@@ -117,9 +117,13 @@ impl From<DataBlock<'_>> for RawPacket {
fn from(block: DataBlock<'_>) -> RawPacket {
let mut packet = RawPacket::new();
let len = block.data.len();
packet.resize_default(10 + len).ok();
packet.resize_default(CCID_HEADER_LEN + len).ok();
packet[0] = 0x80;
packet[1..][..4].copy_from_slice(&len.to_le_bytes());
packet[1..][..4].copy_from_slice(
&u32::try_from(len)
.expect("Packets should not be more than 4GiB")
.to_le_bytes(),
);
packet[5] = 0;
packet[6] = block.seq;
@@ -129,7 +133,7 @@ impl From<DataBlock<'_>> for RawPacket {
packet[8] = 0;
// chain parameter
packet[9] = block.chain as u8;
packet[10..][..len].copy_from_slice(block.data);
packet[CCID_HEADER_LEN..][..len].copy_from_slice(block.data);
packet
}
@@ -220,7 +224,7 @@ macro_rules! command_message {
fn try_from(packet: ExtPacket)
-> core::result::Result<Self, Self::Error>
{
if packet.len() < 10 {
if packet.len() <CCID_HEADER_LEN {
return Err(Error::ShortPacket);
}
if packet[5] != 0 {
-1
View File
@@ -1 +0,0 @@