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 #define SNVS_HPSR_SYS_SECURITY_CFG GENMASK_32(14, 12) 28 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 = 15, 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 uint32_t val = 0; 119 vaddr_t base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 120 SNVS_SIZE); 121 122 val = (io_read32(base + SNVS_HPSR) & SNVS_HPSR_SYS_SECURITY_CFG) >> 123 SNVS_HPSR_SYS_SECURITY_CFG_OFFSET; 124 125 switch (val) { 126 case 0b000: 127 return SNVS_SECURITY_CFG_FAB; 128 case 0b001: 129 return SNVS_SECURITY_CFG_OPEN; 130 case 0b011: 131 return SNVS_SECURITY_CFG_CLOSED; 132 default: 133 return SNVS_SECURITY_CFG_FIELD_RETURN; 134 } 135 } 136 137 bool snvs_is_device_closed(void) 138 { 139 return (snvs_get_security_cfg() == SNVS_SECURITY_CFG_CLOSED); 140 } 141 142 #ifdef CFG_RPMB_FS 143 static enum snvs_ssm_mode snvs_get_ssm_mode(void) 144 { 145 vaddr_t snvs = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC, 146 SNVS_HPSR + sizeof(uint32_t)); 147 uint32_t val = 0; 148 149 val = io_read32(snvs + SNVS_HPSR); 150 val &= HPSR_SSM_ST_MASK; 151 val = val >> HPSR_SSM_ST_SHIFT; 152 DMSG("HPSR: SSM ST Mode: 0x%01"PRIx32, val); 153 return val; 154 } 155 156 bool plat_rpmb_key_is_ready(void) 157 { 158 enum snvs_ssm_mode mode = SNVS_SSM_MODE_INIT; 159 bool ssm_secure = false; 160 161 mode = snvs_get_ssm_mode(); 162 ssm_secure = (mode == SNVS_SSM_MODE_TRUSTED || 163 mode == SNVS_SSM_MODE_SECURE); 164 165 /* 166 * On i.MX6SDL and i.MX6DQ, the security cfg always returns 167 * SNVS_SECURITY_CFG_FAB (000), therefore we ignore the security 168 * configuration for this SoC. 169 */ 170 if (soc_is_imx6sdl() || soc_is_imx6dq()) 171 return ssm_secure; 172 173 return ssm_secure && snvs_is_device_closed(); 174 } 175 #endif /* CFG_RPMB_FS */ 176 177 TEE_Result imx_snvs_set_master_otpmk(void) 178 { 179 if (!is_otpmk_valid()) 180 return TEE_ERROR_BAD_STATE; 181 182 if (is_mks_locked()) { 183 if (is_otpmk_selected()) 184 return TEE_SUCCESS; 185 186 return TEE_ERROR_BAD_STATE; 187 } 188 189 set_mks_otpmk(); 190 191 return TEE_SUCCESS; 192 } 193