chore: fix warning as reported by cargo cippy

This commit is contained in:
Alexander Sieg 2022-05-25 18:44:32 +02:00
parent b2256e49ea
commit 2717df14b2
No known key found for this signature in database
11 changed files with 58 additions and 65 deletions

View File

@ -13,19 +13,19 @@ impl Cipher for AES {
const KEY_SIZE: usize = 16; const KEY_SIZE: usize = 16;
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = Aes128Cbc::new_from_slices(&key, &iv)?; let cipher = Aes128Cbc::new_from_slices(key, iv)?;
return Ok(cipher.encrypt_vec(data)); Ok(cipher.encrypt_vec(data))
} }
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = Aes128Cbc::new_from_slices(&key, &iv)?; let cipher = Aes128Cbc::new_from_slices(key, iv)?;
let result = cipher.decrypt_vec(data); let result = cipher.decrypt_vec(data);
return match result { match result {
Ok(data) => Ok(data), Ok(data) => Ok(data),
Err(err) => Err(Error::BlockModeError(err)), Err(err) => Err(Error::BlockModeError(err)),
}; }
} }
} }

View File

@ -14,19 +14,19 @@ impl Cipher for Tdes {
const KEY_SIZE: usize = 16; const KEY_SIZE: usize = 16;
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?; let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
return Ok(cipher.encrypt_vec(data)); Ok(cipher.encrypt_vec(data))
} }
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?; let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
let result = cipher.decrypt_vec(data); let result = cipher.decrypt_vec(data);
return match result { match result {
Ok(data) => Ok(data), Ok(data) => Ok(data),
Err(err) => Err(Error::BlockModeError(err)), Err(err) => Err(Error::BlockModeError(err)),
}; }
} }
} }

View File

@ -14,19 +14,19 @@ impl Cipher for Tdes2k {
const KEY_SIZE: usize = 16; const KEY_SIZE: usize = 16;
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?; let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
return Ok(cipher.encrypt_vec(data)); Ok(cipher.encrypt_vec(data))
} }
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?; let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
let result = cipher.decrypt_vec(data); let result = cipher.decrypt_vec(data);
return match result { match result {
Ok(data) => Ok(data), Ok(data) => Ok(data),
Err(err) => Err(Error::BlockModeError(err)), Err(err) => Err(Error::BlockModeError(err)),
}; }
} }
} }

View File

@ -14,19 +14,19 @@ impl Cipher for Tdes3k {
const KEY_SIZE: usize = 24; const KEY_SIZE: usize = 24;
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = TDesEde3Cbc::new_from_slices(&key, &iv)?; let cipher = TDesEde3Cbc::new_from_slices(key, iv)?;
return Ok(cipher.encrypt_vec(data)); Ok(cipher.encrypt_vec(data))
} }
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
let cipher = TDesEde3Cbc::new_from_slices(&key, &iv)?; let cipher = TDesEde3Cbc::new_from_slices(key, iv)?;
let result = cipher.decrypt_vec(data); let result = cipher.decrypt_vec(data);
return match result { match result {
Ok(data) => Ok(data), Ok(data) => Ok(data),
Err(err) => Err(Error::BlockModeError(err)), Err(err) => Err(Error::BlockModeError(err)),
}; }
} }
} }

View File

