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 */
is_otpmk_selected(void)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 */
is_mks_locked(void)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. */
set_mks_otpmk(void)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 */
is_otpmk_valid(void)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
snvs_get_security_cfg(void)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
snvs_is_device_closed(void)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
snvs_get_ssm_mode(void)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
plat_rpmb_key_is_ready(void)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
imx_snvs_set_master_otpmk(void)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