Skip to content

Commit a527d0e

Browse files
committed
lpc55-rng: Include SN from platform id cert in initial PRNG seed.
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.
1 parent cea3967 commit a527d0e

File tree

6 files changed

+44
-12
lines changed

6 files changed

+44
-12
lines changed

app/lpc55xpresso/app.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ name = "drv-lpc55-rng"
115115
priority = 3
116116
uses = ["rng", "pmc"]
117117
start = true
118-
stacksize = 3000
118+
stacksize = 4400
119119
task-slots = ["syscon_driver"]
120-
extern-regions = ["dice_rng"]
120+
extern-regions = ["dice_certs", "dice_rng"]
121121

122122
[tasks.pong]
123123
name = "task-pong"

app/rot-carrier/app.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ name = "drv-lpc55-rng"
101101
priority = 5
102102
uses = ["rng", "pmc"]
103103
start = true
104-
stacksize = 3000
104+
stacksize = 4400
105105
task-slots = ["syscon_driver"]
106-
extern-regions = ["dice_rng"]
106+
extern-regions = ["dice_certs", "dice_rng"]
107107

108108
[tasks.sprot]
109109
name = "drv-lpc55-sprot-server"

drv/lpc55-rng/build.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,26 @@ fn main() -> Result<()> {
3434
return Err(anyhow!("no data regions found"));
3535
}
3636

37+
let region = data_regions
38+
.get("dice_certs")
39+
.ok_or_else(|| anyhow::anyhow!("dice_certs data region not found"))?;
40+
writeln!(out, "use crate::config::DataRegion;\n\n")?;
41+
42+
writeln!(
43+
out,
44+
r##"pub const CERT_DATA: DataRegion = DataRegion {{
45+
address: {:#x},
46+
size: {:#x},
47+
}};"##,
48+
region.address, region.size
49+
)?;
50+
3751
let region = data_regions
3852
.get("dice_rng")
3953
.ok_or_else(|| anyhow!("dice_rng data region not found"))?;
4054
writeln!(
4155
out,
42-
r##"use crate::config::DataRegion;
43-
pub const RNG_DATA: DataRegion = DataRegion {{
56+
r##"pub const RNG_DATA: DataRegion = DataRegion {{
4457
address: {:#x},
4558
size: {:#x},
4659
}};"##,

drv/lpc55-rng/src/main.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ use drv_lpc55_syscon_api::Syscon;
1717
use drv_rng_api::RngError;
1818
use hubpack::SerializedSize;
1919
use idol_runtime::{ClientError, NotificationHandler, RequestError};
20-
use lib_dice::{RngData, RngSeed, SeedBuf};
20+
use lib_dice::{
21+
persistid_cert_tmpl::{SUBJECT_CN_LENGTH, SUBJECT_CN_RANGE},
22+
CertData, RngData, RngSeed, SeedBuf,
23+
};
2124
use lib_lpc55_rng::Lpc55Rng;
2225
use rand_chacha::ChaCha20Rng;
2326
use rand_core::{impls, Error, RngCore, SeedableRng};
@@ -39,7 +42,7 @@ mod build {
3942
include!(concat!(env!("OUT_DIR"), "/rng-config.rs"));
4043
}
4144

42-
use build::RNG_DATA;
45+
use build::{CERT_DATA, RNG_DATA};
4346

4447
task_slot!(SYSCON, syscon_driver);
4548

@@ -70,6 +73,7 @@ where
7073
fn new(
7174
seed: RngSeed,
7275
mut reseeder: R,
76+
pid: &[u8],
7377
threshold: usize,
7478
) -> Result<Self, Error> {
7579
let threshold = if threshold == 0 {
@@ -82,6 +86,9 @@ where
8286
// mix platform unique seed drived by measured boot
8387
Digest::update(&mut mixer, seed.as_bytes());
8488

89+
// mix in unique platform id
90+
Digest::update(&mut mixer, pid);
91+
8592
// w/ 32 bytes from HRNG
8693
let mut buf = Zeroizing::new(T::Seed::default());
8794
reseeder.try_fill_bytes(buf.as_mut())?;
@@ -160,10 +167,11 @@ impl Lpc55RngServer {
160167
fn new(
161168
seed: RngSeed,
162169
reseeder: Lpc55Rng,
170+
pid: &[u8],
163171
threshold: usize,
164172
) -> Result<Self, Error> {
165173
Ok(Lpc55RngServer(ReseedingRng::new(
166-
seed, reseeder, threshold,
174+
seed, reseeder, pid, threshold,
167175
)?))
168176
}
169177
}
@@ -234,10 +242,18 @@ fn main() -> ! {
234242
.unwrap_lite()
235243
.seed
236244
};
245+
let pid: [u8; SUBJECT_CN_LENGTH] = {
246+
let cert_data: CertData =
247+
load_data_from_region(&CERT_DATA).unwrap_lite();
248+
cert_data.persistid_cert.0.as_bytes()[SUBJECT_CN_RANGE]
249+
.try_into()
250+
.unwrap_lite()
251+
};
252+
237253
let rng = Lpc55Rng::new(&Syscon::from(SYSCON.get_task_id()));
238254

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

lib/dice/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ mod alias_cert_tmpl;
3030
mod deviceid_cert_tmpl;
3131
mod handoff;
3232
mod mfg;
33-
mod persistid_cert_tmpl;
33+
pub mod persistid_cert_tmpl;
3434
mod persistid_csr_tmpl;
3535
pub use crate::mfg::{
3636
DiceMfg, DiceMfgState, PersistIdSeed, SelfMfg, SerialMfg,

lib/dice/src/persistid_cert_tmpl.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use core::ops::Range;
1212
pub const SIZE: usize = 441;
1313
pub const SERIAL_NUMBER_RANGE: Range<usize> = 15..16;
1414
pub const ISSUER_CN_RANGE: Range<usize> = 82..114;
15-
pub const SUBJECT_CN_RANGE: Range<usize> = 207..239;
15+
pub const SUBJECT_CN_START: usize = 207;
16+
pub const SUBJECT_CN_END: usize = 239;
17+
pub const SUBJECT_CN_RANGE: Range<usize> = SUBJECT_CN_START..SUBJECT_CN_END;
18+
pub const SUBJECT_CN_LENGTH: usize = SUBJECT_CN_END - SUBJECT_CN_START;
1619
pub const PUB_RANGE: Range<usize> = 251..283;
1720
pub const SIG_RANGE: Range<usize> = 377..441;
1821
pub const SIGNDATA_RANGE: Range<usize> = 4..367;

0 commit comments

Comments
 (0)