Skip to content

Commit

Permalink
raw key option
Browse files Browse the repository at this point in the history
  • Loading branch information
pldubouilh committed Feb 25, 2025
1 parent c8425ce commit 5b534ca
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 20 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
TM_TOOL := $(shell git show -s --format=%cd --date=format:%Y-%m-%d HEAD) / $(shell git rev-parse --short HEAD)
export TM_TOOL
TM_TOOL_VERS := $(shell git show -s --format=%cd --date=format:%Y-%m-%d HEAD) / $(shell git rev-parse --short HEAD)
export TM_TOOL_VERS

build::
@echo $(TM_TOOL)
@echo $(TM_TOOL_VERS)
cargo build
cargo clippy --all
cargo fmt --all
Expand All @@ -18,7 +18,7 @@ build-all::
mkdir -p builds
cp target/aarch64-unknown-linux-musl/release/tmtool builds/tmtool-aarch64
echo '```' > builds/buildout
echo $(TM_TOOL) >> builds/buildout
echo $(TM_TOOL_VERS) >> builds/buildout
rustc --version >> builds/buildout
sha256sum builds/tmtool* >> builds/buildout
echo '```' >> builds/buildout
Expand Down
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ Pre-built binaries for aarch64 available in the [releases section](https://githu

## Usage

```bash
$ ./tmtool --help
TrustM Userland tooling
```txt
TrustM Userland tooling.
Designed to help integration with Thistle Verified Boot: https://docs.thistle.tech/tvb
This tool can read and write keys to the Infineon TrustM chip.
Requires a direct i2c connection to the chip.
Currently limited to 64B keys at slots 0xe0e8 and 0xe0e9.
The key writing operation expects a PEM formatted key file.
Usage: tmtool [OPTIONS] <COMMAND>
Commands:
Expand All @@ -26,3 +31,23 @@ Options:
-h, --help Print help
-V, --version Print version
```

Read a key:

```txt
$ ./tmtool read
~~ TrustM initinialised
~~ Key at slot 0xe0e8
[be, de, 82, f5, 6, 16, f6, 79, d3, 10, e6, a0, 47, fb, 44, bf, 34, 56, ee, 71, 33, 4c, 42, c5, a6, f0, b,
a0, 3, e8, 7a, a6, c3, 57, fa, 84, fe, 65, d8, c5, 95, b4, b3, 17, b1, 9d, 63, 8b, 7a, 87, ba, f9, 4f, 65
, 89, 99, 37, e4, 42, 34, 13, 50, a4, 1a]
```

Write a key:

```txt
$ ./tmtool write --key pk.pem
~~ TrustM initinialised
~~ Parsed key at "pk.pem"
~~ Key successfuly written to slot 0xe0e8
```
10 changes: 7 additions & 3 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use clap::{Parser, Subcommand};
name = "TrustM Userland Driver",
author = "Thistle Tech <pierre@thistle.tech>",
arg_required_else_help = true,
version = option_env!("TM_TOOL").unwrap_or("unknown"),
version = option_env!("TM_TOOL_VERS").unwrap_or("unknown"),
long_about = None,
about = "
TrustM Userland tooling.
Expand All @@ -17,7 +17,7 @@ Designed to help integration with Thistle Verified Boot: https://docs.thistle.te
This tool can read and write keys to the Infineon TrustM chip.
Requires a direct i2c connection to the chip.
Currently limited to reading 64B keys at slots 0xe0e8 and 0xe0e9.
Currently limited to 64B keys at slots 0xe0e8 and 0xe0e9.
The key writing operation expects a PEM formatted key file.",
verbatim_doc_comment,
)]
Expand Down Expand Up @@ -51,7 +51,11 @@ pub enum Cmds {
}

#[derive(clap::Args)]
pub struct ReadCmd {}
pub struct ReadCmd {
/// Output raw key bytes to stdout
#[clap(long, short, default_value = "false")]
pub raw: bool,
}

#[derive(clap::Args)]
pub struct WriteCmd {
Expand Down
20 changes: 13 additions & 7 deletions src/cmds.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
extern crate i2cdev;

use std::io::Write;
use std::path::PathBuf;

use crate::trustm::{self, TM_SLOT1, TM_SLOT2};

use anyhow::Result;
use anyhow::*;

pub fn read(device: String, slot: u16) -> Result<()> {
pub fn read(device: String, slot: u16, raw: bool) -> Result<()> {
let mut tm = trustm::TrustM::init(device)?;

tm.write_byte(0x84)?;
Expand Down Expand Up @@ -88,8 +89,13 @@ pub fn read(device: String, slot: u16) -> Result<()> {
tm.read_bytes(&mut pk)?;

let pk = &pk[9..73];
println!("~~ key at slot {:#04x}", slot);
println!("{:x?}", pk);
eprintln!("~~ Key at slot {:#04x}", slot);
eprintln!("{:x?}", pk);

if raw {
std::io::stdout().write_all(pk)?;
std::io::stdout().flush()?;
}

Ok(())
}
Expand All @@ -108,7 +114,7 @@ pub fn write(device: String, slot: u16, keypath: PathBuf) -> Result<()> {
}
let pk = &pk[27..];

println!("~~ parsed key at {:?}", &keypath);
eprintln!("~~ Parsed key at {:?}", &keypath);

let mut tm = trustm::TrustM::init(device)?;

Expand Down Expand Up @@ -221,7 +227,7 @@ pub fn write(device: String, slot: u16, keypath: PathBuf) -> Result<()> {
let data = [0x80, 0x81, 0x00, 0x00, 0x56, 0x30];
tm.write_bytes(&data)?;

println!("~~ key successfuly written to slot {:#04x}", slot);
eprintln!("~~ Key successfuly written to slot {:#04x}", slot);

Ok(())
}
Expand All @@ -231,7 +237,7 @@ pub fn lock(device: String, slot: u16, force: bool) -> Result<()> {

if !force {
// prompt user to make sure they're sure
println!("Are you sure you want to lock the key? This can only be done once per slot. Type 'yes' to proceed.");
eprintln!("Are you sure you want to lock the key? This can only be done once per slot. Type 'yes' to proceed.");
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
if input.trim() != "yes" {
Expand Down Expand Up @@ -348,7 +354,7 @@ pub fn lock(device: String, slot: u16, force: bool) -> Result<()> {
let data = [0x80, 0x81, 0x00, 0x00, 0x56, 0x30];
tm.write_bytes(&data)?;

println!("~~ key at slot {:#04x} is now write-protected", slot);
eprintln!("~~ Key at slot {:#04x} is now write-protected", slot);

Ok(())
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn main() -> Result<()> {
}

match args.command {
args::Cmds::Read(_) => cmds::read(device, key_slot),
args::Cmds::Read(p) => cmds::read(device, key_slot, p.raw),
args::Cmds::Write(p) => cmds::write(device, key_slot, p.key),
args::Cmds::Lock(p) => cmds::lock(device, key_slot, p.force),
}
Expand Down
6 changes: 4 additions & 2 deletions src/trustm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ pub struct TrustM {

impl TrustM {
pub fn init(device: String) -> Result<TrustM> {
let dev = LinuxI2CDevice::new(device, TM_ADDR).context("failed init")?;
let err = "Failed to init TrustM";
let dev = LinuxI2CDevice::new(device, TM_ADDR).context(err)?;
let mut tm = TrustM { dev };

sleep(Duration::from_micros(100 * 1000));

let data: [u8; 3] = [0x88, 0xff, 0xff]; // reset
tm.write_bytes(&data)?;
tm.write_bytes(&data).context(err)?;

sleep(Duration::from_micros(100 * 1000));
eprintln!("~~ TrustM initinialised");
Ok(tm)
}

Expand Down

0 comments on commit 5b534ca

Please sign in to comment.