1#![no_std]
5#![warn(non_ascii_idents, trivial_casts, unused, unused_qualifications)]
6#![deny(unsafe_code)]
7
8use serde::{Deserialize, Serialize};
9use trussed_core::{
10 config::MAX_MEDIUM_DATA_LENGTH,
11 serde_extensions::{Extension, ExtensionClient, ExtensionResult},
12 types::{Bytes, KeyId, Location, Message},
13 Error,
14};
15
16#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
17pub struct OkmId(pub KeyId);
18
19#[derive(Serialize, Deserialize)]
21pub enum KeyOrData<const N: usize> {
22 Key(KeyId),
23 Data(Bytes<N>),
24}
25
26pub struct HkdfExtension;
27
28impl Extension for HkdfExtension {
29 type Request = HkdfRequest;
30 type Reply = HkdfReply;
31}
32
33#[allow(clippy::large_enum_variant)]
34#[derive(Serialize, Deserialize)]
35pub enum HkdfRequest {
36 Extract(HkdfExtractRequest),
37 Expand(HkdfExpandRequest),
38}
39#[derive(Serialize, Deserialize)]
40pub enum HkdfReply {
41 Extract(HkdfExtractReply),
42 Expand(HkdfExpandReply),
43}
44
45impl From<HkdfExpandRequest> for HkdfRequest {
46 fn from(v: HkdfExpandRequest) -> Self {
47 Self::Expand(v)
48 }
49}
50
51impl From<HkdfExtractRequest> for HkdfRequest {
52 fn from(v: HkdfExtractRequest) -> Self {
53 Self::Extract(v)
54 }
55}
56
57impl From<HkdfExpandReply> for HkdfReply {
58 fn from(v: HkdfExpandReply) -> Self {
59 Self::Expand(v)
60 }
61}
62
63impl From<HkdfExtractReply> for HkdfReply {
64 fn from(v: HkdfExtractReply) -> Self {
65 Self::Extract(v)
66 }
67}
68
69impl TryFrom<HkdfRequest> for HkdfExpandRequest {
70 type Error = Error;
71 fn try_from(v: HkdfRequest) -> Result<Self, Error> {
72 match v {
73 HkdfRequest::Expand(v) => Ok(v),
74 _ => Err(Error::InternalError),
75 }
76 }
77}
78impl TryFrom<HkdfRequest> for HkdfExtractRequest {
79 type Error = Error;
80 fn try_from(v: HkdfRequest) -> Result<Self, Error> {
81 match v {
82 HkdfRequest::Extract(v) => Ok(v),
83 _ => Err(Error::InternalError),
84 }
85 }
86}
87
88impl TryFrom<HkdfReply> for HkdfExpandReply {
89 type Error = Error;
90 fn try_from(v: HkdfReply) -> Result<Self, Error> {
91 match v {
92 HkdfReply::Expand(v) => Ok(v),
93 _ => Err(Error::InternalError),
94 }
95 }
96}
97impl TryFrom<HkdfReply> for HkdfExtractReply {
98 type Error = Error;
99 fn try_from(v: HkdfReply) -> Result<Self, Error> {
100 match v {
101 HkdfReply::Extract(v) => Ok(v),
102 _ => Err(Error::InternalError),
103 }
104 }
105}
106
107#[derive(Serialize, Deserialize)]
108pub struct HkdfExtractReply {
109 pub okm: OkmId,
110}
111
112#[derive(Serialize, Deserialize)]
113pub struct HkdfExtractRequest {
114 pub ikm: KeyOrData<MAX_MEDIUM_DATA_LENGTH>,
115 pub salt: Option<KeyOrData<MAX_MEDIUM_DATA_LENGTH>>,
116 pub storage: Location,
118}
119
120#[derive(Serialize, Deserialize)]
121pub struct HkdfExpandReply {
122 pub key: KeyId,
123}
124
125#[derive(Serialize, Deserialize)]
126pub struct HkdfExpandRequest {
127 pub prk: OkmId,
128 pub info: Message,
129 pub len: usize,
130 pub storage: Location,
131}
132
133pub type HkdfResult<'a, R, C> = ExtensionResult<'a, HkdfExtension, R, C>;
134
135pub trait HkdfClient: ExtensionClient<HkdfExtension> {
136 fn hkdf_extract(
137 &mut self,
138 ikm: KeyOrData<MAX_MEDIUM_DATA_LENGTH>,
139 salt: Option<KeyOrData<MAX_MEDIUM_DATA_LENGTH>>,
140 storage: Location,
141 ) -> HkdfResult<'_, HkdfExtractReply, Self> {
142 self.extension(HkdfRequest::Extract(HkdfExtractRequest {
143 ikm,
144 salt,
145 storage,
146 }))
147 }
148 fn hkdf_expand(
149 &mut self,
150 prk: OkmId,
151 info: Message,
152 len: usize,
153 storage: Location,
154 ) -> HkdfResult<'_, HkdfExpandReply, Self> {
155 self.extension(HkdfRequest::Expand(HkdfExpandRequest {
156 prk,
157 info,
158 len,
159 storage,
160 }))
161 }
162}
163
164impl<C: ExtensionClient<HkdfExtension>> HkdfClient for C {}