1 /*
2 * Copyright 2021 MCUX
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_css_pkc.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13 #define TEMPORARY_KEY_SLOT_256 18u
14 /*******************************************************************************
15 * Prototypes
16 ******************************************************************************/
17 static status_t CSS_PRNG_KickOff(void);
18 static status_t CSS_check_key(uint8_t keyIdx, mcuxClCss_KeyProp_t *pKeyProp);
19 /*******************************************************************************
20 * Code
21 ******************************************************************************/
22 /*!
23 * brief CSS Init after power down.
24 *
25 * This function enable all CSS related clocks, enable CSS and start CSS PRNG.
26 * Normally all of these actions are done automatically by boot ROM, but if an application uses Power Down mode
27 * this function must be called before using CSS after wake-up.
28 *
29 * param base CSS peripheral address.
30 *
31 * return kStatus_Success upon success, kStatus_Fail otherwise
32 */
CSS_PowerDownWakeupInit(CSS_Type * base)33 status_t CSS_PowerDownWakeupInit(CSS_Type *base)
34 {
35 status_t status = kStatus_Fail;
36
37 /* Enable all CSS related clocks */
38 ANACTRL->FRO192M_CTRL |= (ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK | ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK);
39 SYSCON->CSS_CLK_CTRL_SET =
40 (SYSCON_CSS_CLK_CTRL_SET_GDET_REFCLK_EN_SET_MASK | SYSCON_CSS_CLK_CTRL_SET_DTRNG_REFCLK_EN_SET_MASK);
41
42 /* De-assert reset */
43 RESET_ClearPeripheralReset(kCSS_RST_SHIFT_RSTn);
44
45 /* Enable CSS clock */
46 CLOCK_EnableClock(kCLOCK_Css);
47
48 /* Enable CSS */
49 mcuxClCss_Enable_Async();
50 /* Wait until CSS is enabled */
51 MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClCss_WaitForOperation(MCUXCLCSS_ERROR_FLAGS_CLEAR));
52 if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClCss_WaitForOperation) != token) && (MCUXCLCSS_STATUS_OK != result))
53 {
54 return kStatus_Fail;
55 }
56 MCUX_CSSL_FP_FUNCTION_CALL_END();
57
58 /* Kick-off CSS PRNG */
59 status = CSS_PRNG_KickOff();
60 if (status != kStatus_Success)
61 {
62 return status;
63 }
64
65 return kStatus_Success;
66 }
67
68 /*!
69 * brief PKC Init after power down.
70 *
71 * This function enables RAM interleave, clocks, zeroize the PKC RAM and reset PKC peripheral.
72 * Normally all of these actions are done automatically by boot ROM, but if an application uses Power Down mode
73 * this function must be called before using PKC after wake-up.
74 *
75 * param base PKC peripheral address.
76 *
77 * return kStatus_Success upon success, kStatus_Fail otherwise
78 */
PKC_PowerDownWakeupInit(PKC_Type * base)79 status_t PKC_PowerDownWakeupInit(PKC_Type *base)
80 {
81 /* set PKC RAM to interleave mode */
82 SYSCON->RAM_INTERLEAVE = SYSCON_RAM_INTERLEAVE_INTERLEAVE_MASK;
83 /* Reset PKC */
84 RESET_PeripheralReset(kPKC_RST_SHIFT_RSTn);
85 /* enable PKC clock */
86 CLOCK_EnableClock(kCLOCK_Pkc);
87
88 /* Zeroize the PKC RAM */
89 for (int i = 0; i < PKC_RAM_SIZE / sizeof(uint32_t); i++)
90 {
91 ((uint32_t *)PKC_RAM_ADDR)[i] = 0x0;
92 }
93
94 return kStatus_Success;
95 }
96
97 /*!
98 * brief PKC Init after power down.
99 *
100 * This function enables RAM interleave, clocks and reset PKC peripheral.
101 *
102 * param base PKC peripheral address.
103 *
104 * return kStatus_Success upon success, kStatus_Fail otherwise
105 */
PKC_InitNoZeroize(PKC_Type * base)106 status_t PKC_InitNoZeroize(PKC_Type *base)
107 {
108 /* set PKC RAM to interleave mode */
109 SYSCON->RAM_INTERLEAVE = SYSCON_RAM_INTERLEAVE_INTERLEAVE_MASK;
110 /* Reset PKC */
111 RESET_PeripheralReset(kPKC_RST_SHIFT_RSTn);
112 /* enable PKC clock */
113 CLOCK_EnableClock(kCLOCK_Pkc);
114
115 return kStatus_Success;
116 }
117
CSS_check_key(uint8_t keyIdx,mcuxClCss_KeyProp_t * pKeyProp)118 static status_t CSS_check_key(uint8_t keyIdx, mcuxClCss_KeyProp_t *pKeyProp)
119 {
120 /* Check if CSS required keys are available in CSS keystore */
121 MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token,
122 mcuxClCss_GetKeyProperties(keyIdx, pKeyProp)); // Get key propertis from the CSS.
123 // mcuxClCss_GetKeyProperties is a flow-protected function: Check the protection token and the return value
124 if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClCss_GetKeyProperties) != token) || (MCUXCLCSS_STATUS_OK != result))
125 return kStatus_Fail;
126 MCUX_CSSL_FP_FUNCTION_CALL_END();
127
128 return kStatus_Success;
129 }
130
CSS_PRNG_KickOff(void)131 static status_t CSS_PRNG_KickOff(void)
132 {
133 mcuxClCss_KeyProp_t key_properties;
134 status_t status = kStatus_Fail;
135
136 /* Check if PRNG already ready */
137 if((CSS->CSS_STATUS & CSS_CSS_STATUS_prng_rdy_MASK) == 0u)
138 {
139 /* Check if key slot 18 is available in CSS keystore */
140 /* Note if you are using slot 18 in your application, please change TEMPORARY_KEY_SLOT_256 to any unused slot */
141 status = CSS_check_key(TEMPORARY_KEY_SLOT_256, &key_properties);
142 if (status != kStatus_Success || key_properties.bits.kactv == 1u)
143 {
144 return kStatus_SlotUnavailable;
145 }
146
147 /* delete empty temp keyslot; */
148 /* Even if KDELETE is requested to delete an inactive key, the css entropy level will be raised to low and the PRNG
149 * will go ready, */
150 MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED(result0, token0, mcuxClCss_KeyDelete_Async(TEMPORARY_KEY_SLOT_256));
151 if ((token0 != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClCss_KeyDelete_Async)) || (result0 != MCUXCLCSS_STATUS_OK_WAIT))
152 {
153 return kStatus_Fail;
154 }
155
156 MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED(result1, token1, mcuxClCss_WaitForOperation(MCUXCLCSS_ERROR_FLAGS_CLEAR));
157 if ((token1 != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClCss_WaitForOperation)) || (result1 != MCUXCLCSS_STATUS_OK))
158 {
159 return kStatus_Fail;
160 }
161 }
162
163 return kStatus_Success;
164 }
165