From af7340b6abc2cc4e8d051522a160cc7f18503476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Wed, 16 Nov 2022 16:19:03 +0100 Subject: [PATCH] Set the management algorithm with the key --- src/lib.rs | 66 ++++++++++++++++++++++++++++++++-------------------- src/state.rs | 17 ++++++++++---- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e1a3e88..1e122ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,7 @@ use trussed::{syscall, try_syscall}; use constants::*; pub type Result = iso7816::Result<()>; -use state::{CommandCache, LoadedState, State}; +use state::{CommandCache, LoadedState, ManagementAlgorithm, State, TouchPolicy}; use crate::piv_types::DynamicAuthenticationTemplate; @@ -259,30 +259,9 @@ where .ok(); } - YubicoPivExtension::SetManagementKey(_touch_policy) => { - // cmd := apdu{ - // instruction: insSetMGMKey, - // param1: 0xff, - // param2: 0xff, - // data: append([]byte{ - // alg3DES, keyCardManagement, 24, - // }, key[:]...), - // } - // TODO check we are authenticated with old management key - - // example: 03 9B 18 - // B0 20 7A 20 DC 39 0B 1B A5 56 CC EB 8D CE 7A 8A C8 23 E6 F5 0D 89 17 AA - if data.len() != 3 + 24 { - return Err(Status::IncorrectDataParameter); - } - let (prefix, new_management_key) = data.split_at(3); - if prefix != [0x03, 0x9b, 0x18] { - return Err(Status::IncorrectDataParameter); - } - let new_management_key: [u8; 24] = new_management_key.try_into().unwrap(); - self.state - .persistent(&mut self.trussed)? - .set_management_key(&new_management_key, &mut self.trussed); + YubicoPivExtension::SetManagementKey(touch_policy) => { + self.load()? + .yubico_set_management_key(data, touch_policy, reply)?; } _ => return Err(Status::FunctionNotSupported), @@ -292,6 +271,43 @@ where } impl<'a, T: trussed::Client + trussed::client::Ed255> LoadedAuthenticator<'a, T> { + pub fn yubico_set_management_key( + &mut self, + data: &[u8], + _touch_policy: TouchPolicy, + reply: &mut Data, + ) -> Result { + // cmd := apdu{ + // instruction: insSetMGMKey, + // param1: 0xff, + // param2: 0xff, + // data: append([]byte{ + // alg3DES, keyCardManagement, 24, + // }, key[:]...), + // } + + if !self.state.runtime.app_security_status.management_verified { + return Err(Status::SecurityStatusNotSatisfied); + } + + // example: 03 9B 18 + // B0 20 7A 20 DC 39 0B 1B A5 56 CC EB 8D CE 7A 8A C8 23 E6 F5 0D 89 17 AA + if data.len() != 3 + 24 { + return Err(Status::IncorrectDataParameter); + } + let (prefix, new_management_key) = data.split_at(3); + if prefix != [0x03, 0x9b, 0x18] { + return Err(Status::IncorrectDataParameter); + } + let new_management_key: [u8; 24] = new_management_key.try_into().unwrap(); + self.state.persistent.set_management_key( + &new_management_key, + ManagementAlgorithm::Tdes, + self.trussed, + ); + Ok(()) + } + // maybe reserve this for the case VerifyLogin::PivPin? pub fn login(&mut self, login: commands::VerifyLogin) -> Result { if let commands::VerifyLogin::PivPin(pin) = login { diff --git a/src/state.rs b/src/state.rs index 07ae7c4..b7bfbd4 100644 --- a/src/state.rs +++ b/src/state.rs @@ -437,17 +437,26 @@ impl Persistent { } pub fn reset_management_key(&mut self, client: &mut impl trussed::Client) { - self.set_management_key(YUBICO_DEFAULT_MANAGEMENT_KEY, client); + self.set_management_key( + YUBICO_DEFAULT_MANAGEMENT_KEY, + YUBICO_DEFAULT_MANAGEMENT_KEY_ALG, + client, + ); } - pub fn set_management_key(&mut self, management_key: &[u8], client: &mut impl trussed::Client) { + pub fn set_management_key( + &mut self, + management_key: &[u8], + alg: ManagementAlgorithm, + client: &mut impl trussed::Client, + ) { // let new_management_key = syscall!(self.trussed.unsafe_inject_tdes_key( - let new_management_key = + let id = syscall!(client .unsafe_inject_shared_key(management_key, trussed::types::Location::Internal,)) .key; let old_management_key = self.keys.management_key.id; - self.keys.management_key.id = new_management_key; + self.keys.management_key = ManagementKey { id, alg }; self.save(client); syscall!(client.delete(old_management_key)); }