1 /***************************************************************************//**
2 * \file cy_crypto_core_hkdf_v2.c
3 * \version 2.120
4 *
5 * \brief
6 * This file provides the source code to the API for the HKDF method
7 * in the Crypto block driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2023), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include "cy_device.h"
29
30 #if defined(CY_IP_MXCRYPTO)
31
32 #include "cy_crypto_core_hkdf_v2.h"
33
34 #if defined(CY_CRYPTO_CFG_HW_V2_ENABLE)
35
36 #if defined(__cplusplus)
37 extern "C" {
38 #endif
39
40 #if (CPUSS_CRYPTO_SHA == 1) && defined(CY_CRYPTO_CFG_HKDF_C)
41
42 #include "cy_crypto_core_hmac_v2.h"
43 #include "cy_crypto_core_mem_v2.h"
44 #include "cy_syslib.h"
45
Cy_Crypto_Core_sha_hashSize(cy_en_crypto_sha_mode_t mode)46 static uint32_t Cy_Crypto_Core_sha_hashSize(cy_en_crypto_sha_mode_t mode)
47 {
48 uint32_t hashSize=0UL;
49
50 switch (mode)
51 {
52 #if defined(CY_CRYPTO_CFG_SHA1_ENABLED)
53 case CY_CRYPTO_MODE_SHA1:
54 hashSize = CY_CRYPTO_SHA1_DIGEST_SIZE;
55 break;
56 #endif
57 #if defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
58 case CY_CRYPTO_MODE_SHA224:
59 hashSize = CY_CRYPTO_SHA224_DIGEST_SIZE;
60 break;
61 case CY_CRYPTO_MODE_SHA256:
62 hashSize = CY_CRYPTO_SHA256_DIGEST_SIZE;
63 break;
64 #endif
65 #if defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
66 case CY_CRYPTO_MODE_SHA384:
67 hashSize = CY_CRYPTO_SHA384_DIGEST_SIZE;
68 break;
69 case CY_CRYPTO_MODE_SHA512:
70 hashSize = CY_CRYPTO_SHA512_DIGEST_SIZE;
71 break;
72 case CY_CRYPTO_MODE_SHA512_224:
73 hashSize = CY_CRYPTO_SHA512_224_DIGEST_SIZE;
74 break;
75 case CY_CRYPTO_MODE_SHA512_256:
76 hashSize = CY_CRYPTO_SHA512_256_DIGEST_SIZE;
77 break;
78 #endif
79 default:
80 hashSize = 0UL;
81 break;
82 }
83
84 return hashSize;
85 }
86
87
88 /*******************************************************************************
89 * Function Name: Cy_Crypto_Core_V2_Hkdf_Extract
90 ****************************************************************************//**
91 *
92 * Performs HKDF Extract calculation.
93 *
94 * \param base
95 * The pointer to the CRYPTO instance.
96 *
97 * \param mode
98 * \ref cy_en_crypto_sha_mode_t
99 *
100 * \param salt
101 * The pointer to salt.
102 *
103 * \param saltLength
104 * The size of a salt.
105 *
106 * \param ikm
107 * The pointer to the Input Key material.
108 *
109 * \param ikmLength
110 * The length of the IKM.
111 *
112 * \param prk
113 * The pointer to store the generated prk.
114 *
115 * \return
116 * \ref cy_en_crypto_status_t
117 *
118 *******************************************************************************/
Cy_Crypto_Core_V2_Hkdf_Extract(CRYPTO_Type * base,cy_en_crypto_sha_mode_t mode,uint8_t const * salt,uint32_t saltLength,uint8_t const * ikm,uint32_t ikmLength,uint8_t * prk)119 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hkdf_Extract(CRYPTO_Type *base, cy_en_crypto_sha_mode_t mode,
120 uint8_t const *salt,
121 uint32_t saltLength,
122 uint8_t const *ikm,
123 uint32_t ikmLength,
124 uint8_t *prk)
125 {
126 cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
127 uint8_t nullSalt[CY_CRYPTO_SHA_MAX_HASH_SIZE] = {0u};
128 uint8_t *saltptr;
129 uint32_t saltlen;
130
131 /* Input parameters verification */
132 if ((NULL == base) || (NULL == prk) || ((NULL == salt) && (0UL != saltLength))
133 ||((NULL == ikm) && (0UL != ikmLength)))
134 {
135 return status;
136 }
137
138 saltptr = (uint8_t *)salt;
139 saltlen = saltLength;
140
141 if(NULL == salt)
142 {
143 saltlen = Cy_Crypto_Core_sha_hashSize(mode);
144 if(saltlen == 0UL)
145 {
146 return status;
147 }
148
149 saltptr = nullSalt;
150 }
151
152 return Cy_Crypto_Core_V2_Hmac(base, prk, ikm, ikmLength, saltptr, saltlen, mode);
153 }
154
155
156 /*******************************************************************************
157 * Function Name: Cy_Crypto_Core_V2_Hkdf_Expand
158 ****************************************************************************//**
159 *
160 * Performs HKDF Expand calculation.
161 *
162 * \param base
163 * The pointer to the CRYPTO instance.
164 *
165 * \param mode
166 * \ref cy_en_crypto_sha_mode_t
167 *
168 * \param prk
169 * The pointer to the pseudo random key.
170 *
171 * \param prkLength
172 * The length of the prk.
173 *
174 * \param info
175 * The pointer to info.
176 *
177 * \param infoLength
178 * The length of the info.
179 *
180 * \param okm
181 * The pointer to Output key material.
182 *
183 * \param okmLength
184 * The length of okm to be generated.
185 *
186 * \return
187 * \ref cy_en_crypto_status_t
188 *
189 *******************************************************************************/
Cy_Crypto_Core_V2_Hkdf_Expand(CRYPTO_Type * base,cy_en_crypto_sha_mode_t mode,uint8_t const * prk,uint32_t prkLength,uint8_t const * info,uint32_t infoLength,uint8_t * okm,uint32_t okmLength)190 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hkdf_Expand(CRYPTO_Type *base, cy_en_crypto_sha_mode_t mode,
191 uint8_t const *prk,
192 uint32_t prkLength,
193 uint8_t const *info,
194 uint32_t infoLength,
195 uint8_t *okm,
196 uint32_t okmLength)
197 {
198 cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
199 uint32_t hashlen;
200 uint32_t n,i;
201 uint8_t counter=0u;
202 uint32_t tLength=0u;
203 uint32_t bytesCopy=0u;
204 uint32_t offset=0u;
205 uint8_t t[CY_CRYPTO_SHA_MAX_HASH_SIZE] = {0u};
206
207
208 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
209
210 CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static cy_stc_crypto_v2_hmac_buffers_t hmacBuffer;
211 CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static cy_stc_crypto_hmac_state_t hmacState;
212
213 #else
214 cy_stc_crypto_hmac_state_t hmacState = {0u};
215 cy_stc_crypto_v2_hmac_buffers_t hmacBuffer = {0u};
216 #endif
217
218
219 /* Input parameters verification */
220 if ((NULL == base) || ((NULL == prk) && (0UL != prkLength)) || ((NULL == info) && (0UL != infoLength))
221 ||((NULL == okm) && (0UL != okmLength)))
222 {
223 return status;
224 }
225
226 Cy_Crypto_Core_V2_MemSet(base, (void*)&hmacState, 0x00U, (uint16_t)sizeof(cy_stc_crypto_hmac_state_t));
227 Cy_Crypto_Core_V2_MemSet(base, (void*)&hmacBuffer, 0x00U, (uint16_t)sizeof(cy_stc_crypto_v2_hmac_buffers_t));
228
229 hashlen = Cy_Crypto_Core_sha_hashSize(mode);
230 if(hashlen == 0u)
231 {
232 return status;
233 }
234
235 n = (okmLength + (hashlen - 1u))/ hashlen;
236
237 if( n > 255u)
238 {
239 return CY_CRYPTO_BAD_PARAMS;
240 }
241
242 for(i=1u; i<=n; i++)
243 {
244 counter++;
245
246 status = Cy_Crypto_Core_V2_Hmac_Init(base, &hmacState, mode, &hmacBuffer);
247 if(status != CY_CRYPTO_SUCCESS)
248 {
249 break;
250 }
251
252 status = Cy_Crypto_Core_V2_Hmac_Start(base, &hmacState, prk, prkLength);
253 if(status != CY_CRYPTO_SUCCESS)
254 {
255 break;
256 }
257
258 status = Cy_Crypto_Core_V2_Hmac_Update(base, &hmacState, t, tLength);
259 if(status != CY_CRYPTO_SUCCESS)
260 {
261 break;
262 }
263
264 status = Cy_Crypto_Core_V2_Hmac_Update(base, &hmacState, info, infoLength);
265 if(status != CY_CRYPTO_SUCCESS)
266 {
267 break;
268 }
269
270 status = Cy_Crypto_Core_V2_Hmac_Update(base, &hmacState, &counter, 1u);
271 if(status != CY_CRYPTO_SUCCESS)
272 {
273 break;
274 }
275
276 status = Cy_Crypto_Core_V2_Hmac_Finish(base, &hmacState, t);
277 if(status != CY_CRYPTO_SUCCESS)
278 {
279 break;
280 }
281
282 status = Cy_Crypto_Core_V2_Hmac_Free(base, &hmacState);
283 if(status != CY_CRYPTO_SUCCESS)
284 {
285 break;
286 }
287
288 if(i != n)
289 {
290 bytesCopy = hashlen;
291 }
292 else
293 {
294 bytesCopy = okmLength - offset;
295 }
296
297 Cy_Crypto_Core_V2_MemCpy(base, (void*)(okm + offset), (void *)t, (uint16_t)bytesCopy);
298 offset += hashlen;
299 tLength = hashlen;
300 }
301
302 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
303 SCB_InvalidateDCache_by_Addr((volatile void *)okm,(int32_t)okmLength);
304 #endif
305 return status;
306 }
307
308
309
310 /*******************************************************************************
311 * Function Name: Cy_Crypto_Core_V2_Hkdf
312 ****************************************************************************//**
313 *
314 * Performs HKDF calculation.
315 *
316 * \param base
317 * The pointer to the CRYPTO instance.
318 *
319 * \param mode
320 * \ref cy_en_crypto_sha_mode_t
321 *
322 * \param salt
323 * The pointer to salt.
324 *
325 * \param saltLength
326 * The size of a salt.
327 *
328 * \param ikm
329 * The pointer to the Input Key material.
330 *
331 * \param ikmLength
332 * The length of the IKM.
333 *
334 * \param info
335 * The pointer to info.
336 *
337 * \param infoLength
338 * The length of the info.
339 *
340 * \param okm
341 * The pointer to Output key material.
342 *
343 * \param okmLength
344 * The length of okm to be generated.
345 *
346 * \return
347 * \ref cy_en_crypto_status_t
348 *
349 *******************************************************************************/
Cy_Crypto_Core_V2_Hkdf(CRYPTO_Type * base,cy_en_crypto_sha_mode_t mode,uint8_t const * salt,uint32_t saltLength,uint8_t const * ikm,uint32_t ikmLength,uint8_t const * info,uint32_t infoLength,uint8_t * okm,uint32_t okmLength)350 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hkdf(CRYPTO_Type *base, cy_en_crypto_sha_mode_t mode,
351 uint8_t const *salt,
352 uint32_t saltLength,
353 uint8_t const *ikm,
354 uint32_t ikmLength,
355 uint8_t const *info,
356 uint32_t infoLength,
357 uint8_t *okm,
358 uint32_t okmLength)
359 {
360 cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
361 uint8_t prk[CY_CRYPTO_SHA_MAX_HASH_SIZE] = {0u};
362
363 /* Input parameters verification */
364 if ((NULL == base) || ((NULL == salt) && (0UL != saltLength))
365 ||((NULL == ikm) && (0UL != ikmLength)) || ((NULL == info) && (0UL != infoLength))
366 ||((NULL == okm) && (0UL != okmLength)))
367 {
368 return status;
369 }
370
371 status = Cy_Crypto_Core_V2_Hkdf_Extract(base, mode, salt, saltLength, ikm, ikmLength, prk);
372 if(status != CY_CRYPTO_SUCCESS)
373 {
374 return status;
375 }
376
377 status = Cy_Crypto_Core_V2_Hkdf_Expand(base, mode, prk, Cy_Crypto_Core_sha_hashSize(mode), info, infoLength, okm, okmLength);
378
379 Cy_Crypto_Core_V2_MemSet(base, prk, 0u, CY_CRYPTO_SHA_MAX_HASH_SIZE);
380
381 return status;
382 }
383
384 #endif /* (CPUSS_CRYPTO_SHA == 1) && defined(CY_CRYPTO_CFG_HKDF_C) */
385
386 #if defined(__cplusplus)
387 }
388 #endif
389
390 #endif /* defined(CY_CRYPTO_CFG_HW_V2_ENABLE) */
391
392 #endif /* defined(CY_IP_MXCRYPTO) */
393
394
395 /* [] END OF FILE */
396