@ -74,11 +74,7 @@ pub fn get_key_size(cipher: CipherType) -> usize {
/// Check Key Slice /// Check Key Slice
pub fn check_key(key: &[u8], cipher: CipherType) -> bool { pub fn check_key(key: &[u8], cipher: CipherType) -> bool {
if key.len() != get_key_size(cipher) { key.len() == get_key_size(cipher)
false
} else {
true
}
} }
/// Set Key Version for DES/TDES Keys /// Set Key Version for DES/TDES Keys

View File

@ -20,9 +20,9 @@ pub fn expand_to_blocksize(data: &mut [u8], blocksize: usize) -> Result<Vec<u8>>
let diff = data.len() % blocksize; let diff = data.len() % blocksize;
if diff == 0 { if diff == 0 {
return Ok(data.to_vec()); Ok(data.to_vec())
} else { } else {
let mut buf = vec![0 as u8; data.len() + blocksize - diff]; let mut buf = vec![0_u8; data.len() + blocksize - diff];
buf[..data.len()].copy_from_slice(data); buf[..data.len()].copy_from_slice(data);
Ok(buf) Ok(buf)
} }

View File

@ -93,7 +93,7 @@ impl Desfire {
let rnd_b_enc = rnd_b_response_body.as_slice(); let rnd_b_enc = rnd_b_response_body.as_slice();
// println!("RND_B_ENC: {:x?}", rnd_b_enc); // println!("RND_B_ENC: {:x?}", rnd_b_enc);
let rnd_b = Tdes::decrypt(rnd_b_enc, key, vec![0 as u8; 8].as_slice()).unwrap(); let rnd_b = Tdes::decrypt(rnd_b_enc, key, vec![0_u8; 8].as_slice()).unwrap();
// println!("RND_B: {:x?}", rnd_b); // println!("RND_B: {:x?}", rnd_b);
let mut rnd_b_rl = rnd_b.clone(); let mut rnd_b_rl = rnd_b.clone();
@ -153,7 +153,7 @@ impl Desfire {
self.session_key = Some(generate_session_key_des(&rnd_a, rnd_b.as_slice()).unwrap()); self.session_key = Some(generate_session_key_des(&rnd_a, rnd_b.as_slice()).unwrap());
// println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap()); // println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap());
self.cbc_iv = Some(vec![0 as u8; 8]); self.cbc_iv = Some(vec![0_u8; 8]);
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap()); // println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
Ok(()) Ok(())
} }
@ -184,7 +184,7 @@ impl Desfire {
) -> Result<(APDUCommand, Vec<u8>, Vec<u8>)> { ) -> Result<(APDUCommand, Vec<u8>, Vec<u8>)> {
// println!("RND_B_ENC: {:x?}", challenge); // println!("RND_B_ENC: {:x?}", challenge);
let rnd_b = AES::decrypt(challenge, key, vec![0 as u8; 16].as_slice()).unwrap(); let rnd_b = AES::decrypt(challenge, key, vec![0_u8; 16].as_slice()).unwrap();
// println!("RND_B: {:x?}", rnd_b); // println!("RND_B: {:x?}", rnd_b);
// auth_iv = rnd_b.clone(); // auth_iv = rnd_b.clone();
@ -192,7 +192,7 @@ impl Desfire {
rnd_b_rl.rotate_left(1); rnd_b_rl.rotate_left(1);
// println!("RND_B_RL: {:x?}", rnd_b_rl); // println!("RND_B_RL: {:x?}", rnd_b_rl);
let rnd_ab = [&rnd_a, rnd_b_rl.as_slice()].concat(); let rnd_ab = [rnd_a, rnd_b_rl.as_slice()].concat();
// println!("RND_AB: {:x?}", rnd_ab); // println!("RND_AB: {:x?}", rnd_ab);
let rnd_ab_enc = AES::encrypt(rnd_ab.as_slice(), key, challenge).unwrap(); let rnd_ab_enc = AES::encrypt(rnd_ab.as_slice(), key, challenge).unwrap();
@ -233,8 +233,8 @@ impl Desfire {
self.session_key = Some(generate_session_key_aes(expected_response, challenge).unwrap()); self.session_key = Some(generate_session_key_aes(expected_response, challenge).unwrap());
// println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap()); // println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap());
self.cbc_iv = Some(vec![0 as u8; 16]); //FIXME: this should be a random value self.cbc_iv = Some(vec![0_u8; 16]); //FIXME: this should be a random value
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap()); // println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
Ok(()) Ok(())
} }
@ -619,7 +619,7 @@ impl Desfire {
ret = response.check(); ret = response.check();
} }
return ret; ret
} }
pub fn read_data_chunk_cmd( pub fn read_data_chunk_cmd(
@ -648,7 +648,7 @@ impl Desfire {
..Default::default() ..Default::default()
}; };
return Ok(cmd_read_data_chunk); Ok(cmd_read_data_chunk)
} }
/// Read data from a file /// Read data from a file
@ -685,13 +685,13 @@ impl Desfire {
let response = self.card.as_ref().unwrap().transmit(cmd_read_data).unwrap(); let response = self.card.as_ref().unwrap().transmit(cmd_read_data).unwrap();
// println!("RESPONSE: {}", response); // println!("RESPONSE: {}", response);
response.check().or_else(|e| return Err(e))?; response.check().map_err(|e| e)?;
// // println!("RESPONSE_DATA: {:x?}, WITHOUT_CMAC: {:x?}", response.body.as_ref().unwrap(), response.body.as_ref().unwrap()[..bytes_toread].to_vec()); // // println!("RESPONSE_DATA: {:x?}, WITHOUT_CMAC: {:x?}", response.body.as_ref().unwrap(), response.body.as_ref().unwrap()[..bytes_toread].to_vec());
read_buffer.append(&mut response.body.unwrap()[..bytes_toread].to_vec()); read_buffer.append(&mut response.body.unwrap()[..bytes_toread].to_vec());
} }
return Ok(read_buffer); Ok(read_buffer)
} }
} }
@ -726,7 +726,7 @@ pub fn generate_keysetting1(
file_directory_access: FileDirectoryAccess, file_directory_access: FileDirectoryAccess,
change_master_key: ChangeMasterKey, change_master_key: ChangeMasterKey,
) -> Result<u8> { ) -> Result<u8> {
return match FromPrimitive::from_u8(change_key) { match FromPrimitive::from_u8(change_key) {
Some(ChangeApplicationKey::MASTERKEY) Some(ChangeApplicationKey::MASTERKEY)
| Some(ChangeApplicationKey::SAMEKEY) | Some(ChangeApplicationKey::SAMEKEY)
| Some(ChangeApplicationKey::ALLKEYS) => Ok((change_key << 4) | Some(ChangeApplicationKey::ALLKEYS) => Ok((change_key << 4)
@ -735,7 +735,7 @@ pub fn generate_keysetting1(
| file_directory_access as u8 | file_directory_access as u8
| change_master_key as u8), | change_master_key as u8),
None => { None => {
if change_key < 0x01 || change_key >= 0x08 { if !(0x01..0x08).contains(&change_key) {
Err(InvalidKeyID) Err(InvalidKeyID)
} else { } else {
Ok((change_key << 4) Ok((change_key << 4)
@ -745,7 +745,7 @@ pub fn generate_keysetting1(
| change_master_key as u8) | change_master_key as u8)
} }
} }
}; }
} }
/// Generate KeySetting2 for Application Creation /// Generate KeySetting2 for Application Creation
@ -759,11 +759,11 @@ pub fn generate_keysetting2(
file_identifier: FileIdentifiers, file_identifier: FileIdentifiers,
num_keys: u8, num_keys: u8,
) -> Result<u8> { ) -> Result<u8> {
return if num_keys < 0x01 || num_keys >= 0x0D { if !(0x01..0x0D).contains(&num_keys) {
Err(NumKeys) Err(NumKeys)
} else { } else {
Ok(crypto_operations as u8 | file_identifier as u8 | num_keys) Ok(crypto_operations as u8 | file_identifier as u8 | num_keys)
}; }
} }
/// Generate FileAccess Rights for File Settings /// Generate FileAccess Rights for File Settings
@ -784,14 +784,14 @@ pub fn generate_file_access_rights(
read_write: u8, read_write: u8,
configure: u8, configure: u8,
) -> Result<u16> { ) -> Result<u16> {
return if read > 0x0F || write >= 0x0F || read_write >= 0x0F || configure >= 0x0F { if read > 0x0F || write >= 0x0F || read_write >= 0x0F || configure >= 0x0F {
Err(InvalidKeyID) Err(InvalidKeyID)
} else { } else {
Ok((((read as u16) << 12) Ok((((read as u16) << 12)
| ((write as u16) << 8) | ((write as u16) << 8)
| ((read_write as u16) << 4) | ((read_write as u16) << 4)
| configure as u16) as u16) | configure as u16) as u16)
}; }
} }
#[cfg(test)] #[cfg(test)]
@ -876,12 +876,12 @@ mod tests {
#[test] #[test]
fn generate_sessionkey_des() { fn generate_sessionkey_des() {
let rndA = hex!("a541a9dc9138df07"); let rnd_a = hex!("a541a9dc9138df07");
let rndB = hex!("cbe55aa893b2da25"); let rnd_b = hex!("cbe55aa893b2da25");
let expected_sessionkey = hex!("a541a9dccbe55aa8a541a9dccbe55aa8"); let expected_sessionkey = hex!("a541a9dccbe55aa8a541a9dccbe55aa8");
let sessionkey = generate_session_key_des(&rndA, &rndB).unwrap(); let sessionkey = generate_session_key_des(&rnd_a, &rnd_b).unwrap();
// println!("expected sessionkey: {:X?}", expected_sessionkey); // println!("expected sessionkey: {:X?}", expected_sessionkey);
// println!("actual sessionkey: {:X?}", sessionkey.as_slice()); // println!("actual sessionkey: {:X?}", sessionkey.as_slice());
@ -891,12 +891,12 @@ mod tests {
#[test] #[test]
fn generate_sessionkey_aes() { fn generate_sessionkey_aes() {
let rndA = hex!("bc14dfde20074617e45a8822f06fdd91"); let rnd_a = hex!("bc14dfde20074617e45a8822f06fdd91");
let rndB = hex!("482ddc54426e6dee560413b8d95471f5"); let rnd_b = hex!("482ddc54426e6dee560413b8d95471f5");
let expected_sessionkey = hex!("bc14dfde482ddc54f06fdd91d95471f5"); let expected_sessionkey = hex!("bc14dfde482ddc54f06fdd91d95471f5");
let sessionkey = generate_session_key_aes(&rndA, &rndB).unwrap(); let sessionkey = generate_session_key_aes(&rnd_a, &rnd_b).unwrap();
// println!("expected sessionkey: {:X?}", expected_sessionkey); // println!("expected sessionkey: {:X?}", expected_sessionkey);
// println!("actual sessionkey: {:X?}", sessionkey.as_slice()); // println!("actual sessionkey: {:X?}", sessionkey.as_slice());
@ -1092,7 +1092,7 @@ mod tests {
}) })
}); });
let rndA = hex!("5f7d1dd12d979173"); let rnd_a = hex!("5f7d1dd12d979173");
let key = CipherKey::new_empty(CipherType::TDES).unwrap(); let key = CipherKey::new_empty(CipherType::TDES).unwrap();
// println!("{:x?}", key.key.deref()); // println!("{:x?}", key.key.deref());
@ -1103,7 +1103,7 @@ mod tests {
}; };
desfire desfire
.authenticate_iso_des(0x00, key.key.as_ref(), Some(rndA)) .authenticate_iso_des(0x00, key.key.as_ref(), Some(rnd_a))
.unwrap(); .unwrap();
let sessionkey_expected = hex!("5f7d1dd1f449db5c5f7d1dd1f449db5c"); let sessionkey_expected = hex!("5f7d1dd1f449db5c5f7d1dd1f449db5c");
@ -1207,7 +1207,7 @@ mod tests {
body: Some(hex!("8fdc476f6bac44fe9150e285abd68d48").to_vec()) body: Some(hex!("8fdc476f6bac44fe9150e285abd68d48").to_vec())
})); }));
let rndA = hex!("2176770e7a6eb4bef00d5e4b201d1e57"); let rnd_a = hex!("2176770e7a6eb4bef00d5e4b201d1e57");
let key = CipherKey::new_empty(CipherType::AES).unwrap(); let key = CipherKey::new_empty(CipherType::AES).unwrap();
// println!("{:x?}", key.key.deref()); // println!("{:x?}", key.key.deref());
@ -1218,7 +1218,7 @@ mod tests {
}; };
desfire desfire
.authenticate_iso_aes(0x00, key.key.as_ref(), Some(rndA)) .authenticate_iso_aes(0x00, key.key.as_ref(), Some(rnd_a))
.unwrap(); .unwrap();
let sessionkey_expected = hex!("2176770e11c512ca201d1e57fde6e15a"); let sessionkey_expected = hex!("2176770e11c512ca201d1e57fde6e15a");

