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)15static 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)66static 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)98static 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)120cc3xx_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)153cc3xx_err_t cc3xx_lowlevel_uninit(void) 154 { 155 return CC3XX_ERR_SUCCESS; 156 } 157