MCUX CLNS
MCUX Crypto Library Normal Secure
 
Loading...
Searching...
No Matches
mcuxClExample_RFC3394_Helper.h
1/*--------------------------------------------------------------------------*/
2/* Copyright 2022-2024 NXP */
3/* */
4/* NXP Proprietary. This software is owned or controlled by NXP and may */
5/* only be used strictly in accordance with the applicable license terms. */
6/* By expressly accepting such terms or by downloading, installing, */
7/* activating and/or otherwise using the software, you are agreeing that */
8/* you have read, and that you agree to comply with and are bound by, such */
9/* license terms. If you do not agree to be bound by the applicable */
10/* license terms, then you may not retain, install, activate or otherwise */
11/* use the software. */
12/*--------------------------------------------------------------------------*/
13
14#ifndef MCUXCLEXAMPLE_RFC3394_HELPER_H_
15#define MCUXCLEXAMPLE_RFC3394_HELPER_H_
16
17#include <mcuxClConfig.h> // Exported features flags header
18#include <mcuxClCore_Platform.h>
19#include <mcuxClEls.h>
22#include <mcuxClMemory_Copy.h>
23
28static inline bool mcuxClExample_rfc3394_wrap(
29 const uint32_t * pInput, //< pointer to key to be wrapped
30 size_t inputLength, //< length of key to be wrapped in bytes
31 const uint8_t * pKek_in, //< pointer to key wrapping key
32 mcuxClEls_KeyIndex_t keyIdx, //< keyslot index of key wrapping key
33 uint8_t extkey, //< 0-use key stored internally at keyIdx as wrapping key, 1-use external pKek_in as wrapping key
34 size_t kekLength, //< length of key wrapping key in bytes
35 uint32_t * pOutput, //< pointer to output buffer, size has to be inputLength + 16 bytes
36 mcuxClEls_KeyProp_t properties //< properties of the key to be wrapped
37)
38{
39 uint32_t concat[MCUXCLELS_CIPHER_BLOCK_SIZE_AES/sizeof(uint32_t)] = { 0u };
40
41 uint32_t input[MCUXCLELS_CIPHER_BLOCK_SIZE_AES/sizeof(uint32_t)] = { 0u };
42 uint8_t pKek[MCUXCLELS_CIPHER_KEY_SIZE_AES_256] = { 0u };
43
45 {
47 pKek_in,
48 kekLength,
49 kekLength));
50
52 {
53 return false;
54 }
55
57 }
58
59 // Intermediate state is stored in pOutput as it is large enough
60
61 // initialize buffer
62 concat[0] = 0xA6A6A6A6u; // first half of concat is the A from the standard, initialized to RFC3394 IV
63 concat[1] = 0xA6A6A6A6u;
64 concat[2] = properties.word.value; // second half of concat is R(input)/B(output), first R consists of properties...
65 concat[3] = 0x00000000u; // ... and ELS padding (zeros)
66 concat[2] = (concat[2] << 24u) | (concat[2] >> 24u) | ((concat[2] & 0x0000ff00u) << 8u) | ((concat[2] >> 8u) & 0x0000ff00u); // swap endianness
67
68 // initialize ELS encryption parameters
69 mcuxClEls_CipherOption_t cipher_options;
70 cipher_options.word.value = 0;
72 cipher_options.bits.dcrpt = MCUXCLELS_CIPHER_ENCRYPT;
73 cipher_options.bits.extkey = extkey;
74
75 // input has to be multiple of 64 bits
76 if (inputLength % sizeof(uint64_t) != 0u)
77 {
78 return false;
79 }
80
81 const uint32_t *pSource = pInput;
82 uint32_t *pDest = pOutput;
83 uint32_t std_n = inputLength/sizeof(uint64_t) + 1u; // n value from standard
84 for(size_t jdx = 0u; jdx < 6u; jdx++)
85 {
86 for(size_t idx = 0u; idx < std_n; idx++)
87 {
88 input[0]=concat[0];
89 input[1]=concat[1];
90 input[2]=concat[2];
91 input[3]=concat[3];
92
93 // Encrypt concatenated A and chunk to be processed
94 MCUX_CSSL_ANALYSIS_START_PATTERN_NULL_POINTER_CONSTANT()
95 MCUX_CSSL_ANALYSIS_START_SUPPRESS_ESCAPING_LOCAL_ADDRESS("Address of concat is for local use only. The call to mcuxClEls_WaitForOperation ensures it cannot escape.")
97 cipher_options,
98 keyIdx,
99 pKek,
100 kekLength,
101 (uint8_t*) input,
103 NULL,
104 (uint8_t*) concat));
105 MCUX_CSSL_ANALYSIS_STOP_SUPPRESS_ESCAPING_LOCAL_ADDRESS()
106 MCUX_CSSL_ANALYSIS_STOP_PATTERN_NULL_POINTER_CONSTANT()
108 {
109 return false;
110 }
112
115 {
116 return false;
117 }
119
120 // Write out processed key chunk
121 pDest[2u*idx + 2u] = concat[2u];
122 pDest[2u*idx + 3u] = concat[3u];
123
124 if( idx == std_n - 1u)
125 {
126 // Load next key chunk
127 concat[2u] = pDest[2u];
128 concat[3u] = pDest[3u];
129 pSource = pDest + 4;
130 }
131 else
132 {
133 // Load next key chunk
134 concat[2u] = pSource[2u*idx + 0u];
135 concat[3u] = pSource[2u*idx + 1u];
136 }
137
138 // XOR round constant into A
139 uint32_t gdx = std_n * jdx + (idx + 1u); // all values should fit into a uint32_t
140 gdx = (gdx << 24u) | (gdx >> 24u) | ((gdx & 0x0000ff00u) << 8u) | ((gdx >> 8u) & 0x0000ff00u); // swap endianness
141 concat[1u] ^= gdx;
142 }
143 }
144 // Write out processed key chunk
145 pDest[0u] = concat[0u];
146 pDest[1u] = concat[1u];
147
148 return true;
149}
150
155static inline bool mcuxClExample_rfc3394_unwrap(
156 const uint32_t * pInput, //< pointer to rfc3394 blob to be wrapped
157 size_t inputLength, //< length of key the rfc3394 blob in bytes
158 const uint8_t * pKek_in, //< pointer to key wrapping key
159 mcuxClEls_KeyIndex_t keyIdx, //< keyslot index of key wrapping key
160 uint8_t extkey, //< 0-use key stored internally at keyIdx as wrapping key, 1-use external pKek_in as wrapping key
161 size_t kekLength, //< length of key wrapping key in bytes
162 uint32_t * pOutput //< pointer to output buffer, size has to inputLength - 8 bytes, contents will be properties|zeros|key
163)
164{
165 uint32_t concat[MCUXCLELS_CIPHER_BLOCK_SIZE_AES/sizeof(uint32_t)] = { 0u };
166
167 uint32_t input[MCUXCLELS_CIPHER_BLOCK_SIZE_AES/sizeof(uint32_t)] = { 0u };
168 uint8_t pKek[MCUXCLELS_CIPHER_KEY_SIZE_AES_256] = { 0u };
169
170 if (extkey == MCUXCLELS_CIPHER_EXTERNAL_KEY)
171 {
173 pKek_in,
174 kekLength,
175 kekLength));
176
178 {
179 return false;
180 }
181
183 }
184
185 // initialize buffer
186 concat[0] = pInput[0]; // first half of concat is the A from the standard, to first chunk of input
187 concat[1] = pInput[1];
188
189 // initialize ELS encryption parameters
190 mcuxClEls_CipherOption_t cipher_options;
191 cipher_options.word.value = 0;
193 cipher_options.bits.dcrpt = MCUXCLELS_CIPHER_DECRYPT;
194 cipher_options.bits.extkey = extkey;
195
196 // input has to be multiple of 64 bits, and needs to be in range
197 if ((inputLength % sizeof(uint64_t) != 0u)
198#ifdef MCUXCL_FEATURE_ELS_PUK_INTERNAL
199 || (inputLength > MCUXCLELS_RFC3394_CONTAINER_SIZE_P256))
200#else
201 || (inputLength > MCUXCLELS_RFC3394_CONTAINER_SIZE_256))
202#endif
203 {
204 return false;
205 }
206
207 uint32_t std_n = inputLength/sizeof(uint64_t) - 1u; // n value from standard
208 const uint32_t *pSource = pInput + 2u; // skip first 64 bits
209 uint32_t *pDest = pOutput;
210 for(size_t jdx = 6u; jdx > 0u; jdx--)
211 {
212 for(size_t idx = std_n; idx > 0u; idx--)
213 {
214 // Load next key chunk
215 MCUX_CSSL_ANALYSIS_START_SUPPRESS_INTEGER_OVERFLOW("Index calculation cannot wrap.")
216 concat[2u] = pSource[2u * (idx-1u) + 0u];
217 concat[3u] = pSource[2u * (idx-1u) + 1u];
218 MCUX_CSSL_ANALYSIS_STOP_SUPPRESS_INTEGER_OVERFLOW()
219
220 // XOR round constant into A
221 MCUX_CSSL_ANALYSIS_START_SUPPRESS_INTEGER_WRAP("The result will fit into 32 bit, as inputLength has an upper bound as checked above.")
222 uint32_t gdx = std_n * (jdx-1u) + idx; // all values should fit into a uint32_t
223 MCUX_CSSL_ANALYSIS_STOP_SUPPRESS_INTEGER_WRAP()
224 gdx = (gdx << 24u) | (gdx >> 24u) | ((gdx & 0x0000ff00u) << 8u) | ((gdx >> 8u) & 0x0000ff00u); // swap endianness
225 concat[1u] ^= gdx;
226
227 input[0]=concat[0];
228 input[1]=concat[1];
229 input[2]=concat[2];
230 input[3]=concat[3];
231
232 // Decrypt concatenated A and chunk to be processed
233 MCUX_CSSL_ANALYSIS_START_PATTERN_NULL_POINTER_CONSTANT()
234 MCUX_CSSL_ANALYSIS_START_SUPPRESS_ESCAPING_LOCAL_ADDRESS("Address of concat is for local use only. The call to mcuxClEls_WaitForOperation ensures it cannot escape.")
236 cipher_options,
237 keyIdx,
238 pKek,
239 kekLength,
240 (uint8_t*) input,
242 NULL,
243 (uint8_t*) concat));
244 MCUX_CSSL_ANALYSIS_STOP_SUPPRESS_ESCAPING_LOCAL_ADDRESS()
245 MCUX_CSSL_ANALYSIS_STOP_PATTERN_NULL_POINTER_CONSTANT()
247 {
248 return false;
249 }
251
254 {
255 return false;
256 }
258
259 // Write out processed key chunk
260 MCUX_CSSL_ANALYSIS_START_SUPPRESS_INTEGER_OVERFLOW("Index calculation cannot wrap.")
261 pDest[2u * (idx-1u) + 0u] = concat[2u];
262 pDest[2u * (idx-1u) + 1u] = concat[3u];
263 MCUX_CSSL_ANALYSIS_STOP_SUPPRESS_INTEGER_OVERFLOW()
264 }
265 pSource = pDest;
266 }
267 pDest[0] = (pDest[0] << 24u) | (pDest[0] >> 24u) | ((pDest[0] & 0x0000ff00u) << 8u) | ((pDest[0] >> 8u) & 0x0000ff00u); // swap endianness
268 // Check padding
269 if((concat[0u] != 0xA6A6A6A6u) || (concat[1u] != 0xA6A6A6A6u))
270 {
271 return false;
272 }
273 return true;
274}
275
276#endif /* MCUXCLEXAMPLE_RFC3394_HELPER_H_ */
Definition of function identifiers for the flow protection mechanism.
Top-level include file for the ELS driver.
Memory header for copy functions.
Provides the API for the CSSL flow protection mechanism.
#define MCUXCLELS_CIPHER_BLOCK_SIZE_AES
Definition mcuxClEls_Cipher.h:87
#define MCUXCLELS_CIPHER_DECRYPT
Set this option at mcuxClEls_CipherOption_t.dcrpt to perform a decryption.
Definition mcuxClEls_Cipher.h:63
#define MCUXCLELS_CIPHERPARAM_ALGORITHM_AES_ECB
Set this option at mcuxClEls_CipherOption_t.cphmde to use AES engine in Electornic Code Book (ECB) mo...
Definition mcuxClEls_Cipher.h:76
#define MCUXCLELS_CIPHER_ENCRYPT
Set this option at mcuxClEls_CipherOption_t.dcrpt to perform an encryption.
Definition mcuxClEls_Cipher.h:62
#define MCUXCLELS_CIPHER_EXTERNAL_KEY
Set this option at mcuxClEls_CipherOption_t.extkey to use a key located in CPU memory provided by pKe...
Definition mcuxClEls_Cipher.h:73
#define MCUXCLELS_CIPHER_KEY_SIZE_AES_256
Size of an AES192 key: 256 bit (32 bytes)
Definition mcuxClEls_Cipher.h:98
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_Cipher_Async(mcuxClEls_CipherOption_t options, mcuxClEls_KeyIndex_t keyIdx, uint8_t const *pKey, size_t keyLength, uint8_t const *pInput, size_t inputLength, uint8_t *pIV, uint8_t *pOutput)
Performs AES encryption/decryption.
#define MCUXCLELS_ERROR_FLAGS_CLEAR
Set this option at mcuxClEls_ErrorHandling_t to clear all ELS error flags.
Definition mcuxClEls_Common.h:110
MCUXCLELS_API mcuxClEls_Status_t mcuxClEls_WaitForOperation(mcuxClEls_ErrorHandling_t errorHandling)
Wait for an ELS operation and optionally clear the error status.
#define MCUXCLELS_RFC3394_CONTAINER_SIZE_256
Size of RFC3394 container for 256 bit key.
Definition mcuxClEls_KeyManagement.h:107
#define MCUXCLELS_STATUS_OK
No error occurred.
Definition mcuxClEls_Types.h:171
#define MCUXCLELS_STATUS_OK_WAIT
An _Async function successfully started an ELS command. Call mcuxClEls_WaitForOperation to complete i...
Definition mcuxClEls_Types.h:172
uint32_t mcuxClEls_KeyIndex_t
Type for ELS keystore indices.
Definition mcuxClEls_Types.h:222
void mcuxClMemory_copy(uint8_t *pDst, uint8_t const *pSrc, size_t length, size_t bufLength)
Copies a memory buffer to another location.
#define MCUX_CSSL_FP_FUNCTION_CALL_VOID_BEGIN(...)
Call a flow protected void function and check the protection token.
Definition mcuxCsslFlowProtection.h:652
#define MCUX_CSSL_FP_FUNCTION_CALL_VOID_END(...)
End a void function call section started by MCUX_CSSL_FP_FUNCTION_CALL_VOID_BEGIN.
Definition mcuxCsslFlowProtection.h:683
#define MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(...)
Call a flow protected function and check the protection token.
Definition mcuxCsslFlowProtection.h:581
#define MCUX_CSSL_FP_FUNCTION_CALLED(...)
Expectation of a called function.
Definition mcuxCsslFlowProtection.h:735
#define MCUX_CSSL_FP_FUNCTION_CALL_END(...)
End a function call section started by MCUX_CSSL_FP_FUNCTION_CALL_BEGIN.
Definition mcuxCsslFlowProtection.h:616
Command option bit field for mcuxClEls_Cipher_Async.
Definition mcuxClEls_Cipher.h:121
uint32_t value
Accesses the bit field as a full word.
Definition mcuxClEls_Cipher.h:124
struct mcuxClEls_CipherOption_t::@3 bits
Access mcuxClEls_CipherOption_t bit-wise.
uint32_t cphmde
Define cipher mode.
Definition mcuxClEls_Cipher.h:130
uint32_t extkey
Define whether an external key from memory or ELS internal key should be used.
Definition mcuxClEls_Cipher.h:138
struct mcuxClEls_CipherOption_t::@2 word
Access mcuxClEls_CipherOption_t word-wise.
uint32_t dcrpt
Define operation mode.
Definition mcuxClEls_Cipher.h:129
Type for ELS key store key properties.
Definition mcuxClEls_Types.h:226
struct mcuxClEls_KeyProp_t::@40 word
Access mcuxClEls_KeyProp_t word-wise.
uint32_t value
Accesses the bit field as a full word; initialize with a combination of constants from MCUXCLELS_KEYP...
Definition mcuxClEls_Types.h:229