Skip to content

Commit

Permalink
lpc55-rng: Include SN from platform id cert in initial PRNG seed.
Browse files Browse the repository at this point in the history
Platforms assigned a unique serial number can include this string in the
initial seed to ensure uniqueness in the bit stream produced by the RNG.

We now construct the intial seed as:

```
SEED_0 = sha3_256(DICE_SEED | SN | HRNG(32))
```

Extracting the Platform Id / serial number from the platform identity
cert required exposing the relevant module from the lib-dice crate. We
also add additional constants to the template module that are required
to know the length of the platform id string at compile time.
  • Loading branch information
flihp committed Jul 11, 2024
1 parent fd2ab68 commit 509e53d
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 13 deletions.
4 changes: 2 additions & 2 deletions app/lpc55xpresso/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ name = "drv-lpc55-rng"
priority = 3
uses = ["rng", "pmc"]
start = true
stacksize = 2704
stacksize = 4200
task-slots = ["syscon_driver"]
extern-regions = ["dice_rng"]
extern-regions = ["dice_certs", "dice_rng"]

[tasks.pong]
name = "task-pong"
Expand Down
4 changes: 2 additions & 2 deletions app/rot-carrier/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ name = "drv-lpc55-rng"
priority = 5
uses = ["rng", "pmc"]
start = true
stacksize = 2704
stacksize = 4200
task-slots = ["syscon_driver"]
extern-regions = ["dice_rng"]
extern-regions = ["dice_certs", "dice_rng"]

[tasks.sprot]
name = "drv-lpc55-sprot-server"
Expand Down
17 changes: 15 additions & 2 deletions drv/lpc55-rng/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,26 @@ fn main() -> Result<()> {
return Err(anyhow!("no data regions found"));
}

let region = data_regions
.get("dice_certs")
.ok_or_else(|| anyhow::anyhow!("dice_certs data region not found"))?;
writeln!(out, "use crate::config::DataRegion;\n\n")?;

writeln!(
out,
r##"pub const CERT_DATA: DataRegion = DataRegion {{
address: {:#x},
size: {:#x},
}};"##,
region.address, region.size
)?;

let region = data_regions
.get("dice_rng")
.ok_or_else(|| anyhow!("dice_rng data region not found"))?;
writeln!(
out,
r##"use crate::config::DataRegion;
pub const RNG_DATA: DataRegion = DataRegion {{
r##"pub const RNG_DATA: DataRegion = DataRegion {{
address: {:#x},
size: {:#x},
}};"##,
Expand Down
31 changes: 26 additions & 5 deletions drv/lpc55-rng/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use drv_lpc55_syscon_api::Syscon;
use drv_rng_api::RngError;
use hubpack::SerializedSize;
use idol_runtime::{ClientError, NotificationHandler, RequestError};
use lib_dice::{RngData, RngSeed, SeedBuf};
use lib_dice::{
persistid_cert_tmpl::{SUBJECT_CN_LENGTH, SUBJECT_CN_RANGE},
CertData, RngData, RngSeed, SeedBuf,
};
use lib_lpc55_rng::Lpc55Rng;
use rand_chacha::ChaCha20Rng;
use rand_core::{impls, Error, RngCore, SeedableRng};
Expand All @@ -39,7 +42,7 @@ mod build {
include!(concat!(env!("OUT_DIR"), "/rng-config.rs"));
}

use build::RNG_DATA;
use build::{CERT_DATA, RNG_DATA};

task_slot!(SYSCON, syscon_driver);

Expand Down Expand Up @@ -70,6 +73,7 @@ where
fn new(
seed: Option<&RngSeed>,
mut reseeder: R,
pid: Option<&[u8; SUBJECT_CN_LENGTH]>,
threshold: usize,
) -> Result<Self, Error> {
let threshold = if threshold == 0 {
Expand All @@ -84,6 +88,11 @@ where
Digest::update(&mut mixer, seed.as_bytes());
}

if let Some(pid) = pid {
// mix in unique platform id
Digest::update(&mut mixer, pid);
}

// w/ 32 bytes from HRNG
let mut buf = Zeroizing::new(T::Seed::default());
reseeder.try_fill_bytes(buf.as_mut())?;
Expand Down Expand Up @@ -162,10 +171,11 @@ impl Lpc55RngServer {
fn new(
seed: Option<&RngSeed>,
reseeder: Lpc55Rng,
pid: Option<&[u8; SUBJECT_CN_LENGTH]>,
threshold: usize,
) -> Result<Self, Error> {
Ok(Lpc55RngServer(ReseedingRng::new(
seed, reseeder, threshold,
seed, reseeder, pid, threshold,
)?))
}
}
Expand Down Expand Up @@ -235,11 +245,22 @@ fn main() -> ! {
Some(rng_data) => Some(rng_data.seed),
_ => None,
};
let pid: Option<[u8; SUBJECT_CN_LENGTH]> =
match load_data_from_region::<CertData>(&CERT_DATA) {
Some(cert_data) => Some(
cert_data.persistid_cert.0.as_bytes()[SUBJECT_CN_RANGE]
.try_into()
.unwrap_lite(),
),
_ => None,
};

let rng = Lpc55Rng::new(&Syscon::from(SYSCON.get_task_id()));

let threshold = 0x100000; // 1 MiB
let mut rng = Lpc55RngServer::new(seed.as_ref(), rng, threshold)
.expect("Failed to create Lpc55RngServer");
let mut rng =
Lpc55RngServer::new(seed.as_ref(), rng, pid.as_ref(), threshold)
.expect("Failed to create Lpc55RngServer");
let mut buffer = [0u8; idl::INCOMING_SIZE];

loop {
Expand Down
2 changes: 1 addition & 1 deletion lib/dice/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mod alias_cert_tmpl;
mod deviceid_cert_tmpl;
mod handoff;
mod mfg;
mod persistid_cert_tmpl;
pub mod persistid_cert_tmpl;
mod persistid_csr_tmpl;
pub use crate::mfg::{
DiceMfg, DiceMfgState, PersistIdSeed, SelfMfg, SerialMfg,
Expand Down
5 changes: 4 additions & 1 deletion lib/dice/src/persistid_cert_tmpl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use core::ops::Range;
pub const SIZE: usize = 441;
pub const SERIAL_NUMBER_RANGE: Range<usize> = 15..16;
pub const ISSUER_CN_RANGE: Range<usize> = 82..114;
pub const SUBJECT_CN_RANGE: Range<usize> = 207..239;
pub const SUBJECT_CN_START: usize = 207;
pub const SUBJECT_CN_END: usize = 239;
pub const SUBJECT_CN_RANGE: Range<usize> = SUBJECT_CN_START..SUBJECT_CN_END;
pub const SUBJECT_CN_LENGTH: usize = SUBJECT_CN_END - SUBJECT_CN_START;
pub const PUB_RANGE: Range<usize> = 251..283;
pub const SIG_RANGE: Range<usize> = 377..441;
pub const SIGNDATA_RANGE: Range<usize> = 4..367;
Expand Down

0 comments on commit 509e53d

Please sign in to comment.