Skip to content

Commit

Permalink
Add CMAC verification of keyblobs, generate encrypted keyblobs
Browse files Browse the repository at this point in the history
  • Loading branch information
roblabla committed Jan 24, 2019
1 parent 7f8d8bd commit 570a418
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
37 changes: 37 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ block-modes = "0.2"
aes = "0.3"
num-traits = "0.2"
derive_more = "0.13"
cmac = "0.2.0"

[features]
binaries = ["structopt", "cargo_metadata", "scroll", "goblin"]
8 changes: 8 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub enum Error {
Ini(#[cause] ini::ini::Error, Backtrace),
#[display(fmt = "Key derivation error: {}", _0)]
Crypto(String, Backtrace),
#[display(fmt = "Invalid keyblob {}: {}.", _1, _0)]
MacError(cmac::crypto_mac::MacError, usize, Backtrace),
#[display(fmt = "Invalid PFS0: {}.", _0)]
InvalidPfs0(&'static str, Backtrace),
#[display(fmt = "Failed to convert filename to UTF8: {}.", _0)]
Expand Down Expand Up @@ -80,3 +82,9 @@ impl From<FromUtf8Error> for Error {
Error::Utf8Conversion(String::from_utf8_lossy(err.as_bytes()).into_owned(), err.utf8_error(), Backtrace::new())
}
}

impl From<(usize, cmac::crypto_mac::MacError)> for Error {
fn from((id, err): (usize, cmac::crypto_mac::MacError)) -> Error {
Error::MacError(err, id, Backtrace::new())
}
}
33 changes: 28 additions & 5 deletions src/pki.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use std::io::{self, ErrorKind};
use std::path::Path;
use crate::error::Error;
use aes::Aes128;
use cmac::Cmac;
use cmac::crypto_mac::Mac;
use block_modes::{Ctr128, BlockModeIv, BlockMode};
use block_modes::block_padding::ZeroPadding;
use aes::block_cipher_trait::generic_array::GenericArray;
Expand Down Expand Up @@ -36,11 +38,30 @@ impl_debug!(EncryptedKeyblob);
impl_debug!(Keyblob);
impl_debug!(Modulus);

impl Keyblob {
fn encrypt(&self, key: &Aes128Key, mac_key: &Aes128Key, keyblob_id: usize) -> Result<EncryptedKeyblob, Error> {
let mut encrypted_keyblob = [0; 0xB0];
encrypted_keyblob[0x20..].copy_from_slice(&self.0);

let mut crypter = Ctr128::<Aes128, ZeroPadding>::new_fixkey(GenericArray::from_slice(&key.0), GenericArray::from_slice(&encrypted_keyblob[0x10..0x20]));
crypter.encrypt_nopad(&mut encrypted_keyblob[0x20..])?;

let mut cmac = Cmac::<Aes128>::new_varkey(&mac_key.0[..]).unwrap();
cmac.input(&encrypted_keyblob[0x10..]);
encrypted_keyblob[..0x10].copy_from_slice(cmac.result().code().as_slice());
Ok(EncryptedKeyblob(encrypted_keyblob))
}
}

impl EncryptedKeyblob {
fn decrypt(&self, key: &Aes128Key) -> Result<Keyblob, Error> {
fn decrypt(&self, key: &Aes128Key, mac_key: &Aes128Key, keyblob_id: usize) -> Result<Keyblob, Error> {
let mut keyblob = [0; 0x90];
keyblob.copy_from_slice(&self.0[0x20..]);

let mut cmac = Cmac::<Aes128>::new_varkey(&mac_key.0[..]).unwrap();
cmac.input(&self.0[0x10..]);
cmac.verify(&self.0[..0x10]).map_err(|err| (keyblob_id, err))?;

let mut crypter = Ctr128::<Aes128, ZeroPadding>::new_fixkey(GenericArray::from_slice(&key.0), GenericArray::from_slice(&self.0[0x10..0x20]));
crypter.decrypt_nopad(&mut keyblob)?;

Expand Down Expand Up @@ -380,10 +401,12 @@ impl Keys {
}
}
for i in 0..6 {
match (&self.keyblob_keys[i], &self.keyblob_mac_keys[i], &self.encrypted_keyblobs[i]) {
(Some(keyblob_key), Some(_keyblob_mac_key), Some(encrypted_keyblob)) => {
// TODO: Calculate cmac
self.keyblobs[i] = Some(encrypted_keyblob.decrypt(keyblob_key)?);
match (&self.keyblob_keys[i], &self.keyblob_mac_keys[i], &mut self.encrypted_keyblobs[i], &mut self.keyblobs[i]) {
(Some(keyblob_key), Some(keyblob_mac_key), Some(encrypted_keyblob), ref mut keyblob @ None) => {
**keyblob = Some(encrypted_keyblob.decrypt(keyblob_key, keyblob_mac_key, i)?);
},
(Some(keyblob_key), Some(keyblob_mac_key), ref mut encrypted_keyblob @ None, Some(keyblob)) => {
**encrypted_keyblob = Some(keyblob.encrypt(keyblob_key, keyblob_mac_key, i)?);
},
_ => continue
}
Expand Down

0 comments on commit 570a418

Please sign in to comment.