libcros 0.6.6

A Rust library that provides easy-to-use functions for interacting with a Chrome device
Documentation
#![allow(non_snake_case)]

pub use crate::tlcl::bytes::{read_be16, read_be32, write_be16, write_be32};
use crate::tlcl::tpm12::constants::{
  TPM_ALL_LOCALITIES, TPM_DIGEST, TPM_LOC_THREE, TPM_NV_AUTH_POLICY, TPM_PCR_INFO_SHORT,
  TPM_PCR_SELECTION,
};

const EMPTY_PCR_SELECTION_SHA1: [u8; 20] = [
  0x79, 0xdd, 0xda, 0xfd, 0xc1, 0x97, 0xdc, 0xcc, 0xe9, 0x98, 0x9a, 0xee, 0xf5, 0x52, 0x89, 0xee,
  0x24, 0x96, 0x4c, 0xac,
];

pub fn decode_pcr_info(
  response: &[u8],
  cursor: &mut usize,
  end: usize,
  pcr_info: *mut TPM_PCR_INFO_SHORT,
) -> bool {
  if end.saturating_sub(*cursor) < core::mem::size_of::<u16>() {
    return false;
  }

  let size_of_select = read_be16(unsafe { response.as_ptr().add(*cursor) });
  let encoded_size = core::mem::size_of::<TPM_PCR_INFO_SHORT>() - 3 + size_of_select as usize;
  if end.saturating_sub(*cursor) < encoded_size || size_of_select as usize > 3 {
    return false;
  }

  let mut pcr_select = [0u8; 3];
  let select_start = *cursor + core::mem::size_of::<u16>();
  pcr_select[..size_of_select as usize]
    .copy_from_slice(&response[select_start..select_start + size_of_select as usize]);
  *cursor += core::mem::size_of::<u16>() + size_of_select as usize;

  if end.saturating_sub(*cursor) < 1 + core::mem::size_of::<TPM_DIGEST>() {
    return false;
  }

  let locality = response[*cursor];
  *cursor += 1;

  let mut digest = [0u8; core::mem::size_of::<TPM_DIGEST>()];
  digest.copy_from_slice(&response[*cursor..*cursor + core::mem::size_of::<TPM_DIGEST>()]);
  *cursor += core::mem::size_of::<TPM_DIGEST>();

  let info = TPM_PCR_INFO_SHORT {
    pcrSelection: TPM_PCR_SELECTION {
      sizeOfSelect: size_of_select,
      pcrSelect: pcr_select,
    },
    localityAtRelease: locality,
    digestAtRelease: TPM_DIGEST { digest },
  };

  unsafe {
    pcr_info.write_unaligned(info);
  }
  true
}

pub fn init_default_nv_auth_policy(policy: *mut TPM_NV_AUTH_POLICY) {
  let pcr_info = TPM_PCR_INFO_SHORT {
    pcrSelection: TPM_PCR_SELECTION {
      sizeOfSelect: u16::from_be(3),
      pcrSelect: [0, 0, 0],
    },
    localityAtRelease: (TPM_ALL_LOCALITIES & !TPM_LOC_THREE) as u8,
    digestAtRelease: TPM_DIGEST {
      digest: EMPTY_PCR_SELECTION_SHA1,
    },
  };

  unsafe {
    core::ptr::addr_of_mut!((*policy).pcr_info_read).write_unaligned(pcr_info);
    core::ptr::addr_of_mut!((*policy).pcr_info_write).write_unaligned(pcr_info);
  }
}

pub fn init_define_space_default_auth_policy(policy: *mut TPM_NV_AUTH_POLICY) {
  let pcr_info = TPM_PCR_INFO_SHORT {
    pcrSelection: TPM_PCR_SELECTION {
      sizeOfSelect: u16::from_be(3),
      pcrSelect: [0, 0, 0],
    },
    localityAtRelease: TPM_ALL_LOCALITIES as u8,
    digestAtRelease: TPM_DIGEST { digest: [0u8; 20] },
  };

  unsafe {
    core::ptr::addr_of_mut!((*policy).pcr_info_read).write_unaligned(pcr_info);
    core::ptr::addr_of_mut!((*policy).pcr_info_write).write_unaligned(pcr_info);
  }
}