Skip to content

Commit

Permalink
Import HkdfExtension from Nitrokey/trussed-hkdf-backend
Browse files Browse the repository at this point in the history
The HkdfExtension was previously maintained in a separate repository and
together with a custom backend.  Every additional backend adds some
overhead, both in the firmware and for maintenance.  Therefore this
patch moves the trussed-hkdf crate with the HkdfExtension as an
extension into this repository and implements it for the StagingBackend,
replacing the HkdfBackend.

This patch also releases trussed-hkdf v0.2.0 and trussed-staging v0.3.0.

Fixes: Nitrokey/trussed-hkdf-backend#6
  • Loading branch information
robin-nitrokey committed Mar 25, 2024
1 parent a9557b0 commit e016b25
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 19 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased][]

[Unreleased]: https://github.com/trussed-dev/trussed-staging/compare/v0.3.0...HEAD

-

## [0.3.0][] - 2024-03-25

[0.3.0]: https://github.com/trussed-dev/trussed-staging/compare/v0.2.0...v0.3.0

- Remove `manage` from default features.
- Implement `HkdfExtension` (moved from [Nitrokey/trussed-hkdf-backend][])

[Unreleased]: https://github.com/trussed-dev/trussed-staging/compare/v0.2.0...HEAD
[Nitrokey/trussed-hkdf-backend]: https://github.com/Nitrokey/trussed-hkdf-backend

## [0.2.0][] - 2024-03-15

Expand Down
15 changes: 11 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: CC0-1.0

[workspace]
members = ["extensions/chunked", "extensions/manage", "extensions/wrap-key-to-file"]
members = ["extensions/chunked", "extensions/hkdf", "extensions/manage", "extensions/wrap-key-to-file"]

[workspace.package]
authors = ["Nitrokey GmbH <[email protected]>"]
Expand All @@ -17,7 +17,7 @@ trussed = { version = "0.1.0", features = ["serde-extensions"] }

[package]
name = "trussed-staging"
version = "0.2.0"
version = "0.3.0"
description = "Work in progress trussed features"
authors.workspace = true
edition.workspace = true
Expand All @@ -30,23 +30,29 @@ serde-byte-array.workspace = true
trussed.workspace = true

chacha20poly1305 = { version = "0.10", default-features = false, features = ["heapless", "reduced-round"], optional = true }
rand_core = { version = "0.6.4", default-features = false }
delog = "0.1.6"
hkdf = { version = "0.12", optional = true }
rand_core = { version = "0.6.4", default-features = false }
sha2 = { version = "0.10", default-features = false, optional = true }
littlefs2 = "0.4.0"

trussed-chunked = { version = "0.1.0", optional = true }
trussed-hkdf = { version = "0.2.0", optional = true }
trussed-manage = { version = "0.1.0", optional = true }
trussed-wrap-key-to-file = { version = "0.1.0", optional = true }

[dev-dependencies]
hex-literal = "0.3.4"
hmac = "0.12.0"
trussed = { workspace = true, features = ["virt"] }

[features]
default = []

wrap-key-to-file = ["chacha20poly1305", "trussed-wrap-key-to-file"]
chunked = ["trussed-chunked", "chacha20poly1305/stream"]
hkdf = ["trussed-hkdf", "dep:hkdf", "dep:sha2"]
manage = ["trussed-manage"]
wrap-key-to-file = ["chacha20poly1305", "trussed-wrap-key-to-file"]

virt = ["std", "trussed/virt"]
std = []
Expand All @@ -64,5 +70,6 @@ trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "45ed62ba9
littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "ebd27e49ca321089d01d8c9b169c4aeb58ceeeca" }

trussed-chunked = { path = "extensions/chunked" }
trussed-hkdf = { path = "extensions/hkdf" }
trussed-manage = { path = "extensions/manage" }
trussed-wrap-key-to-file = { path = "extensions/wrap-key-to-file" }
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ check:
RUSTLFAGS='-Dwarnings' cargo check --all-features --all-targets --workspace
RUSTLFAGS='-Dwarnings' cargo check --no-default-features
RUSTLFAGS='-Dwarnings' cargo check --features chunked
RUSTLFAGS='-Dwarnings' cargo check --features hkdf
RUSTLFAGS='-Dwarnings' cargo check --features manage
RUSTLFAGS='-Dwarnings' cargo check --features wrap-key-to-file

Expand Down
34 changes: 34 additions & 0 deletions extensions/hkdf/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!--
Copyright (C) Nitrokey GmbH
SPDX-License-Identifier: CC0-1.0
-->

# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased][]

[Unreleased]: https://github.com/trussed-dev/trussed-staging/compare/hkdf-v0.2.0...HEAD

-

## [0.2.0][] - 2024-03-25

[0.2.0]: https://github.com/trussed-dev/trussed-staging/releases/tag/hkdf-v0.2.0

- Move the `trussed-hkdf` crate from the [Nitrokey/trussed-hkdf-backend][]
repository into the [trussed-dev/trussed-staging][] repository
- Remove the `HkdfBackend`. The `HkdfExtension` is now implemented by the
`StagingBackend` in `trussed-staging` if the `hkdf` feature is enabled

[Nitrokey/trussed-hkdf-backend]: https://github.com/Nitrokey/trussed-hkdf-backend
[trussed-dev/trussed-staging]: https://github.com/trussed-dev/trussed-staging

## [0.1.0][] - 2024-02-20

