S32 SDK
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 
58 /*******************************************************************************
59  * Definitions
60  ******************************************************************************/
61 
62 /* Represents the size of a CSE_PRAM page in bytes */
63 #define CSEC_PAGE_SIZE_IN_BYTES (16U)
64 
65 /* Represents the number of CSE_PRAM pages available for data (excluding the
66 first page, used for command header) */
67 #define CSEC_DATA_PAGES_AVAILABLE (7U)
68 /* Represents the number of bytes in CSE_PRAM available for data (excluding the
69 first page, used for command header) */
70 #define CSEC_DATA_BYTES_AVAILABLE (112U)
71 
72 /* Represents the shift used for converting CSE_PRAM pages number to/from bytes number */
73 #define CSEC_BYTES_TO_FROM_PAGES_SHIFT (4U)
74 /* Represents the shift used for converting CSE_PRAM pages number to/from bits number */
75 #define CSEC_BYTES_TO_FROM_BITS_SHIFT (3U)
76 
77 /* Represents the size in bytes of the M1 entry (used for key management) */
78 #define CSEC_M1_SIZE_IN_BYTES (16U)
79 /* Represents the size in bytes of the M2 entry (used for key management) */
80 #define CSEC_M2_SIZE_IN_BYTES (32U)
81 /* Represents the size in bytes of the M3 entry (used for key management) */
82 #define CSEC_M3_SIZE_IN_BYTES (16U)
83 /* Represents the size in bytes of the M4 entry (used for key management) */
84 #define CSEC_M4_SIZE_IN_BYTES (32U)
85 /* Represents the size in bytes of the M5 entry (used for key management) */
86 #define CSEC_M5_SIZE_IN_BYTES (16U)
87 
88 /* Pointer to runtime state structure.*/
89 static csec_state_t * g_csecStatePtr = NULL;
90 
91 /* The FTFC interrupt handler, used when a CSEc command is completed. */
92 void FTFC_IRQHandler(void);
93 
94 /*******************************************************************************
95  * Private Functions
96  ******************************************************************************/
97 
98 static void CSEC_DRV_InitState(csec_key_id_t keyId,
99  csec_cmd_t cmd,
100  const uint8_t * inBuff,
101  uint8_t * outBuff,
102  uint32_t length);
103 
104 /* Rounds up the value to the first number multiple of roundTo */
105 static inline uint32_t CSEC_DRV_RoundTo(uint32_t value,
106  uint32_t roundTo)
107 {
108  return (value + (roundTo - 1U)) & ~(roundTo - 1U);
109 }
110 
111 static void CSEC_DRV_StartEncDecECBCmd(void);
112 static void CSEC_DRV_ContinueEncDecECBCmd(void);
113 static void CSEC_DRV_StartEncDecCBCCmd(void);
114 static void CSEC_DRV_ContinueEncDecCBCCmd(void);
115 static void CSEC_DRV_StartGenMACCmd(void);
116 static void CSEC_DRV_ContinueGenMACCmd(void);
117 static void CSEC_DRV_StartVerifMACCmd(void);
118 static void CSEC_DRV_ContinueVerifMACCmd(void);
119 
120 /*******************************************************************************
121  * Code
122  ******************************************************************************/
123 
124 /*FUNCTION**********************************************************************
125  *
126  * Function Name : CSEC_DRV_Init
127  * Description : This function initializes the internal state of the driver
128  * and enables the FTFC interrupt.
129  *
130  * Implements : CSEC_DRV_Init_Activity
131  * END**************************************************************************/
133 {
134  DEV_ASSERT(state != NULL);
135 
136  g_csecStatePtr = state;
137  g_csecStatePtr->cmdInProgress = false;
138 
140 }
141 
142 /*FUNCTION**********************************************************************
143  *
144  * Function Name : CSEC_DRV_Deinit
145  * Description : This function clears the internal state of the driver and
146  * disables the FTFC interrupt.
147  *
148  * Implements : CSEC_DRV_Deinit_Activity
149  * END**************************************************************************/
151 {
152  g_csecStatePtr = NULL;
153 
155 }
156 
157 /*FUNCTION**********************************************************************
158  *
159  * Function Name : CSEC_DRV_EncryptECB
160  * Description : This function performs the AES-128 encryption in ECB mode of
161  * the input plain text buffer.
162  *
163  * Implements : CSEC_DRV_EncryptECB_Activity
164  * END**************************************************************************/
166  const uint8_t * plainText,
167  uint32_t length,
168  uint8_t * cipherText)
169 {
170  DEV_ASSERT(plainText != NULL);
171  DEV_ASSERT(cipherText != NULL);
172 
173  if (g_csecStatePtr->cmdInProgress)
174  {
175  return STATUS_BUSY;
176  }
177 
178  /* Initialize the internal state of the driver */
179  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_ECB, plainText, cipherText, length);
180 
182 
183  while (g_csecStatePtr->cmdInProgress)
184  {
185  /* Wait until the execution of the command is complete */
187 
189  }
190 
191  return g_csecStatePtr->errCode;
192 }
193 
194 /*FUNCTION**********************************************************************
195  *
196  * Function Name : CSEC_DRV_DecryptECB
197  * Description : This function performs the AES-128 decryption in ECB mode of
198  * the input cipher text buffer.
199  *
200  * Implements : CSEC_DRV_DecryptECB_Activity
201  * END**************************************************************************/
203  const uint8_t * cipherText,
204  uint32_t length,
205  uint8_t * plainText)
206 {
207  DEV_ASSERT(plainText != NULL);
208  DEV_ASSERT(cipherText != NULL);
209 
210  if (g_csecStatePtr->cmdInProgress)
211  {
212  return STATUS_BUSY;
213  }
214  /* Initialize the internal state of the driver */
215  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_ECB, cipherText, plainText, length);
216 
218 
219  while (g_csecStatePtr->cmdInProgress)
220  {
221  /* Wait until the execution of the command is complete */
223 
225  }
226 
227  return g_csecStatePtr->errCode;
228 }
229 
230 /*FUNCTION**********************************************************************
231  *
232  * Function Name : CSEC_DRV_EncryptCBC
233  * Description : This function performs the AES-128 encryption in CBC mode of
234  * the input cipher text buffer.
235  *
236  * Implements : CSEC_DRV_EncryptCBC_Activity
237  * END**************************************************************************/
239  const uint8_t * plainText,
240  uint32_t length,
241  const uint8_t * iv,
242  uint8_t * cipherText)
243 {
244  DEV_ASSERT(plainText != NULL);
245  DEV_ASSERT(cipherText != NULL);
246  DEV_ASSERT(iv != NULL);
247 
248  if (g_csecStatePtr->cmdInProgress)
249  {
250  return STATUS_BUSY;
251  }
252 
253  /* Initialize the internal state of the driver */
254  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_CBC, plainText, cipherText, length);
255  g_csecStatePtr->iv = iv;
256 
258 
259  while (g_csecStatePtr->cmdInProgress)
260  {
261  /* Wait until the execution of the command is complete */
263 
265  }
266 
267  return g_csecStatePtr->errCode;
268 }
269 
270 /*FUNCTION**********************************************************************
271  *
272  * Function Name : CSEC_DRV_DecryptCBC
273  * Description : This function performs the AES-128 decryption in CBC mode of
274  * the input cipher text buffer.
275  *
276  * Implements : CSEC_DRV_DecryptCBC_Activity
277  * END**************************************************************************/
279  const uint8_t * cipherText,
280  uint16_t length,
281  const uint8_t * iv,
282  uint8_t * plainText)
283 {
284  DEV_ASSERT(plainText != NULL);
285  DEV_ASSERT(cipherText != NULL);
286  DEV_ASSERT(iv != NULL);
287 
288  if (g_csecStatePtr->cmdInProgress)
289  {
290  return STATUS_BUSY;
291  }
292 
293  /* Initialize the internal state of the driver */
294  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_CBC, cipherText, plainText, length);
295  g_csecStatePtr->iv = iv;
296 
298 
299  while (g_csecStatePtr->cmdInProgress)
300  {
301  /* Wait until the execution of the command is complete */
303 
305  }
306 
307  return g_csecStatePtr->errCode;
308 }
309 
310 /*FUNCTION**********************************************************************
311  *
312  * Function Name : CSEC_DRV_GenerateMAC
313  * Description : This function calculates the MAC of a given message using
314  * CMAC with AES-128.
315  *
316  * Implements : CSEC_DRV_GenerateMAC_Activity
317  * END**************************************************************************/
319  const uint8_t * msg,
320  uint32_t msgLen,
321  uint8_t * cmac)
322 {
323  DEV_ASSERT(msg != NULL);
324  DEV_ASSERT(cmac != NULL);
325 
326  if (g_csecStatePtr->cmdInProgress)
327  {
328  return STATUS_BUSY;
329  }
330 
331  /* Initialize the internal state of the driver */
333  g_csecStatePtr->msgLen = msgLen;
334 
336 
337  while (g_csecStatePtr->cmdInProgress)
338  {
339  /* Wait until the execution of the command is complete */
341 
343  }
344 
345  return g_csecStatePtr->errCode;
346 }
347 
348 /*FUNCTION**********************************************************************
349  *
350  * Function Name : CSEC_DRV_GenerateMACAddrMode
351  * Description : This function calculates the MAC of a given message using
352  * CMAC with AES-128. It is different from the CSEC_DRV_GenerateMAC function in
353  * the sense that it does not involve an extra copy of the data on which the
354  * CMAC is computed and the message pointer should be a pointer to Flash memory.
355  *
356  * Implements : CSEC_DRV_GenerateMACAddrMode_Activity
357  * END**************************************************************************/
359  const uint8_t * msg,
360  uint32_t msgLen,
361  uint8_t * cmac)
362 {
363  status_t stat;
364 
365  DEV_ASSERT(msg != NULL);
366  DEV_ASSERT(cmac != NULL);
367 
368  if (g_csecStatePtr->cmdInProgress)
369  {
370  return STATUS_BUSY;
371  }
372  g_csecStatePtr->cmdInProgress = true;
373 
374  /* Write the address of the message */
376  /* Write the size of the message (in bits) */
378  /* Write the command header. This will trigger the command execution. */
380 
381  /* Read the status of the execution */
382  stat = CSEC_HAL_ReadErrorBits();
383  /* Read the resulted MAC */
384  if (stat == STATUS_SUCCESS)
385  {
387  }
388 
389  g_csecStatePtr->cmdInProgress = false;
390 
391  return stat;
392 }
393 
394 /*FUNCTION**********************************************************************
395  *
396  * Function Name : CSEC_DRV_VerifyMAC
397  * Description : This function verifies the MAC of a given message using CMAC
398  * with AES-128.
399  *
400  * Implements : CSEC_DRV_VerifyMAC_Activity
401  * END**************************************************************************/
403  const uint8_t * msg,
404  uint32_t msgLen,
405  const uint8_t * mac,
406  uint16_t macLen,
407  bool * verifStatus)
408 {
409  DEV_ASSERT(msg != NULL);
410  DEV_ASSERT(mac != NULL);
411  DEV_ASSERT(verifStatus != NULL);
412 
413  if (g_csecStatePtr->cmdInProgress)
414  {
415  return STATUS_BUSY;
416  }
417 
418  /* Initialize the internal state of the driver */
420  g_csecStatePtr->msgLen = msgLen;
421  g_csecStatePtr->verifStatus = verifStatus;
422  g_csecStatePtr->macWritten = false;
423  g_csecStatePtr->mac = mac;
424  g_csecStatePtr->macLen = macLen;
425 
427 
428  while (g_csecStatePtr->cmdInProgress)
429  {
430  /* Wait until the execution of the command is complete */
432 
434  }
435 
436  return g_csecStatePtr->errCode;
437 }
438 
439 /*FUNCTION**********************************************************************
440  *
441  * Function Name : CSEC_DRV_VerifyMACAddrMode
442  * Description : This function verifies the MAC of a given message using CMAC
443  * with AES-128. It is different from the CSEC_DRV_VerifyMAC function in the
444  * sense that it does not involve an extra copy of the data on which the CMAC is
445  * computed and the message pointer should be a pointer to Flash memory.
446  *
447  * Implements : CSEC_DRV_VerifyMACAddrMode_Activity
448  * END**************************************************************************/
450  const uint8_t * msg,
451  uint32_t msgLen,
452  const uint8_t * mac,
453  uint16_t macLen,
454  bool * verifStatus)
455 {
456  status_t stat;
457 
458  DEV_ASSERT(msg != NULL);
459  DEV_ASSERT(mac != NULL);
460  DEV_ASSERT(verifStatus != NULL);
461 
462  if (g_csecStatePtr->cmdInProgress)
463  {
464  return STATUS_BUSY;
465  }
466  g_csecStatePtr->cmdInProgress = true;
467 
468  /* Write the address of the message */
470  /* Write the MAC to be verified */
472  /* Write the size of the message (in bits) */
474  /* Write the number of bits of the MAC to be compared */
476  /* Write the command header. This will trigger the command execution. */
478 
479  /* Read the status of the execution */
480  stat = CSEC_HAL_ReadErrorBits();
481 
482  /* Read the result of the MAC verification */
483  if (stat == STATUS_SUCCESS)
484  {
486  }
487 
488  g_csecStatePtr->cmdInProgress = false;
489 
490  return stat;
491 }
492 
493 /*FUNCTION**********************************************************************
494  *
495  * Function Name : CSEC_DRV_LoadKey
496  * Description : This function updates an internal key per the SHE
497  * specification.
498  *
499  * Implements : CSEC_DRV_LoadKey_Activity
500  * END**************************************************************************/
502  const uint8_t * m1,
503  const uint8_t * m2,
504  const uint8_t * m3,
505  uint8_t * m4,
506  uint8_t * m5)
507 {
508  status_t stat;
509 
510  DEV_ASSERT(m1 != NULL);
511  DEV_ASSERT(m2 != NULL);
512  DEV_ASSERT(m3 != NULL);
513  DEV_ASSERT(m4 != NULL);
514  DEV_ASSERT(m5 != NULL);
515 
516  if (g_csecStatePtr->cmdInProgress)
517  {
518  return STATUS_BUSY;
519  }
520  g_csecStatePtr->cmdInProgress = true;
521 
522  /* Write the values of M1-M3 */
526  /* Write the command header. This will trigger the command execution. */
528 
529  /* Wait until the execution of the command is complete */
531 
532  /* Read the status of the execution */
533  stat = CSEC_HAL_ReadErrorBits();
534 
535  /* Read the obtained M4 and M5 */
536  if (stat == STATUS_SUCCESS)
537  {
540  }
541 
542  g_csecStatePtr->cmdInProgress = false;
543 
544  return stat;
545 }
546 
547 /*FUNCTION**********************************************************************
548  *
549  * Function Name : CSEC_DRV_LoadPlainKey
550  * Description : Updates the RAM key memory slot with a 128-bit plaintext.
551  *
552  * Implements : CSEC_DRV_LoadPlainKey_Activity
553  * END**************************************************************************/
554 status_t CSEC_DRV_LoadPlainKey(const uint8_t * plainKey)
555 {
556  status_t stat;
557 
558  DEV_ASSERT(plainKey != NULL);
559 
560  if (g_csecStatePtr->cmdInProgress)
561  {
562  return STATUS_BUSY;
563  }
564  g_csecStatePtr->cmdInProgress = true;
565 
566  /* Write the bytes of the key */
568  /* Write the command header. This will trigger the command execution. */
570 
571  /* Wait until the execution of the command is complete */
573 
574  /* Read the status of the execution */
575  stat = CSEC_HAL_ReadErrorBits();
576 
577  g_csecStatePtr->cmdInProgress = false;
578 
579  return stat;
580 }
581 
582 /*FUNCTION**********************************************************************
583  *
584  * Function Name : CSEC_DRV_ExportRAMKey
585  * Description : This function exports the RAM_KEY into a format protected by
586  * SECRET_KEY.
587  *
588  * Implements : CSEC_DRV_ExportRAMKey_Activity
589  * END**************************************************************************/
591  uint8_t * m2,
592  uint8_t * m3,
593  uint8_t * m4,
594  uint8_t * m5)
595 {
596  status_t stat;
597 
598  DEV_ASSERT(m1 != NULL);
599  DEV_ASSERT(m2 != NULL);
600  DEV_ASSERT(m3 != NULL);
601  DEV_ASSERT(m4 != NULL);
602  DEV_ASSERT(m5 != NULL);
603 
604  if (g_csecStatePtr->cmdInProgress)
605  {
606  return STATUS_BUSY;
607  }
608  g_csecStatePtr->cmdInProgress = true;
609 
610  /* Write the command header. This will trigger the command execution. */
612 
613  /* Wait until the execution of the command is complete */
615 
616  /* Read the status of the execution */
617  stat = CSEC_HAL_ReadErrorBits();
618  if (stat == STATUS_SUCCESS)
619  {
620  /* Read the M1-M5 values associated with the key */
626  }
627 
628  g_csecStatePtr->cmdInProgress = false;
629 
630  return stat;
631 }
632 
633 /*FUNCTION**********************************************************************
634  *
635  * Function Name : CSEC_DRV_InitRNG
636  * Description : The function initializes the seed and derives a key for the
637  * PRNG. The function must be called before CMD_RND after every power cycle/reset.
638  *
639  * Implements : CSEC_DRV_InitRNG_Activity
640  * END**************************************************************************/
642 {
643  status_t stat;
644 
645  if (g_csecStatePtr->cmdInProgress)
646  {
647  return STATUS_BUSY;
648  }
649  g_csecStatePtr->cmdInProgress = true;
650 
651  /* Write the command header. This will trigger the command execution. */
653 
654  /* Wait until the execution of the command is complete */
656 
657  /* Read the status of the execution */
658  stat = CSEC_HAL_ReadErrorBits();
659 
660  g_csecStatePtr->cmdInProgress = false;
661 
662  return stat;
663 }
664 
665 /*FUNCTION**********************************************************************
666  *
667  * Function Name : CSEC_DRV_ExtendSeed
668  * Description : Extends the seed of the PRNG by compressing the former seed
669  * value and the supplied entropy into a new seed. This new seed is then to be
670  * used to generate a random number by invoking the CMD_RND command. The random
671  * number generator must be initialized by CMD_INIT_RNG before the seed may be
672  * extended.
673  *
674  * Implements : CSEC_DRV_ExtendSeed_Activity
675  * END**************************************************************************/
676 status_t CSEC_DRV_ExtendSeed(const uint8_t * entropy)
677 {
678  status_t stat;
679 
680  DEV_ASSERT(entropy != NULL);
681 
682  if (g_csecStatePtr->cmdInProgress)
683  {
684  return STATUS_BUSY;
685  }
686  g_csecStatePtr->cmdInProgress = true;
687 
688  /* Write the entropy parameter */
690  /* Write the command header. This will trigger the command execution. */
692 
693  /* Wait until the execution of the command is complete */
695 
696  /* Read the status of the execution */
697  stat = CSEC_HAL_ReadErrorBits();
698 
699  g_csecStatePtr->cmdInProgress = false;
700 
701  return stat;
702 }
703 
704 /*FUNCTION**********************************************************************
705  *
706  * Function Name : CSEC_DRV_GenerateRND
707  * Description : The function returns a vector of 128 random bits. The random
708  * number generator has to be initialized by calling CSEC_DRV_InitRNG before
709  * random numbers can be supplied.
710  *
711  * Implements : CSEC_DRV_GenerateRND_Activity
712  * END**************************************************************************/
714 {
715  status_t stat;
716 
717  DEV_ASSERT(rnd != NULL);
718 
719  if (g_csecStatePtr->cmdInProgress)
720  {
721  return STATUS_BUSY;
722  }
723  g_csecStatePtr->cmdInProgress = true;
724 
725  /* Write the command header. This will trigger the command execution. */
727 
728  /* Wait until the execution of the command is complete */
730 
731  /* Read the status of the execution */
732  stat = CSEC_HAL_ReadErrorBits();
733  /* Read the resulted random bytes */
734  if (stat == STATUS_SUCCESS)
735  {
737  }
738 
739  g_csecStatePtr->cmdInProgress = false;
740 
741  return stat;
742 }
743 
744 /*FUNCTION**********************************************************************
745  *
746  * Function Name : CSEC_DRV_BootFailure
747  * Description : The function is called during later stages of the boot
748  * process to detect a failure.
749  *
750  * Implements : CSEC_DRV_BootFailure_Activity
751  * END**************************************************************************/
753 {
754  status_t stat;
755 
756  if (g_csecStatePtr->cmdInProgress)
757  {
758  return STATUS_BUSY;
759  }
760  g_csecStatePtr->cmdInProgress = true;
761 
762  /* Write the command header. This will trigger the command execution. */
764 
765  /* Wait until the execution of the command is complete */
767 
768  /* Read the status of the execution */
769  stat = CSEC_HAL_ReadErrorBits();
770 
771  g_csecStatePtr->cmdInProgress = false;
772 
773  return stat;
774 }
775 
776 /*FUNCTION**********************************************************************
777  *
778  * Function Name : CSEC_DRV_BootOK
779  * Description : The function is called during later stages of the boot
780  * process to mark successful boot verification.
781  *
782  * Implements : CSEC_DRV_BootOK_Activity
783  * END**************************************************************************/
785 {
786  status_t stat;
787 
788  if (g_csecStatePtr->cmdInProgress)
789  {
790  return STATUS_BUSY;
791  }
792  g_csecStatePtr->cmdInProgress = true;
793 
794  /* Write the command header. This will trigger the command execution. */
796 
797  /* Wait until the execution of the command is complete */
799 
800  /* Read the status of the execution */
801  stat = CSEC_HAL_ReadErrorBits();
802 
803  g_csecStatePtr->cmdInProgress = false;
804 
805  return stat;
806 }
807 
808 /*FUNCTION**********************************************************************
809  *
810  * Function Name : CSEC_DRV_BootDefine
811  * Description : The function implements an extension of the SHE standard to
812  * define both the user boot size and boot method.
813  *
814  * Implements : CSEC_DRV_BootDefine_Activity
815  * END**************************************************************************/
816 status_t CSEC_DRV_BootDefine(uint32_t bootSize,
817  csec_boot_flavor_t bootFlavor)
818 {
819  uint8_t flavor = (uint8_t)bootFlavor;
820  status_t stat;
821 
822  if (g_csecStatePtr->cmdInProgress)
823  {
824  return STATUS_BUSY;
825  }
826  g_csecStatePtr->cmdInProgress = true;
827 
828  /* Write the boot size and the boot flavor parameters */
831  /* Write the command header. This will trigger the command execution. */
833 
834  /* Wait until the execution of the command is complete */
836 
837  /* Read the status of the execution */
838  stat = CSEC_HAL_ReadErrorBits();
839 
840  g_csecStatePtr->cmdInProgress = false;
841 
842  return stat;
843 }
844 
845 /*FUNCTION**********************************************************************
846  *
847  * Function Name : CSEC_DRV_GetID
848  * Description : This function returns the identity (UID) and the value of the
849  * status register protected by a MAC over a challenge and the data.
850  *
851  * Implements : CSEC_DRV_GetID_Activity
852  * END**************************************************************************/
853 status_t CSEC_DRV_GetID(const uint8_t * challenge,
854  uint8_t * uid,
855  uint8_t * sreg,
856  uint8_t * mac)
857 {
858  status_t stat;
859 
860  DEV_ASSERT(challenge != NULL);
861  DEV_ASSERT(uid != NULL);
862  DEV_ASSERT(sreg != NULL);
863  DEV_ASSERT(mac != NULL);
864 
865  if (g_csecStatePtr->cmdInProgress)
866  {
867  return STATUS_BUSY;
868  }
869  g_csecStatePtr->cmdInProgress = true;
870 
871  /* Write the challenge */
873  /* Write the command header. This will trigger the command execution. */
875 
876  /* Wait until the execution of the command is complete */
878 
879  /* Read the status of the execution */
880  stat = CSEC_HAL_ReadErrorBits();
881  if (stat == STATUS_SUCCESS)
882  {
883  /* Read the UID */
885  /* Read the value of the SREG register */
887  /* Read the MAC over the UID and the SREG */
889  }
890 
891  g_csecStatePtr->cmdInProgress = false;
892 
893  return stat;
894 }
895 
896 /*FUNCTION**********************************************************************
897  *
898  * Function Name : CSEC_DRV_DbgChal
899  * Description : This function obtains a random number which the user shall
900  * use along with the MASTER_ECU_KEY and UID to return an authorization request.
901  *
902  * Implements : CSEC_DRV_DbgChal_Activity
903  * END**************************************************************************/
904 status_t CSEC_DRV_DbgChal(uint8_t * challenge)
905 {
906  status_t stat;
907 
908  DEV_ASSERT(challenge != NULL);
909 
910  if (g_csecStatePtr->cmdInProgress)
911  {
912  return STATUS_BUSY;
913  }
914  g_csecStatePtr->cmdInProgress = true;
915 
916  /* Write the command header. This will trigger the command execution. */
918 
919  /* Wait until the execution of the command is complete */
921 
922  /* Read the status of the execution */
923  stat = CSEC_HAL_ReadErrorBits();
924  /* Read the challenge generated by the CSEc module */
925  if (stat == STATUS_SUCCESS)
926  {
928  }
929 
930  g_csecStatePtr->cmdInProgress = false;
931 
932  return stat;
933 }
934 
935 /*FUNCTION**********************************************************************
936  *
937  * Function Name : CSEC_DRV_DbgAuth
938  * Description : This function erases all keys (actual and outdated) stored in
939  * NVM Memory if the authorization is confirmed by CSEc.
940  *
941  * Implements : CSEC_DRV_DbgAuth_Activity
942  * END**************************************************************************/
943 status_t CSEC_DRV_DbgAuth(const uint8_t * authorization)
944 {
945  status_t stat;
946 
947  DEV_ASSERT(authorization != NULL);
948 
949  if (g_csecStatePtr->cmdInProgress)
950  {
951  return STATUS_BUSY;
952  }
953  g_csecStatePtr->cmdInProgress = true;
954 
955  /* Write the authorization computed from the challenge */
957  /* Write the command header. This will trigger the command execution. */
959 
960  /* Wait until the execution of the command is complete */
962 
963  /* Read the status of the execution */
964  stat = CSEC_HAL_ReadErrorBits();
965 
966  g_csecStatePtr->cmdInProgress = false;
967 
968  return stat;
969 }
970 
971 /*FUNCTION**********************************************************************
972  *
973  * Function Name : CSEC_DRV_MPCompress
974  * Description : This function accesses a Miyaguchi-Prenell compression
975  * feature within the CSEc feature set to compress the given messages.
976  *
977  * Implements : CSEC_DRV_MPCompress_Activity
978  * END**************************************************************************/
979 status_t CSEC_DRV_MPCompress(const uint8_t * msg,
980  uint16_t msgLen,
981  uint8_t * mpCompress)
982 {
983  DEV_ASSERT(msg != NULL);
984  DEV_ASSERT(mpCompress != NULL);
985 
986  if (g_csecStatePtr->cmdInProgress)
987  {
988  return STATUS_BUSY;
989  }
990 
992  status_t stat = STATUS_SUCCESS;
993  uint32_t index = 0;
994  uint16_t numPagesLeft = msgLen;
995 
996  /* Loop and launch commands until the end of the message */
997  while (numPagesLeft > 0U)
998  {
999  uint8_t numPages = (uint8_t)((msgLen > CSEC_DATA_PAGES_AVAILABLE) ?
1000  CSEC_DATA_PAGES_AVAILABLE : msgLen);
1001  uint8_t numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1002 
1003  /* Write the message */
1005  /* Write the size of the message */
1007  /* Write the command header. This will trigger the command execution. */
1009 
1010  /* Wait until the execution of the command is complete */
1012 
1013  /* Read the status of the execution */
1014  stat = CSEC_HAL_ReadErrorBits();
1015  if (stat != STATUS_SUCCESS)
1016  {
1017  break;
1018  }
1019 
1020  numPagesLeft = (uint16_t)(numPagesLeft - numPages);
1021  index = (uint32_t)(index + numBytes);
1022  if (seq == CSEC_CALL_SEQ_FIRST)
1023  {
1025  }
1026  }
1027 
1028  /* Read the result of the compression */
1029  if (stat == STATUS_SUCCESS)
1030  {
1032  }
1033 
1034  return stat;
1035 }
1036 
1037 /*FUNCTION**********************************************************************
1038  *
1039  * Function Name : CSEC_DRV_EncryptECBAsync
1040  * Description : This function starts the AES-128 encryption in ECB mode of
1041  * the input plain text buffer, in an asynchronous manner.
1042  *
1043  * Implements : CSEC_DRV_EncryptECBAsync_Activity
1044  * END**************************************************************************/
1046  const uint8_t * plainText,
1047  uint32_t length,
1048  uint8_t * cipherText)
1049 {
1050  if (g_csecStatePtr->cmdInProgress)
1051  {
1052  return STATUS_BUSY;
1053  }
1054 
1055  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_ECB, plainText, cipherText, length);
1056 
1058 
1059  /* Enable interrupt */
1060  CSEC_HAL_SetInterrupt(true);
1061 
1062  return STATUS_SUCCESS;
1063 }
1064 
1065 /*FUNCTION**********************************************************************
1066  *
1067  * Function Name : CSEC_DRV_DecryptECBAsync
1068  * Description : This function starts the AES-128 decryption in ECB mode of
1069  * the input cipher text buffer, in an asynchronous manner.
1070  *
1071  * Implements : CSEC_DRV_DecryptECBAsync_Activity
1072  * END**************************************************************************/
1074  const uint8_t * cipherText,
1075  uint32_t length,
1076  uint8_t * plainText)
1077 {
1078  if (g_csecStatePtr->cmdInProgress)
1079  {
1080  return STATUS_BUSY;
1081  }
1082 
1083  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_ECB, cipherText, plainText, length);
1084 
1086 
1087  /* Enable interrupt */
1088  CSEC_HAL_SetInterrupt(true);
1089 
1090  return STATUS_SUCCESS;
1091 }
1092 
1093 /*FUNCTION**********************************************************************
1094  *
1095  * Function Name : CSEC_DRV_EncryptCBCAsync
1096  * Description : This function starts the AES-128 encryption in CBC mode of
1097  * the input cipher text buffer, in an asynchronous manner.
1098  *
1099  * Implements : CSEC_DRV_EncryptCBCAsync_Activity
1100  * END**************************************************************************/
1102  const uint8_t * cipherText,
1103  uint16_t length,
1104  const uint8_t * iv,
1105  uint8_t * plainText)
1106 {
1107  if (g_csecStatePtr->cmdInProgress)
1108  {
1109  return STATUS_BUSY;
1110  }
1111 
1112  CSEC_DRV_InitState(keyId, CSEC_CMD_ENC_CBC, cipherText, plainText, length);
1113  g_csecStatePtr->iv = iv;
1114 
1116 
1117  /* Enable interrupt */
1118  CSEC_HAL_SetInterrupt(true);
1119 
1120  return STATUS_SUCCESS;
1121 }
1122 
1123 /*FUNCTION**********************************************************************
1124  *
1125  * Function Name : CSEC_DRV_DecryptCBCAsync
1126  * Description : This function starts the AES-128 decryption in CBC mode of
1127  * the input cipher text buffer, in an asynchronous manner.
1128  *
1129  * Implements : CSEC_DRV_DecryptCBCAsync_Activity
1130  * END**************************************************************************/
1132  const uint8_t * cipherText,
1133  uint32_t length,
1134  const uint8_t * iv,
1135  uint8_t * plainText)
1136 {
1137  if (g_csecStatePtr->cmdInProgress)
1138  {
1139  return STATUS_BUSY;
1140  }
1141 
1142  CSEC_DRV_InitState(keyId, CSEC_CMD_DEC_CBC, cipherText, plainText, length);
1143  g_csecStatePtr->iv = iv;
1144 
1146 
1147  /* Enable interrupt */
1148  CSEC_HAL_SetInterrupt(true);
1149 
1150  return STATUS_SUCCESS;
1151 }
1152 
1153 /*FUNCTION**********************************************************************
1154  *
1155  * Function Name : CSEC_DRV_GenerateMACAsync
1156  * Description : This function starts the computation the MAC of a given
1157  * message using CMAC with AES-128, in an asynchronous manner.
1158  *
1159  * Implements : CSEC_DRV_GenerateMACAsync_Activity
1160  * END**************************************************************************/
1162  const uint8_t * msg,
1163  uint32_t msgLen,
1164  uint8_t * cmac)
1165 {
1166  if (g_csecStatePtr->cmdInProgress)
1167  {
1168  return STATUS_BUSY;
1169  }
1170 
1172  g_csecStatePtr->msgLen = msgLen;
1173 
1175 
1176  /* Enable interrupt */
1177  CSEC_HAL_SetInterrupt(true);
1178 
1179  return STATUS_SUCCESS;
1180 }
1181 
1182 /*FUNCTION**********************************************************************
1183  *
1184  * Function Name : CSEC_DRV_VerifyMACAsync
1185  * Description : This function starts the verification the MAC of a given
1186  * message using CMAC with AES-128, in an asynchronous manner.
1187  *
1188  * Implements : CSEC_DRV_VerifyMACAsync_Activity
1189  * END**************************************************************************/
1191  const uint8_t * msg,
1192  uint32_t msgLen,
1193  const uint8_t * mac,
1194  uint16_t macLen,
1195  bool * verifStatus)
1196 {
1197  if (g_csecStatePtr->cmdInProgress)
1198  {
1199  return STATUS_BUSY;
1200  }
1201 
1203  g_csecStatePtr->msgLen = msgLen;
1204  g_csecStatePtr->verifStatus = verifStatus;
1205  g_csecStatePtr->macWritten = false;
1206  g_csecStatePtr->mac = mac;
1207  g_csecStatePtr->macLen = macLen;
1208 
1210 
1211  /* Enable interrupt */
1212  CSEC_HAL_SetInterrupt(true);
1213 
1214  return STATUS_SUCCESS;
1215 }
1216 
1217 /*FUNCTION**********************************************************************
1218  *
1219  * Function Name : CSEC_DRV_GetAsyncCmdStatus
1220  * Description : This function checks the status of the execution of an
1221  * asynchronous command. If the command is still in progress, returns STATUS_BUSY.
1222  *
1223  * Implements : CSEC_DRV_GetAsyncCmdStatus_Activity
1224  * END**************************************************************************/
1226 {
1227  if (!g_csecStatePtr->cmdInProgress)
1228  {
1229  return g_csecStatePtr->errCode;
1230  }
1231 
1232  return STATUS_BUSY;
1233 }
1234 
1235 /*FUNCTION**********************************************************************
1236  *
1237  * Function Name : CSEC_DRV_InitState
1238  * Description : Initializes the internal state of the driver with a given
1239  * input buffer, output buffer, key, length, command, and marks the command as
1240  * in progress.
1241  *
1242  * END**************************************************************************/
1244  csec_cmd_t cmd,
1245  const uint8_t * inBuff,
1246  uint8_t * outBuff,
1247  uint32_t length)
1248 {
1249  g_csecStatePtr->cmdInProgress = true;
1250  g_csecStatePtr->cmd = cmd;
1251  g_csecStatePtr->inputBuff = inBuff;
1252  g_csecStatePtr->outputBuff = outBuff;
1253  g_csecStatePtr->keyId = keyId;
1254  g_csecStatePtr->fullSize = length;
1255  g_csecStatePtr->index = 0U;
1256  g_csecStatePtr->errCode = STATUS_SUCCESS;
1257  g_csecStatePtr->seq = CSEC_CALL_SEQ_FIRST;
1258 }
1259 
1260 /*FUNCTION**********************************************************************
1261  *
1262  * Function Name : FTFC_IRQHandler
1263  * Description : Implementation of the FTFC interrupt handler. Handles completed
1264  * commands lauched by using the asynchronous CSEc driver API which were
1265  *
1266  * END**************************************************************************/
1268 {
1269  uint8_t fstat = (uint8_t)(FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK);
1270 
1271  /* Previous command execution ended, continue execution */
1272  if ((fstat != 0U) && g_csecStatePtr->cmdInProgress)
1273  {
1274  if ((g_csecStatePtr->cmd == CSEC_CMD_ENC_ECB) || (g_csecStatePtr->cmd == CSEC_CMD_DEC_ECB))
1275  {
1277  }
1278  else if ((g_csecStatePtr->cmd == CSEC_CMD_ENC_CBC) || (g_csecStatePtr->cmd == CSEC_CMD_DEC_CBC))
1279  {
1281  }
1282  else if (g_csecStatePtr->cmd == CSEC_CMD_GENERATE_MAC)
1283  {
1285  }
1286  else if (g_csecStatePtr->cmd == CSEC_CMD_VERIFY_MAC)
1287  {
1289  }
1290  else
1291  {
1292  /* Do nothing, all the asynchronous operations were checked above */
1293  }
1294 
1295  /* If finished processing, disable interrupt */
1296  if (!g_csecStatePtr->cmdInProgress)
1297  {
1298  CSEC_HAL_SetInterrupt(false);
1299 
1300  if (g_csecStatePtr->callback != NULL)
1301  {
1302  g_csecStatePtr->callback(g_csecStatePtr->cmd, g_csecStatePtr->callbackParam);
1303  }
1304  }
1305  }
1306 }
1307 
1308 /*FUNCTION**********************************************************************
1309  *
1310  * Function Name : CSEC_DRV_StartEncDecECBCmd
1311  * Description : Initializes the CSE_PRAM and the internal state for
1312  * encryption/decryption using ECB mode commands.
1313  *
1314  * END**************************************************************************/
1316 {
1317  uint32_t numPagesLeft = (g_csecStatePtr->fullSize - g_csecStatePtr->index) >> CSEC_BYTES_TO_FROM_PAGES_SHIFT;
1318  uint16_t numPages = (uint16_t)((numPagesLeft > CSEC_DATA_PAGES_AVAILABLE) ? CSEC_DATA_PAGES_AVAILABLE : numPagesLeft);
1319  uint8_t numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1320 
1321  /* Write the plain/cipher text */
1322  CSEC_HAL_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1323  /* Write the size of the plain/cipher text (in pages) */
1325 
1326  g_csecStatePtr->partSize = numBytes;
1327 
1328  /* Write the command header. This will trigger the command execution. */
1329  CSEC_HAL_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1330 }
1331 
1332 /*FUNCTION**********************************************************************
1333  *
1334  * Function Name : CSEC_DRV_StartEncDecCBCCmd
1335  * Description : Initializes the CSE_PRAM and the internal state for
1336  * encryption/decryption using CBC mode commands.
1337  *
1338  * END**************************************************************************/
1340 {
1341  uint32_t numPagesLeft = (g_csecStatePtr->fullSize - g_csecStatePtr->index) >> CSEC_BYTES_TO_FROM_PAGES_SHIFT;
1342  uint16_t numPages = (uint16_t)((numPagesLeft > CSEC_DATA_PAGES_AVAILABLE) ? CSEC_DATA_PAGES_AVAILABLE : numPagesLeft);
1343  uint8_t numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1344 
1345  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1346  {
1347  numPages = (uint16_t)((numPagesLeft > (CSEC_DATA_PAGES_AVAILABLE - 1U)) ? (CSEC_DATA_PAGES_AVAILABLE - 1U) : numPagesLeft);
1348  numBytes = (uint8_t)(numPages << CSEC_BYTES_TO_FROM_PAGES_SHIFT);
1349 
1350  /* Write the initialization vector */
1352  /* Write the plain/cipher text */
1353  CSEC_HAL_WriteCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1354  }
1355  else
1356  {
1357  /* Write the plain/cipher text */
1358  CSEC_HAL_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1359  }
1360 
1361  /* Write the size of the plain/cipher text (in pages) */
1363 
1364  g_csecStatePtr->partSize = numBytes;
1365 
1366  /* Write the command header. This will trigger the command execution. */
1367  CSEC_HAL_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1368 }
1369 
1370 /*FUNCTION**********************************************************************
1371  *
1372  * Function Name : CSEC_DRV_StartGenMACCmd
1373  * Description : Initializes the CSE_PRAM and the internal state for the
1374  * CMAC generation command.
1375  *
1376  * END**************************************************************************/
1378 {
1379  uint8_t numBytes = (uint8_t)(((g_csecStatePtr->fullSize - g_csecStatePtr->index) >
1380  CSEC_DATA_BYTES_AVAILABLE) ? CSEC_DATA_BYTES_AVAILABLE : (g_csecStatePtr->fullSize - g_csecStatePtr->index));
1381 
1382  /* Write the plain/cipher text */
1383  CSEC_HAL_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1384  /* Write the size of the message (in bits) */
1386 
1387  g_csecStatePtr->partSize = numBytes;
1388 
1389  /* Write the command header. This will trigger the command execution. */
1390  CSEC_HAL_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1391 }
1392 
1393 /*FUNCTION**********************************************************************
1394  *
1395  * Function Name : CSEC_DRV_StartVerifMACCmd
1396  * Description : Initializes the CSE_PRAM and the internal state for the
1397  * CMAC verification command.
1398  *
1399  * END**************************************************************************/
1401 {
1402  uint8_t numBytes = (uint8_t)(((g_csecStatePtr->fullSize - g_csecStatePtr->index) >
1403  CSEC_DATA_BYTES_AVAILABLE) ? CSEC_DATA_BYTES_AVAILABLE : (g_csecStatePtr->fullSize - g_csecStatePtr->index));
1404  uint8_t macOffset = (uint8_t)CSEC_DRV_RoundTo(numBytes, 0x10);
1405 
1406  /* Write the plain/cipher text */
1407  CSEC_HAL_WriteCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->inputBuff[g_csecStatePtr->index], numBytes);
1408  /* Write the size of the message (in bits) */
1410 
1411  /* Write the number of bits of the MAC to be compared */
1413 
1414  /* If there is available space in CSE_PRAM, write the MAC to be verified */
1416  {
1418  g_csecStatePtr->macWritten = true;
1419  }
1420 
1421  g_csecStatePtr->partSize = numBytes;
1422 
1423  /* Write the command header. This will trigger the command execution. */
1424  CSEC_HAL_WriteCommandHeader(g_csecStatePtr->cmd, CSEC_FUNC_FORMAT_COPY, g_csecStatePtr->seq, g_csecStatePtr->keyId);
1425 }
1426 
1427 /*FUNCTION**********************************************************************
1428  *
1429  * Function Name : CSEC_DRV_ContinueEncDecECBCmd
1430  * Description : Continues the execution of encryption/decryption using ECB
1431  * mode. Reads the partial result, updates the internal state and launches
1432  * another command, if necessary.
1433  *
1434  * END**************************************************************************/
1436 {
1437  /* Read the status of the execution */
1438  g_csecStatePtr->errCode = CSEC_HAL_ReadErrorBits();
1439  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1440  {
1441  /* Do not continue launching commands if an error occurred */
1442  g_csecStatePtr->cmdInProgress = false;
1443  return;
1444  }
1445 
1446  /* Get partial result */
1447  CSEC_HAL_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->outputBuff[g_csecStatePtr->index], (uint8_t)g_csecStatePtr->partSize);
1448 
1449  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1450 
1451  /* Decide if more commands are needed */
1452  if (g_csecStatePtr->index >= g_csecStatePtr->fullSize)
1453  {
1454  g_csecStatePtr->cmdInProgress = false;
1455  }
1456  else
1457  {
1458  /* Continue launching commands */
1460  }
1461 }
1462 
1463 /*FUNCTION**********************************************************************
1464  *
1465  * Function Name : CSEC_DRV_ContinueEncDecCBCCmd
1466  * Description : Continues the execution of encryption/decryption using CBC
1467  * mode. Reads the partial result, updates the internal state and launches
1468  * another command, if necessary.
1469  *
1470  * END**************************************************************************/
1472 {
1473  /* Read the status of the execution */
1474  g_csecStatePtr->errCode = CSEC_HAL_ReadErrorBits();
1475  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1476  {
1477  /* Do not continue launching commands if an error occurred */
1478  g_csecStatePtr->cmdInProgress = false;
1479  return;
1480  }
1481 
1482  /* Get partial result */
1483  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1484  {
1485  CSEC_HAL_ReadCommandBytes(FEATURE_CSEC_PAGE_2_OFFSET, &g_csecStatePtr->outputBuff[g_csecStatePtr->index],
1486  (uint8_t)g_csecStatePtr->partSize);
1487  g_csecStatePtr->seq = CSEC_CALL_SEQ_SUBSEQUENT;
1488  }
1489  else
1490  {
1491  CSEC_HAL_ReadCommandBytes(FEATURE_CSEC_PAGE_1_OFFSET, &g_csecStatePtr->outputBuff[g_csecStatePtr->index],
1492  (uint8_t)g_csecStatePtr->partSize);
1493  }
1494 
1495  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1496 
1497  if (g_csecStatePtr->index >= g_csecStatePtr->fullSize)
1498  {
1499  g_csecStatePtr->cmdInProgress = false;
1500  }
1501  else
1502  {
1503  /* Continue launching commands */
1505  }
1506 }
1507 
1508 
1509 /*FUNCTION**********************************************************************
1510  *
1511  * Function Name : CSEC_DRV_ContinueGenMACCmd
1512  * Description : Continues the execution of CMAC generation. Reads the status
1513  * of the execution, updates the internal state and launches another command,
1514  * if necessary. If there is no need to launch another command, reads the
1515  * resulted CMAC.
1516  *
1517  * END**************************************************************************/
1519 {
1520  /* Read the status of the execution */
1521  g_csecStatePtr->errCode = CSEC_HAL_ReadErrorBits();
1522  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1523  {
1524  /* Do not continue launching commands if an error occurred */
1525  g_csecStatePtr->cmdInProgress = false;
1526  return;
1527  }
1528 
1529  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1530  {
1531  g_csecStatePtr->seq = CSEC_CALL_SEQ_SUBSEQUENT;
1532  }
1533 
1534  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1535 
1536  /* Decide if more commands are needed */
1537  if (g_csecStatePtr->index >= g_csecStatePtr->fullSize)
1538  {
1539  g_csecStatePtr->cmdInProgress = false;
1541  }
1542  else
1543  {
1544  /* Continue launching commands */
1546  }
1547 }
1548 
1549 /*FUNCTION**********************************************************************
1550  *
1551  * Function Name : CSEC_DRV_ContinueVerifMACCmd
1552  * Description : Continues the execution of CMAC verification. Reads the status
1553  * of the execution, updates the internal state and launches another command,
1554  * if necessary. If there is no need to launch another command, reads the
1555  * verification status.
1556  *
1557  * END**************************************************************************/
1559 {
1560  /* Read the status of the execution */
1561  g_csecStatePtr->errCode = CSEC_HAL_ReadErrorBits();
1562  if (g_csecStatePtr->errCode != STATUS_SUCCESS)
1563  {
1564  /* Do not continue launching commands if an error occurred */
1565  g_csecStatePtr->cmdInProgress = false;
1566  return;
1567  }
1568 
1569  if (g_csecStatePtr->seq == CSEC_CALL_SEQ_FIRST)
1570  {
1571  g_csecStatePtr->seq = CSEC_CALL_SEQ_SUBSEQUENT;
1572  }
1573 
1574  g_csecStatePtr->index += (uint8_t)g_csecStatePtr->partSize;
1575 
1576  /* Decide if more commands are needed */
1577  g_csecStatePtr->cmdInProgress = !g_csecStatePtr->macWritten;
1578 
1579  if (!g_csecStatePtr->cmdInProgress)
1580  {
1582  }
1583  else
1584  {
1585  /* Continue launching commands */
1587  }
1588 }
1589 
1590 /*FUNCTION**********************************************************************
1591  *
1592  * Function Name : CSEC_DRV_InstallCallback
1593  * Description : Installs a callback function which will be invoked when an
1594  * asynchronous command finishes its execution.
1595  *
1596  * Implements : CSEC_DRV_InstallCallback_Activity
1597  * END**************************************************************************/
1598 void CSEC_DRV_InstallCallback(csec_callback_t callbackFunc, void *callbackParam)
1599 {
1600  g_csecStatePtr->callback = callbackFunc;
1601  g_csecStatePtr->callbackParam = callbackParam;
1602 }
1603 
1604 /******************************************************************************
1605  * EOF
1606  *****************************************************************************/
status_t CSEC_DRV_LoadPlainKey(const uint8_t *plainKey)
Updates the RAM key memory slot with a 128-bit plaintext.
Definition: csec_driver.c:554
status_t CSEC_DRV_GetAsyncCmdStatus()
Checks the status of the execution of an asynchronous command.
Definition: csec_driver.c:1225
bool cmdInProgress
Definition: csec_driver.h:71
#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)
#define CSEC_DATA_PAGES_AVAILABLE
Definition: csec_driver.c:67
static void CSEC_DRV_ContinueEncDecECBCmd(void)
Definition: csec_driver.c:1435
static void CSEC_DRV_ContinueEncDecCBCCmd(void)
Definition: csec_driver.c:1471
#define CSEC_M3_SIZE_IN_BYTES
Definition: csec_driver.c:82
#define FEATURE_CSEC_BOOT_FLAVOR_OFFSET
CSE_PRAM offset of the boot flavor parameter used by the following commands: CMD_BOOT_DEFINE.
bool macWritten
Definition: csec_driver.h:84
static void CSEC_HAL_WaitCommandCompletion(void)
Waits for the completion of a CSEc command.
Definition: csec_hal.h:336
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:853
Internal driver state information.
Definition: csec_driver.h:70
static void CSEC_DRV_StartEncDecECBCmd(void)
Definition: csec_driver.c:1315
#define FTFC_FSTAT_CCIF_MASK
Definition: S32K144.h:3839
#define CSEC_BYTES_TO_FROM_PAGES_SHIFT
Definition: csec_driver.c:73
#define FEATURE_CSEC_PAGE_7_OFFSET
CSE_PRAM offset of page 7.
void CSEC_DRV_Init(csec_state_t *state)
Initializes the internal state of the driver and enables the FTFC interrupt.
Definition: csec_driver.c:132
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:943
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:1190
#define CSEC_M1_SIZE_IN_BYTES
Definition: csec_driver.c:78
static void CSEC_HAL_WriteCommandHeader(csec_cmd_t funcId, csec_func_format_t funcFormat, csec_call_sequence_t callSeq, csec_key_id_t keyId)
Writes the command header to CSE_PRAM.
Definition: csec_hal.h:229
START_FUNCTION_DECLARATION_RAMSECTION void CSEC_HAL_WriteCmdAndWait(csec_cmd_t funcId, csec_func_format_t funcFormat, csec_call_sequence_t callSeq, csec_key_id_t keyId) END_FUNCTION_DECLARATION_RAMSECTION static inline void CSEC_HAL_SetInterrupt(bool enable)
Writes the command header to CSE_PRAM and waits for completion.
Definition: csec_hal.h:432
csec_key_id_t keyId
Definition: csec_driver.h:78
status_t CSEC_DRV_BootOK()
Marks a successful boot verification during later stages of the boot process.
Definition: csec_driver.c:784
status_t CSEC_DRV_MPCompress(const uint8_t *msg, uint16_t msgLen, uint8_t *mpCompress)
Compresses the given messages by accessing the Miyaguchi-Prenell compression feature with in the CSEc...
Definition: csec_driver.c:979
#define FEATURE_CSEC_PAGE_3_OFFSET
CSE_PRAM offset of page 3.
#define CSEC_BYTES_TO_FROM_BITS_SHIFT
Definition: csec_driver.c:75
#define FEATURE_CSEC_PAGE_4_OFFSET
CSE_PRAM offset of page 4.
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:449
status_t CSEC_DRV_InitRNG()
Initializes the seed and derives a key for the PRNG.
Definition: csec_driver.c:641
#define FEATURE_CSEC_PAGE_2_OFFSET
CSE_PRAM offset of page 2.
const uint8_t * iv
Definition: csec_driver.h:80
static void CSEC_DRV_StartVerifMACCmd(void)
Definition: csec_driver.c:1400
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:80
#define CSEC_DATA_BYTES_AVAILABLE
Definition: csec_driver.c:70
status_t CSEC_DRV_ExtendSeed(const uint8_t *entropy)
Extends the seed of the PRNG.
Definition: csec_driver.c:676
static void CSEC_DRV_StartEncDecCBCCmd(void)
Definition: csec_driver.c:1339
#define DEV_ASSERT(x)
Definition: devassert.h:78
void CSEC_HAL_WriteCommandBytes(uint8_t offset, const uint8_t *bytes, uint8_t numBytes)
Writes command bytes to CSE_PRAM.
Definition: csec_hal.c:61
status_t CSEC_DRV_BootFailure()
Signals a failure detected during later stages of the boot process.
Definition: csec_driver.c:752
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:1073
#define FEATURE_CSEC_SREG_OFFSET
CSE_PRAM offset of the SREG parameter used by the following commands: CMD_GET_ID. ...
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:1243
csec_callback_t callback
Definition: csec_driver.h:87
bool * verifStatus
Definition: csec_driver.h:83
#define FEATURE_CSEC_VERIFICATION_STATUS_OFFSET
CSE_PRAM offset of the verification status parameter used by the following commands: CMD_VERIFY_MAC (...
csec_cmd_t cmd
Definition: csec_driver.h:72
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:1045
uint32_t partSize
Definition: csec_driver.h:77
csec_cmd_t
CSEc commands which follow the same values as the SHE command definition.
Definition: csec_hal.h:108
uint32_t msgLen
Definition: csec_driver.h:82
#define CSEC_PAGE_SIZE_IN_BYTES
Definition: csec_driver.c:63
void CSEC_DRV_InstallCallback(csec_callback_t callbackFunc, void *callbackParam)
Installs a callback function which will be invoked when an asynchronous command finishes its executio...
Definition: csec_driver.c:1598
uint8_t * outputBuff
Definition: csec_driver.h:74
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
status_t CSEC_DRV_DecryptCBC(csec_key_id_t keyId, const uint8_t *cipherText, uint16_t length, const uint8_t *iv, uint8_t *plainText)
Performs the AES-128 decryption in CBC mode.
Definition: csec_driver.c:278
#define FEATURE_CSEC_PAGE_5_OFFSET
CSE_PRAM offset of page 5.
void CSEC_HAL_ReadCommandBytes(uint8_t offset, uint8_t *bytes, uint8_t numBytes)
Reads command bytes from CSE_PRAM.
Definition: csec_hal.c:170
void CSEC_HAL_WriteCommandWords(uint8_t offset, const uint32_t *words, uint8_t numWords)
Writes command words to CSE_PRAM.
Definition: csec_hal.c:148
status_t CSEC_DRV_DecryptECB(csec_key_id_t keyId, const uint8_t *cipherText, uint32_t length, uint8_t *plainText)
Performs the AES-128 decryption in ECB mode.
Definition: csec_driver.c:202
status_t CSEC_DRV_EncryptCBC(csec_key_id_t keyId, const uint8_t *plainText, uint32_t length, const uint8_t *iv, uint8_t *cipherText)
Performs the AES-128 encryption in CBC mode.
Definition: csec_driver.c:238
#define FTFC
Definition: S32K144.h:3798
static status_t CSEC_HAL_ReadErrorBits(void)
Reads the error bits from PRAM.
Definition: csec_hal.h:353
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:358
static void CSEC_DRV_ContinueVerifMACCmd(void)
Definition: csec_driver.c:1558
void FTFC_IRQHandler(void)
Definition: csec_driver.c:1267
#define FEATURE_CSEC_FLASH_START_ADDRESS_OFFSET
CSE_PRAM offset of the Flash start address parameter used by the following commands: CMD_GENERATE_MAC...
static void CSEC_DRV_ContinueGenMACCmd(void)
Definition: csec_driver.c:1518
void CSEC_DRV_Deinit()
Clears the internal state of the driver and disables the FTFC interrupt.
Definition: csec_driver.c:150
uint8_t CSEC_HAL_ReadCommandByte(uint8_t offset)
Reads a command byte from CSE_PRAM.
Definition: csec_hal.c:224
#define FEATURE_CSEC_PAGE_1_OFFSET
CSE_PRAM offset of page 1.
status_t errCode
Definition: csec_driver.h:79
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:501
uint32_t macLen
Definition: csec_driver.h:86
csec_call_sequence_t
Specifies if the information is the first or a following function call.
Definition: csec_hal.h:185
status_t CSEC_DRV_EncryptECB(csec_key_id_t keyId, const uint8_t *plainText, uint32_t length, uint8_t *cipherText)
Performs the AES-128 encryption in ECB mode.
Definition: csec_driver.c:165
#define FEATURE_CSEC_MAC_LENGTH_OFFSET
CSE_PRAM offset of the MAC length parameter used by the following commands: CMD_VERIFY_MAC (both copy...
uint32_t index
Definition: csec_driver.h:75
csec_boot_flavor_t
Specifies the boot type for the BOOT_DEFINE command.
Definition: csec_driver.h:47
const uint8_t * mac
Definition: csec_driver.h:85
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:1131
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
#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.
csec_call_sequence_t seq
Definition: csec_driver.h:81
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:590
status_t CSEC_DRV_GenerateRND(uint8_t *rnd)
Generates a vector of 128 random bits.
Definition: csec_driver.c:713
status_t CSEC_DRV_EncryptCBCAsync(csec_key_id_t keyId, const uint8_t *cipherText, uint16_t length, const uint8_t *iv, uint8_t *plainText)
Asynchronously performs the AES-128 encryption in CBC mode.
Definition: csec_driver.c:1101
#define CSEC_M4_SIZE_IN_BYTES
Definition: csec_driver.c:84
uint32_t fullSize
Definition: csec_driver.h:76
static uint32_t CSEC_DRV_RoundTo(uint32_t value, uint32_t roundTo)
Definition: csec_driver.c:105
const uint8_t * inputBuff
Definition: csec_driver.h:73
#define FEATURE_CSEC_BOOT_SIZE_OFFSET
CSE_PRAM offset of the boot size parameter used by the following commands: CMD_BOOT_DEFINE.
void CSEC_HAL_WriteCommandHalfWord(uint8_t offset, uint16_t halfWord)
Writes a command half word to CSE_PRAM.
Definition: csec_hal.c:91
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:904
void(* csec_callback_t)(csec_cmd_t completedCmd, void *callbackParam)
CSEc asynchronous command complete callback function type.
Definition: csec_driver.h:59
void * callbackParam
Definition: csec_driver.h:88
static csec_state_t * g_csecStatePtr
Definition: csec_driver.c:89
static void CSEC_DRV_StartGenMACCmd(void)
Definition: csec_driver.c:1377
status_t CSEC_DRV_GenerateMAC(csec_key_id_t keyId, const uint8_t *msg, uint32_t msgLen, uint8_t *cmac)
Calculates the MAC of a given message using CMAC with AES-128.
Definition: csec_driver.c:318
csec_key_id_t
Specify the KeyID to be used to implement the requested cryptographic operation.
Definition: csec_hal.h:139
uint16_t CSEC_HAL_ReadCommandHalfWord(uint8_t offset)
Reads a command half word from CSE_PRAM.
Definition: csec_hal.c:201
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)
Verifies the MAC of a given message using CMAC with AES-128.
Definition: csec_driver.c:402
#define CSEC_M5_SIZE_IN_BYTES
Definition: csec_driver.c:86
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:816
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:1161
void CSEC_HAL_WriteCommandByte(uint8_t offset, uint8_t byte)
Writes a command byte to CSE_PRAM.
Definition: csec_hal.c:118