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