1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2020 Pengutronix 4 * Rouven Czerwinski <entwicklung@pengutronix.de> 5 * Copyright 2022 NXP 6 */ 7 8 #include <drivers/imx_snvs.h> 9 #include <io.h> 10 #include <mm/core_memprot.h> 11 #include <mm/core_mmu.h> 12 #include <stdint.h> 13 #include <tee/tee_fs.h> 14 #include <types_ext.h> 15 #include <trace.h> 16 17 #define SNVS_HPLR 0x00 18 #define SNVS_HPCOMR 0x04 19 #define SNVS_HPSR 0x14 20 #define SNVS_LPLR 0x34 21 #define SNVS_LPMKCR 0x3C 22 23 #define HPSR_SSM_ST_MASK GENMASK_32(11, 8) 24 #define HPSR_SSM_ST_SHIFT 8 25 26 #define SNVS_HPSR_SYS_SECURITY_CFG_OFFSET 12 27 28 #define SNVS_HPSR_OTPMK_SYND GENMASK_32(24, 16) 29 #define SNVS_HPSR_OTPMK_ZERO BIT(27) 30 31 #define SNVS_HPLR_MKS_SL BIT32(9) 32 33 #define SNVS_LPLR_MKS_HL BIT32(9) 34 35 #define SNVS_HPCOMR_MKS_EN BIT32(13) 36 #define SNVS_HPCOMR_NPSWA_EN BIT32(31) 37 38 #define SNVS_LPMKCR_MKCR_MKS_SEL GENMASK_32(1, 0) 39 40 enum snvs_ssm_mode { 41 SNVS_SSM_MODE_INIT, 42 SNVS_SSM_MODE_HARD_FAIL, 43 SNVS_SSM_MODE_SOFT_FAIL = 3, 44 SNVS_SSM_MODE_INIT_INTERMEDIATE = 8, 45 SNVS_SSM_MODE_CHECK, 46 SNVS_SSM_MODE_NON_SECURE = 11, 47 SNVS_SSM_MODE_TRUSTED = 13, 48 SNVS_SSM_MODE_SECURE = 15, 49 }; 50 51 enum snvs_security_cfg { 52 SNVS_SECURITY_CFG_FAB, 53 SNVS_SECURITY_CFG_OPEN, 54 SNVS_SECURITY_CFG_CLOSED, 55 SNVS_SECURITY_CFG_FIELD_RETURN, 56 }; 57 58 /* 59 * Return true if the master key is OTPMK, false otherwise. 60 */ 61 static bool is_otpmk_selected(void) 62 { 63 uint32_t hp_mks = 0; 64 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 65 66 hp_mks = io_read32(base + SNVS_HPCOMR); 67 68 /* 69 * The master key selection might be done by the MASTER_KEY_SEL field 70 * of LPMKCR instead. 71 */ 72 if (hp_mks & SNVS_HPCOMR_MKS_EN) { 73 uint32_t lp_mks = io_read32(base + SNVS_LPMKCR); 74 75 if (lp_mks & SNVS_LPMKCR_MKCR_MKS_SEL) 76 return false; 77 } 78 79 return true; 80 } 81 82 /* 83 * Return true if the master key selection is locked, false otherwise. 84 */ 85 static bool is_mks_locked(void) 86 { 87 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 88 89 return io_read32(base + SNVS_HPLR) & SNVS_HPLR_MKS_SL || 90 io_read32(base + SNVS_LPLR) & SNVS_LPLR_MKS_HL; 91 } 92 93 /* Set the Master key to use OTPMK and lock it. */ 94 static void set_mks_otpmk(void) 95 { 96 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 97 98 io_setbits32(base + SNVS_HPCOMR, SNVS_HPCOMR_MKS_EN); 99 io_clrbits32(base + SNVS_LPMKCR, SNVS_LPMKCR_MKCR_MKS_SEL); 100 io_clrbits32(base + SNVS_HPLR, SNVS_HPLR_MKS_SL); 101 io_setbits32(base + SNVS_LPLR, SNVS_LPLR_MKS_HL); 102 } 103 104 /* 105 * Return true if OTPMK is valid, false otherwise. 106 */ 107 static bool is_otpmk_valid(void) 108 { 109 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 110 uint32_t status = io_read32(base + SNVS_HPSR); 111 112 return !(status & (SNVS_HPSR_OTPMK_ZERO | SNVS_HPSR_OTPMK_SYND)); 113 } 114 115 #ifdef CFG_MX8M 116 #define SNVS_HPSR_SYS_SECURITY_CFG GENMASK_32(15, 12) 117 118 static enum snvs_security_cfg snvs_get_security_cfg(void) 119 { 120 uint32_t val = 0; 121 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 122 SNVS_SIZE); 123 124 val = (io_read32(base + SNVS_HPSR) & SNVS_HPSR_SYS_SECURITY_CFG) >> 125 SNVS_HPSR_SYS_SECURITY_CFG_OFFSET; 126 127 switch (val) { 128 case 0b0000: 129 case 0b1000: 130 return SNVS_SECURITY_CFG_FAB; 131 case 0b0001: 132 case 0b0010: 133 case 0b0011: 134 return SNVS_SECURITY_CFG_OPEN; 135 case 0b1010: 136 case 0b1001: 137 case 0b1011: 138 return SNVS_SECURITY_CFG_CLOSED; 139 default: 140 return SNVS_SECURITY_CFG_FIELD_RETURN; 141 } 142 } 143 #else 144 #define SNVS_HPSR_SYS_SECURITY_CFG GENMASK_32(14, 12) 145 146 static enum snvs_security_cfg snvs_get_security_cfg(void) 147 { 148 uint32_t val = 0; 149 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 150 SNVS_SIZE); 151 152 val = (io_read32(base + SNVS_HPSR) & SNVS_HPSR_SYS_SECURITY_CFG) >> 153 SNVS_HPSR_SYS_SECURITY_CFG_OFFSET; 154 155 switch (val) { 156 case 0b000: 157 return SNVS_SECURITY_CFG_FAB; 158 case 0b001: 159 return SNVS_SECURITY_CFG_OPEN; 160 case 0b011: 161 return SNVS_SECURITY_CFG_CLOSED; 162 default: 163 return SNVS_SECURITY_CFG_FIELD_RETURN; 164 } 165 } 166 #endif 167 168 bool snvs_is_device_closed(void) 169 { 170 return (snvs_get_security_cfg() == SNVS_SECURITY_CFG_CLOSED); 171 } 172 173 #ifdef CFG_RPMB_FS 174 static enum snvs_ssm_mode snvs_get_ssm_mode(void) 175 { 176 vaddr_t snvs = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 177 SNVS_HPSR + sizeof(uint32_t)); 178 uint32_t val = 0; 179 180 val = io_read32(snvs + SNVS_HPSR); 181 val &= HPSR_SSM_ST_MASK; 182 val = val >> HPSR_SSM_ST_SHIFT; 183 DMSG("HPSR: SSM ST Mode: 0x%01"PRIx32, val); 184 return val; 185 } 186 187 bool plat_rpmb_key_is_ready(void) 188 { 189 enum snvs_ssm_mode mode = SNVS_SSM_MODE_INIT; 190 bool ssm_secure = false; 191 192 mode = snvs_get_ssm_mode(); 193 ssm_secure = (mode == SNVS_SSM_MODE_TRUSTED || 194 mode == SNVS_SSM_MODE_SECURE); 195 196 /* 197 * On i.MX6SDL and i.MX6DQ, the security cfg always returns 198 * SNVS_SECURITY_CFG_FAB (000), therefore we ignore the security 199 * configuration for this SoC. 200 */ 201 if (soc_is_imx6sdl() || soc_is_imx6dq()) 202 return ssm_secure; 203 204 return ssm_secure && snvs_is_device_closed(); 205 } 206 #endif /* CFG_RPMB_FS */ 207 208 TEE_Result imx_snvs_set_master_otpmk(void) 209 { 210 if (!is_otpmk_valid()) 211 return TEE_ERROR_BAD_STATE; 212 213 if (is_mks_locked()) { 214 if (is_otpmk_selected()) 215 return TEE_SUCCESS; 216 217 return TEE_ERROR_BAD_STATE; 218 } 219 220 set_mks_otpmk(); 221 222 return TEE_SUCCESS; 223 } 224