1 /* 2 * Copyright (c) 2022, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 #include <stdint.h> 10 11 #include <drivers/clk.h> 12 #include <drivers/delay_timer.h> 13 #include <drivers/st/stm32_pka.h> 14 #include <drivers/st/stm32mp_reset.h> 15 #include <lib/mmio.h> 16 #include <lib/utils.h> 17 #include <libfdt.h> 18 #include <plat/common/platform.h> 19 20 #include <platform_def.h> 21 22 /* 23 * For our comprehension in this file 24 * _len are in BITs 25 * _size are in BYTEs 26 * _nbw are in number of PKA_word (PKA_word = u64) 27 */ 28 29 #define UINT8_LEN 8U 30 #define UINT64_LEN (UINT8_LEN * sizeof(uint64_t)) 31 #define WORD_SIZE (sizeof(uint64_t)) 32 #define OP_NBW_FROM_LEN(len) (DIV_ROUND_UP_2EVAL((len), UINT64_LEN) + 1) 33 #define OP_NBW_FROM_SIZE(s) OP_NBW_FROM_LEN((s) * UINT8_LEN) 34 #define OP_SIZE_FROM_SIZE(s) (OP_NBW_FROM_SIZE(s) * WORD_SIZE) 35 36 #define DT_PKA_COMPAT "st,stm32-pka64" 37 38 #define MAX_ECC_SIZE_LEN 640U 39 #define MAX_EO_NBW OP_NBW_FROM_LEN(MAX_ECC_SIZE_LEN) 40 41 /* PKA registers */ 42 /* PKA control register */ 43 #define _PKA_CR 0x0U 44 /* PKA status register */ 45 #define _PKA_SR 0x4U 46 /* PKA clear flag register */ 47 #define _PKA_CLRFR 0x8U 48 /* PKA version register */ 49 #define _PKA_VERR 0x1FF4U 50 /* PKA identification register */ 51 #define _PKA_IPIDR 0x1FF8U 52 53 /* PKA control register fields */ 54 #define _PKA_CR_MODE_MASK GENMASK(13, 8) 55 #define _PKA_CR_MODE_SHIFT 8U 56 #define _PKA_CR_MODE_ADD 0x9U 57 #define _PKA_CR_MODE_ECDSA_VERIF 0x26U 58 #define _PKA_CR_START BIT(1) 59 #define _PKA_CR_EN BIT(0) 60 61 /* PKA status register fields */ 62 #define _PKA_SR_BUSY BIT(16) 63 #define _PKA_SR_LMF BIT(1) 64 #define _PKA_SR_INITOK BIT(0) 65 66 /* PKA it flag fields (used in CR, SR and CLRFR) */ 67 #define _PKA_IT_MASK (GENMASK(21, 19) | BIT(17)) 68 #define _PKA_IT_SHIFT 17U 69 #define _PKA_IT_OPERR BIT(21) 70 #define _PKA_IT_ADDRERR BIT(20) 71 #define _PKA_IT_RAMERR BIT(19) 72 #define _PKA_IT_PROCEND BIT(17) 73 74 /* PKA version register fields */ 75 #define _PKA_VERR_MAJREV_MASK GENMASK(7, 4) 76 #define _PKA_VERR_MAJREV_SHIFT 4U 77 #define _PKA_VERR_MINREV_MASK GENMASK(3, 0) 78 #define _PKA_VERR_MINREV_SHIFT 0U 79 80 /* RAM magic offset */ 81 #define _PKA_RAM_START 0x400U 82 #define _PKA_RAM_SIZE 5336U 83 84 /* ECDSA verification */ 85 #define _PKA_RAM_N_LEN 0x408U /* 64 */ 86 #define _PKA_RAM_P_LEN 0x4C8U /* 64 */ 87 #define _PKA_RAM_A_SIGN 0x468U /* 64 */ 88 #define _PKA_RAM_A 0x470U /* EOS */ 89 #define _PKA_RAM_P 0x4D0U /* EOS */ 90 #define _PKA_RAM_XG 0x678U /* EOS */ 91 #define _PKA_RAM_YG 0x6D0U /* EOS */ 92 #define _PKA_RAM_XQ 0x12F8U /* EOS */ 93 #define _PKA_RAM_YQ 0x1350U /* EOS */ 94 #define _PKA_RAM_SIGN_R 0x10E0U /* EOS */ 95 #define _PKA_RAM_SIGN_S 0xC68U /* EOS */ 96 #define _PKA_RAM_HASH_Z 0x13A8U /* EOS */ 97 #define _PKA_RAM_PRIME_N 0x1088U /* EOS */ 98 #define _PKA_RAM_ECDSA_VERIFY 0x5D0U /* 64 */ 99 #define _PKA_RAM_ECDSA_VERIFY_VALID 0xD60DULL 100 #define _PKA_RAM_ECDSA_VERIFY_INVALID 0xA3B7ULL 101 102 #define PKA_TIMEOUT_US 1000000U 103 #define TIMEOUT_US_1MS 1000U 104 #define PKA_RESET_DELAY 20U 105 106 struct curve_parameters { 107 uint32_t a_sign; /* 0 positive, 1 negative */ 108 uint8_t *a; /* Curve coefficient |a| */ 109 size_t a_size; 110 uint8_t *p; /* Curve modulus value */ 111 uint32_t p_len; 112 uint8_t *xg; /* Curve base point G coordinate x */ 113 size_t xg_size; 114 uint8_t *yg; /* Curve base point G coordinate y */ 115 size_t yg_size; 116 uint8_t *n; /* Curve prime order n */ 117 uint32_t n_len; 118 }; 119 120 static const struct curve_parameters curve_def[] = { 121 #if PKA_USE_NIST_P256 122 [PKA_NIST_P256] = { 123 .p_len = 256U, 124 .n_len = 256U, 125 .p = (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 128 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 129 .n = (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 130 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 131 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 132 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}, 133 .a_sign = 1U, 134 .a = (uint8_t[]){0x03}, 135 .a_size = 1U, 136 .xg = (uint8_t[]){0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 137 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 138 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 139 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96}, 140 .xg_size = 32U, 141 .yg = (uint8_t[]){0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 142 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 143 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 144 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5}, 145 .yg_size = 32U, 146 }, 147 #endif 148 #if PKA_USE_BRAINPOOL_P256R1 149 [PKA_BRAINPOOL_P256R1] = { 150 .p_len = 256, 151 .n_len = 256, 152 .p = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 153 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 154 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, 155 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77}, 156 .n = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 157 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 158 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, 159 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7}, 160 .a = (uint8_t[]){0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 161 0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7, 162 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, 163 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9}, 164 .a_size = 32U, 165 .xg = (uint8_t[]){0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 166 0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF, 167 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, 168 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62}, 169 .xg_size = 32U, 170 .yg = (uint8_t[]){0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 171 0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9, 172 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, 173 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97}, 174 .yg_size = 32U, 175 }, 176 #endif 177 #if PKA_USE_BRAINPOOL_P256T1 178 [PKA_BRAINPOOL_P256T1] = { 179 .p_len = 256, 180 .n_len = 256, 181 .p = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 182 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 183 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, 184 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77}, 185 .n = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 186 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 187 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, 188 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7}, 189 .a = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 190 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 191 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, 192 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x74}, 193 .a_size = 32U, 194 .xg = (uint8_t[]){0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 195 0x73, 0x22, 0x13, 0xB2, 0x3A, 0x65, 0x61, 0x49, 196 0xAF, 0xA1, 0x42, 0xC4, 0x7A, 0xAF, 0xBC, 0x2B, 197 0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13, 0x05, 0xF4}, 198 .xg_size = 32U, 199 .yg = (uint8_t[]){0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 200 0x7F, 0x7B, 0x22, 0xE1, 0x46, 0x44, 0x41, 0x7E, 201 0x69, 0xBC, 0xB6, 0xDE, 0x39, 0xD0, 0x27, 0x00, 202 0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25, 0xC9, 0xBE}, 203 .yg_size = 32U, 204 }, 205 #endif 206 #if PKA_USE_NIST_P521 207 [PKA_NIST_P521] = { 208 .p_len = 521, 209 .n_len = 521, 210 .p = (uint8_t[]){ 0x01, 0xff, 211 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 212 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 213 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 214 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 215 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 216 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 217 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 218 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 219 .n = (uint8_t[]){ 0x01, 0xff, 220 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 221 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 222 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 223 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 224 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 225 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0, 226 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae, 227 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09}, 228 .a_sign = 1, 229 .a = (uint8_t[]){0x03}, 230 .a_size = 1U, 231 .xg = (uint8_t[]){ 0xc6, 232 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 233 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 234 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 235 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 236 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 237 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 238 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 239 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66}, 240 .xg_size = 65U, 241 .yg = (uint8_t[]){ 0x01, 0x18, 242 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 243 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 244 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 245 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 246 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 247 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 248 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 249 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50}, 250 .yg_size = 66U, 251 }, 252 #endif 253 }; 254 255 static struct stm32_pka_platdata pka_pdata; 256 257 #pragma weak stm32_pka_get_platdata 258 259 int stm32_pka_get_platdata(struct stm32_pka_platdata *pdata) 260 { 261 return -ENODEV; 262 } 263 264 static int stm32_pka_parse_fdt(void) 265 { 266 int node; 267 struct dt_node_info info; 268 void *fdt; 269 270 if (fdt_get_address(&fdt) == 0) { 271 return -FDT_ERR_NOTFOUND; 272 } 273 274 node = dt_get_node(&info, -1, DT_PKA_COMPAT); 275 if (node < 0) { 276 ERROR("No PKA entry in DT\n"); 277 return -FDT_ERR_NOTFOUND; 278 } 279 280 if (info.status == DT_DISABLED) { 281 return -FDT_ERR_NOTFOUND; 282 } 283 284 if ((info.base == 0) || (info.clock < 0) || (info.reset < 0)) { 285 return -FDT_ERR_BADVALUE; 286 } 287 288 pka_pdata.base = (uintptr_t)info.base; 289 pka_pdata.clock_id = (unsigned long)info.clock; 290 pka_pdata.reset_id = (unsigned int)info.reset; 291 292 return 0; 293 } 294 295 static int pka_wait_bit(uintptr_t base, uint32_t bit) 296 { 297 uint64_t timeout = timeout_init_us(PKA_TIMEOUT_US); 298 299 while ((mmio_read_32(base + _PKA_SR) & bit) != bit) { 300 if (timeout_elapsed(timeout)) { 301 WARN("timeout waiting %x\n", bit); 302 return -ETIMEDOUT; 303 } 304 } 305 306 return 0; 307 308 } 309 310 static void pka_disable(uintptr_t base) 311 { 312 mmio_clrbits_32(base + _PKA_CR, _PKA_CR_EN); 313 } 314 315 static int pka_enable(uintptr_t base, uint32_t mode) 316 { 317 /* Set mode and disable interrupts */ 318 mmio_clrsetbits_32(base + _PKA_CR, _PKA_IT_MASK | _PKA_CR_MODE_MASK, 319 _PKA_CR_MODE_MASK & (mode << _PKA_CR_MODE_SHIFT)); 320 321 mmio_setbits_32(base + _PKA_CR, _PKA_CR_EN); 322 323 return pka_wait_bit(base, _PKA_SR_INITOK); 324 } 325 326 /* 327 * Data are already loaded in PKA internal RAM 328 * MODE is set 329 * We start process, and wait for its end. 330 */ 331 static int stm32_pka_process(uintptr_t base) 332 { 333 mmio_setbits_32(base + _PKA_CR, _PKA_CR_START); 334 335 return pka_wait_bit(base, _PKA_IT_PROCEND); 336 } 337 338 /** 339 * @brief Write ECC operand to PKA RAM. 340 * @note PKA expect to write u64 word, each u64 are: the least significant bit is 341 * bit 0; the most significant bit is bit 63. 342 * We write eo_nbw (ECC operand Size) u64, value that depends of the chosen 343 * prime modulus length in bits. 344 * First less signicant u64 is written to low address 345 * Most significant u64 to higher address. 346 * And at last address we write a u64(0x0) 347 * @note This function doesn't only manage endianness (as bswap64 do), but also 348 * complete most significant incomplete u64 with 0 (if data is not a u64 349 * multiple), and fill u64 last address with 0. 350 * @param addr: PKA_RAM address to write the buffer 'data' 351 * @param data: is a BYTE list with most significant bytes first 352 * @param data_size: nb of byte in data 353 * @param eo_nbw: is ECC Operand size in 64bits word (including the extra 0) 354 * (note it depends of the prime modulus length, not the data size) 355 * @retval 0 if OK. 356 * -EINVAL if data_size and eo_nbw are inconsistent, ie data doesn't 357 * fit in defined eo_nbw, or eo_nbw bigger than hardware limit. 358 */ 359 static int write_eo_data(uintptr_t addr, uint8_t *data, unsigned int data_size, 360 unsigned int eo_nbw) 361 { 362 uint32_t word_index; 363 int data_index; 364 365 if ((eo_nbw < OP_NBW_FROM_SIZE(data_size)) || (eo_nbw > MAX_EO_NBW)) { 366 return -EINVAL; 367 } 368 369 /* Fill value */ 370 data_index = (int)data_size - 1; 371 for (word_index = 0U; word_index < eo_nbw; word_index++) { 372 uint64_t tmp = 0ULL; 373 unsigned int i = 0U; /* index in the tmp U64 word */ 374 375 /* Stop if end of tmp or end of data */ 376 while ((i < sizeof(tmp)) && (data_index >= 0)) { 377 tmp |= (uint64_t)(data[data_index]) << (UINT8_LEN * i); 378 i++; /* Move byte index in current (u64)tmp */ 379 data_index--; /* Move to just next most significat byte */ 380 } 381 382 mmio_write_64(addr + word_index * sizeof(tmp), tmp); 383 } 384 385 return 0; 386 } 387 388 static unsigned int get_ecc_op_nbword(enum stm32_pka_ecdsa_curve_id cid) 389 { 390 if (cid >= ARRAY_SIZE(curve_def)) { 391 ERROR("CID %u is out of boundaries\n", cid); 392 panic(); 393 } 394 395 return OP_NBW_FROM_LEN(curve_def[cid].n_len); 396 } 397 398 static int stm32_pka_ecdsa_verif_configure_curve(uintptr_t base, enum stm32_pka_ecdsa_curve_id cid) 399 { 400 int ret; 401 unsigned int eo_nbw = get_ecc_op_nbword(cid); 402 403 mmio_write_64(base + _PKA_RAM_N_LEN, curve_def[cid].n_len); 404 mmio_write_64(base + _PKA_RAM_P_LEN, curve_def[cid].p_len); 405 mmio_write_64(base + _PKA_RAM_A_SIGN, curve_def[cid].a_sign); 406 407 ret = write_eo_data(base + _PKA_RAM_A, curve_def[cid].a, curve_def[cid].a_size, eo_nbw); 408 if (ret < 0) { 409 return ret; 410 } 411 412 ret = write_eo_data(base + _PKA_RAM_PRIME_N, 413 curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN), 414 eo_nbw); 415 if (ret < 0) { 416 return ret; 417 } 418 419 ret = write_eo_data(base + _PKA_RAM_P, curve_def[cid].p, 420 div_round_up(curve_def[cid].p_len, UINT8_LEN), eo_nbw); 421 if (ret < 0) { 422 return ret; 423 } 424 425 ret = write_eo_data(base + _PKA_RAM_XG, curve_def[cid].xg, curve_def[cid].xg_size, eo_nbw); 426 if (ret < 0) { 427 return ret; 428 } 429 430 ret = write_eo_data(base + _PKA_RAM_YG, curve_def[cid].yg, curve_def[cid].yg_size, eo_nbw); 431 if (ret < 0) { 432 return ret; 433 } 434 435 return 0; 436 } 437 438 static int stm32_pka_ecdsa_verif_check_return(uintptr_t base) 439 { 440 uint64_t value; 441 uint32_t sr; 442 443 sr = mmio_read_32(base + _PKA_SR); 444 if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) { 445 WARN("Detected error(s): %s%s%s\n", 446 (sr & _PKA_IT_OPERR) ? "Operation " : "", 447 (sr & _PKA_IT_ADDRERR) ? "Address " : "", 448 (sr & _PKA_IT_RAMERR) ? "RAM" : ""); 449 return -EINVAL; 450 } 451 452 value = mmio_read_64(base + _PKA_RAM_ECDSA_VERIFY); 453 if (value == _PKA_RAM_ECDSA_VERIFY_VALID) { 454 return 0; 455 } 456 457 if (value == _PKA_RAM_ECDSA_VERIFY_INVALID) { 458 return -EAUTH; 459 } 460 461 return -EINVAL; 462 } 463 464 /** 465 * @brief Check if BigInt stored in data is 0 466 * 467 * @param data: a BYTE array with most significant bytes first 468 * @param size: data size 469 * 470 * @retval: true: if data represents a 0 value (ie all bytes == 0) 471 * false: if data represents a non-zero value. 472 */ 473 static bool is_zero(uint8_t *data, unsigned int size) 474 { 475 unsigned int i; 476 477 for (i = 0U; i < size; i++) { 478 if (data[i] != 0U) { 479 return false; 480 } 481 } 482 483 return true; 484 } 485 486 /** 487 * @brief Compare two BigInt: 488 * @param xdata_a: a BYTE array with most significant bytes first 489 * @param size_a: nb of Byte of 'a' 490 * @param data_b: a BYTE array with most significant bytes first 491 * @param size_b: nb of Byte of 'b' 492 * 493 * @retval: true if data_a < data_b 494 * false if data_a >= data_b 495 */ 496 static bool is_smaller(uint8_t *data_a, unsigned int size_a, 497 uint8_t *data_b, unsigned int size_b) 498 { 499 unsigned int i; 500 501 i = MAX(size_a, size_b) + 1U; 502 do { 503 uint8_t a, b; 504 505 i--; 506 if (size_a < i) { 507 a = 0U; 508 } else { 509 a = data_a[size_a - i]; 510 } 511 512 if (size_b < i) { 513 b = 0U; 514 } else { 515 b = data_b[size_b - i]; 516 } 517 518 if (a < b) { 519 return true; 520 } 521 522 if (a > b) { 523 return false; 524 } 525 } while (i != 0U); 526 527 return false; 528 } 529 530 static int stm32_pka_ecdsa_check_param(void *sig_r_ptr, unsigned int sig_r_size, 531 void *sig_s_ptr, unsigned int sig_s_size, 532 void *pk_x_ptr, unsigned int pk_x_size, 533 void *pk_y_ptr, unsigned int pk_y_size, 534 enum stm32_pka_ecdsa_curve_id cid) 535 { 536 /* Public Key check */ 537 /* Check Xq < p */ 538 if (!is_smaller(pk_x_ptr, pk_x_size, 539 curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) { 540 WARN("%s Xq < p inval\n", __func__); 541 return -EINVAL; 542 } 543 544 /* Check Yq < p */ 545 if (!is_smaller(pk_y_ptr, pk_y_size, 546 curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) { 547 WARN("%s Yq < p inval\n", __func__); 548 return -EINVAL; 549 } 550 551 /* Signature check */ 552 /* Check 0 < r < n */ 553 if (!is_smaller(sig_r_ptr, sig_r_size, 554 curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) && 555 !is_zero(sig_r_ptr, sig_r_size)) { 556 WARN("%s 0< r < n inval\n", __func__); 557 return -EINVAL; 558 } 559 560 /* Check 0 < s < n */ 561 if (!is_smaller(sig_s_ptr, sig_s_size, 562 curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) && 563 !is_zero(sig_s_ptr, sig_s_size)) { 564 WARN("%s 0< s < n inval\n", __func__); 565 return -EINVAL; 566 } 567 568 return 0; 569 } 570 571 /* 572 * @brief Initialize the PKA driver. 573 * @param None. 574 * @retval 0 if OK, negative value else. 575 */ 576 int stm32_pka_init(void) 577 { 578 int err; 579 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 580 uint32_t ver; 581 uint32_t id; 582 #endif 583 584 err = stm32_pka_parse_fdt(); 585 if (err != 0) { 586 err = stm32_pka_get_platdata(&pka_pdata); 587 if (err != 0) { 588 return err; 589 } 590 } 591 592 clk_enable(pka_pdata.clock_id); 593 594 if (stm32mp_reset_assert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) { 595 panic(); 596 } 597 598 udelay(PKA_RESET_DELAY); 599 if (stm32mp_reset_deassert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) { 600 panic(); 601 } 602 603 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 604 id = mmio_read_32(pka_pdata.base + _PKA_IPIDR); 605 ver = mmio_read_32(pka_pdata.base + _PKA_VERR); 606 607 VERBOSE("STM32 PKA[%x] V%u.%u\n", id, 608 (ver & _PKA_VERR_MAJREV_MASK) >> _PKA_VERR_MAJREV_SHIFT, 609 (ver & _PKA_VERR_MINREV_MASK) >> _PKA_VERR_MINREV_SHIFT); 610 #endif 611 return 0; 612 } 613 614 int stm32_pka_ecdsa_verif(void *hash, unsigned int hash_size, 615 void *sig_r_ptr, unsigned int sig_r_size, 616 void *sig_s_ptr, unsigned int sig_s_size, 617 void *pk_x_ptr, unsigned int pk_x_size, 618 void *pk_y_ptr, unsigned int pk_y_size, 619 enum stm32_pka_ecdsa_curve_id cid) 620 { 621 int ret; 622 uintptr_t base = pka_pdata.base; 623 unsigned int eo_nbw = get_ecc_op_nbword(cid); 624 625 if ((hash == NULL) || (sig_r_ptr == NULL) || (sig_s_ptr == NULL) || 626 (pk_x_ptr == NULL) || (pk_y_ptr == NULL)) { 627 INFO("%s invalid input param\n", __func__); 628 return -EINVAL; 629 } 630 631 ret = stm32_pka_ecdsa_check_param(sig_r_ptr, sig_r_size, 632 sig_s_ptr, sig_s_size, 633 pk_x_ptr, pk_x_size, 634 pk_y_ptr, pk_y_size, 635 cid); 636 if (ret < 0) { 637 INFO("%s check param error %d\n", __func__, ret); 638 goto out; 639 } 640 641 if ((mmio_read_32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) { 642 INFO("%s busy\n", __func__); 643 ret = -EBUSY; 644 goto out; 645 } 646 647 /* Fill PKA RAM */ 648 /* With curve id values */ 649 ret = stm32_pka_ecdsa_verif_configure_curve(base, cid); 650 if (ret < 0) { 651 goto out; 652 } 653 654 /* With pubkey */ 655 ret = write_eo_data(base + _PKA_RAM_XQ, pk_x_ptr, pk_x_size, eo_nbw); 656 if (ret < 0) { 657 goto out; 658 } 659 660 ret = write_eo_data(base + _PKA_RAM_YQ, pk_y_ptr, pk_y_size, eo_nbw); 661 if (ret < 0) { 662 goto out; 663 } 664 665 /* With hash */ 666 ret = write_eo_data(base + _PKA_RAM_HASH_Z, hash, hash_size, eo_nbw); 667 if (ret < 0) { 668 goto out; 669 } 670 671 /* With signature */ 672 ret = write_eo_data(base + _PKA_RAM_SIGN_R, sig_r_ptr, sig_r_size, eo_nbw); 673 if (ret < 0) { 674 goto out; 675 } 676 677 ret = write_eo_data(base + _PKA_RAM_SIGN_S, sig_s_ptr, sig_s_size, eo_nbw); 678 if (ret < 0) { 679 goto out; 680 } 681 682 /* Set mode to ecdsa signature verification */ 683 ret = pka_enable(base, _PKA_CR_MODE_ECDSA_VERIF); 684 if (ret < 0) { 685 WARN("%s set mode pka error %d\n", __func__, ret); 686 goto out; 687 } 688 689 /* Start processing and wait end */ 690 ret = stm32_pka_process(base); 691 if (ret < 0) { 692 WARN("%s process error %d\n", __func__, ret); 693 goto out; 694 } 695 696 /* Check return status */ 697 ret = stm32_pka_ecdsa_verif_check_return(base); 698 699 /* Unset end proc */ 700 mmio_setbits_32(base + _PKA_CLRFR, _PKA_IT_PROCEND); 701 702 out: 703 /* Disable PKA (will stop all pending proccess and reset RAM) */ 704 pka_disable(base); 705 706 return ret; 707 } 708