[0.1.0]: https://github.com/Nitrokey/trussed-hkdf-backend/releases/tag/v0.1.0

Initial release of the `HkdfExtension` and its implementation in the `HkdfBackend`.
14 changes: 14 additions & 0 deletions extensions/hkdf/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (C) Nitrokey GmbH
# SPDX-License-Identifier: CC0-1.0

[package]
name = "trussed-hkdf"
version = "0.2.0"
authors.workspace = true
edition.workspace = true
repository.workspace = true
license.workspace = true

[dependencies]
serde.workspace = true
trussed.workspace = true
164 changes: 164 additions & 0 deletions extensions/hkdf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright (C) Nitrokey GmbH
// SPDX-License-Identifier: Apache-2.0 or MIT

#![no_std]
#![warn(non_ascii_idents, trivial_casts, unused, unused_qualifications)]
#![deny(unsafe_code)]

use serde::{Deserialize, Serialize};
use trussed::{
config::MAX_MEDIUM_DATA_LENGTH,
serde_extensions::{Extension, ExtensionClient, ExtensionResult},
types::{Bytes, KeyId, Location, Message},
Error,
};

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct OkmId(pub KeyId);

/// Can represent either data or a key
#[derive(Serialize, Deserialize)]
pub enum KeyOrData<const N: usize> {
Key(KeyId),
Data(Bytes<N>),
}

pub struct HkdfExtension;

impl Extension for HkdfExtension {
type Request = HkdfRequest;
type Reply = HkdfReply;
}

#[allow(clippy::large_enum_variant)]
#[derive(Serialize, Deserialize)]
pub enum HkdfRequest {
Extract(HkdfExtractRequest),
Expand(HkdfExpandRequest),
}
#[derive(Serialize, Deserialize)]
pub enum HkdfReply {
Extract(HkdfExtractReply),
Expand(HkdfExpandReply),
}

impl From<HkdfExpandRequest> for HkdfRequest {
fn from(v: HkdfExpandRequest) -> Self {
Self::Expand(v)
}
}

impl From<HkdfExtractRequest> for HkdfRequest {
fn from(v: HkdfExtractRequest) -> Self {
Self::Extract(v)
}
}

impl From<HkdfExpandReply> for HkdfReply {
fn from(v: HkdfExpandReply) -> Self {
Self::Expand(v)
}
}

impl From<HkdfExtractReply> for HkdfReply {
fn from(v: HkdfExtractReply) -> Self {
Self::Extract(v)
}
}

impl TryFrom<HkdfRequest> for HkdfExpandRequest {
type Error = Error;
fn try_from(v: HkdfRequest) -> Result<Self, Error> {
match v {
HkdfRequest::Expand(v) => Ok(v),
_ => Err(Error::InternalError),
}
}
}
impl TryFrom<HkdfRequest> for HkdfExtractRequest {
type Error = Error;
fn try_from(v: HkdfRequest) -> Result<Self, Error> {
match v {
HkdfRequest::Extract(v) => Ok(v),
_ => Err(Error::InternalError),
}
}
}

impl TryFrom<HkdfReply> for HkdfExpandReply {
type Error = Error;
fn try_from(v: HkdfReply) -> Result<Self, Error> {
match v {
HkdfReply::Expand(v) => Ok(v),
_ => Err(Error::InternalError),
}
}
}
impl TryFrom<HkdfReply> for HkdfExtractReply {
type Error = Error;
fn try_from(v: HkdfReply) -> Result<Self, Error> {
match v {
HkdfReply::Extract(v) => Ok(v),
_ => Err(Error::InternalError),
}
}
}

#[derive(Serialize, Deserialize)]
pub struct HkdfExtractReply {
pub okm: OkmId,
}

#[derive(Serialize, Deserialize)]
pub struct HkdfExtractRequest {
pub ikm: KeyOrData<MAX_MEDIUM_DATA_LENGTH>,
pub salt: Option<KeyOrData<MAX_MEDIUM_DATA_LENGTH>>,
/// Location to store the OKM
pub storage: Location,
}

#[derive(Serialize, Deserialize)]
pub struct HkdfExpandReply {
pub key: KeyId,
}

#[derive(Serialize, Deserialize)]
pub struct HkdfExpandRequest {
pub prk: OkmId,
pub info: Message,
pub len: usize,
pub storage: Location,
}

pub type HkdfResult<'a, R, C> = ExtensionResult<'a, HkdfExtension, R, C>;

pub trait HkdfClient: ExtensionClient<HkdfExtension> {
fn hkdf_extract(
&mut self,
ikm: KeyOrData<MAX_MEDIUM_DATA_LENGTH>,
salt: Option<KeyOrData<MAX_MEDIUM_DATA_LENGTH>>,
storage: Location,
) -> HkdfResult<'_, HkdfExtractReply, Self> {
self.extension(HkdfRequest::Extract(HkdfExtractRequest {
ikm,
salt,
storage,
}))
}
fn hkdf_expand(
&mut self,
prk: OkmId,
info: Message,
len: usize,
storage: Location,
) -> HkdfResult<'_, HkdfExpandReply, Self> {
self.extension(HkdfRequest::Expand(HkdfExpandRequest {
prk,
info,
len,
storage,
}))
}
}

impl<C: ExtensionClient<HkdfExtension>> HkdfClient for C {}
Loading

0 comments on commit e016b25

Please sign in to comment.