View File

@ -116,5 +116,6 @@ pub enum FileTypes {
mod apduinstructions; mod apduinstructions;
mod apdustatuscodes; mod apdustatuscodes;
#[allow(clippy::module_inception)]
pub mod desfire; pub mod desfire;
pub use crate::desfire::desfire::Desfire; pub use crate::desfire::desfire::Desfire;

View File

@ -113,12 +113,7 @@ impl TryFrom<APDUCommand> for Vec<u8> {
type Error = Error; type Error = Error;
fn try_from(cmd: APDUCommand) -> Result<Self> { fn try_from(cmd: APDUCommand) -> Result<Self> {
let mut v: Vec<u8> = vec![]; let mut v = vec![cmd.cla, cmd.ins, cmd.p1, cmd.p2];
//build header
v.push(cmd.cla);
v.push(cmd.ins);
v.push(cmd.p1);
v.push(cmd.p2);
//build body according to case //build body according to case
match cmd.case { match cmd.case {

View File

@ -56,7 +56,8 @@ impl APDUResponse {
pub fn new(raw: &[u8]) -> Self { pub fn new(raw: &[u8]) -> Self {
if raw.len() < 2 { if raw.len() < 2 {
panic!("APDU response must be at least 2 bytes long"); panic!("APDU response must be at least 2 bytes long");
} else if raw.len() == 2 { }
if raw.len() == 2 {
APDUResponse { APDUResponse {
body: None, body: None,
sw1: raw[0], sw1: raw[0],
@ -104,7 +105,7 @@ impl APDUResponse {
pub fn check(&self) -> Result<()> { pub fn check(&self) -> Result<()> {
if self.sw1 == 0x91 { if self.sw1 == 0x91 {
return match FromPrimitive::from_u8(self.sw2) { match FromPrimitive::from_u8(self.sw2) {
Some(APDUStatusWord2::OperationOk) => Ok(()), Some(APDUStatusWord2::OperationOk) => Ok(()),
Some(APDUStatusWord2::NoChanges) => Ok(()), Some(APDUStatusWord2::NoChanges) => Ok(()),
Some(APDUStatusWord2::IllegalCommandCode) => Err(IllegalCommandCode), Some(APDUStatusWord2::IllegalCommandCode) => Err(IllegalCommandCode),
@ -122,7 +123,7 @@ impl APDUResponse {
Some(APDUStatusWord2::FileNotFound) => Err(FileNotFound), Some(APDUStatusWord2::FileNotFound) => Err(FileNotFound),
Some(APDUStatusWord2::ApplicationNotFound) => Err(ApplicationNotFound), Some(APDUStatusWord2::ApplicationNotFound) => Err(ApplicationNotFound),
None => Err(InvalidStatusWord), None => Err(InvalidStatusWord),
}; }
} else { } else {
Err(InvalidStatusWord) Err(InvalidStatusWord)
} }

View File

@ -3,7 +3,7 @@ use num_derive::FromPrimitive;
#[derive(FromPrimitive)] #[derive(FromPrimitive)]
#[repr(u16)] #[repr(u16)]
pub enum APDUStatusWord { pub enum APDUStatusWord {
/// Kommando erfolgreich ausgefhrt. xx Datenbytes knnen mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls /// Kommando erfolgreich ausgefhrt. xx Datenbytes knnen mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
DataReady = 0x6100, DataReady = 0x6100,
/// Die zurckgegebenen Daten knnen fehlerhaft sein. /// Die zurckgegebenen Daten knnen fehlerhaft sein.
@ -108,7 +108,7 @@ pub enum APDUStatusWord {
/// Parameter P1/P2 falsch /// Parameter P1/P2 falsch
WrongParameters2 = 0x6B00, WrongParameters2 = 0x6B00,
/// Falsche Lnge Le; xx gibt die korrekte Lnge an Statuswort zur Steuerung des T=0-Protokolls /// Falsche Lnge Le; xx gibt die korrekte Lnge an Statuswort zur Steuerung des T=0-Protokolls
InvalidLe = 0x6C00, InvalidLe = 0x6C00,
/// Das Kommando (INS) wird nicht untersttzt /// Das Kommando (INS) wird nicht untersttzt