csec_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
19 #include "csec_driver.h"
20 #include "csec_hw_access.h"
21 #include "osif.h"
22 
60 /*******************************************************************************
61  * Definitions
62  ******************************************************************************/
63 
64 /* Represents the size of a CSE_PRAM page in bytes */
65 #define CSEC_PAGE_SIZE_IN_BYTES (16U)
66 
67 /* Represents the number of CSE_PRAM pages available for data (excluding the
68 first page, used for command header) */
69 #define CSEC_DATA_PAGES_AVAILABLE (7U)
70 /* Represents the number of bytes in CSE_PRAM available for data (excluding the
71 first page, used for command header) */
72 #define CSEC_DATA_BYTES_AVAILABLE (112U)
73 
74 /* Represents the shift used for converting CSE_PRAM pages number to/from bytes number */
75 #define CSEC_BYTES_TO_FROM_PAGES_SHIFT (4U)
76 /* Represents the shift used for converting CSE_PRAM pages number to/from bits number */
77 #define CSEC_BYTES_TO_FROM_BITS_SHIFT (3U)
78 
79 /* Represents the size in bytes of the M1 entry (used for key management) */
80 #define CSEC_M1_SIZE_IN_BYTES (16U)
81 /* Represents the size in bytes of the M2 entry (used for key management) */
82 #define CSEC_M2_SIZE_IN_BYTES (32U)
83 /* Represents the size in bytes of the M3 entry (used for key management) */
84 #define CSEC_M3_SIZE_IN_BYTES (16U)
85 /* Represents the size in bytes of the M4 entry (used for key management) */
86 #define CSEC_M4_SIZE_IN_BYTES (32U)
87 /* Represents the size in bytes of the M5 entry (used for key management) */
88 #define CSEC_M5_SIZE_IN_BYTES (16U)
89 
90 /* Pointer to runtime state structure.*/
91 static csec_state_t * g_csecStatePtr = NULL;
92 
93 /* The FTFC interrupt handler, used when a CSEc command is completed. */
94 void FTFC_IRQHandler(void);
95 
96 /*******************************************************************************
97  * Private Functions
98  ******************************************************************************/
99 
100 static void CSEC_DRV_InitState(csec_key_id_t keyId,
101  csec_cmd_t cmd,
102  const uint8_t * inBuff,
103  uint8_t * outBuff,
104  uint32_t length);
105 
106 /* Rounds up the value to the first number multiple of roundTo */
107 static inline uint32_t CSEC_DRV_RoundTo(uint32_t value,
108  uint32_t roundTo)
109 {
110  return (value + (roundTo - 1U)) & ~(roundTo - 1U);
111 }
112 
113 static void CSEC_DRV_StartEncDecECBCmd(void);
114 static void CSEC_DRV_ContinueEncDecECBCmd(void);
115 static void CSEC_DRV_StartEncDecCBCCmd(void);
116 static void CSEC_DRV_ContinueEncDecCBCCmd(void);
117 static void CSEC_DRV_StartGenMACCmd(void);
118 static void CSEC_DRV_ContinueGenMACCmd(void);
119 static void CSEC_DRV_StartVerifMACCmd(void);
120 static void CSEC_DRV_ContinueVerifMACCmd(void);
121 
122 /*******************************************************************************
123  * Code
124  ******************************************************************************/
125 
126 /*FUNCTION**********************************************************************
127  *
128  * Function Name : CSEC_DRV_Init
129  * Description : This function initializes the internal state of the driver
130  * and enables the FTFC interrupt.
131  *
132  * Implements : CSEC_DRV_Init_Activity
133  * END**************************************************************************/
135 {
136  DEV_ASSERT(state != NULL);
137 
138  g_csecStatePtr = state;
139  g_csecStatePtr->cmdInProgress = false;
140 
142 
143  OSIF_TimeDelay(0U);
144 }
145 
146 /*FUNCTION**********************************************************************
147  *
148  * Function Name : CSEC_DRV_Deinit
149  * Description : This function clears the internal state of the driver and
150  * disables the FTFC interrupt.
151  *
152  * Implements : CSEC_DRV_Deinit_Activity
153  * END**************************************************************************/
155 {
156  g_csecStatePtr = NULL;
157 
159 }
160 
161 /*FUNCTION**********************************************************************
162  *
163  * Function Name : CSEC_DRV_EncryptECB
164  * Description : This function performs the AES-128 encryption in ECB mode of
165  * the input plain text buffer.
166  *
167  * Implements : CSEC_DRV_EncryptECB_Activity
168  * END**************************************************************************/
170  const uint8_t * plainText,
171  uint32_t length,
172  uint8_t * cipherText,
173  uint32_t timeout)
174 {
175  DEV_ASSERT(plainText != NULL);
176  DEV_ASSERT(cipherText != NULL);
177  DEV_ASSERT(g_csecStatePtr != NULL);
178 
179  uint32_t startTime = 0;
180  uint32_t crtTime = 0;
181 
182  if (g_csecStatePtr->cmdInProgress)
183  {
184  return STATUS_BUSY;
185  }
186 
187  /* Initialize the internal state of the driver */
188  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_ECB, plainText, cipherText, length);
189 
190  startTime = OSIF_GetMilliseconds();
191 
193 
194  while (g_csecStatePtr->cmdInProgress)
195  {
196  /* Wait until the execution of the command is complete */
197  CSEC_WaitCommandCompletion();
198 
199  crtTime = OSIF_GetMilliseconds();
200  if (crtTime > (startTime + timeout))
201  {
203 
204  g_csecStatePtr->errCode = STATUS_TIMEOUT;
205  break;
206  }
207 
209  }
210 
211  return g_csecStatePtr->errCode;
212 }
213 
214 /*FUNCTION**********************************************************************
215  *
216  * Function Name : CSEC_DRV_DecryptECB
217  * Description : This function performs the AES-128 decryption in ECB mode of
218  * the input cipher text buffer.
219  *
220  * Implements : CSEC_DRV_DecryptECB_Activity
221  * END**************************************************************************/
223  const uint8_t * cipherText,
224  uint32_t length,
225  uint8_t * plainText,
226  uint32_t timeout)
227 {
228  DEV_ASSERT(plainText != NULL);
229  DEV_ASSERT(cipherText != NULL);
230  DEV_ASSERT(g_csecStatePtr != NULL);
231 
232  uint32_t startTime = 0;
233  uint32_t crtTime = 0;
234 
235  if (g_csecStatePtr->cmdInProgress)
236  {
237  return STATUS_BUSY;
238  }
239  /* Initialize the internal state of the driver */
240  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_ECB, cipherText, plainText, length);
241 
242  startTime = OSIF_GetMilliseconds();
243 
245 
246  while (g_csecStatePtr->cmdInProgress)
247  {
248  /* Wait until the execution of the command is complete */
249  CSEC_WaitCommandCompletion();
250 
251  crtTime = OSIF_GetMilliseconds();
252  if (crtTime > (startTime + timeout))
253  {
255 
256  g_csecStatePtr->errCode = STATUS_TIMEOUT;
257  break;
258  }
259 
261  }
262 
263  return g_csecStatePtr->errCode;
264 }
265 
266 /*FUNCTION**********************************************************************
267  *
268  * Function Name : CSEC_DRV_EncryptCBC
269  * Description : This function performs the AES-128 encryption in CBC mode of
270  * the input cipher text buffer.
271  *
272  * Implements : CSEC_DRV_EncryptCBC_Activity
273  * END**************************************************************************/
275  const uint8_t * plainText,
276  uint32_t length,
277  const uint8_t * iv,
278  uint8_t * cipherText,
279  uint32_t timeout)
280 {
281  DEV_ASSERT(plainText != NULL);
282  DEV_ASSERT(cipherText != NULL);
283  DEV_ASSERT(iv != NULL);
284  DEV_ASSERT(g_csecStatePtr != NULL);
285 
286  uint32_t startTime = 0;
287  uint32_t crtTime = 0;
288 
289  if (g_csecStatePtr->cmdInProgress)
290  {
291  return STATUS_BUSY;
292  }
293 
294  /* Initialize the internal state of the driver */
295  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_CBC, plainText, cipherText, length);
296  g_csecStatePtr->iv = iv;
297 
298  startTime = OSIF_GetMilliseconds();
299 
301 
302  while (g_csecStatePtr->cmdInProgress)
303  {
304  /* Wait until the execution of the command is complete */
305  CSEC_WaitCommandCompletion();
306 
307  crtTime = OSIF_GetMilliseconds();
308  if (crtTime > (startTime + timeout))
309  {
311 
312  g_csecStatePtr->errCode = STATUS_TIMEOUT;
313  break;
314  }
315 
317  }
318 
319  return g_csecStatePtr->errCode;
320 }
321 
322 /*FUNCTION**********************************************************************
323  *
324  * Function Name : CSEC_DRV_DecryptCBC
325  * Description : This function performs the AES-128 decryption in CBC mode of
326  * the input cipher text buffer.
327  *
328  * Implements : CSEC_DRV_DecryptCBC_Activity
329  * END**************************************************************************/
331  const uint8_t * cipherText,
332  uint32_t length,
333  const uint8_t * iv,
334  uint8_t * plainText,
335  uint32_t timeout)
336 {
337  DEV_ASSERT(plainText != NULL);
338  DEV_ASSERT(cipherText != NULL);
339  DEV_ASSERT(iv != NULL);
340  DEV_ASSERT(g_csecStatePtr != NULL);
341 
342  uint32_t startTime = 0;
343  uint32_t crtTime = 0;
344 
345  if (g_csecStatePtr->cmdInProgress)
346  {
347  return STATUS_BUSY;
348  }
349 
350  /* Initialize the internal state of the driver */
351  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_CBC, cipherText, plainText, length);
352  g_csecStatePtr->iv = iv;
353 
354  startTime = OSIF_GetMilliseconds();
355 
357 
358  while (g_csecStatePtr->cmdInProgress)
359  {
360  /* Wait until the execution of the command is complete */
361  CSEC_WaitCommandCompletion();
362 
363  crtTime = OSIF_GetMilliseconds();
364  if (crtTime > (startTime + timeout))
365  {
367 
368  g_csecStatePtr->errCode = STATUS_TIMEOUT;
369  break;
370  }
371 
373  }
374 
375  return g_csecStatePtr->errCode;
376 }
377 
378 /*FUNCTION**********************************************************************
379  *
380  * Function Name : CSEC_DRV_GenerateMAC
381  * Description : This function calculates the MAC of a given message using
382  * CMAC with AES-128.
383  *
384  * Implements : CSEC_DRV_GenerateMAC_Activity
385  * END**************************************************************************/
387  const uint8_t * msg,
388  uint32_t msgLen,
389  uint8_t * cmac,
390  uint32_t timeout)
391 {
392  DEV_ASSERT(msg != NULL);
393  DEV_ASSERT(cmac != NULL);
394  DEV_ASSERT(g_csecStatePtr != NULL);
395 
396  uint32_t startTime = 0;
397  uint32_t crtTime = 0;
398 
399  if (g_csecStatePtr->cmdInProgress)
400  {
401  return STATUS_BUSY;
402  }
403 
404  /* Initialize the internal state of the driver */
406  g_csecStatePtr->msgLen = msgLen;
407 
408  startTime = OSIF_GetMilliseconds();
409 
411 
412  while (g_csecStatePtr->cmdInProgress)
413  {
414  /* Wait until the execution of the command is complete */
415  CSEC_WaitCommandCompletion();
416 
417  crtTime = OSIF_GetMilliseconds();
418  if (crtTime > (startTime + timeout))
419  {
421 
422  g_csecStatePtr->errCode = STATUS_TIMEOUT;
423  break;
424  }
425 
427  }
428 
429  return g_csecStatePtr->errCode;
430 }
431 
432 /*FUNCTION**********************************************************************
433  *
434  * Function Name : CSEC_DRV_GenerateMACAddrMode
435  * Description : This function calculates the MAC of a given message using
436  * CMAC with AES-128. It is different from the CSEC_DRV_GenerateMAC function in
437  * the sense that it does not involve an extra copy of the data on which the
438  * CMAC is computed and the message pointer should be a pointer to Flash memory.
439  *
440  * Implements : CSEC_DRV_GenerateMACAddrMode_Activity
441  * END**************************************************************************/
443  const uint8_t * msg,
444  uint32_t msgLen,
445  uint8_t * cmac)
446 {
447  DEV_ASSERT(msg != NULL);
448  DEV_ASSERT(cmac != NULL);
449  DEV_ASSERT(g_csecStatePtr != NULL);
450 
451  status_t stat;
452 
453  if (g_csecStatePtr->cmdInProgress)
454  {
455  return STATUS_BUSY;
456  }
457  g_csecStatePtr->cmdInProgress = true;
458 
459  /* Write the address of the message */
460  CSEC_WriteCommandWords(FEATURE_CSEC_FLASH_START_ADDRESS_OFFSET, (uint32_t *)&msg, 1U);
461  /* Write the size of the message (in bits) */
462  CSEC_WriteCommandWords(FEATURE_CSEC_MESSAGE_LENGTH_OFFSET, &msgLen, 1U);
463  /* Write the command header. This will trigger the command execution. */
464  CSEC_WriteCmdAndWait(CSEC_CMD_GENERATE_MAC, CSEC_FUNC_FORMAT_ADDR, CSEC_CALL_SEQ_FIRST, keyId);
465 
466  /* Read the status of the execution */
467  stat = CSEC_ReadErrorBits();
468  /* Read the resulted MAC */
469  if (stat == STATUS_SUCCESS)
470  {
471  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, cmac, CSEC_PAGE_SIZE_IN_BYTES);
472  }
473 
474  g_csecStatePtr->cmdInProgress = false;
475 
476  return stat;
477 }
478 
479 /*FUNCTION**********************************************************************
480  *
481  * Function Name : CSEC_DRV_VerifyMAC
482  * Description : This function verifies the MAC of a given message using CMAC
483  * with AES-128.
484  *
485  * Implements : CSEC_DRV_VerifyMAC_Activity
486  * END**************************************************************************/
488  const uint8_t * msg,
489  uint32_t msgLen,
490  const uint8_t * mac,
491  uint16_t macLen,
492  bool * verifStatus,
493  uint32_t timeout)
494 {
495  DEV_ASSERT(msg != NULL);
496  DEV_ASSERT(mac != NULL);
497  DEV_ASSERT(verifStatus != NULL);
498  DEV_ASSERT(g_csecStatePtr != NULL);
499 
500  uint32_t startTime = 0;
501  uint32_t crtTime = 0;
502 
503  if (g_csecStatePtr->cmdInProgress)
504  {
505  return STATUS_BUSY;
506  }
507 
508  /* Initialize the internal state of the driver */
510  g_csecStatePtr->msgLen = msgLen;
511  g_csecStatePtr->verifStatus = verifStatus;
512  g_csecStatePtr->macWritten = false;
513  g_csecStatePtr->mac = mac;
514  g_csecStatePtr->macLen = macLen;
515 
516  startTime = OSIF_GetMilliseconds();
517 
519 
520  while (g_csecStatePtr->cmdInProgress)
521  {
522  /* Wait until the execution of the command is complete */
523  CSEC_WaitCommandCompletion();
524 
525  crtTime = OSIF_GetMilliseconds();
526  if (crtTime > (startTime + timeout))
527  {
529 
530  g_csecStatePtr->errCode = STATUS_TIMEOUT;
531  break;
532  }
533 
535  }
536 
537  return g_csecStatePtr->errCode;
538 }
539 
540 /*FUNCTION**********************************************************************
541  *
542  * Function Name : CSEC_DRV_VerifyMACAddrMode
543  * Description : This function verifies the MAC of a given message using CMAC
544  * with AES-128. It is different from the CSEC_DRV_VerifyMAC function in the
545  * sense that it does not involve an extra copy of the data on which the CMAC is
546  * computed and the message pointer should be a pointer to Flash memory.
547  *
548  * Implements : CSEC_DRV_VerifyMACAddrMode_Activity
549  * END**************************************************************************/
551  const uint8_t * msg,
552  uint32_t msgLen,
553  const uint8_t * mac,
554  uint16_t macLen,
555  bool * verifStatus)
556 {
557  DEV_ASSERT(msg != NULL);
558  DEV_ASSERT(mac != NULL);
559  DEV_ASSERT(verifStatus != NULL);
560  DEV_ASSERT(g_csecStatePtr != NULL);
561 
562  status_t stat;
563 
564  if (g_csecStatePtr->cmdInProgress)
565  {
566  return STATUS_BUSY;
567  }
568  g_csecStatePtr->cmdInProgress = true;
569 
570  /* Write the address of the message */
571  CSEC_WriteCommandWords(FEATURE_CSEC_FLASH_START_ADDRESS_OFFSET, (uint32_t *)&msg, 1U);
572  /* Write the MAC to be verified */
573  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, mac, CSEC_PAGE_SIZE_IN_BYTES);
574  /* Write the size of the message (in bits) */
575  CSEC_WriteCommandWords(FEATURE_CSEC_MESSAGE_LENGTH_OFFSET, &msgLen, 1U);
576  /* Write the number of bits of the MAC to be compared */
577  CSEC_WriteCommandHalfWord(FEATURE_CSEC_MAC_LENGTH_OFFSET, macLen);
578  /* Write the command header. This will trigger the command execution. */
579  CSEC_WriteCmdAndWait(CSEC_CMD_VERIFY_MAC, CSEC_FUNC_FORMAT_ADDR, CSEC_CALL_SEQ_FIRST, keyId);
580 
581  /* Read the status of the execution */
582  stat = CSEC_ReadErrorBits();
583 
584  /* Read the result of the MAC verification */
585  if (stat == STATUS_SUCCESS)
586  {
587  *verifStatus = (CSEC_ReadCommandHalfWord(FEATURE_CSEC_VERIFICATION_STATUS_OFFSET) == 0U);
588  }
589 
590  g_csecStatePtr->cmdInProgress = false;
591 
592  return stat;
593 }
594 
595 /*FUNCTION**********************************************************************
596  *
597  * Function Name : CSEC_DRV_LoadKey
598  * Description : This function updates an internal key per the SHE
599  * specification.
600  *
601  * Implements : CSEC_DRV_LoadKey_Activity
602  * END**************************************************************************/
604  const uint8_t * m1,
605  const uint8_t * m2,
606  const uint8_t * m3,
607  uint8_t * m4,
608  uint8_t * m5)
609 {
610  status_t stat;
611 
612  DEV_ASSERT(m1 != NULL);
613  DEV_ASSERT(m2 != NULL);
614  DEV_ASSERT(m3 != NULL);
615  DEV_ASSERT(m4 != NULL);
616  DEV_ASSERT(m5 != NULL);
617  DEV_ASSERT(g_csecStatePtr != NULL);
618 
619  if (g_csecStatePtr->cmdInProgress)
620  {
621  return STATUS_BUSY;
622  }
623  g_csecStatePtr->cmdInProgress = true;
624 
625  /* Write the values of M1-M3 */
626  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, m1, CSEC_M1_SIZE_IN_BYTES);
627  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, m2, CSEC_M2_SIZE_IN_BYTES);
628  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_4_OFFSET, m3, CSEC_M3_SIZE_IN_BYTES);
629  /* Write the command header. This will trigger the command execution. */
630  CSEC_WriteCommandHeader(CSEC_CMD_LOAD_KEY, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, keyId);
631 
632  /* Wait until the execution of the command is complete */
633  CSEC_WaitCommandCompletion();
634 
635  /* Read the status of the execution */
636  stat = CSEC_ReadErrorBits();
637 
638  /* Read the obtained M4 and M5 */
639  if (stat == STATUS_SUCCESS)
640  {
641  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_5_OFFSET, m4, CSEC_M4_SIZE_IN_BYTES);
642  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_7_OFFSET, m5, CSEC_M5_SIZE_IN_BYTES);
643  }
644 
645  g_csecStatePtr->cmdInProgress = false;
646 
647  return stat;
648 }
649 
650 /*FUNCTION**********************************************************************
651  *
652  * Function Name : CSEC_DRV_LoadPlainKey
653  * Description : Updates the RAM key memory slot with a 128-bit plaintext.
654  *
655  * Implements : CSEC_DRV_LoadPlainKey_Activity
656  * END**************************************************************************/
657 status_t CSEC_DRV_LoadPlainKey(const uint8_t * plainKey)
658 {
659  DEV_ASSERT(plainKey != NULL);
660  DEV_ASSERT(g_csecStatePtr != NULL);
661 
662  status_t stat;
663 
664  if (g_csecStatePtr->cmdInProgress)
665  {
666  return STATUS_BUSY;
667  }
668  g_csecStatePtr->cmdInProgress = true;
669 
670  /* Write the bytes of the key */
671  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, plainKey, CSEC_PAGE_SIZE_IN_BYTES);
672  /* Write the command header. This will trigger the command execution. */
673  CSEC_WriteCommandHeader(CSEC_CMD_LOAD_PLAIN_KEY, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_RAM_KEY);
674 
675  /* Wait until the execution of the command is complete */
676  CSEC_WaitCommandCompletion();
677 
678  /* Read the status of the execution */
679  stat = CSEC_ReadErrorBits();
680 
681  g_csecStatePtr->cmdInProgress = false;
682 
683  return stat;
684 }
685 
686 /*FUNCTION**********************************************************************
687  *
688  * Function Name : CSEC_DRV_ExportRAMKey
689  * Description : This function exports the RAM_KEY into a format protected by
690  * SECRET_KEY.
691  *
692  * Implements : CSEC_DRV_ExportRAMKey_Activity
693  * END**************************************************************************/
695  uint8_t * m2,
696  uint8_t * m3,
697  uint8_t * m4,
698  uint8_t * m5)
699 {
700  DEV_ASSERT(m1 != NULL);
701  DEV_ASSERT(m2 != NULL);
702  DEV_ASSERT(m3 != NULL);
703  DEV_ASSERT(m4 != NULL);
704  DEV_ASSERT(m5 != NULL);
705  DEV_ASSERT(g_csecStatePtr != NULL);
706 
707  status_t stat;
708 
709  if (g_csecStatePtr->cmdInProgress)
710  {
711  return STATUS_BUSY;
712  }
713  g_csecStatePtr->cmdInProgress = true;
714 
715  /* Write the command header. This will trigger the command execution. */
716  CSEC_WriteCommandHeader(CSEC_CMD_EXPORT_RAM_KEY, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_RAM_KEY);
717 
718  /* Wait until the execution of the command is complete */
719  CSEC_WaitCommandCompletion();
720 
721  /* Read the status of the execution */
722  stat = CSEC_ReadErrorBits();
723  if (stat == STATUS_SUCCESS)
724  {
725  /* Read the M1-M5 values associated with the key */
726  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, m1, CSEC_M1_SIZE_IN_BYTES);
727  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, m2, CSEC_M2_SIZE_IN_BYTES);
728  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_4_OFFSET, m3, CSEC_M3_SIZE_IN_BYTES);
729  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_5_OFFSET, m4, CSEC_M4_SIZE_IN_BYTES);
730  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_7_OFFSET, m5, CSEC_M5_SIZE_IN_BYTES);
731  }
732 
733  g_csecStatePtr->cmdInProgress = false;
734 
735  return stat;
736 }
737 
738 /*FUNCTION**********************************************************************
739  *
740  * Function Name : CSEC_DRV_InitRNG
741  * Description : The function initializes the seed and derives a key for the
742  * PRNG. The function must be called before CMD_RND after every power cycle/reset.
743  *
744  * Implements : CSEC_DRV_InitRNG_Activity
745  * END**************************************************************************/
747 {
748  DEV_ASSERT(g_csecStatePtr != NULL);
749 
750  status_t stat;
751 
752  if (g_csecStatePtr->cmdInProgress)
753  {
754  return STATUS_BUSY;
755  }
756  g_csecStatePtr->cmdInProgress = true;
757 
758  /* Write the command header. This will trigger the command execution. */
759  CSEC_WriteCommandHeader(CSEC_CMD_INIT_RNG, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
760 
761  /* Wait until the execution of the command is complete */
762  CSEC_WaitCommandCompletion();
763 
764  /* Read the status of the execution */
765  stat = CSEC_ReadErrorBits();
766 
767  g_csecStatePtr->cmdInProgress = false;
768 
769  return stat;
770 }
771 
772 /*FUNCTION**********************************************************************
773  *
774  * Function Name : CSEC_DRV_ExtendSeed
775  * Description : Extends the seed of the PRNG by compressing the former seed
776  * value and the supplied entropy into a new seed. This new seed is then to be
777  * used to generate a random number by invoking the CMD_RND command. The random
778  * number generator must be initialized by CMD_INIT_RNG before the seed may be
779  * extended.
780  *
781  * Implements : CSEC_DRV_ExtendSeed_Activity
782  * END**************************************************************************/
783 status_t CSEC_DRV_ExtendSeed(const uint8_t * entropy)
784 {
785  DEV_ASSERT(entropy != NULL);
786  DEV_ASSERT(g_csecStatePtr != NULL);
787 
788  status_t stat;
789 
790  if (g_csecStatePtr->cmdInProgress)
791  {
792  return STATUS_BUSY;
793  }
794  g_csecStatePtr->cmdInProgress = true;
795 
796  /* Write the entropy parameter */
797  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, entropy, CSEC_PAGE_SIZE_IN_BYTES);
798  /* Write the command header. This will trigger the command execution. */
799  CSEC_WriteCommandHeader(CSEC_CMD_EXTEND_SEED, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
800 
801  /* Wait until the execution of the command is complete */
802  CSEC_WaitCommandCompletion();
803 
804  /* Read the status of the execution */
805  stat = CSEC_ReadErrorBits();
806 
807  g_csecStatePtr->cmdInProgress = false;
808 
809  return stat;
810 }
811 
812 /*FUNCTION**********************************************************************
813  *
814  * Function Name : CSEC_DRV_GenerateRND
815  * Description : The function returns a vector of 128 random bits. The random
816  * number generator has to be initialized by calling CSEC_DRV_InitRNG before
817  * random numbers can be supplied.
818  *
819  * Implements : CSEC_DRV_GenerateRND_Activity
820  * END**************************************************************************/
822 {
823  DEV_ASSERT(rnd != NULL);
824  DEV_ASSERT(g_csecStatePtr != NULL);
825 
826  status_t stat;
827 
828  if (g_csecStatePtr->cmdInProgress)
829  {
830  return STATUS_BUSY;
831  }
832  g_csecStatePtr->cmdInProgress = true;
833 
834  /* Write the command header. This will trigger the command execution. */
835  CSEC_WriteCommandHeader(CSEC_CMD_RND, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
836 
837  /* Wait until the execution of the command is complete */
838  CSEC_WaitCommandCompletion();
839 
840  /* Read the status of the execution */
841  stat = CSEC_ReadErrorBits();
842  /* Read the resulted random bytes */
843  if (stat == STATUS_SUCCESS)
844  {
845  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, rnd, CSEC_PAGE_SIZE_IN_BYTES);
846  }
847 
848  g_csecStatePtr->cmdInProgress = false;
849 
850  return stat;
851 }
852 
853 /*FUNCTION**********************************************************************
854  *
855  * Function Name : CSEC_DRV_BootFailure
856  * Description : The function is called during later stages of the boot
857  * process to detect a failure.
858  *
859  * Implements : CSEC_DRV_BootFailure_Activity
860  * END**************************************************************************/
862 {
863  DEV_ASSERT(g_csecStatePtr != NULL);
864 
865  status_t stat;
866 
867  if (g_csecStatePtr->cmdInProgress)
868  {
869  return STATUS_BUSY;
870  }
871  g_csecStatePtr->cmdInProgress = true;
872 
873  /* Write the command header. This will trigger the command execution. */
874  CSEC_WriteCommandHeader(CSEC_CMD_BOOT_FAILURE, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
875 
876  /* Wait until the execution of the command is complete */
877  CSEC_WaitCommandCompletion();
878 
879  /* Read the status of the execution */
880  stat = CSEC_ReadErrorBits();
881 
882  g_csecStatePtr->cmdInProgress = false;
883 
884  return stat;
885 }
886 
887 /*FUNCTION**********************************************************************
888  *
889  * Function Name : CSEC_DRV_BootOK
890  * Description : The function is called during later stages of the boot
891  * process to mark successful boot verification.
892  *
893  * Implements : CSEC_DRV_BootOK_Activity
894  * END**************************************************************************/
896 {
897  DEV_ASSERT(g_csecStatePtr != NULL);
898 
899  status_t stat;
900 
901  if (g_csecStatePtr->cmdInProgress)
902  {
903  return STATUS_BUSY;
904  }
905  g_csecStatePtr->cmdInProgress = true;
906 
907  /* Write the command header. This will trigger the command execution. */
908  CSEC_WriteCommandHeader(CSEC_CMD_BOOT_OK, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
909 
910  /* Wait until the execution of the command is complete */
911  CSEC_WaitCommandCompletion();
912 
913  /* Read the status of the execution */
914  stat = CSEC_ReadErrorBits();
915 
916  g_csecStatePtr->cmdInProgress = false;
917 
918  return stat;
919 }
920 
921 /*FUNCTION**********************************************************************
922  *
923  * Function Name : CSEC_DRV_BootDefine
924  * Description : The function implements an extension of the SHE standard to
925  * define both the user boot size and boot method.
926  *
927  * Implements : CSEC_DRV_BootDefine_Activity
928  * END**************************************************************************/
929 status_t CSEC_DRV_BootDefine(uint32_t bootSize,
930  csec_boot_flavor_t bootFlavor)
931 {
932  DEV_ASSERT(g_csecStatePtr != NULL);
933 
934  uint8_t flavor = (uint8_t)bootFlavor;
935  status_t stat;
936 
937  if (g_csecStatePtr->cmdInProgress)
938  {
939  return STATUS_BUSY;
940  }
941  g_csecStatePtr->cmdInProgress = true;
942 
943  /* Write the boot size and the boot flavor parameters */
944  CSEC_WriteCommandWords(FEATURE_CSEC_BOOT_SIZE_OFFSET, &bootSize, 1U);
945  CSEC_WriteCommandByte(FEATURE_CSEC_BOOT_FLAVOR_OFFSET, flavor);
946  /* Write the command header. This will trigger the command execution. */
947  CSEC_WriteCommandHeader(CSEC_CMD_BOOT_DEFINE, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
948 
949  /* Wait until the execution of the command is complete */
950  CSEC_WaitCommandCompletion();
951 
952  /* Read the status of the execution */
953  stat = CSEC_ReadErrorBits();
954 
955  g_csecStatePtr->cmdInProgress = false;
956 
957  return stat;
958 }
959 
960 /*FUNCTION**********************************************************************
961  *
962  * Function Name : CSEC_DRV_GetID
963  * Description : This function returns the identity (UID) and the value of the
964  * status register protected by a MAC over a challenge and the data.
965  *
966  * Implements : CSEC_DRV_GetID_Activity
967  * END**************************************************************************/
968 status_t CSEC_DRV_GetID(const uint8_t * challenge,
969  uint8_t * uid,
970  uint8_t * sreg,
971  uint8_t * mac)
972 {
973  DEV_ASSERT(challenge != NULL);
974  DEV_ASSERT(uid != NULL);
975  DEV_ASSERT(sreg != NULL);
976  DEV_ASSERT(mac != NULL);
977  DEV_ASSERT(g_csecStatePtr != NULL);
978 
979  status_t stat;
980 
981  if (g_csecStatePtr->cmdInProgress)
982  {
983  return STATUS_BUSY;
984  }
985  g_csecStatePtr->cmdInProgress = true;
986 
987  /* Write the challenge */
988  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, challenge, CSEC_PAGE_SIZE_IN_BYTES);
989  /* Write the command header. This will trigger the command execution. */
990  CSEC_WriteCommandHeader(CSEC_CMD_GET_ID, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
991 
992  /* Wait until the execution of the command is complete */
993  CSEC_WaitCommandCompletion();
994 
995  /* Read the status of the execution */
996  stat = CSEC_ReadErrorBits();
997  if (stat == STATUS_SUCCESS)
998  {
999  /* Read the UID */
1000  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, uid, (uint8_t)(CSEC_PAGE_SIZE_IN_BYTES - 1U));
1001  /* Read the value of the SREG register */
1002  *sreg = CSEC_ReadCommandByte(FEATURE_CSEC_SREG_OFFSET);
1003  /* Read the MAC over the UID and the SREG */
1004  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_3_OFFSET, mac, CSEC_PAGE_SIZE_IN_BYTES);
1005  }
1006 
1007  g_csecStatePtr->cmdInProgress = false;
1008 
1009  return stat;
1010 }
1011 
1012 /*FUNCTION**********************************************************************
1013  *
1014  * Function Name : CSEC_DRV_DbgChal
1015  * Description : This function obtains a random number which the user shall
1016  * use along with the MASTER_ECU_KEY and UID to return an authorization request.
1017  *
1018  * Implements : CSEC_DRV_DbgChal_Activity
1019  * END**************************************************************************/
1020 status_t CSEC_DRV_DbgChal(uint8_t * challenge)
1021 {
1022  DEV_ASSERT(challenge != NULL);
1023  DEV_ASSERT(g_csecStatePtr != NULL);
1024 
1025  status_t stat;
1026 
1027  if (g_csecStatePtr->cmdInProgress)
1028  {
1029  return STATUS_BUSY;
1030  }
1031  g_csecStatePtr->cmdInProgress = true;
1032 
1033  /* Write the command header. This will trigger the command execution. */
1034  CSEC_WriteCommandHeader(CSEC_CMD_DBG_CHAL, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
1035 
1036  /* Wait until the execution of the command is complete */
1037  CSEC_WaitCommandCompletion();
1038 
1039  /* Read the status of the execution */
1040  stat = CSEC_ReadErrorBits();
1041  /* Read the challenge generated by the CSEc module */
1042  if (stat == STATUS_SUCCESS)
1043  {
1044  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, challenge, CSEC_PAGE_SIZE_IN_BYTES);
1045  }
1046 
1047  g_csecStatePtr->cmdInProgress = false;
1048 
1049  return stat;
1050 }
1051 
1052 /*FUNCTION**********************************************************************
1053  *
1054  * Function Name : CSEC_DRV_DbgAuth
1055  * Description : This function erases all keys (actual and outdated) stored in
1056  * NVM Memory if the authorization is confirmed by CSEc.
1057  *
1058  * Implements : CSEC_DRV_DbgAuth_Activity
1059  * END**************************************************************************/
1060 status_t CSEC_DRV_DbgAuth(const uint8_t * authorization)
1061 {
1062  DEV_ASSERT(authorization != NULL);
1063  DEV_ASSERT(g_csecStatePtr != NULL);
1064 
1065  status_t stat;
1066 
1067  if (g_csecStatePtr->cmdInProgress)
1068  {
1069  return STATUS_BUSY;
1070  }
1071  g_csecStatePtr->cmdInProgress = true;
1072 
1073  /* Write the authorization computed from the challenge */
1074  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, authorization, CSEC_PAGE_SIZE_IN_BYTES);
1075  /* Write the command header. This will trigger the command execution. */
1076  CSEC_WriteCommandHeader(CSEC_CMD_DBG_AUTH, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, CSEC_SECRET_KEY);
1077 
1078  /* Wait until the execution of the command is complete */
1079  CSEC_WaitCommandCompletion();
1080 
1081  /* Read the status of the execution */
1082  stat = CSEC_ReadErrorBits();
1083 
1084  g_csecStatePtr->cmdInProgress = false;
1085 
1086  return stat;
1087 }
1088 
1089 /*FUNCTION**********************************************************************
1090  *
1091  * Function Name : CSEC_DRV_MPCompress
1092  * Description : This function accesses a Miyaguchi-Prenell compression
1093  * feature within the CSEc feature set to compress the given messages.
1094  *
1095  * Implements : CSEC_DRV_MPCompress_Activity
1096  * END**************************************************************************/
1097 status_t CSEC_DRV_MPCompress(const uint8_t * msg,
1098  uint16_t msgLen,
1099  uint8_t * mpCompress,
1100  uint32_t timeout)
1101 {
1102  DEV_ASSERT(msg != NULL);
1103  DEV_ASSERT(mpCompress != NULL);
1104  DEV_ASSERT(g_csecStatePtr != NULL);
1105 
1106  uint32_t startTime = 0;
1107  uint32_t crtTime = 0;
1109  status_t stat = STATUS_SUCCESS;
1110  uint32_t index = 0;
1111  uint16_t numPagesLeft = msgLen;
1112 
1113  if (g_csecStatePtr->cmdInProgress)
1114  {
1115  return STATUS_BUSY;
1116  }
1117 
1118  startTime = OSIF_GetMilliseconds();
1119 
1120  /* Loop and launch commands until the end of the message */
1121  while (numPagesLeft > 0U)
1122  {
1123  uint8_t numPages = (uint8_t)((numPagesLeft > CSEC_DATA_PAGES_AVAILABLE) ?
1124  CSEC_DATA_PAGES_AVAILABLE : numPagesLeft);
1125  uint8_t numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1126 
1127  /* Write the message */
1128  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &msg[index], numBytes);
1129  /* Write the size of the message */
1130  CSEC_WriteCommandHalfWord(FEATURE_CSEC_PAGE_LENGTH_OFFSET, msgLen);
1131  /* Write the command header. This will trigger the command execution. */
1132  CSEC_WriteCommandHeader(CSEC_CMD_MP_COMPRESS, CSEC_FUNC_FORMAT_COPY, seq, CSEC_SECRET_KEY);
1133 
1134  /* Wait until the execution of the command is complete */
1135  CSEC_WaitCommandCompletion();
1136 
1137  crtTime = OSIF_GetMilliseconds();
1138  if (crtTime > (startTime + timeout))
1139  {
1141 
1142  stat = STATUS_TIMEOUT;
1143  }
1144 
1145  if (stat == STATUS_SUCCESS)
1146  {
1147  /* Read the status of the execution */
1148  stat = CSEC_ReadErrorBits();
1149  }
1150 
1151  if (stat != STATUS_SUCCESS)
1152  {
1153  break;
1154  }
1155 
1156  numPagesLeft = (uint16_t)(numPagesLeft - numPages);
1157  index = (uint32_t)(index + numBytes);
1158  if (seq == CSEC_CALL_SEQ_FIRST)
1159  {
1161  }
1162  }
1163 
1164  /* Read the result of the compression */
1165  if (stat == STATUS_SUCCESS)
1166  {
1167  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, mpCompress, CSEC_PAGE_SIZE_IN_BYTES);
1168  }
1169 
1170  return stat;
1171 }
1172 
1173 /*FUNCTION**********************************************************************
1174  *
1175  * Function Name : CSEC_DRV_EncryptECBAsync
1176  * Description : This function starts the AES-128 encryption in ECB mode of
1177  * the input plain text buffer, in an asynchronous manner.
1178  *
1179  * Implements : CSEC_DRV_EncryptECBAsync_Activity
1180  * END**************************************************************************/
1182  const uint8_t * plainText,
1183  uint32_t length,
1184  uint8_t * cipherText)
1185 {
1186  DEV_ASSERT(plainText != NULL);
1187  DEV_ASSERT(cipherText != NULL);
1188  DEV_ASSERT(g_csecStatePtr != NULL);
1189 
1190  if (g_csecStatePtr->cmdInProgress)
1191  {
1192  return STATUS_BUSY;
1193  }
1194 
1195  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_ECB, plainText, cipherText, length);
1196 
1198 
1199  /* Enable interrupt */
1200  CSEC_SetInterrupt(true);
1201 
1202  return STATUS_SUCCESS;
1203 }
1204 
1205 /*FUNCTION**********************************************************************
1206  *
1207  * Function Name : CSEC_DRV_DecryptECBAsync
1208  * Description : This function starts the AES-128 decryption in ECB mode of
1209  * the input cipher text buffer, in an asynchronous manner.
1210  *
1211  * Implements : CSEC_DRV_DecryptECBAsync_Activity
1212  * END**************************************************************************/
1214  const uint8_t * cipherText,
1215  uint32_t length,
1216  uint8_t * plainText)
1217 {
1218  DEV_ASSERT(plainText != NULL);
1219  DEV_ASSERT(cipherText != NULL);
1220  DEV_ASSERT(g_csecStatePtr != NULL);
1221 
1222  if (g_csecStatePtr->cmdInProgress)
1223  {
1224  return STATUS_BUSY;
1225  }
1226 
1227  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_ECB, cipherText, plainText, length);
1228 
1230 
1231  /* Enable interrupt */
1232  CSEC_SetInterrupt(true);
1233 
1234  return STATUS_SUCCESS;
1235 }
1236 
1237 /*FUNCTION**********************************************************************
1238  *
1239  * Function Name : CSEC_DRV_EncryptCBCAsync
1240  * Description : This function starts the AES-128 encryption in CBC mode of
1241  * the input cipher text buffer, in an asynchronous manner.
1242  *
1243  * Implements : CSEC_DRV_EncryptCBCAsync_Activity
1244  * END**************************************************************************/
1246  const uint8_t * plainText,
1247  uint32_t length,
1248  const uint8_t * iv,
1249  uint8_t * cipherText)
1250 {
1251  DEV_ASSERT(plainText != NULL);
1252  DEV_ASSERT(cipherText != NULL);
1253  DEV_ASSERT(iv != NULL);
1254  DEV_ASSERT(g_csecStatePtr != NULL);
1255 
1256  if (g_csecStatePtr->cmdInProgress)
1257  {
1258  return STATUS_BUSY;
1259  }
1260 
1261  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_CBC, plainText, cipherText, length);
1262  g_csecStatePtr->iv = iv;
1263 
1265 
1266  /* Enable interrupt */
1267  CSEC_SetInterrupt(true);
1268 
1269  return STATUS_SUCCESS;
1270 }
1271 
1272 /*FUNCTION**********************************************************************
1273  *
1274  * Function Name : CSEC_DRV_DecryptCBCAsync
1275  * Description : This function starts the AES-128 decryption in CBC mode of
1276  * the input cipher text buffer, in an asynchronous manner.
1277  *
1278  * Implements : CSEC_DRV_DecryptCBCAsync_Activity
1279  * END**************************************************************************/
1281  const uint8_t * cipherText,
1282  uint32_t length,
1283  const uint8_t * iv,
1284  uint8_t * plainText)
1285 {
1286  DEV_ASSERT(plainText != NULL);
1287  DEV_ASSERT(cipherText != NULL);
1288  DEV_ASSERT(iv != NULL);
1289  DEV_ASSERT(g_csecStatePtr != NULL);
1290 
1291  if (g_csecStatePtr->cmdInProgress)
1292  {
1293  return STATUS_BUSY;
1294  }
1295 
1296  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_CBC, cipherText, plainText, length);
1297  g_csecStatePtr->iv = iv;
1298 
1300 
1301  /* Enable interrupt */
1302  CSEC_SetInterrupt(true);
1303 
1304  return STATUS_SUCCESS;
1305 }
1306 
1307 /*FUNCTION**********************************************************************
1308  *
1309  * Function Name : CSEC_DRV_GenerateMACAsync
1310  * Description : This function starts the computation the MAC of a given
1311  * message using CMAC with AES-128, in an asynchronous manner.
1312  *
1313  * Implements : CSEC_DRV_GenerateMACAsync_Activity
1314  * END**************************************************************************/
1316  const uint8_t * msg,
1317  uint32_t msgLen,
1318  uint8_t * cmac)
1319 {
1320  DEV_ASSERT(msg != NULL);
1321  DEV_ASSERT(cmac != NULL);
1322  DEV_ASSERT(g_csecStatePtr != NULL);
1323 
1324  if (g_csecStatePtr->cmdInProgress)
1325  {
1326  return STATUS_BUSY;
1327  }
1328 
1330  g_csecStatePtr->msgLen = msgLen;
1331 
1333 
1334  /* Enable interrupt */
1335  CSEC_SetInterrupt(true);
1336 
1337  return STATUS_SUCCESS;
1338 }
1339 
1340 /*FUNCTION**********************************************************************
1341  *
1342  * Function Name : CSEC_DRV_VerifyMACAsync
1343  * Description : This function starts the verification the MAC of a given
1344  * message using CMAC with AES-128, in an asynchronous manner.
1345  *
1346  * Implements : CSEC_DRV_VerifyMACAsync_Activity
1347  * END**************************************************************************/
1349  const uint8_t * msg,
1350  uint32_t msgLen,
1351  const uint8_t * mac,
1352  uint16_t macLen,
1353  bool * verifStatus)
1354 {
1355  DEV_ASSERT(msg != NULL);
1356  DEV_ASSERT(mac != NULL);
1357  DEV_ASSERT(verifStatus != NULL);
1358  DEV_ASSERT(g_csecStatePtr != NULL);
1359 
1360  if (g_csecStatePtr->cmdInProgress)
1361  {
1362  return STATUS_BUSY;
1363  }
1364 
1366  g_csecStatePtr->msgLen = msgLen;
1367  g_csecStatePtr->verifStatus = verifStatus;
1368  g_csecStatePtr->macWritten = false;
1369  g_csecStatePtr->mac = mac;
1370  g_csecStatePtr->macLen = macLen;
1371 
1373 
1374  /* Enable interrupt */
1375  CSEC_SetInterrupt(true);
1376 
1377  return STATUS_SUCCESS;
1378 }
1379 
1380 /*FUNCTION**********************************************************************
1381  *
1382  * Function Name : CSEC_DRV_GetAsyncCmdStatus
1383  * Description : This function checks the status of the execution of an
1384  * asynchronous command. If the command is still in progress, returns STATUS_BUSY.
1385  *
1386  * Implements : CSEC_DRV_GetAsyncCmdStatus_Activity
1387  * END**************************************************************************/
1389 {
1390  DEV_ASSERT(g_csecStatePtr != NULL);
1391 
1392  if (!g_csecStatePtr->cmdInProgress)
1393  {
1394  return g_csecStatePtr->errCode;
1395  }
1396 
1397  return STATUS_BUSY;
1398 }
1399 
1400 /*FUNCTION**********************************************************************
1401  *
1402  * Function Name : CSEC_DRV_InitState
1403  * Description : Initializes the internal state of the driver with a given
1404  * input buffer, output buffer, key, length, command, and marks the command as
1405  * in progress.
1406  *
1407  * END**************************************************************************/
1409  csec_cmd_t cmd,
1410  const uint8_t * inBuff,
1411  uint8_t * outBuff,
1412  uint32_t length)
1413 {
1414  g_csecStatePtr->cmdInProgress = true;
1415  g_csecStatePtr->cmd = cmd;
1416  g_csecStatePtr->inputBuff = inBuff;
1417  g_csecStatePtr->outputBuff = outBuff;
1418  g_csecStatePtr->keyId = keyId;
1419  g_csecStatePtr->fullSize = length;
1420  g_csecStatePtr->index = 0U;
1421  g_csecStatePtr->errCode = STATUS_SUCCESS;
1422  g_csecStatePtr->seq = CSEC_CALL_SEQ_FIRST;
1423 }
1424 
1425 /*FUNCTION**********************************************************************
1426  *
1427  * Function Name : FTFC_IRQHandler
1428  * Description : Implementation of the FTFC interrupt handler. Handles completed
1429  * commands lauched by using the asynchronous CSEc driver API which were
1430  *
1431  * END**************************************************************************/
1433 {
1434  uint8_t fstat = (uint8_t)(FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK);
1435 
1436  /* Previous command execution ended, continue execution */
1437  if ((fstat != 0U) && g_csecStatePtr->cmdInProgress)
1438  {
1439  if ((g_csecStatePtr->cmd == CSEC_CMD_ENC_ECB) || (g_csecStatePtr->cmd == CSEC_CMD_DEC_ECB))
1440  {
1442  }
1443  else if ((g_csecStatePtr->cmd == CSEC_CMD_ENC_CBC) || (g_csecStatePtr->cmd == CSEC_CMD_DEC_CBC))
1444  {
1446  }
1447  else if (g_csecStatePtr->cmd == CSEC_CMD_GENERATE_MAC)
1448  {
1450  }
1451  else if (g_csecStatePtr->cmd == CSEC_CMD_VERIFY_MAC)
1452  {
1454  }
1455  else
1456  {
1457  /* Do nothing, all the asynchronous operations were checked above */
1458  }
1459 
1460  /* If finished processing, disable interrupt */
1461  if (!g_csecStatePtr->cmdInProgress)
1462  {
1463  CSEC_SetInterrupt(false);
1464 
1465  if (g_csecStatePtr->callback != NULL)
1466  {
1467  g_csecStatePtr->callback((uint32_t)g_csecStatePtr->cmd, g_csecStatePtr->callbackParam);
1468  }
1469  }
1470  }
1471 }
1472 
1473 /*FUNCTION**********************************************************************
1474  *
1475  * Function Name : CSEC_DRV_StartEncDecECBCmd
1476  * Description : Initializes the CSE_PRAM and the internal state for
1477  * encryption/decryption using ECB mode commands.
1478  *
1479  * END**************************************************************************/
1481 {
1482  uint32_t numPagesLeft = (g_csecStatePtr->fullSize - g_csecStatePtr->index) >> CSEC_BYTES_TO_FROM_PAGES_SHIFT;
1483  uint16_t numPages = (uint16_t)((numPagesLeft > CSEC_DATA_PAGES_AVAILABLE) ? CSEC_DATA_PAGES_AVAILABLE : numPagesLeft);
1484  uint8_t numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1485 
1486  /* Write the plain/cipher text */
1487  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1488  /* Write the size of the plain/cipher text (in pages) */
1489  CSEC_WriteCommandHalfWord(FEATURE_CSEC_PAGE_LENGTH_OFFSET, numPages);
1490 
1491  g_csecStatePtr->partSize = numBytes;
1492 
1493  /* Write the command header. This will trigger the command execution. */
1494  CSEC_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1495 }
1496 
1497 /*FUNCTION**********************************************************************
1498  *
1499  * Function Name : CSEC_DRV_StartEncDecCBCCmd
1500  * Description : Initializes the CSE_PRAM and the internal state for
1501  * encryption/decryption using CBC mode commands.
1502  *
1503  * END**************************************************************************/
1505 {
1506  uint32_t numPagesLeft = (g_csecStatePtr->fullSize - g_csecStatePtr->index) >> CSEC_BYTES_TO_FROM_PAGES_SHIFT;
1507  uint16_t numPages = (uint16_t)((numPagesLeft > CSEC_DATA_PAGES_AVAILABLE) ? CSEC_DATA_PAGES_AVAILABLE : numPagesLeft);
1508  uint8_t numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1509 
1510  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1511  {
1512  numPages = (uint16_t)((numPagesLeft > (CSEC_DATA_PAGES_AVAILABLE - 1U)) ? (CSEC_DATA_PAGES_AVAILABLE - 1U) : numPagesLeft);
1513  numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1514 
1515  /* Write the initialization vector */
1516  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, g_csecStatePtr->iv, CSEC_PAGE_SIZE_IN_BYTES);
1517  /* Write the plain/cipher text */
1518  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1519  }
1520  else
1521  {
1522  /* Write the plain/cipher text */
1523  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1524  }
1525 
1526  /* Write the size of the plain/cipher text (in pages) */
1527  CSEC_WriteCommandHalfWord(FEATURE_CSEC_PAGE_LENGTH_OFFSET, (uint16_t)(g_csecStatePtr->fullSize >> CSEC_BYTES_TO_FROM_PAGES_SHIFT));
1528 
1529  g_csecStatePtr->partSize = numBytes;
1530 
1531  /* Write the command header. This will trigger the command execution. */
1532  CSEC_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1533 }
1534 
1535 /*FUNCTION**********************************************************************
1536  *
1537  * Function Name : CSEC_DRV_StartGenMACCmd
1538  * Description : Initializes the CSE_PRAM and the internal state for the
1539  * CMAC generation command.
1540  *
1541  * END**************************************************************************/
1543 {
1544  uint8_t numBytes = (uint8_t)(((g_csecStatePtr->fullSize - g_csecStatePtr->index) >
1545  CSEC_DATA_BYTES_AVAILABLE) ? CSEC_DATA_BYTES_AVAILABLE : (g_csecStatePtr->fullSize - g_csecStatePtr->index));
1546 
1547  /* Write the plain/cipher text */
1548  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1549  /* Write the size of the message (in bits) */
1550  CSEC_WriteCommandWords(FEATURE_CSEC_MESSAGE_LENGTH_OFFSET, &g_csecStatePtr->msgLen, 1U);
1551 
1552  g_csecStatePtr->partSize = numBytes;
1553 
1554  /* Write the command header. This will trigger the command execution. */
1555  CSEC_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1556 }
1557 
1558 /*FUNCTION**********************************************************************
1559  *
1560  * Function Name : CSEC_DRV_StartVerifMACCmd
1561  * Description : Initializes the CSE_PRAM and the internal state for the
1562  * CMAC verification command.
1563  *
1564  * END**************************************************************************/
1566 {
1567  uint8_t numBytes = (uint8_t)(((g_csecStatePtr->fullSize - g_csecStatePtr->index) >
1568  CSEC_DATA_BYTES_AVAILABLE) ? CSEC_DATA_BYTES_AVAILABLE : (g_csecStatePtr->fullSize - g_csecStatePtr->index));
1569  uint8_t macOffset = (uint8_t)CSEC_DRV_RoundTo(numBytes, 0x10);
1570 
1571  /* Write the plain/cipher text */
1572  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1573  /* Write the size of the message (in bits) */
1574  CSEC_WriteCommandWords(FEATURE_CSEC_MESSAGE_LENGTH_OFFSET, &g_csecStatePtr->msgLen, 1U);
1575 
1576  /* Write the number of bits of the MAC to be compared */
1577  CSEC_WriteCommandHalfWord(FEATURE_CSEC_MAC_LENGTH_OFFSET, (uint16_t)g_csecStatePtr->macLen);
1578 
1579  /* If there is available space in CSE_PRAM, write the MAC to be verified */
1581  {
1582  CSEC_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET + macOffset, g_csecStatePtr->mac, CSEC_PAGE_SIZE_IN_BYTES);
1583  g_csecStatePtr->macWritten = true;
1584  }
1585 
1586  g_csecStatePtr->partSize = numBytes;
1587 
1588  /* Write the command header. This will trigger the command execution. */
1589  CSEC_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1590 }
1591 
1592 /*FUNCTION**********************************************************************
1593  *
1594  * Function Name : CSEC_DRV_ContinueEncDecECBCmd
1595  * Description : Continues the execution of encryption/decryption using ECB
1596  * mode. Reads the partial result, updates the internal state and launches
1597  * another command, if necessary.
1598  *
1599  * END**************************************************************************/
1601 {
1602  /* Read the status of the execution */
1603  g_csecStatePtr->errCode = CSEC_ReadErrorBits();
1604  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1605  {
1606  /* Do not continue launching commands if an error occurred */
1607  g_csecStatePtr->cmdInProgress = false;
1608  return;
1609  }
1610 
1611  /* Get partial result */
1612  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->outputBuff[g_csecStatePtr->index], (uint8_t)g_csecStatePtr->partSize);
1613 
1614  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1615 
1616  /* Decide if more commands are needed */
1617  if (g_csecStatePtr->index >= g_csecStatePtr->fullSize)
1618  {
1619  g_csecStatePtr->cmdInProgress = false;
1620  }
1621  else
1622  {
1623  /* Continue launching commands */
1625  }
1626 }
1627 
1628 /*FUNCTION**********************************************************************
1629  *
1630  * Function Name : CSEC_DRV_ContinueEncDecCBCCmd
1631  * Description : Continues the execution of encryption/decryption using CBC
1632  * mode. Reads the partial result, updates the internal state and launches
1633  * another command, if necessary.
1634  *
1635  * END**************************************************************************/
1637 {
1638  /* Read the status of the execution */
1639  g_csecStatePtr->errCode = CSEC_ReadErrorBits();
1640  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1641  {
1642  /* Do not continue launching commands if an error occurred */
1643  g_csecStatePtr->cmdInProgress = false;
1644  return;
1645  }
1646 
1647  /* Get partial result */
1648  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1649  {
1650  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, &g_csecStatePtr->outputBuff[g_csecStatePtr->index],
1651  (uint8_t)g_csecStatePtr->partSize);
1652  g_csecStatePtr->seq = CSEC_CALL_SEQ_SUBSEQUENT;
1653  }
1654  else
1655  {
1656  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->outputBuff[g_csecStatePtr->index],
1657  (uint8_t)g_csecStatePtr->partSize);
1658  }
1659 
1660  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1661 
1662  if (g_csecStatePtr->index >= g_csecStatePtr->fullSize)
1663  {
1664  g_csecStatePtr->cmdInProgress = false;
1665  }
1666  else
1667  {
1668  /* Continue launching commands */
1670  }
1671 }
1672 
1673 
1674 /*FUNCTION**********************************************************************
1675  *
1676  * Function Name : CSEC_DRV_ContinueGenMACCmd
1677  * Description : Continues the execution of CMAC generation. Reads the status
1678  * of the execution, updates the internal state and launches another command,
1679  * if necessary. If there is no need to launch another command, reads the
1680  * resulted CMAC.
1681  *
1682  * END**************************************************************************/
1684 {
1685  /* Read the status of the execution */
1686  g_csecStatePtr->errCode = CSEC_ReadErrorBits();
1687  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1688  {
1689  /* Do not continue launching commands if an error occurred */
1690  g_csecStatePtr->cmdInProgress = false;
1691  return;
1692  }
1693 
1694  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1695  {
1696  g_csecStatePtr->seq = CSEC_CALL_SEQ_SUBSEQUENT;
1697  }
1698 
1699  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1700 
1701  /* Decide if more commands are needed */
1702  if (g_csecStatePtr->index >= g_csecStatePtr->fullSize)
1703  {
1704  g_csecStatePtr->cmdInProgress = false;
1705  CSEC_ReadCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, g_csecStatePtr->outputBuff, CSEC_PAGE_SIZE_IN_BYTES);
1706  }
1707  else
1708  {
1709  /* Continue launching commands */
1711  }
1712 }
1713 
1714 /*FUNCTION**********************************************************************
1715  *
1716  * Function Name : CSEC_DRV_ContinueVerifMACCmd
1717  * Description : Continues the execution of CMAC verification. Reads the status
1718  * of the execution, updates the internal state and launches another command,
1719  * if necessary. If there is no need to launch another command, reads the
1720  * verification status.
1721  *
1722  * END**************************************************************************/
1724 {
1725  /* Read the status of the execution */
1726  g_csecStatePtr->errCode = CSEC_ReadErrorBits();
1727  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1728  {
1729  /* Do not continue launching commands if an error occurred */
1730  g_csecStatePtr->cmdInProgress = false;
1731  return;
1732  }
1733 
1734  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1735  {
1736  g_csecStatePtr->seq = CSEC_CALL_SEQ_SUBSEQUENT;
1737  }
1738 
1739  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1740 
1741  /* Decide if more commands are needed */
1742  g_csecStatePtr->cmdInProgress = !g_csecStatePtr->macWritten;
1743 
1744  if (!g_csecStatePtr->cmdInProgress)
1745  {
1746  *(g_csecStatePtr->verifStatus) = (CSEC_ReadCommandHalfWord(FEATURE_CSEC_VERIFICATION_STATUS_OFFSET) == 0U);
1747  }
1748  else
1749  {
1750  /* Continue launching commands */
1752  }
1753 }
1754 
1755 /*FUNCTION**********************************************************************
1756  *
1757  * Function Name : CSEC_DRV_InstallCallback
1758  * Description : Installs a callback function which will be invoked when an
1759  * asynchronous command finishes its execution.
1760  *
1761  * Implements : CSEC_DRV_InstallCallback_Activity
1762  * END**************************************************************************/
1763 void CSEC_DRV_InstallCallback(security_callback_t callbackFunc, void *callbackParam)
1764 {
1765  DEV_ASSERT(g_csecStatePtr != NULL);
1766 
1767  g_csecStatePtr->callback = callbackFunc;
1768  g_csecStatePtr->callbackParam = callbackParam;
1769 }
1770 
1771 /*FUNCTION**********************************************************************
1772  *
1773  * Function Name : CSEC_DRV_CancelCommand
1774  * Description : Cancels a previously launched asynchronous command.
1775  *
1776  * Implements : CSEC_DRV_CancelCommand_Activity
1777  * END**************************************************************************/
1779 {
1780  DEV_ASSERT(g_csecStatePtr != NULL);
1781 
1782  if (g_csecStatePtr->cmdInProgress)
1783  {
1784  CSEC_SetInterrupt(false);
1785 
1786  /* Wait until the execution of the previous command is complete */
1787  CSEC_WaitCommandCompletion();
1788 
1789  if ((g_csecStatePtr->cmd != CSEC_CMD_ENC_ECB) && (g_csecStatePtr->cmd != CSEC_CMD_DEC_ECB))
1790  {
1791  /* Was there any command already launched? If so, break the sequence */
1792  if (g_csecStatePtr->fullSize != g_csecStatePtr->partSize)
1793  {
1794  /* Write the command header. CallSeq is set to 0 in order to trigger a command
1795  * that will generate a sequence error, breaking the chain of calls. */
1796  CSEC_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, CSEC_CALL_SEQ_FIRST, g_csecStatePtr->keyId);
1797 
1798  /* Wait until the execution of the command is complete */
1799  CSEC_WaitCommandCompletion();
1800  }
1801  }
1802 
1803  g_csecStatePtr->cmdInProgress = false;
1804  }
1805 }
1806 
1807 /******************************************************************************
1808  * EOF
1809  *****************************************************************************/
status_t CSEC_DRV_LoadPlainKey(const uint8_t *plainKey)
Updates the RAM key memory slot with a 128-bit plaintext.
Definition: csec_driver.c:657
status_t CSEC_DRV_GetAsyncCmdStatus()
Checks the status of the execution of an asynchronous command.
Definition: csec_driver.c:1388
#define FEATURE_CSEC_FLASH_START_ADDRESS_OFFSET
CSE_PRAM offset of the Flash start address parameter used by the following commands: CMD_GENERATE_MAC...
bool cmdInProgress
Definition: csec_driver.h:187
#define CSEC_DATA_PAGES_AVAILABLE
Definition: csec_driver.c:69
static void CSEC_DRV_ContinueEncDecECBCmd(void)
Definition: csec_driver.c:1600
static void CSEC_DRV_ContinueEncDecCBCCmd(void)
Definition: csec_driver.c:1636
security_callback_t callback
Definition: csec_driver.h:203
#define CSEC_M3_SIZE_IN_BYTES
Definition: csec_driver.c:84
void CSEC_DRV_InstallCallback(security_callback_t callbackFunc, void *callbackParam)
Installs a callback function which will be invoked when an asynchronous command finishes its executio...
Definition: csec_driver.c:1763
#define FEATURE_CSEC_PAGE_5_OFFSET
CSE_PRAM offset of page 5.
void OSIF_TimeDelay(const uint32_t delay)
Delays execution for a number of milliseconds.
status_t CSEC_DRV_GetID(const uint8_t *challenge, uint8_t *uid, uint8_t *sreg, uint8_t *mac)
Returns the identity (UID) and the value of the status register protected by a MAC over a challenge a...
Definition: csec_driver.c:968
Internal driver state information.
Definition: csec_driver.h:186
static void CSEC_DRV_StartEncDecECBCmd(void)
Definition: csec_driver.c:1480
#define FTFC_FSTAT_CCIF_MASK
Definition: S32K118.h:3682
#define CSEC_BYTES_TO_FROM_PAGES_SHIFT
Definition: csec_driver.c:75
status_t CSEC_DRV_DecryptCBC(csec_key_id_t keyId, const uint8_t *cipherText, uint32_t length, const uint8_t *iv, uint8_t *plainText, uint32_t timeout)
Performs the AES-128 decryption in CBC mode.
Definition: csec_driver.c:330
void CSEC_DRV_Init(csec_state_t *state)
Initializes the internal state of the driver and enables the FTFC interrupt.
Definition: csec_driver.c:134
status_t CSEC_DRV_DbgAuth(const uint8_t *authorization)
Erases all keys (actual and outdated) stored in NVM Memory if the authorization is confirmed by CSEc...
Definition: csec_driver.c:1060
status_t CSEC_DRV_VerifyMACAsync(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, const uint8_t *mac, uint16_t macLen, bool *verifStatus)
Asynchronously verifies the MAC of a given message using CMAC with AES-128.
Definition: csec_driver.c:1348
#define CSEC_M1_SIZE_IN_BYTES
Definition: csec_driver.c:80
csec_key_id_t
Specify the KeyID to be used to implement the requested cryptographic operation.
Definition: csec_driver.h:100
csec_key_id_t keyId
Definition: csec_driver.h:194
status_t CSEC_DRV_BootOK()
Marks a successful boot verification during later stages of the boot process.
Definition: csec_driver.c:895
#define FEATURE_CSEC_VERIFICATION_STATUS_OFFSET
CSE_PRAM offset of the verification status parameter used by the following commands: CMD_VERIFY_MAC (...
uint32_t OSIF_GetMilliseconds(void)
Returns the number of miliseconds elapsed since starting the internal timer or starting the scheduler...
#define CSEC_BYTES_TO_FROM_BITS_SHIFT
Definition: csec_driver.c:77
status_t CSEC_DRV_EncryptCBCAsync(csec_key_id_t keyId, const uint8_t *plainText, uint32_t length, const uint8_t *iv, uint8_t *cipherText)
Asynchronously performs the AES-128 encryption in CBC mode.
Definition: csec_driver.c:1245
status_t CSEC_DRV_VerifyMAC(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, const uint8_t *mac, uint16_t macLen, bool *verifStatus, uint32_t timeout)
Verifies the MAC of a given message using CMAC with AES-128.
Definition: csec_driver.c:487
status_t CSEC_DRV_VerifyMACAddrMode(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, const uint8_t *mac, uint16_t macLen, bool *verifStatus)
Verifies the MAC of a given message (located in Flash) using CMAC with AES-128.
Definition: csec_driver.c:550
status_t CSEC_DRV_InitRNG()
Initializes the seed and derives a key for the PRNG.
Definition: csec_driver.c:746
const uint8_t * iv
Definition: csec_driver.h:196
static void CSEC_DRV_StartVerifMACCmd(void)
Definition: csec_driver.c:1565
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
#define CSEC_M2_SIZE_IN_BYTES
Definition: csec_driver.c:82
#define CSEC_DATA_BYTES_AVAILABLE
Definition: csec_driver.c:72
status_t CSEC_DRV_ExtendSeed(const uint8_t *entropy)
Extends the seed of the PRNG.
Definition: csec_driver.c:783
static void CSEC_DRV_StartEncDecCBCCmd(void)
Definition: csec_driver.c:1504
#define FEATURE_CSEC_PAGE_7_OFFSET
CSE_PRAM offset of page 7.
#define DEV_ASSERT(x)
Definition: devassert.h:77
#define FEATURE_CSEC_PAGE_LENGTH_OFFSET
CSE_PRAM offset of the page length parameter used by the following commands: CMD_ENC_ECB, CMD_ENC_CBC, CMD_DEC_ECB, CMD_DEC_CBC, CMD_MP_COMPRESS.
status_t CSEC_DRV_EncryptECB(csec_key_id_t keyId, const uint8_t *plainText, uint32_t length, uint8_t *cipherText, uint32_t timeout)
Performs the AES-128 encryption in ECB mode.
Definition: csec_driver.c:169
status_t CSEC_DRV_BootFailure()
Signals a failure detected during later stages of the boot process.
Definition: csec_driver.c:861
status_t CSEC_DRV_DecryptECBAsync(csec_key_id_t keyId, const uint8_t *cipherText, uint32_t length, uint8_t *plainText)
Asynchronously performs the AES-128 decryption in ECB mode.
Definition: csec_driver.c:1213
static void CSEC_DRV_InitState(csec_key_id_t keyId, csec_cmd_t cmd, const uint8_t *inBuff, uint8_t *outBuff, uint32_t length)
Definition: csec_driver.c:1408
bool * verifStatus
Definition: csec_driver.h:199
#define FEATURE_CSEC_PAGE_3_OFFSET
CSE_PRAM offset of page 3.
csec_cmd_t cmd
Definition: csec_driver.h:188
status_t CSEC_DRV_EncryptECBAsync(csec_key_id_t keyId, const uint8_t *plainText, uint32_t length, uint8_t *cipherText)
Asynchronously performs the AES-128 encryption in ECB mode.
Definition: csec_driver.c:1181
uint32_t partSize
Definition: csec_driver.h:193
#define FEATURE_CSEC_BOOT_SIZE_OFFSET
CSE_PRAM offset of the boot size parameter used by the following commands: CMD_BOOT_DEFINE.
status_t CSEC_DRV_DecryptECB(csec_key_id_t keyId, const uint8_t *cipherText, uint32_t length, uint8_t *plainText, uint32_t timeout)
Performs the AES-128 decryption in ECB mode.
Definition: csec_driver.c:222
uint32_t msgLen
Definition: csec_driver.h:198
#define CSEC_PAGE_SIZE_IN_BYTES
Definition: csec_driver.c:65
uint8_t * outputBuff
Definition: csec_driver.h:190
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:44
#define FEATURE_CSEC_MAC_LENGTH_OFFSET
CSE_PRAM offset of the MAC length parameter used by the following commands: CMD_VERIFY_MAC (both copy...
void(* security_callback_t)(uint32_t completedCmd, void *callbackParam)
Callback for security modules.
Definition: callbacks.h:168
status_t CSEC_DRV_EncryptCBC(csec_key_id_t keyId, const uint8_t *plainText, uint32_t length, const uint8_t *iv, uint8_t *cipherText, uint32_t timeout)
Performs the AES-128 encryption in CBC mode.
Definition: csec_driver.c:274
#define FTFC
Definition: S32K118.h:3641
status_t CSEC_DRV_GenerateMACAddrMode(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, uint8_t *cmac)
Calculates the MAC of a given message (located in Flash) using CMAC with AES-128. ...
Definition: csec_driver.c:442
static void CSEC_DRV_ContinueVerifMACCmd(void)
Definition: csec_driver.c:1723
void FTFC_IRQHandler(void)
Definition: csec_driver.c:1432
static void CSEC_DRV_ContinueGenMACCmd(void)
Definition: csec_driver.c:1683
void CSEC_DRV_Deinit()
Clears the internal state of the driver and disables the FTFC interrupt.
Definition: csec_driver.c:154
status_t errCode
Definition: csec_driver.h:195
#define FEATURE_CSEC_PAGE_4_OFFSET
CSE_PRAM offset of page 4.
status_t CSEC_DRV_LoadKey(csec_key_id_t keyId, const uint8_t *m1, const uint8_t *m2, const uint8_t *m3, uint8_t *m4, uint8_t *m5)
Updates an internal key per the SHE specification.
Definition: csec_driver.c:603
uint32_t macLen
Definition: csec_driver.h:202
#define FEATURE_CSEC_BOOT_FLAVOR_OFFSET
CSE_PRAM offset of the boot flavor parameter used by the following commands: CMD_BOOT_DEFINE.
uint32_t index
Definition: csec_driver.h:191
status_t CSEC_DRV_MPCompress(const uint8_t *msg, uint16_t msgLen, uint8_t *mpCompress, uint32_t timeout)
Compresses the given messages by accessing the Miyaguchi-Prenell compression feature with in the CSEc...
Definition: csec_driver.c:1097
void CSEC_DRV_CancelCommand(void)
Cancels a previously launched asynchronous command.
Definition: csec_driver.c:1778
csec_boot_flavor_t
Specifies the boot type for the BOOT_DEFINE command.
Definition: csec_driver.h:170
const uint8_t * mac
Definition: csec_driver.h:201
status_t CSEC_DRV_DecryptCBCAsync(csec_key_id_t keyId, const uint8_t *cipherText, uint32_t length, const uint8_t *iv, uint8_t *plainText)
Asynchronously performs the AES-128 decryption in CBC mode.
Definition: csec_driver.c:1280
csec_call_sequence_t
Specifies if the information is the first or a following function call.
Definition: csec_driver.h:160
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
csec_cmd_t
CSEc commands which follow the same values as the SHE command definition.
Definition: csec_driver.h:130
csec_call_sequence_t seq
Definition: csec_driver.h:197
status_t CSEC_DRV_ExportRAMKey(uint8_t *m1, uint8_t *m2, uint8_t *m3, uint8_t *m4, uint8_t *m5)
Exports the RAM_KEY into a format protected by SECRET_KEY.
Definition: csec_driver.c:694
status_t CSEC_DRV_GenerateRND(uint8_t *rnd)
Generates a vector of 128 random bits.
Definition: csec_driver.c:821
#define FEATURE_CSEC_SREG_OFFSET
CSE_PRAM offset of the SREG parameter used by the following commands: CMD_GET_ID. ...
#define FEATURE_CSEC_PAGE_1_OFFSET
CSE_PRAM offset of page 1.
#define CSEC_M4_SIZE_IN_BYTES
Definition: csec_driver.c:86
uint32_t fullSize
Definition: csec_driver.h:192
status_t CSEC_DRV_GenerateMAC(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, uint8_t *cmac, uint32_t timeout)
Calculates the MAC of a given message using CMAC with AES-128.
Definition: csec_driver.c:386
static uint32_t CSEC_DRV_RoundTo(uint32_t value, uint32_t roundTo)
Definition: csec_driver.c:107
#define FEATURE_CSEC_MESSAGE_LENGTH_OFFSET
CSE_PRAM offset of the message length parameter used by the following commands: CMD_GENERATE_MAC, CMD_VERIFY_MAC (both copy and pointer methods)
const uint8_t * inputBuff
Definition: csec_driver.h:189
status_t CSEC_DRV_DbgChal(uint8_t *challenge)
Obtains a random number which the user shall use along with the MASTER_ECU_KEY and UID to return an a...
Definition: csec_driver.c:1020
void * callbackParam
Definition: csec_driver.h:204
static csec_state_t * g_csecStatePtr
Definition: csec_driver.c:91
static void CSEC_DRV_StartGenMACCmd(void)
Definition: csec_driver.c:1542
#define FEATURE_CSEC_PAGE_2_OFFSET
CSE_PRAM offset of page 2.
#define CSEC_M5_SIZE_IN_BYTES
Definition: csec_driver.c:88
status_t CSEC_DRV_BootDefine(uint32_t bootSize, csec_boot_flavor_t bootFlavor)
Implements an extension of the SHE standard to define both the user boot size and boot method...
Definition: csec_driver.c:929
status_t CSEC_DRV_GenerateMACAsync(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, uint8_t *cmac)
Asynchronously calculates the MAC of a given message using CMAC with AES-128.
Definition: csec_driver.c:1315