Skip to content

Commit d5c973b

Browse files
nils-cercariolo-stGrom-
authored andcommitted
[api/service/doc] Add derive key service and api functions
1 parent 88acf93 commit d5c973b

12 files changed

+1436
-0
lines changed

api/stse_derive_keys.c

Lines changed: 406 additions & 0 deletions
Large diffs are not rendered by default.

api/stse_derive_keys.h

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/*!
2+
******************************************************************************
3+
* \file stse_derive_keys.h
4+
* \brief STSE Derive Keys API Layer (header)
5+
* \author STMicroelectronics - CS application team
6+
*
7+
******************************************************************************
8+
* \attention
9+
*
10+
* <h2><center>&copy; COPYRIGHT 2025 STMicroelectronics</center></h2>
11+
*
12+
* This software is licensed under terms that can be found in the LICENSE file in
13+
* the root directory of this software component.
14+
* If no LICENSE file comes with this software, it is provided AS-IS.
15+
*
16+
*****************************************************************************/
17+
18+
#ifndef STSE_DERIVE_KEYS_H
19+
#define STSE_DERIVE_KEYS_H
20+
21+
#include "services/stsafea/stsafea_derive_keys.h"
22+
23+
/*! \defgroup stse_derive_keys STSE Derive Keys
24+
* \ingroup stse_api
25+
* \brief STSE derive keys API set
26+
* \details The derive keys API set provides high level functions to derive keys in STSE devices.
27+
* @{
28+
*/
29+
30+
/**
31+
* @brief Derive a single key from a master key stored in a slot.
32+
* \details A wrapper for Extract+Expand. Derives a key using optional salt and context,
33+
* returning the result to the host buffer.
34+
* \param[in] pSTSE Pointer to STSE Handler.
35+
* \param[in] master_slot Slot containing the master key (IKM).
36+
* \param[in] pSalt Salt data (Optional, can be NULL).
37+
* \param[in] salt_length Length of salt.
38+
* \param[in] pContext Context/Info string (Optional, can be NULL).
39+
* \param[in] context_len Length of context.
40+
* \param[out] pOutput_key Buffer for the derived key (Pre-allocated).
41+
* \param[in] key_length Desired derived key length.
42+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise
43+
* \details \include{doc} stse_derive_key.dox
44+
*/
45+
stse_ReturnCode_t stse_derive_key(
46+
stse_Handler_t *pSTSE,
47+
PLAT_UI8 master_slot,
48+
PLAT_UI8 *pSalt,
49+
PLAT_UI16 salt_length,
50+
PLAT_UI8 *pContext,
51+
PLAT_UI16 context_len,
52+
PLAT_UI8 *pOutput_key,
53+
PLAT_UI16 key_length);
54+
55+
/**
56+
* @brief Simplest HKDF derivation using a context with explicit length.
57+
* \details Derives a key from a master slot using the provided context.
58+
* Uses a default empty salt.
59+
* \param[in] pSTSE Pointer to STSE Handler.
60+
* \param[in] master_slot Slot containing the master key.
61+
* \param[in] pContext Context/Info data.
62+
* \param[in] context_len Length of the context data.
63+
* \param[out] pOutput_key Buffer for the derived key.
64+
* \param[in] key_length Desired derived key length.
65+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise
66+
* \details \include{doc} stse_derive_key_simple.dox
67+
*/
68+
stse_ReturnCode_t stse_derive_key_simple(
69+
stse_Handler_t *pSTSE,
70+
PLAT_UI8 master_slot,
71+
PLAT_UI8 *pContext,
72+
PLAT_UI16 context_len,
73+
PLAT_UI8 *pOutput_key,
74+
PLAT_UI16 key_length);
75+
76+
/**
77+
* @brief Perform HKDF-Extract only and store PRK in a slot.
78+
* \details Creates a session/context-specific PRK inside the secure element.
79+
* This PRK can be used for subsequent Expand operations.
80+
* \param[in] pSTSE Pointer to STSE Handler.
81+
* \param[in] master_slot Slot containing the master key.
82+
* \param[in] pSalt Salt data.
83+
* \param[in] salt_length Length of salt.
84+
* \param[out] pPrk_slot Output: Slot number where PRK was stored.
85+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise.
86+
* \details \include{doc} stse_derive_key_extract.dox
87+
*/
88+
stse_ReturnCode_t stse_derive_key_extract(
89+
stse_Handler_t *pSTSE,
90+
PLAT_UI8 master_slot,
91+
PLAT_UI8 *pSalt,
92+
PLAT_UI16 salt_length,
93+
PLAT_UI8 *pPrk_slot);
94+
95+
/**
96+
* @brief Perform HKDF-Expand only from an existing PRK slot.
97+
* \details Derives a key from a previously extracted PRK using the provided Context/Info.
98+
* \param[in] pSTSE Pointer to STSE Handler.
99+
* \param[in] prk_slot Slot containing the PRK (must be 32 bytes).
100+
* \param[in] pContext Context/Info data.
101+
* \param[in] context_len Length of context.
102+
* \param[out] pOutput_key Buffer for the derived key.
103+
* \param[in] key_length Desired derived key length.
104+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise.
105+
* \details \include{doc} stse_derive_key_expand.dox
106+
*/
107+
stse_ReturnCode_t stse_derive_key_expand(
108+
stse_Handler_t *pSTSE,
109+
PLAT_UI8 prk_slot,
110+
PLAT_UI8 *pContext,
111+
PLAT_UI16 context_len,
112+
PLAT_UI8 *pOutput_key,
113+
PLAT_UI16 key_length);
114+
115+
/**
116+
* @brief Derive encryption and MAC keys for a session.
117+
* \details Convenience function:
118+
* 1. Extract PRK from master using session_id.
119+
* 2. Expand "ENC" -> Encryption Key.
120+
* 3. Expand "MAC" -> Authentication Key.
121+
* \param[in] pSTSE Pointer to STSE Handler.
122+
* \param[in] master_slot Slot containing master key.
123+
* \param[in] session_id Session identifier (salt).
124+
* \param[out] pEnc_key Buffer for encryption key.
125+
* \param[in] enc_key_len Length of encryption key.
126+
* \param[out] pMac_key Buffer for MAC key.
127+
* \param[in] mac_key_len Length of MAC key.
128+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise.
129+
* \details \include{doc} stse_derive_session_keys.dox
130+
*/
131+
stse_ReturnCode_t stse_derive_session_keys(
132+
stse_Handler_t *pSTSE,
133+
PLAT_UI8 master_slot,
134+
PLAT_UI32 session_id,
135+
PLAT_UI8 *pEnc_key,
136+
PLAT_UI16 enc_key_len,
137+
PLAT_UI8 *pMac_key,
138+
PLAT_UI16 mac_key_len);
139+
140+
/**
141+
* @brief Derive a key and store it securely in a slot.
142+
* \details Performs Extract+Expand but routes result to an internal slot.
143+
* The key is therefore never exposed.
144+
* \param[in] pSTSE Pointer to STSE Handler.
145+
* \param[in] master_slot Slot containing master key.
146+
* \param[in] pSalt Salt data.
147+
* \param[in] salt_length Length of salt.
148+
* \param[in] pContext Context/Info data.
149+
* \param[in] context_len Length of context.
150+
* \param[in] pKey_info Configuration for the destination slot.
151+
* \param[out] pOutput_slot Output: Slot number where key was created.
152+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise.
153+
* \details \include{doc} stse_derive_key_to_slot.dox
154+
*/
155+
stse_ReturnCode_t stse_derive_key_to_slot(
156+
stse_Handler_t *pSTSE,
157+
PLAT_UI8 master_slot,
158+
PLAT_UI8 *pSalt,
159+
PLAT_UI16 salt_length,
160+
PLAT_UI8 *pContext,
161+
PLAT_UI16 context_len,
162+
stsafe_output_key_description_information_t *pKey_info,
163+
PLAT_UI8 *pOutput_slot);
164+
165+
/**
166+
* @brief Efficiently derive multiple keys from a PRK in one command.
167+
* \details Uses HKDF-Expand to generate up to 32 keys at once.
168+
* Note: Uses the first context string for the entire batch.
169+
* \param[in] pSTSE Pointer to STSE Handler.
170+
* \param[in] prk_slot Slot containing PRK.
171+
* \param[in] pContexts Array of context strings.
172+
* \param[in] pContext_lens Array of context lengths.
173+
* \param[out] pOutput_keys Array of output buffers.
174+
* \param[in] pKey_lengths Array of requested key lengths.
175+
* \param[in] num_keys Number of keys to derive.
176+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise.
177+
* \details \include{doc} stse_derive_key_expand_multiple.dox
178+
*/
179+
stse_ReturnCode_t stse_derive_key_expand_multiple(
180+
stse_Handler_t *pSTSE,
181+
PLAT_UI8 prk_slot,
182+
PLAT_UI8 **pContexts,
183+
PLAT_UI16 *pContext_lens,
184+
PLAT_UI8 **pOutput_keys,
185+
PLAT_UI16 *pKey_lengths,
186+
PLAT_UI8 num_keys);
187+
188+
/**
189+
* @brief Derive a key using raw Input Key Material (IKM).
190+
* \details Use when the source key is not stored in the secure element.
191+
* The IKM is passed in the command payload and is not stored.
192+
* \param[in] pSTSE Pointer to STSE Handler.
193+
* \param[in] pIkm Pointer to Input Key Material.
194+
* \param[in] ikm_length Length of IKM.
195+
* \param[in] pSalt Salt data.
196+
* \param[in] salt_length Length of salt.
197+
* \param[in] pContext Context/Info data.
198+
* \param[in] context_len Length of context.
199+
* \param[out] pOutput_key Buffer for derived key.
200+
* \param[in] key_length Length of derived key.
201+
* \return \ref STSE_OK on success ; \ref stse_ReturnCode_t error code otherwise.
202+
* \details \include{doc} stse_derive_key_from_ikm.dox
203+
*/
204+
stse_ReturnCode_t stse_derive_key_from_ikm(
205+
stse_Handler_t *pSTSE,
206+
PLAT_UI8 *pIkm,
207+
PLAT_UI16 ikm_length,
208+
PLAT_UI8 *pSalt,
209+
PLAT_UI16 salt_length,
210+
PLAT_UI8 *pContext,
211+
PLAT_UI16 context_len,
212+
PLAT_UI8 *pOutput_key,
213+
PLAT_UI16 key_length);
214+
215+
216+
#endif /* STSE_DERIVE_KEYS_H */
217+
218+
/*! @}*/
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
\b Description
2+
The following diagram illustrates the interactions performed between the Host and the target STSE device to derive a key and return it to the host.
3+
\n\n
4+
5+
@startuml
6+
participant "HOST" as HOST
7+
participant "STSE" as STSE
8+
9+
activate HOST $STSE_ACTIVITY
10+
group stse_derive_key
11+
HOST -> STSE : Derive Key Command (HKDF Extract + Expand)\n[Input: Slot + Salt + Info]
12+
activate STSE $STSE_ACTIVITY
13+
return Response (Derived Key Data)
14+
end
15+
deactivate HOST
16+
@enduml
17+
18+
\n\n \b Use-case \b example
19+
\n The following applicative code snippet illustrates how to derive a key using a salt and context.
20+
\n\n
21+
22+
\code{.c}
23+
/* ## Derive Key to Host Buffer */
24+
PLAT_UI8 derived_key[32];
25+
PLAT_UI8 salt[] = {0x01, 0x02, 0x03, 0x04};
26+
PLAT_UI8 context[] = "app-context";
27+
28+
stse_ret = stse_derive_key(
29+
&stse_handler,
30+
STSE_MASTER_KEY_SLOT,
31+
salt, sizeof(salt),
32+
context, sizeof(context)-1,
33+
derived_key, 32
34+
);
35+
36+
if (stse_ret != STSE_OK)
37+
{
38+
/* Handle Error */
39+
}
40+
\endcode
41+
42+
\sa stse_init
43+
44+
<div style="page-break-after: always;"></div>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
\b Description
2+
This command performs the HKDF-Expand step only. It takes a previously extracted PRK (stored in a slot) and expands it into a new key using the provided context information.
3+
\n\n
4+
5+
@startuml
6+
participant "HOST" as HOST
7+
participant "STSE" as STSE
8+
9+
activate HOST $STSE_ACTIVITY
10+
group stse_derive_key_expand
11+
HOST -> STSE : Derive Key Command (HKDF Expand Only)\n[Input: PRK Slot + Info]
12+
activate STSE $STSE_ACTIVITY
13+
return Response (Derived Key Data)
14+
end
15+
deactivate HOST
16+
@enduml
17+
18+
\n\n \b Use-case \b example
19+
\n\n
20+
21+
\code{.c}
22+
/* ## HKDF Expand from PRK */
23+
PLAT_UI8 output_key[16];
24+
PLAT_UI8 context[] = "expansion-context";
25+
26+
/* Assumes prk_slot was populated by a previous extract call */
27+
stse_ret = stse_derive_key_expand(
28+
&stse_handler,
29+
prk_slot,
30+
context, sizeof(context)-1,
31+
output_key, 16
32+
);
33+
\endcode
34+
35+
\sa stse_init
36+
37+
<div style="page-break-after: always;"></div>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
\b Description
2+
This function uses the HKDF-Expand command to derive multiple keys (up to 32) in a single transaction. This is more efficient than calling stse_derive_key_expand() multiple times.
3+
\n\n
4+
5+
@startuml
6+
participant "HOST" as HOST
7+
participant "STSE" as STSE
8+
9+
activate HOST $STSE_ACTIVITY
10+
group stse_derive_key_expand_multiple
11+
HOST -> STSE : Derive Key Command (NumKeys=N)\n[Input: PRK Slot + Context]
12+
activate STSE $STSE_ACTIVITY
13+
STSE -> STSE : Generate Key 1, Key 2... Key N
14+
return Response (Key 1 Data, Key 2 Data... Key N Data)
15+
end
16+
deactivate HOST
17+
@enduml
18+
19+
\n\n \b Use-case \b example
20+
\n\n
21+
22+
\code{.c}
23+
/* ## Derive Multiple Keys */
24+
PLAT_UI8 *outputs[2];
25+
PLAT_UI16 lengths[2] = {16, 16};
26+
PLAT_UI8 key1[16], key2[16];
27+
28+
outputs[0] = key1;
29+
outputs[1] = key2;
30+
31+
stse_ret = stse_derive_key_expand_multiple(
32+
&stse_handler,
33+
prk_slot,
34+
NULL, NULL, /* Use default/no context */
35+
outputs,
36+
lengths,
37+
2
38+
);
39+
\endcode
40+
41+
\sa stse_init
42+
43+
<div style="page-break-after: always;"></div>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
\b Description
2+
This command performs the HKDF-Extract step only. It generates a Pseudo-Random Key (PRK) from the input key material and salt, storing the result in an internal secure slot.
3+
\n\n
4+
5+
@startuml
6+
participant "HOST" as HOST
7+
participant "STSE" as STSE
8+
9+
activate HOST $STSE_ACTIVITY
10+
group stse_derive_key_extract
11+
HOST -> STSE : Derive Key Command (HKDF Extract Only)\n[Input: Master Slot + Salt]
12+
activate STSE $STSE_ACTIVITY
13+
STSE -> STSE : Generate PRK -> Store in internal slot
14+
return Response (PRK Slot Number)
15+
end
16+
deactivate HOST
17+
@enduml
18+
19+
\n\n \b Use-case \b example
20+
\n\n
21+
22+
\code{.c}
23+
/* ## HKDF Extract PRK */
24+
PLAT_UI8 salt[] = {0xAA, 0xBB, 0xCC, 0xDD};
25+
PLAT_UI8 prk_slot;
26+
27+
stse_ret = stse_derive_key_extract(
28+
&stse_handler,
29+
STSE_MASTER_KEY_SLOT,
30+
salt, sizeof(salt),
31+
&prk_slot
32+
);
33+
\endcode
34+
35+
\sa stse_init
36+
37+
<div style="page-break-after: always;"></div>

0 commit comments

Comments
 (0)