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 cea3967 commit a527d0e
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 12 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 = 3000
stacksize = 4400
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 = 3000
stacksize = 4400
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
24 changes: 20 additions & 4 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: RngSeed,
mut reseeder: R,
pid: &[u8],
threshold: usize,
) -> Result<Self, Error> {
let threshold = if threshold == 0 {
Expand All @@ -82,6 +86,9 @@ where
// mix platform unique seed drived by measured boot
Digest::update(&mut mixer, seed.as_bytes());

// 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 @@ -160,10 +167,11 @@ impl Lpc55RngServer {
fn new(
seed: RngSeed,
reseeder: Lpc55Rng,
pid: &[u8],
threshold: usize,
) -> Result<Self, Error> {
Ok(Lpc55RngServer(ReseedingRng::new(
seed, reseeder, threshold,
seed, reseeder, pid, threshold,
)?))
}
}
Expand Down Expand Up @@ -234,10 +242,18 @@ fn main() -> ! {
.unwrap_lite()
.seed
};
let pid: [u8; SUBJECT_CN_LENGTH] = {
let cert_data: CertData =
load_data_from_region(&CERT_DATA).unwrap_lite();
cert_data.persistid_cert.0.as_bytes()[SUBJECT_CN_RANGE]
.try_into()
.unwrap_lite()
};

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

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

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 a527d0e

Please sign in to comment.