1 /*
2  * Copyright (c) 2021-2024, The TrustedFirmware-M Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "cc3xx_init.h"
9 
10 #include "cc3xx_dev.h"
11 #include "cc3xx_engine_state.h"
12 #include <assert.h>
13 #include "cc3xx_rng.h"
14 
check_features(void)15 static void check_features(void)
16 {
17     /* Check for hashing support */
18 #if defined (CC3XX_CONFIG_HASH_SHA224_ENABLE) || defined(CC3XX_CONFIG_HASH_SHA256_ENABLE)
19     assert(P_CC3XX->host_rgf.host_boot & (1 << 17)); /* HASH_EXISTS_LOCAL */
20     assert(P_CC3XX->host_rgf.host_boot & (1 << 15)); /* SHA_256_PRSNT_LOCAL */
21 #endif /* defined (CC3XX_CONFIG_HASH_SHA224_ENABLE) || CC3XX_CONFIG_HASH_SHA256_ENABLE */
22 
23 #ifdef CC3XX_CONFIG_AES_CTR_ENABLE
24     assert(P_CC3XX->host_rgf.host_boot & (1 << 30)); /* AES_EXISTS_LOCAL */
25     assert(P_CC3XX->host_rgf.host_boot & (1 << 25)); /* CTR_EXISTS_LOCAL */
26     assert(P_CC3XX->aes.aes_hw_flags & (1 << 3)); /* CTR_EXISTS */
27 #endif
28 
29 #ifdef CC3XX_CONFIG_AES_ECB_ENABLE
30     assert(P_CC3XX->host_rgf.host_boot & (1 << 30)); /* AES_EXISTS_LOCAL */
31 #endif
32 
33 #ifdef CC3XX_CONFIG_AES_CBC_ENABLE
34     assert(P_CC3XX->host_rgf.host_boot & (1 << 30)); /* AES_EXISTS_LOCAL */
35 #endif
36 
37 #ifdef CC3XX_CONFIG_AES_GCM_ENABLE
38     assert(P_CC3XX->host_rgf.host_boot & (1 << 30)); /* AES_EXISTS_LOCAL */
39 #endif
40 
41 #ifdef CC3XX_CONFIG_AES_CMAC_ENABLE
42     assert(P_CC3XX->host_rgf.host_boot & (1 << 30)); /* AES_EXISTS_LOCAL */
43     assert(P_CC3XX->host_rgf.host_boot & (1 << 21)); /* AES_CMAC_EXISTS_LOCAL */
44 #endif
45 
46 #ifdef CC3XX_CONFIG_AES_CCM_ENABLE
47     assert(P_CC3XX->host_rgf.host_boot & (1 << 30)); /* AES_EXISTS_LOCAL */
48     assert(P_CC3XX->host_rgf.host_boot & (1 << 22)); /* AES_CCM_EXISTS_LOCAL */
49 #endif
50 
51 #ifdef CC3XX_CONFIG_AES_TUNNELLING_ENABLE
52     assert(P_CC3XX->host_rgf.host_boot & (1 << 27)); /* TUNNELLING_ENB_LOCAL */
53     assert(P_CC3XX->aes.aes_hw_flags & (1 << 10)); /* AES_TUNNEL_EXISTS */
54 #endif
55 
56 #ifdef CC3XX_CONFIG_CHACHA_ENABLE
57     assert(!P_CC3XX->host_rgf.host_remove_chacha_engine);
58     assert(P_CC3XX->chacha.chacha_hw_flags & 1); /* CHACHA_EXISTS */
59 #endif
60 
61 #ifdef CC3XX_CONFIG_RNG_ENABLE
62     assert(P_CC3XX->host_rgf.host_boot & (1 << 11)); /* RNG_EXISTS_LOCAL */
63 #endif
64 }
65 
setup_dfa_countermeasures(void)66 static cc3xx_err_t setup_dfa_countermeasures(void)
67 {
68 #ifdef CC3XX_CONFIG_DFA_MITIGATIONS_ENABLE
69     const uint32_t dfa_is_supported = P_CC3XX->aes.aes_hw_flags & (0x1 << 12);
70     uint32_t lock_dfa_enabled = dfa_is_supported;
71 #else
72     /* If the DFA countermeasures are not enabled, the setup just locks them to false
73      * regardless of the HW being capable of DFA support or not
74      */
75     uint32_t lock_dfa_enabled = false;
76 #endif
77 
78 #ifdef CC3XX_CONFIG_AES_TUNNELLING_ENABLE
79     /* If tunnelling is enabled then the DFA countermeasures will need to be
80      * switched off while it is in use. Because of this, FORCE_DFA_ENABLE needs
81      * to be switched off.
82      */
83     lock_dfa_enabled = false;
84 #endif /* CC3XX_CONFIG_AES_TUNNELLING_ENABLE */
85 
86     /* If the AES DFA countermeasures are supported, enable them. */
87     if (lock_dfa_enabled) {
88         P_CC3XX->ao.host_ao_lock_bits |= 0b1U << 7; /* Set HOST_FORCE_DFA_ENABLE */
89     } else {
90         P_CC3XX->ao.host_ao_lock_bits &= ~(0b1U << 7); /* Unset HOST_FORCE_DFA_ENABLE */
91     }
92     P_CC3XX->ao.host_ao_lock_bits |= 0b1U << 8; /* Set HOST_DFA_ENABLE_LOCK */
93 
94     return CC3XX_ERR_SUCCESS;
95 }
96 
97 #ifdef CC3XX_CONFIG_DPA_MITIGATIONS_ENABLE
setup_dpa_countermeasures(void)98 static cc3xx_err_t setup_dpa_countermeasures(void)
99 {
100     cc3xx_err_t err;
101     uint8_t aes_rbg_seed;
102 
103     /* Some countermeasures are supported only for certain revisions */
104     switch (P_CC3XX->id.peripheral_id_0) {
105     case 0xC1:
106         P_CC3XX->aes.aes_dummy_rounds_enable = 0x1;
107         while(!P_CC3XX->aes.aes_rbg_seeding_rdy){}
108         err = cc3xx_lowlevel_rng_get_random((uint8_t *)&aes_rbg_seed, 1);
109         if (err != CC3XX_ERR_SUCCESS) {
110             return err;
111         }
112         P_CC3XX->aes.aes_rbg_seed = aes_rbg_seed;
113         break;
114     }
115 
116     return CC3XX_ERR_SUCCESS;
117 }
118 #endif /* CC3XX_CONFIG_DPA_MITIGATIONS_ENABLE */
119 
cc3xx_lowlevel_init(void)120 cc3xx_err_t cc3xx_lowlevel_init(void)
121 {
122     cc3xx_err_t err;
123 
124     /* If on a debug build, check that the CC3XX has all the features that have
125      * been chosen by config */
126     check_features();
127 
128     /* Configure entire system to litte endian */
129     P_CC3XX->host_rgf.host_rgf_endian = 0x0U;
130 
131     err = setup_dfa_countermeasures();
132     if (err != CC3XX_ERR_SUCCESS) {
133         return err;
134     }
135 
136 #ifdef CC3XX_CONFIG_DPA_MITIGATIONS_ENABLE
137     err = setup_dpa_countermeasures();
138     if (err != CC3XX_ERR_SUCCESS) {
139         return err;
140     }
141 #endif /* CC3XX_CONFIG_DPA_MITIGATIONS_ENABLE */
142 
143     /* Set AHB to secure */
144     P_CC3XX->ahb.ahbm_hnonsec = 0b00U;
145 
146     /* Reset engine to PASSTHROUGH / None */
147     cc3xx_engine_in_use = CC3XX_ENGINE_NONE;
148     P_CC3XX->cc_ctl.crypto_ctl = CC3XX_ENGINE_NONE;
149 
150     return CC3XX_ERR_SUCCESS;
151 }
152 
cc3xx_lowlevel_uninit(void)153 cc3xx_err_t cc3xx_lowlevel_uninit(void)
154 {
155     return CC3XX_ERR_SUCCESS;
156 }
157