1 /***************************************************************************//**
2 * \file cy_cryptolite_hmac.c
3 * \version 2.50
4 *
5 * \brief
6 * Provides API implementation of the Cryptolite HAMC-SHA256 PDL driver.
7 *
8 ********************************************************************************
9 * Copyright 2020 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24
25 #include "cy_device.h"
26
27 #if defined (CY_IP_MXCRYPTOLITE)
28
29 #include "cy_cryptolite_hmac.h"
30
31 #if defined(__cplusplus)
32 extern "C" {
33 #endif
34
35 #if (CRYPTOLITE_SHA_PRESENT == 1)
36 #if defined(CY_CRYPTOLITE_CFG_HMAC_C) && defined(CY_CRYPTOLITE_CFG_SHA2_256_ENABLED)
37
38 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Directive 4.7', 3, \
39 'Coverity does not seem to allow return of a error status without a check.')
40
41 /*****************************************************************************
42 * Cy_Cryptolite_Hmac_Sha256_Init
43 ******************************************************************************
44 *
45 * The function to initialize the HMAC SHA256 operation.
46 *
47 * base
48 * The pointer to the Cryptolite instance.
49 *
50 * cfContext
51 * The pointer to the cy_stc_cryptolite_context_hmac_sha256_t structure that stores all
52 * internal variables for Cryptolite driver.
53 *
54 * return
55 * cy_en_cryptolite_status_t
56 *
57 *******************************************************************************/
Cy_Cryptolite_Hmac_Sha256_Init(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_hmac_sha256_t * cfContext)58 cy_en_cryptolite_status_t Cy_Cryptolite_Hmac_Sha256_Init(CRYPTOLITE_Type *base,
59 cy_stc_cryptolite_context_hmac_sha256_t *cfContext)
60 {
61 cy_en_cryptolite_status_t status;
62
63 /* Input parameters verification */
64 if ((NULL == base) || (NULL == cfContext))
65 {
66 return CY_CRYPTOLITE_BAD_PARAMS;
67 }
68
69 cfContext->blocksize = (uint16_t)CY_CRYPTOLITE_SHA256_BLOCK_SIZE;
70 cfContext->digestsize = (uint16_t)CY_CRYPTOLITE_SHA256_HASH_SIZE;
71 /*Init SHA 256*/
72 status = Cy_Cryptolite_Sha256_Init( base, &cfContext->ctx_sha256);
73
74 return status;
75 }
76
77 /*******************************************************************************
78 * Cy_Cryptolite_Hmac_Sha256_Start
79 ******************************************************************************
80 *
81 * Initializes the initial Hash vector.
82 *
83 * base
84 * The pointer to the CRYPTOLITE instance.
85 *
86 * key
87 * The pointer to the HMAC key.
88 *
89 * keyLength
90 * The length of the HMAC key.
91 *
92 * cfContext
93 * The pointer to the cy_stc_cryptolite_context_hmac_sha256_t structure that stores all
94 * internal variables for Cryptolite driver.
95 *
96 * return
97 * cy_en_cryptolite_status_t
98 *
99 *******************************************************************************/
Cy_Cryptolite_Hmac_Sha256_Start(CRYPTOLITE_Type * base,uint8_t const * key,uint32_t keyLength,cy_stc_cryptolite_context_hmac_sha256_t * cfContext)100 cy_en_cryptolite_status_t Cy_Cryptolite_Hmac_Sha256_Start(CRYPTOLITE_Type *base,
101 uint8_t const *key,
102 uint32_t keyLength,
103 cy_stc_cryptolite_context_hmac_sha256_t *cfContext)
104 {
105 uint32_t i;
106 uint32_t blockSizeTmp;
107 uint32_t digestSizeTmp;
108 uint8_t *ipadPtrTmp;
109 uint8_t *opadPtrTmp;
110 uint8_t *m0KeyPtrTmp;
111
112 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_SUCCESS;
113
114 /* Input parameters verification */
115 if ((NULL == base) || (NULL == cfContext) || ((NULL == key) && (0UL != keyLength)) )
116 {
117 return CY_CRYPTOLITE_BAD_PARAMS;
118 }
119
120 blockSizeTmp = cfContext->blocksize;
121 digestSizeTmp = cfContext->digestsize;
122 ipadPtrTmp = (uint8_t*)cfContext->ipad;
123 opadPtrTmp = (uint8_t*)cfContext->opad;
124 m0KeyPtrTmp = (uint8_t*)cfContext->m0Key;
125
126 /*check if IP is busy*/
127 if ((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
128 {
129 return CY_CRYPTOLITE_HW_BUSY;
130 }
131
132 for (i=0U; i < CY_CRYPTOLITE_SHA256_BLOCK_SIZE; i++)
133 {
134 cfContext->ipad[i] = 0;
135 cfContext->opad[i] = 0;
136 cfContext->m0Key[i] = 0;
137 }
138
139 /* Steps 1-3 according to FIPS 198-1 */
140 if (keyLength > blockSizeTmp)
141 {
142 /* The key is larger than the block size. Do a hash on the key. */
143 status = Cy_Cryptolite_Sha256_Start( base, &cfContext->ctx_sha256);
144
145 if (CY_CRYPTOLITE_SUCCESS == status)
146 {
147 status = Cy_Cryptolite_Sha256_Update (base, key, keyLength, &cfContext->ctx_sha256);
148 }
149 if (CY_CRYPTOLITE_SUCCESS == status)
150 {
151 status = Cy_Cryptolite_Sha256_Finish (base, m0KeyPtrTmp, &cfContext->ctx_sha256);
152 }
153 /* Append zeros */
154 for (i=0U; i < (uint32_t)(blockSizeTmp - digestSizeTmp); i++)
155 {
156 m0KeyPtrTmp[digestSizeTmp + i] = 0x00u;
157 }
158 }
159 else /*(keyLength < blockSizeTmp)*/
160 {
161 /* If the key is shorter than the block, append zeros */
162 for (i=0U; i < keyLength; i++)
163 {
164 m0KeyPtrTmp[i] = key[i];
165 }
166 /* Append zeros */
167 for (i=0U; i < (uint32_t)(blockSizeTmp - keyLength); i++)
168 {
169 m0KeyPtrTmp[keyLength + i] = 0x00u;
170 }
171 }
172
173 if (CY_CRYPTOLITE_SUCCESS == status)
174 {
175 /* Steps 4 and 7 according to FIPS 198-1 */
176 for (i=0U; i < blockSizeTmp; i++)
177 {
178 ipadPtrTmp[i] = CY_CRYPTOLITE_HMAC_IPAD ^ m0KeyPtrTmp[i];
179 opadPtrTmp[i] = CY_CRYPTOLITE_HMAC_0PAD ^ m0KeyPtrTmp[i];
180 }
181
182 /* Step 6 according to FIPS 198-1 */
183 status = Cy_Cryptolite_Sha256_Start( base, &cfContext->ctx_sha256);
184
185 if (CY_CRYPTOLITE_SUCCESS == status)
186 {
187 status = Cy_Cryptolite_Sha256_Update (base, ipadPtrTmp, blockSizeTmp, &cfContext->ctx_sha256);
188 }
189 }
190
191 return status;
192 }
193
194 /*******************************************************************************
195 * Cy_Cryptolite_Hmac_Sha256_Update
196 ********************************************************************************
197 *
198 * Performs the SHA256 calculation on one message.
199 *
200 * base
201 * The pointer to the CRYPTOLITE instance.
202 *
203 * cfContext
204 * The pointer to the cy_stc_cryptolite_context_hmac_sha256_t structure that stores all
205 * internal variables for Cryptolite driver.
206 *
207 * message
208 * The pointer to the message whose Hash is being computed.
209 *
210 * messageSize
211 * The size of the message whose Hash is being computed.
212 *
213 * return
214 * cy_en_cryptolite_status_t
215 *
216 *******************************************************************************/
Cy_Cryptolite_Hmac_Sha256_Update(CRYPTOLITE_Type * base,uint8_t const * message,uint32_t messageSize,cy_stc_cryptolite_context_hmac_sha256_t * cfContext)217 cy_en_cryptolite_status_t Cy_Cryptolite_Hmac_Sha256_Update(CRYPTOLITE_Type *base,
218 uint8_t const *message,
219 uint32_t messageSize,
220 cy_stc_cryptolite_context_hmac_sha256_t *cfContext)
221 {
222 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
223
224 if (0UL == messageSize)
225 {
226 return CY_CRYPTOLITE_SUCCESS;
227 }
228
229 /* Input parameters verification */
230 if ((NULL == base) || (NULL == cfContext) || (NULL == message))
231 {
232 return status;
233 }
234
235 /*check if IP is busy*/
236 if ((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
237 {
238 return CY_CRYPTOLITE_HW_BUSY;
239 }
240
241 /* Append a message */
242 status = Cy_Cryptolite_Sha256_Update (base, message, messageSize, &cfContext->ctx_sha256);
243
244 return status;
245 }
246
247 /*******************************************************************************
248 * Cy_Cryptolite_Hmac_Sha256_Finish
249 ******************************************************************************
250 *
251 * Completes the SHA256 calculation.
252 *
253 * base
254 * The pointer to the CRYPTOLITE instance.
255 *
256 * cfContext
257 * the pointer to the cy_stc_cryptolite_context_hmac_sha256_t structure that stores all
258 * internal variables for Cryptolite driver.
259 *
260 * hmac
261 * The pointer to the calculated Hash hmac.
262 *
263 * return
264 * cy_en_cryptolite_status_t
265 *
266 *******************************************************************************/
Cy_Cryptolite_Hmac_Sha256_Finish(CRYPTOLITE_Type * base,uint8_t * hmac,cy_stc_cryptolite_context_hmac_sha256_t * cfContext)267 cy_en_cryptolite_status_t Cy_Cryptolite_Hmac_Sha256_Finish(CRYPTOLITE_Type *base,
268 uint8_t *hmac,
269 cy_stc_cryptolite_context_hmac_sha256_t *cfContext)
270 {
271 uint32_t blockSizeTmp;
272 uint32_t digestSizeTmp;
273 uint8_t *ipadPtrTmp;
274 uint8_t *opadPtrTmp;
275 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
276
277 /* Input parameters verification */
278 if ((NULL == base) || (NULL == cfContext) || (NULL == hmac))
279 {
280 return status;
281 }
282
283 blockSizeTmp = cfContext->blocksize;
284 digestSizeTmp = cfContext->digestsize;
285 ipadPtrTmp = (uint8_t*)cfContext->ipad;
286 opadPtrTmp = (uint8_t*)cfContext->opad;
287
288 /*check if IP is busy*/
289 if ((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
290 {
291 return CY_CRYPTOLITE_HW_BUSY;
292 }
293
294 /*Finish message hash and calculate hmac*/
295 status = Cy_Cryptolite_Sha256_Finish (base, ipadPtrTmp, &cfContext->ctx_sha256);
296
297 /* Here is the ready part of HASH: Hash((Key^ipad)||text) */
298 if (CY_CRYPTOLITE_SUCCESS == status)
299 {
300 /* Steps 8, 9 according to FIPS 198-1 */
301 status = Cy_Cryptolite_Sha256_Start( base, &cfContext->ctx_sha256);
302
303 if (CY_CRYPTOLITE_SUCCESS == status)
304 {
305 status = Cy_Cryptolite_Sha256_Update (base, opadPtrTmp, blockSizeTmp, &cfContext->ctx_sha256);
306 }
307 /* Append HASH from Step 6 */
308 if (CY_CRYPTOLITE_SUCCESS == status)
309 {
310 status = Cy_Cryptolite_Sha256_Update (base, ipadPtrTmp, digestSizeTmp, &cfContext->ctx_sha256);
311 }
312 if (CY_CRYPTOLITE_SUCCESS == status)
313 {
314 status = Cy_Cryptolite_Sha256_Finish (base, hmac, &cfContext->ctx_sha256);
315 }
316 }
317
318 return status;
319 }
320
321 /*******************************************************************************
322 * Cy_Cryptolite_Hmac_Sha256_Free
323 ******************************************************************************
324 *
325 * Clears the used memory and context data.
326 *
327 * base
328 * The pointer to the CRYPTOLITE instance.
329 *
330 * cfContext
331 * the pointer to the cy_stc_cryptolite_context_hmac_sha256_t structure that stores all
332 * internal variables for Cryptolite driver.
333 *
334 * return
335 * cy_en_cryptolite_status_t
336 *
337 *******************************************************************************/
Cy_Cryptolite_Hmac_Sha256_Free(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_hmac_sha256_t * cfContext)338 cy_en_cryptolite_status_t Cy_Cryptolite_Hmac_Sha256_Free(CRYPTOLITE_Type *base,
339 cy_stc_cryptolite_context_hmac_sha256_t *cfContext)
340 {
341 uint32_t i;
342
343 /* Input parameters verification */
344 if (NULL != cfContext)
345 {
346 /* Clear the context memory */
347 for (i=0U; i < CY_CRYPTOLITE_HMAC_MAX_PAD_SIZE; i++)
348 {
349 cfContext->ipad[i] = 0;
350 cfContext->opad[i] = 0;
351 cfContext->m0Key[i] = 0;
352 }
353 cfContext->blocksize = 0;
354 cfContext->digestsize = 0;
355
356 /*Clear hash context*/
357 (void)Cy_Cryptolite_Sha256_Free (base, &cfContext->ctx_sha256);
358 }
359
360 return CY_CRYPTOLITE_SUCCESS;
361 }
362
363 /*******************************************************************************
364 * Cy_Cryptolite_Hmac_Sha256_Run
365 ******************************************************************************
366 *
367 * This function performs the HAMC SHA256 MAC function.
368 * Provide the required parameters and the pointer
369 * to the context structure when making this function call.
370 * It is independent of the previous Crypto state because it already contains
371 * preparation, calculation, and finalization steps.
372 *
373 * base
374 * The pointer to the CRYPTOLITE instance.
375 *
376 * cfContext
377 * the pointer to the cy_stc_cryptolite_context_hmac_sha256_t structure that stores all
378 * internal variables for Cryptolite driver.
379 *
380 * message
381 * The pointer to a message whose HMAC is being computed.
382 *
383 * messageSize
384 * The size of a message in bytes.
385 *
386 * hmac
387 * The pointer to the hmac.
388 *
389 * return
390 * cy_en_cryptolite_status_t
391 *
392 *******************************************************************************/
Cy_Cryptolite_Hmac_Sha256_Run(CRYPTOLITE_Type * base,uint8_t const * key,uint32_t keyLength,uint8_t const * message,uint32_t messageSize,uint8_t * hmac,cy_stc_cryptolite_context_hmac_sha256_t * cfContext)393 cy_en_cryptolite_status_t Cy_Cryptolite_Hmac_Sha256_Run(CRYPTOLITE_Type *base,
394 uint8_t const *key,
395 uint32_t keyLength,
396 uint8_t const *message,
397 uint32_t messageSize,
398 uint8_t *hmac,
399 cy_stc_cryptolite_context_hmac_sha256_t *cfContext)
400 {
401 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
402 /* Input parameters verification */
403 if ((NULL == base) || (NULL == cfContext) || (NULL == hmac) || ((NULL == message) && (0UL != messageSize))
404 || ((NULL == key) && (0UL != keyLength)))
405 {
406 return status;
407 }
408
409 status = Cy_Cryptolite_Hmac_Sha256_Init (base, cfContext);
410
411 if (CY_CRYPTOLITE_SUCCESS == status)
412 {
413 status = Cy_Cryptolite_Hmac_Sha256_Start (base, key, keyLength, cfContext);
414 }
415 if (CY_CRYPTOLITE_SUCCESS == status)
416 {
417 status = Cy_Cryptolite_Hmac_Sha256_Update (base, message, messageSize, cfContext);
418 }
419 if (CY_CRYPTOLITE_SUCCESS == status)
420 {
421 status = Cy_Cryptolite_Hmac_Sha256_Finish (base, hmac, cfContext);
422 }
423 if (CY_CRYPTOLITE_SUCCESS == status)
424 {
425 status = Cy_Cryptolite_Hmac_Sha256_Free (base, cfContext);
426 }
427
428 return status;
429 }
430 CY_MISRA_BLOCK_END('MISRA C-2012 Directive 4.7')
431
432 #endif
433 #endif /* CY_CRYPTOLITE_CFG_HMAC_C */
434
435 #if defined(__cplusplus)
436 }
437 #endif
438
439
440 #endif /* CY_IP_MXCRYPTOLITE */
441 /* [] END OF FILE */
442