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_BAD BIT(14) 27 #define SNVS_HPSR_SYS_SECURITY_CLOSED BIT(13) 28 #define SNVS_HPSR_SYS_SECURITY_OPEN BIT(12) 29 #define SNVS_HPSR_OTPMK_SYND GENMASK_32(24, 16) 30 #define SNVS_HPSR_OTPMK_ZERO BIT(27) 31 32 #define SNVS_HPLR_MKS_SL BIT32(9) 33 34 #define SNVS_LPLR_MKS_HL BIT32(9) 35 36 #define SNVS_HPCOMR_MKS_EN BIT32(13) 37 #define SNVS_HPCOMR_NPSWA_EN BIT32(31) 38 39 #define SNVS_LPMKCR_MKCR_MKS_SEL GENMASK_32(1, 0) 40 41 enum snvs_ssm_mode { 42 SNVS_SSM_MODE_INIT, 43 SNVS_SSM_MODE_HARD_FAIL, 44 SNVS_SSM_MODE_SOFT_FAIL = 3, 45 SNVS_SSM_MODE_INIT_INTERMEDIATE = 8, 46 SNVS_SSM_MODE_CHECK, 47 SNVS_SSM_MODE_NON_SECURE = 11, 48 SNVS_SSM_MODE_TRUSTED = 13, 49 SNVS_SSM_MODE_SECURE, 50 }; 51 52 enum snvs_security_cfg { 53 SNVS_SECURITY_CFG_FAB, 54 SNVS_SECURITY_CFG_OPEN, 55 SNVS_SECURITY_CFG_CLOSED, 56 SNVS_SECURITY_CFG_FIELD_RETURN, 57 }; 58 59 /* 60 * Return true if the master key is OTPMK, false otherwise. 61 */ 62 static bool is_otpmk_selected(void) 63 { 64 uint32_t hp_mks = 0; 65 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 66 67 hp_mks = io_read32(base + SNVS_HPCOMR); 68 69 /* 70 * The master key selection might be done by the MASTER_KEY_SEL field 71 * of LPMKCR instead. 72 */ 73 if (hp_mks & SNVS_HPCOMR_MKS_EN) { 74 uint32_t lp_mks = io_read32(base + SNVS_LPMKCR); 75 76 if (lp_mks & SNVS_LPMKCR_MKCR_MKS_SEL) 77 return false; 78 } 79 80 return true; 81 } 82 83 /* 84 * Return true if the master key selection is locked, false otherwise. 85 */ 86 static bool is_mks_locked(void) 87 { 88 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 89 90 return io_read32(base + SNVS_HPLR) & SNVS_HPLR_MKS_SL || 91 io_read32(base + SNVS_LPLR) & SNVS_LPLR_MKS_HL; 92 } 93 94 /* Set the Master key to use OTPMK and lock it. */ 95 static void set_mks_otpmk(void) 96 { 97 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 98 99 io_setbits32(base + SNVS_HPCOMR, SNVS_HPCOMR_MKS_EN); 100 io_clrbits32(base + SNVS_LPMKCR, SNVS_LPMKCR_MKCR_MKS_SEL); 101 io_clrbits32(base + SNVS_HPLR, SNVS_HPLR_MKS_SL); 102 io_setbits32(base + SNVS_LPLR, SNVS_LPLR_MKS_HL); 103 } 104 105 /* 106 * Return true if OTPMK is valid, false otherwise. 107 */ 108 static bool is_otpmk_valid(void) 109 { 110 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, SNVS_SIZE); 111 uint32_t status = io_read32(base + SNVS_HPSR); 112 113 return !(status & (SNVS_HPSR_OTPMK_ZERO | SNVS_HPSR_OTPMK_SYND)); 114 } 115 116 static enum snvs_security_cfg snvs_get_security_cfg(void) 117 { 118 vaddr_t snvs = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 119 SNVS_HPSR + sizeof(uint32_t)); 120 uint32_t val = 0; 121 122 val = io_read32(snvs + SNVS_HPSR); 123 DMSG("HPSR: 0x%"PRIx32, val); 124 if (val & SNVS_HPSR_SYS_SECURITY_BAD) 125 return SNVS_SECURITY_CFG_FIELD_RETURN; 126 else if (val & SNVS_HPSR_SYS_SECURITY_CLOSED) 127 return SNVS_SECURITY_CFG_CLOSED; 128 else if (val & SNVS_HPSR_SYS_SECURITY_OPEN) 129 return SNVS_SECURITY_CFG_OPEN; 130 else if (val > 4 && val < 8) 131 return SNVS_SECURITY_CFG_OPEN; 132 133 return SNVS_SECURITY_CFG_FAB; 134 } 135 136 bool snvs_is_device_closed(void) 137 { 138 return (snvs_get_security_cfg() == SNVS_SECURITY_CFG_CLOSED); 139 } 140 141 #ifdef CFG_RPMB_FS 142 static enum snvs_ssm_mode snvs_get_ssm_mode(void) 143 { 144 vaddr_t snvs = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 145 SNVS_HPSR + sizeof(uint32_t)); 146 uint32_t val = 0; 147 148 val = io_read32(snvs + SNVS_HPSR); 149 val &= HPSR_SSM_ST_MASK; 150 val = val >> HPSR_SSM_ST_SHIFT; 151 DMSG("HPSR: SSM ST Mode: 0x%01"PRIx32, val); 152 return val; 153 } 154 155 bool plat_rpmb_key_is_ready(void) 156 { 157 enum snvs_ssm_mode mode = SNVS_SSM_MODE_INIT; 158 enum snvs_security_cfg security = SNVS_SECURITY_CFG_OPEN; 159 bool ssm_secure = false; 160 161 mode = snvs_get_ssm_mode(); 162 security = snvs_get_security_cfg(); 163 ssm_secure = (mode == SNVS_SSM_MODE_TRUSTED || 164 mode == SNVS_SSM_MODE_SECURE); 165 166 /* 167 * On i.MX6SDL and i.MX6DQ, the security cfg always returns 168 * SNVS_SECURITY_CFG_FAB (000), therefore we ignore the security 169 * configuration for this SoC. 170 */ 171 if (soc_is_imx6sdl() || soc_is_imx6dq()) 172 return ssm_secure; 173 174 return ssm_secure && (security == SNVS_SECURITY_CFG_CLOSED); 175 } 176 #endif /* CFG_RPMB_FS */ 177 178 TEE_Result imx_snvs_set_master_otpmk(void) 179 { 180 if (is_otpmk_valid()) 181 return TEE_ERROR_BAD_STATE; 182 183 if (is_mks_locked()) { 184 if (is_otpmk_selected()) 185 return TEE_SUCCESS; 186 187 return TEE_ERROR_BAD_STATE; 188 } 189 190 set_mks_otpmk(); 191 192 return TEE_SUCCESS; 193 } 194