mirror of
https://gitlab.com/fabinfra/fabaccess/nfc_rs.git
synced 2025-03-12 06:41:46 +01:00
Merge branch 'fix/clippy-warnings' into 'main'
chore: fix warning as reported by `cargo cippy` See merge request fabinfra/fabaccess/nfc_rs!6
This commit is contained in:
commit
2d550a5bc3
@ -13,19 +13,19 @@ impl Cipher for AES {
|
||||
const KEY_SIZE: usize = 16;
|
||||
|
||||
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>> {
|
||||
let cipher = Aes128Cbc::new_from_slices(&key, &iv)?;
|
||||
let cipher = Aes128Cbc::new_from_slices(key, iv)?;
|
||||
|
||||
let result = cipher.decrypt_vec(data);
|
||||
return match result {
|
||||
match result {
|
||||
Ok(data) => Ok(data),
|
||||
Err(err) => Err(Error::BlockModeError(err)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,19 +14,19 @@ impl Cipher for Tdes {
|
||||
const KEY_SIZE: usize = 16;
|
||||
|
||||
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>> {
|
||||
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?;
|
||||
let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
|
||||
|
||||
let result = cipher.decrypt_vec(data);
|
||||
return match result {
|
||||
match result {
|
||||
Ok(data) => Ok(data),
|
||||
Err(err) => Err(Error::BlockModeError(err)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,19 +14,19 @@ impl Cipher for Tdes2k {
|
||||
const KEY_SIZE: usize = 16;
|
||||
|
||||
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>> {
|
||||
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?;
|
||||
let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
|
||||
|
||||
let result = cipher.decrypt_vec(data);
|
||||
return match result {
|
||||
match result {
|
||||
Ok(data) => Ok(data),
|
||||
Err(err) => Err(Error::BlockModeError(err)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,19 +14,19 @@ impl Cipher for Tdes3k {
|
||||
const KEY_SIZE: usize = 24;
|
||||
|
||||
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>> {
|
||||
let cipher = TDesEde3Cbc::new_from_slices(&key, &iv)?;
|
||||
let cipher = TDesEde3Cbc::new_from_slices(key, iv)?;
|
||||
|
||||
let result = cipher.decrypt_vec(data);
|
||||
return match result {
|
||||
match result {
|
||||
Ok(data) => Ok(data),
|
||||
Err(err) => Err(Error::BlockModeError(err)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,11 +74,7 @@ pub fn get_key_size(cipher: CipherType) -> usize {
|
||||
|
||||
/// Check Key Slice
|
||||
pub fn check_key(key: &[u8], cipher: CipherType) -> bool {
|
||||
if key.len() != get_key_size(cipher) {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
key.len() == get_key_size(cipher)
|
||||
}
|
||||
|
||||
/// Set Key Version for DES/TDES Keys
|
||||
|
@ -20,9 +20,9 @@ pub fn expand_to_blocksize(data: &mut [u8], blocksize: usize) -> Result<Vec<u8>>
|
||||
let diff = data.len() % blocksize;
|
||||
|
||||
if diff == 0 {
|
||||
return Ok(data.to_vec());
|
||||
Ok(data.to_vec())
|
||||
} 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);
|
||||
Ok(buf)
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ impl Desfire {
|
||||
let rnd_b_enc = rnd_b_response_body.as_slice();
|
||||
// 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);
|
||||
|
||||
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());
|
||||
// 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());
|
||||
Ok(())
|
||||
}
|
||||
@ -184,7 +184,7 @@ impl Desfire {
|
||||
) -> Result<(APDUCommand, Vec<u8>, Vec<u8>)> {
|
||||
// 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);
|
||||
|
||||
// auth_iv = rnd_b.clone();
|
||||
@ -192,7 +192,7 @@ impl Desfire {
|
||||
rnd_b_rl.rotate_left(1);
|
||||
// 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);
|
||||
|
||||
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());
|
||||
// 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
|
||||
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
|
||||
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());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -619,7 +619,7 @@ impl Desfire {
|
||||
ret = response.check();
|
||||
}
|
||||
|
||||
return ret;
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn read_data_chunk_cmd(
|
||||
@ -648,7 +648,7 @@ impl Desfire {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
return Ok(cmd_read_data_chunk);
|
||||
Ok(cmd_read_data_chunk)
|
||||
}
|
||||
|
||||
/// Read data from a file
|
||||
@ -685,13 +685,13 @@ impl Desfire {
|
||||
let response = self.card.as_ref().unwrap().transmit(cmd_read_data).unwrap();
|
||||
// println!("RESPONSE: {}", response);
|
||||
|
||||
response.check().or_else(|e| return Err(e))?;
|
||||
response.check()?;
|
||||
// // 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());
|
||||
}
|
||||
|
||||
return Ok(read_buffer);
|
||||
Ok(read_buffer)
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,7 +726,7 @@ pub fn generate_keysetting1(
|
||||
file_directory_access: FileDirectoryAccess,
|
||||
change_master_key: ChangeMasterKey,
|
||||
) -> Result<u8> {
|
||||
return match FromPrimitive::from_u8(change_key) {
|
||||
match FromPrimitive::from_u8(change_key) {
|
||||
Some(ChangeApplicationKey::MASTERKEY)
|
||||
| Some(ChangeApplicationKey::SAMEKEY)
|
||||
| Some(ChangeApplicationKey::ALLKEYS) => Ok((change_key << 4)
|
||||
@ -735,7 +735,7 @@ pub fn generate_keysetting1(
|
||||
| file_directory_access as u8
|
||||
| change_master_key as u8),
|
||||
None => {
|
||||
if change_key < 0x01 || change_key >= 0x08 {
|
||||
if !(0x01..0x08).contains(&change_key) {
|
||||
Err(InvalidKeyID)
|
||||
} else {
|
||||
Ok((change_key << 4)
|
||||
@ -745,7 +745,7 @@ pub fn generate_keysetting1(
|
||||
| change_master_key as u8)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate KeySetting2 for Application Creation
|
||||
@ -759,11 +759,11 @@ pub fn generate_keysetting2(
|
||||
file_identifier: FileIdentifiers,
|
||||
num_keys: u8,
|
||||
) -> Result<u8> {
|
||||
return if num_keys < 0x01 || num_keys >= 0x0D {
|
||||
if !(0x01..0x0D).contains(&num_keys) {
|
||||
Err(NumKeys)
|
||||
} else {
|
||||
Ok(crypto_operations as u8 | file_identifier as u8 | num_keys)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate FileAccess Rights for File Settings
|
||||
@ -784,14 +784,14 @@ pub fn generate_file_access_rights(
|
||||
read_write: u8,
|
||||
configure: u8,
|
||||
) -> 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)
|
||||
} else {
|
||||
Ok((((read as u16) << 12)
|
||||
| ((write as u16) << 8)
|
||||
| ((read_write as u16) << 4)
|
||||
| configure as u16) as u16)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -876,12 +876,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn generate_sessionkey_des() {
|
||||
let rndA = hex!("a541a9dc9138df07");
|
||||
let rndB = hex!("cbe55aa893b2da25");
|
||||
let rnd_a = hex!("a541a9dc9138df07");
|
||||
let rnd_b = hex!("cbe55aa893b2da25");
|
||||
|
||||
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!("actual sessionkey: {:X?}", sessionkey.as_slice());
|
||||
@ -891,12 +891,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn generate_sessionkey_aes() {
|
||||
let rndA = hex!("bc14dfde20074617e45a8822f06fdd91");
|
||||
let rndB = hex!("482ddc54426e6dee560413b8d95471f5");
|
||||
let rnd_a = hex!("bc14dfde20074617e45a8822f06fdd91");
|
||||
let rnd_b = hex!("482ddc54426e6dee560413b8d95471f5");
|
||||
|
||||
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!("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();
|
||||
// println!("{:x?}", key.key.deref());
|
||||
|
||||
@ -1103,7 +1103,7 @@ mod tests {
|
||||
};
|
||||
|
||||
desfire
|
||||
.authenticate_iso_des(0x00, key.key.as_ref(), Some(rndA))
|
||||
.authenticate_iso_des(0x00, key.key.as_ref(), Some(rnd_a))
|
||||
.unwrap();
|
||||
|
||||
let sessionkey_expected = hex!("5f7d1dd1f449db5c5f7d1dd1f449db5c");
|
||||
@ -1207,7 +1207,7 @@ mod tests {
|
||||
body: Some(hex!("8fdc476f6bac44fe9150e285abd68d48").to_vec())
|
||||
}));
|
||||
|
||||
let rndA = hex!("2176770e7a6eb4bef00d5e4b201d1e57");
|
||||
let rnd_a = hex!("2176770e7a6eb4bef00d5e4b201d1e57");
|
||||
let key = CipherKey::new_empty(CipherType::AES).unwrap();
|
||||
// println!("{:x?}", key.key.deref());
|
||||
|
||||
@ -1218,7 +1218,7 @@ mod tests {
|
||||
};
|
||||
|
||||
desfire
|
||||
.authenticate_iso_aes(0x00, key.key.as_ref(), Some(rndA))
|
||||
.authenticate_iso_aes(0x00, key.key.as_ref(), Some(rnd_a))
|
||||
.unwrap();
|
||||
|
||||
let sessionkey_expected = hex!("2176770e11c512ca201d1e57fde6e15a");
|
||||
|
@ -116,5 +116,6 @@ pub enum FileTypes {
|
||||
|
||||
mod apduinstructions;
|
||||
mod apdustatuscodes;
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod desfire;
|
||||
pub use crate::desfire::desfire::Desfire;
|
||||
|
@ -113,12 +113,7 @@ impl TryFrom<APDUCommand> for Vec<u8> {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(cmd: APDUCommand) -> Result<Self> {
|
||||
let mut v: Vec<u8> = vec![];
|
||||
//build header
|
||||
v.push(cmd.cla);
|
||||
v.push(cmd.ins);
|
||||
v.push(cmd.p1);
|
||||
v.push(cmd.p2);
|
||||
let mut v = vec![cmd.cla, cmd.ins, cmd.p1, cmd.p2];
|
||||
|
||||
//build body according to case
|
||||
match cmd.case {
|
||||
|
@ -56,7 +56,8 @@ impl APDUResponse {
|
||||
pub fn new(raw: &[u8]) -> Self {
|
||||
if raw.len() < 2 {
|
||||
panic!("APDU response must be at least 2 bytes long");
|
||||
} else if raw.len() == 2 {
|
||||
}
|
||||
if raw.len() == 2 {
|
||||
APDUResponse {
|
||||
body: None,
|
||||
sw1: raw[0],
|
||||
@ -104,7 +105,7 @@ impl APDUResponse {
|
||||
|
||||
pub fn check(&self) -> Result<()> {
|
||||
if self.sw1 == 0x91 {
|
||||
return match FromPrimitive::from_u8(self.sw2) {
|
||||
match FromPrimitive::from_u8(self.sw2) {
|
||||
Some(APDUStatusWord2::OperationOk) => Ok(()),
|
||||
Some(APDUStatusWord2::NoChanges) => Ok(()),
|
||||
Some(APDUStatusWord2::IllegalCommandCode) => Err(IllegalCommandCode),
|
||||
@ -122,7 +123,7 @@ impl APDUResponse {
|
||||
Some(APDUStatusWord2::FileNotFound) => Err(FileNotFound),
|
||||
Some(APDUStatusWord2::ApplicationNotFound) => Err(ApplicationNotFound),
|
||||
None => Err(InvalidStatusWord),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
Err(InvalidStatusWord)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use num_derive::FromPrimitive;
|
||||
#[derive(FromPrimitive)]
|
||||
#[repr(u16)]
|
||||
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,
|
||||
|
||||
/// Die zurckgegebenen Daten knnen fehlerhaft sein.
|
||||
@ -108,7 +108,7 @@ pub enum APDUStatusWord {
|
||||
/// Parameter P1/P2 falsch
|
||||
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,
|
||||
|
||||
/// Das Kommando (INS) wird nicht untersttzt
|
||||
|
Loading…
x
Reference in New Issue
Block a user