Small CCID improvements

This commit is contained in:
Nicolas Stalder
2020-10-09 17:45:13 +02:00
parent f8c3a8ccf7
commit e74150c635
3 changed files with 65 additions and 30 deletions
+12 -3
View File
@@ -40,10 +40,13 @@ pub const CLOCK_FREQUENCY_KHZ: [u8; 4] = [0xfc, 0x0d, 0x00, 0x00];
// (not relevant, fixed fixed for legacy reasonse
// Yubico: 307200 bps, gnuk: 9600
// pub const DATA_RATE_BPS: [u8; 4] = [0x00, 0xb0, 0x04, 0x00];
// pub const DATA_RATE_BPS: [u8; 4] = [0x80, 0x25, 0x00, 0x00];
// ICCD spec: "9600bps, not relevant, fixed for legacy reason"
pub const DATA_RATE_BPS: [u8; 4] = [0x80, 0x25, 0x00, 0x00];
// 254 (as per ICCD spec)
// Yubico: 2038, gnuk: 254
// pub const MAX_IFSD: [u8; 4] = [0xf6, 0x07, 0x00, 0x00];
// ICCD spec: "For T = 1: 000000FEh"
pub const MAX_IFSD: [u8; 4] = [0xfe, 0x00, 0x00, 0x00];
// "The value shall be between 261 + 10 and 65544 + 10
@@ -62,9 +65,11 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
// bcdCCID rev1.10
0x10, 0x01,
// bMaxSlotIndex
NUM_SLOTS - 1,
// NUM_SLOTS - 1,
// "An USB-ICC is regarded as a single slot CCID."
0x00,
// bVoltageSupport (5.0V + 3.0V + 1.8V)
0x07,
0x01,
// dwProtocols: T=1 only (0 = T=0, 3 = T0+T1)
0x02, 0x00, 0x00, 0x00,
@@ -112,7 +117,10 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
// Auto baud rate change
// Auto parameter negotiation made by CCID
// Short and extended APDU level exchange
0xFE, 0x00, 0x04, 0x00,
// 0xFE, 0x00, 0x04, 0x00,
// ICCD: lower word (=0840): only requests valid for USB-ICC
// upper word: 0000 = char level, 0002 = short APDU, 0004 = short+exteded APDU
0x40, 0x08, 0x04, 0x00,
// dwMaxCCIDMsgLen (3072)
// gnuk: 271
@@ -128,6 +136,7 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
// wlcdLayout (none)
0x00, 0x00,
// bPinSupport
// ICCD: "No PIN pad, not relevant, fixed for legacy reasons"
PIN_SUPPORT,
// bMaxCCIDBusySlots
MAX_BUSY_SLOTS,
+8
View File
@@ -118,6 +118,14 @@ impl<N: ArrayLength<u8>> Der<N> {
self.extend_from_slice(value)
}
/// Write an arbitrary tag-length-value with 2-byte tag
/// NB: everything in ISO 7816 is big-endian
pub fn raw_tlv2(&mut self, tag: u16, value: &[u8]) -> Result {
self.extend_from_slice(&tag.to_be_bytes())?;
self.write_length_field(value.len())?;
self.extend_from_slice(value)
}
///// Write the given input as integer.
/////
///// Assumes `input` is the big-endian representation of a non-negative `Integer`
+45 -27
View File
@@ -380,6 +380,24 @@ where
let packet = DataBlock::new(
self.seq,
Chain::BeginsAndEnds,
// PivApplet just uses:
// 3B 80 80 01 01
//
// 3B 88 80 01 80 57 53 6F 6C 6F 20 42 83
// T=0, T=1, card issuer's data "Solo B"
// https://smartcard-atr.apdu.fr/parse?ATR=3B+88+80+01+80+57+53+6F+6C+6F+20+42+83
//
// T=0, T=1, command chaining/extended Lc+Le/no logical channels, card issuer's data "Solo B"
// 3B 8C 80 01 80 73 C0 21 C0 56 53 6F 6C 6F 20 42 D4
// https://smartcard-atr.apdu.fr/parse?ATR=3B+8C+80+01+80+73+C0+21+C0+56+53+6F+6C+6F+20+42+D4
b";\x8c\x80\x01\x80s\xc0!\xc0VSolo B\xd4"
//
// Not sure if we also need some TA/TB/TC data as in
// https://smartcard-atr.apdu.fr/parse?ATR=3B+F8+13+00+00+81+31+FE+15+59+75+62+69+6B+65+79+34+D4
// At least TB(1) is deprecated, so it makes no sense
// Also, there TD(1) = 0x81 and TD(2) = 0x31 both refer to protocol T=1 which seems wrong
// don't remember where i got this from
// &[0x3b, 0x8c,0x80,0x01],
// "corrected"?
@@ -400,37 +418,37 @@ where
// ],
// Yubikey FIDO+CCID
// 3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4
&[
// TS
0x3b,
// TO = TA1, TB1, TB2, TB3 follow, 8 historical bytes
0xf8,
// &[
// // TS
// 0x3b,
// // TO = TA1, TB1, TB2, TB3 follow, 8 historical bytes
// 0xf8,
// TA1 = default clock (5MHz), default clock rate conversion (372)o
// But sets Di to 3 instead of default of 1
0x13,
// TB1 deprecated, should not transmit
0x00,
// TC1 = "extra guard time", default of 0
0x00,
// // TA1 = default clock (5MHz), default clock rate conversion (372)o
// // But sets Di to 3 instead of default of 1
// 0x13,
// // TB1 deprecated, should not transmit
// 0x00,
// // TC1 = "extra guard time", default of 0
// 0x00,
// TD1 = (Y2, T) -> follows D2, T = 1
0x81,
// TD2 = (Y2, T)
0x31,
// TA2
0xfe,
// TB2
0x15,
// T1 = first historical byte
0x59,
// // TD1 = (Y2, T) -> follows D2, T = 1
// 0x81,
// // TD2 = (Y2, T)
// 0x31,
// // TA2
// 0xfe,
// // TB2
// 0x15,
// // T1 = first historical byte
// 0x59,
// "SoloBee"
0x53, 0x6F, 0x6C, 0x6F, 0x42, 0x65 ,0x65,
// // "SoloBee"
// 0x53, 0x6F, 0x6C, 0x6F, 0x42, 0x65 ,0x65,
// Checksum
0x94,
],
// // Checksum
// 0x94,
// ],
// Yubikey NEO OTP+U2F+CCID
// 3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1
);