1 /***************************************************************************//**
2 * \file cy_cryptolite_hkdf.c
3 * \version 2.30
4 *
5 * \brief
6 * This file provides the source code to the API for the HKDF method
7 * in the CRYPTOLITE 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_MXCRYPTOLITE)
31
32 #include "cy_cryptolite_hkdf.h"
33
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37
38 #if (CRYPTOLITE_SHA_PRESENT == 1)
39 #if defined(CY_CRYPTOLITE_CFG_HKDF_C) && defined(CY_CRYPTOLITE_CFG_HMAC_C)
40
41 #include "cy_cryptolite_utils.h"
42 #include "cy_cryptolite_vu.h"
43
44 /*******************************************************************************
45 * Function Name: Cy_Cryptolite_Hkdf_Extract
46 ****************************************************************************//**
47 *
48 * Performs HKDF Extract calculation.
49 *
50 * \param base
51 * The pointer to the CRYPTOLITE instance.
52 *
53 * \param salt
54 * The pointer to salt.
55 *
56 * \param saltLength
57 * The size of a salt.
58 *
59 * \param ikm
60 * The pointer to the Input Key material.
61 *
62 * \param ikmLength
63 * The length of the IKM.
64 *
65 * \param prk
66 * The pointer to store the generated prk.
67 *
68 * \return
69 * \ref cy_en_cryptolite_status_t
70 *
71 *******************************************************************************/
Cy_Cryptolite_Hkdf_Extract(CRYPTOLITE_Type * base,uint8_t const * salt,uint32_t saltLength,uint8_t const * ikm,uint32_t ikmLength,uint8_t * prk)72 cy_en_cryptolite_status_t Cy_Cryptolite_Hkdf_Extract(CRYPTOLITE_Type *base,
73 uint8_t const *salt,
74 uint32_t saltLength,
75 uint8_t const *ikm,
76 uint32_t ikmLength,
77 uint8_t *prk)
78 {
79 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
80 CY_ALIGN(4) uint8_t nullSalt[CY_CRYPTOLITE_SHA256_HASH_SIZE] = {0u};
81 uint8_t *saltptr;
82 uint32_t saltlen;
83 cy_stc_cryptolite_context_hmac_sha256_t hmac_ctx;
84
85 /* Input parameters verification */
86 if ((NULL == base) || (NULL == prk) || ((NULL == salt) && (0UL != saltLength))
87 ||((NULL == ikm) && (0UL != ikmLength)))
88 {
89 return status;
90 }
91
92 saltptr = (uint8_t *)salt;
93 saltlen = saltLength;
94
95 if(NULL == salt)
96 {
97 Cy_Cryptolite_Memset (nullSalt, 0u, CY_CRYPTOLITE_SHA256_HASH_SIZE);
98 saltlen = CY_CRYPTOLITE_SHA256_HASH_SIZE;
99 saltptr = nullSalt;
100 }
101
102 return Cy_Cryptolite_Hmac_Sha256_Run(base, saltptr, saltlen, ikm, ikmLength, prk, &hmac_ctx);
103 }
104
105
106 /*******************************************************************************
107 * Function Name: Cy_Cryptolite_Hkdf_Expand
108 ****************************************************************************//**
109 *
110 * Performs HKDF Expand calculation.
111 *
112 * \param base
113 * The pointer to the CRYPTOLITE instance.
114 *
115 * \param prk
116 * The pointer to the pseudo random key.
117 *
118 * \param prkLength
119 * The length of the prk.
120 *
121 * \param info
122 * The pointer to info.
123 *
124 * \param infoLength
125 * The length of the info.
126 *
127 * \param okm
128 * The pointer to Output key material.
129 *
130 * \param okmLength
131 * The length of okm to be generated.
132 *
133 * \return
134 * \ref cy_en_cryptolite_status_t
135 *
136 *******************************************************************************/
Cy_Cryptolite_Hkdf_Expand(CRYPTOLITE_Type * base,uint8_t const * prk,uint32_t prkLength,uint8_t const * info,uint32_t infoLength,uint8_t * okm,uint32_t okmLength)137 cy_en_cryptolite_status_t Cy_Cryptolite_Hkdf_Expand(CRYPTOLITE_Type *base,
138 uint8_t const *prk,
139 uint32_t prkLength,
140 uint8_t const *info,
141 uint32_t infoLength,
142 uint8_t *okm,
143 uint32_t okmLength)
144 {
145 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
146 uint32_t hashlen = CY_CRYPTOLITE_SHA256_HASH_SIZE;
147 uint32_t n,i;
148 uint8_t counter=0u;
149 uint32_t tLength=0u;
150 uint32_t bytesCopy=0u;
151 uint32_t offset=0u;
152 uint8_t t[CY_CRYPTOLITE_SHA256_HASH_SIZE] = {0u};
153 cy_stc_cryptolite_context_hmac_sha256_t cfContext;
154
155
156 /* Input parameters verification */
157 if ((NULL == base) || ((NULL == prk) && (0UL != prkLength)) || ((NULL == info) && (0UL != infoLength))
158 ||((NULL == okm) && (0UL != okmLength)))
159 {
160 return status;
161 }
162
163 n = (okmLength + (hashlen - 1u))/ hashlen;
164
165 if( n > 255u)
166 {
167 return CY_CRYPTOLITE_BAD_PARAMS;
168 }
169
170 for(i=1u; i<=n; i++)
171 {
172 counter++;
173
174 status = Cy_Cryptolite_Hmac_Sha256_Init (base, &cfContext);
175 if(status != CY_CRYPTOLITE_SUCCESS)
176 {
177 break;
178 }
179
180 status = Cy_Cryptolite_Hmac_Sha256_Start (base, prk, prkLength, &cfContext);
181 if(status != CY_CRYPTOLITE_SUCCESS)
182 {
183 break;
184 }
185
186 status = Cy_Cryptolite_Hmac_Sha256_Update (base, t, tLength, &cfContext);
187 if(status != CY_CRYPTOLITE_SUCCESS)
188 {
189 break;
190 }
191
192 status = Cy_Cryptolite_Hmac_Sha256_Update (base, info, infoLength, &cfContext);
193 if(status != CY_CRYPTOLITE_SUCCESS)
194 {
195 break;
196 }
197
198 status = Cy_Cryptolite_Hmac_Sha256_Update (base, &counter, 1u, &cfContext);
199 if(status != CY_CRYPTOLITE_SUCCESS)
200 {
201 break;
202 }
203
204 status = Cy_Cryptolite_Hmac_Sha256_Finish (base, t, &cfContext);
205 if(status != CY_CRYPTOLITE_SUCCESS)
206 {
207 break;
208 }
209
210 status = Cy_Cryptolite_Hmac_Sha256_Free(base, &cfContext);
211 if(status != CY_CRYPTOLITE_SUCCESS)
212 {
213 break;
214 }
215
216 if(i != n)
217 {
218 bytesCopy = hashlen;
219 }
220 else
221 {
222 bytesCopy = okmLength - offset;
223 }
224
225 status = Cy_Cryptolite_Memcpy(base, (okm + offset), t, bytesCopy);
226 if(status != CY_CRYPTOLITE_SUCCESS)
227 {
228 break;
229 }
230
231 offset += hashlen;
232 tLength = hashlen;
233 }
234
235 return status;
236 }
237
238
239
240 /*******************************************************************************
241 * Function Name: Cy_Cryptolite_Hkdf
242 ****************************************************************************//**
243 *
244 * Performs HKDF calculation.
245 *
246 * \param base
247 * The pointer to the CRYPTOLITE instance.
248 *
249 * \param salt
250 * The pointer to salt.
251 *
252 * \param saltLength
253 * The size of a salt.
254 *
255 * \param ikm
256 * The pointer to the Input Key material.
257 *
258 * \param ikmLength
259 * The length of the IKM.
260 *
261 * \param info
262 * The pointer to info.
263 *
264 * \param infoLength
265 * The length of the info.
266 *
267 * \param okm
268 * The pointer to Output key material.
269 *
270 * \param okmLength
271 * The length of okm to be generated.
272 *
273 * \return
274 * \ref cy_en_cryptolite_status_t
275 *
276 *******************************************************************************/
Cy_Cryptolite_Hkdf(CRYPTOLITE_Type * base,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)277 cy_en_cryptolite_status_t Cy_Cryptolite_Hkdf(CRYPTOLITE_Type *base,
278 uint8_t const *salt,
279 uint32_t saltLength,
280 uint8_t const *ikm,
281 uint32_t ikmLength,
282 uint8_t const *info,
283 uint32_t infoLength,
284 uint8_t *okm,
285 uint32_t okmLength)
286 {
287 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
288 CY_ALIGN(4) uint8_t prk[CY_CRYPTOLITE_SHA256_HASH_SIZE] = {0u};
289
290 /* Input parameters verification */
291 if ((NULL == base) || ((NULL == salt) && (0UL != saltLength))
292 ||((NULL == ikm) && (0UL != ikmLength)) || ((NULL == info) && (0UL != infoLength))
293 ||((NULL == okm) && (0UL != okmLength)))
294 {
295 return status;
296 }
297
298 Cy_Cryptolite_Memset (prk, 0u, CY_CRYPTOLITE_SHA256_HASH_SIZE);
299
300 status = Cy_Cryptolite_Hkdf_Extract(base, salt, saltLength, ikm, ikmLength, prk);
301 if(status != CY_CRYPTOLITE_SUCCESS)
302 {
303 return status;
304 }
305
306 status = Cy_Cryptolite_Hkdf_Expand(base, prk, CY_CRYPTOLITE_SHA256_HASH_SIZE, info, infoLength, okm, okmLength);
307
308 Cy_Cryptolite_Memset ( prk, 0u, CY_CRYPTOLITE_SHA256_HASH_SIZE);
309
310 return status;
311 }
312
313
314 #endif /* CRYPTOLITE_SHA_PRESENT */
315 #endif /* defined(CY_CRYPTOLITE_CFG_HKDF_C) && defined(CY_CRYPTOLITE_CFG_HMAC_C) */
316
317 #if defined(__cplusplus)
318 }
319 #endif
320
321
322 #endif /* defined(CY_IP_MXCRYPTOLITE) */
323
324
325 /* [] END OF FILE */
326