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 static int stm32_pka_parse_fdt(void) 258 { 259 int node; 260 struct dt_node_info info; 261 void *fdt; 262 263 if (fdt_get_address(&fdt) == 0) { 264 return -FDT_ERR_NOTFOUND; 265 } 266 267 node = dt_get_node(&info, -1, DT_PKA_COMPAT); 268 if (node < 0) { 269 ERROR("No PKA entry in DT\n"); 270 return -FDT_ERR_NOTFOUND; 271 } 272 273 if (info.status == DT_DISABLED) { 274 return -FDT_ERR_NOTFOUND; 275 } 276 277 if ((info.base == 0) || (info.clock < 0) || (info.reset < 0)) { 278 return -FDT_ERR_BADVALUE; 279 } 280 281 pka_pdata.base = (uintptr_t)info.base; 282 pka_pdata.clock_id = (unsigned long)info.clock; 283 pka_pdata.reset_id = (unsigned int)info.reset; 284 285 return 0; 286 } 287 288 static int pka_wait_bit(uintptr_t base, uint32_t bit) 289 { 290 uint64_t timeout = timeout_init_us(PKA_TIMEOUT_US); 291 292 while ((mmio_read_32(base + _PKA_SR) & bit) != bit) { 293 if (timeout_elapsed(timeout)) { 294 WARN("timeout waiting %x\n", bit); 295 return -ETIMEDOUT; 296 } 297 } 298 299 return 0; 300 301 } 302 303 static void pka_disable(uintptr_t base) 304 { 305 mmio_clrbits_32(base + _PKA_CR, _PKA_CR_EN); 306 } 307 308 static int pka_enable(uintptr_t base, uint32_t mode) 309 { 310 /* Set mode and disable interrupts */ 311 mmio_clrsetbits_32(base + _PKA_CR, _PKA_IT_MASK | _PKA_CR_MODE_MASK, 312 _PKA_CR_MODE_MASK & (mode << _PKA_CR_MODE_SHIFT)); 313 314 mmio_setbits_32(base + _PKA_CR, _PKA_CR_EN); 315 316 return pka_wait_bit(base, _PKA_SR_INITOK); 317 } 318 319 /* 320 * Data are already loaded in PKA internal RAM 321 * MODE is set 322 * We start process, and wait for its end. 323 */ 324 static int stm32_pka_process(uintptr_t base) 325 { 326 mmio_setbits_32(base + _PKA_CR, _PKA_CR_START); 327 328 return pka_wait_bit(base, _PKA_IT_PROCEND); 329 } 330 331 /** 332 * @brief Write ECC operand to PKA RAM. 333 * @note PKA expect to write u64 word, each u64 are: the least significant bit is 334 * bit 0; the most significant bit is bit 63. 335 * We write eo_nbw (ECC operand Size) u64, value that depends of the chosen 336 * prime modulus length in bits. 337 * First less signicant u64 is written to low address 338 * Most significant u64 to higher address. 339 * And at last address we write a u64(0x0) 340 * @note This function doesn't only manage endianness (as bswap64 do), but also 341 * complete most significant incomplete u64 with 0 (if data is not a u64 342 * multiple), and fill u64 last address with 0. 343 * @param addr: PKA_RAM address to write the buffer 'data' 344 * @param data: is a BYTE list with most significant bytes first 345 * @param data_size: nb of byte in data 346 * @param eo_nbw: is ECC Operand size in 64bits word (including the extra 0) 347 * (note it depends of the prime modulus length, not the data size) 348 * @retval 0 if OK. 349 * -EINVAL if data_size and eo_nbw are inconsistent, ie data doesn't 350 * fit in defined eo_nbw, or eo_nbw bigger than hardware limit. 351 */ 352 static int write_eo_data(uintptr_t addr, uint8_t *data, unsigned int data_size, 353 unsigned int eo_nbw) 354 { 355 uint32_t word_index; 356 int data_index; 357 358 if ((eo_nbw < OP_NBW_FROM_SIZE(data_size)) || (eo_nbw > MAX_EO_NBW)) { 359 return -EINVAL; 360 } 361 362 /* Fill value */ 363 data_index = (int)data_size - 1; 364 for (word_index = 0U; word_index < eo_nbw; word_index++) { 365 uint64_t tmp = 0ULL; 366 unsigned int i = 0U; /* index in the tmp U64 word */ 367 368 /* Stop if end of tmp or end of data */ 369 while ((i < sizeof(tmp)) && (data_index >= 0)) { 370 tmp |= (uint64_t)(data[data_index]) << (UINT8_LEN * i); 371 i++; /* Move byte index in current (u64)tmp */ 372 data_index--; /* Move to just next most significat byte */ 373 } 374 375 mmio_write_64(addr + word_index * sizeof(tmp), tmp); 376 } 377 378 return 0; 379 } 380 381 static unsigned int get_ecc_op_nbword(enum stm32_pka_ecdsa_curve_id cid) 382 { 383 if (cid >= ARRAY_SIZE(curve_def)) { 384 ERROR("CID %u is out of boundaries\n", cid); 385 panic(); 386 } 387 388 return OP_NBW_FROM_LEN(curve_def[cid].n_len); 389 } 390 391 static int stm32_pka_ecdsa_verif_configure_curve(uintptr_t base, enum stm32_pka_ecdsa_curve_id cid) 392 { 393 int ret; 394 unsigned int eo_nbw = get_ecc_op_nbword(cid); 395 396 mmio_write_64(base + _PKA_RAM_N_LEN, curve_def[cid].n_len); 397 mmio_write_64(base + _PKA_RAM_P_LEN, curve_def[cid].p_len); 398 mmio_write_64(base + _PKA_RAM_A_SIGN, curve_def[cid].a_sign); 399 400 ret = write_eo_data(base + _PKA_RAM_A, curve_def[cid].a, curve_def[cid].a_size, eo_nbw); 401 if (ret < 0) { 402 return ret; 403 } 404 405 ret = write_eo_data(base + _PKA_RAM_PRIME_N, 406 curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN), 407 eo_nbw); 408 if (ret < 0) { 409 return ret; 410 } 411 412 ret = write_eo_data(base + _PKA_RAM_P, curve_def[cid].p, 413 div_round_up(curve_def[cid].p_len, UINT8_LEN), eo_nbw); 414 if (ret < 0) { 415 return ret; 416 } 417 418 ret = write_eo_data(base + _PKA_RAM_XG, curve_def[cid].xg, curve_def[cid].xg_size, eo_nbw); 419 if (ret < 0) { 420 return ret; 421 } 422 423 ret = write_eo_data(base + _PKA_RAM_YG, curve_def[cid].yg, curve_def[cid].yg_size, eo_nbw); 424 if (ret < 0) { 425 return ret; 426 } 427 428 return 0; 429 } 430 431 static int stm32_pka_ecdsa_verif_check_return(uintptr_t base) 432 { 433 uint64_t value; 434 uint32_t sr; 435 436 sr = mmio_read_32(base + _PKA_SR); 437 if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) { 438 WARN("Detected error(s): %s%s%s\n", 439 (sr & _PKA_IT_OPERR) ? "Operation " : "", 440 (sr & _PKA_IT_ADDRERR) ? "Address " : "", 441 (sr & _PKA_IT_RAMERR) ? "RAM" : ""); 442 return -EINVAL; 443 } 444 445 value = mmio_read_64(base + _PKA_RAM_ECDSA_VERIFY); 446 if (value == _PKA_RAM_ECDSA_VERIFY_VALID) { 447 return 0; 448 } 449 450 if (value == _PKA_RAM_ECDSA_VERIFY_INVALID) { 451 return -EAUTH; 452 } 453 454 return -EINVAL; 455 } 456 457 /** 458 * @brief Check if BigInt stored in data is 0 459 * 460 * @param data: a BYTE array with most significant bytes first 461 * @param size: data size 462 * 463 * @retval: true: if data represents a 0 value (ie all bytes == 0) 464 * false: if data represents a non-zero value. 465 */ 466 static bool is_zero(uint8_t *data, unsigned int size) 467 { 468 unsigned int i; 469 470 for (i = 0U; i < size; i++) { 471 if (data[i] != 0U) { 472 return false; 473 } 474 } 475 476 return true; 477 } 478 479 /** 480 * @brief Compare two BigInt: 481 * @param xdata_a: a BYTE array with most significant bytes first 482 * @param size_a: nb of Byte of 'a' 483 * @param data_b: a BYTE array with most significant bytes first 484 * @param size_b: nb of Byte of 'b' 485 * 486 * @retval: true if data_a < data_b 487 * false if data_a >= data_b 488 */ 489 static bool is_smaller(uint8_t *data_a, unsigned int size_a, 490 uint8_t *data_b, unsigned int size_b) 491 { 492 unsigned int i; 493 494 i = MAX(size_a, size_b) + 1U; 495 do { 496 uint8_t a, b; 497 498 i--; 499 if (size_a < i) { 500 a = 0U; 501 } else { 502 a = data_a[size_a - i]; 503 } 504 505 if (size_b < i) { 506 b = 0U; 507 } else { 508 b = data_b[size_b - i]; 509 } 510 511 if (a < b) { 512 return true; 513 } 514 515 if (a > b) { 516 return false; 517 } 518 } while (i != 0U); 519 520 return false; 521 } 522 523 static int stm32_pka_ecdsa_check_param(void *sig_r_ptr, unsigned int sig_r_size, 524 void *sig_s_ptr, unsigned int sig_s_size, 525 void *pk_x_ptr, unsigned int pk_x_size, 526 void *pk_y_ptr, unsigned int pk_y_size, 527 enum stm32_pka_ecdsa_curve_id cid) 528 { 529 /* Public Key check */ 530 /* Check Xq < p */ 531 if (!is_smaller(pk_x_ptr, pk_x_size, 532 curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) { 533 WARN("%s Xq < p inval\n", __func__); 534 return -EINVAL; 535 } 536 537 /* Check Yq < p */ 538 if (!is_smaller(pk_y_ptr, pk_y_size, 539 curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) { 540 WARN("%s Yq < p inval\n", __func__); 541 return -EINVAL; 542 } 543 544 /* Signature check */ 545 /* Check 0 < r < n */ 546 if (!is_smaller(sig_r_ptr, sig_r_size, 547 curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) && 548 !is_zero(sig_r_ptr, sig_r_size)) { 549 WARN("%s 0< r < n inval\n", __func__); 550 return -EINVAL; 551 } 552 553 /* Check 0 < s < n */ 554 if (!is_smaller(sig_s_ptr, sig_s_size, 555 curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) && 556 !is_zero(sig_s_ptr, sig_s_size)) { 557 WARN("%s 0< s < n inval\n", __func__); 558 return -EINVAL; 559 } 560 561 return 0; 562 } 563 564 /* 565 * @brief Initialize the PKA driver. 566 * @param None. 567 * @retval 0 if OK, negative value else. 568 */ 569 int stm32_pka_init(void) 570 { 571 int err; 572 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 573 uint32_t ver; 574 uint32_t id; 575 #endif 576 577 err = stm32_pka_parse_fdt(); 578 if (err != 0) { 579 return err; 580 } 581 582 clk_enable(pka_pdata.clock_id); 583 584 if (stm32mp_reset_assert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) { 585 panic(); 586 } 587 588 udelay(PKA_RESET_DELAY); 589 if (stm32mp_reset_deassert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) { 590 panic(); 591 } 592 593 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 594 id = mmio_read_32(pka_pdata.base + _PKA_IPIDR); 595 ver = mmio_read_32(pka_pdata.base + _PKA_VERR); 596 597 VERBOSE("STM32 PKA[%x] V%u.%u\n", id, 598 (ver & _PKA_VERR_MAJREV_MASK) >> _PKA_VERR_MAJREV_SHIFT, 599 (ver & _PKA_VERR_MINREV_MASK) >> _PKA_VERR_MINREV_SHIFT); 600 #endif 601 return 0; 602 } 603 604 int stm32_pka_ecdsa_verif(void *hash, unsigned int hash_size, 605 void *sig_r_ptr, unsigned int sig_r_size, 606 void *sig_s_ptr, unsigned int sig_s_size, 607 void *pk_x_ptr, unsigned int pk_x_size, 608 void *pk_y_ptr, unsigned int pk_y_size, 609 enum stm32_pka_ecdsa_curve_id cid) 610 { 611 int ret; 612 uintptr_t base = pka_pdata.base; 613 unsigned int eo_nbw = get_ecc_op_nbword(cid); 614 615 if ((hash == NULL) || (sig_r_ptr == NULL) || (sig_s_ptr == NULL) || 616 (pk_x_ptr == NULL) || (pk_y_ptr == NULL)) { 617 INFO("%s invalid input param\n", __func__); 618 return -EINVAL; 619 } 620 621 ret = stm32_pka_ecdsa_check_param(sig_r_ptr, sig_r_size, 622 sig_s_ptr, sig_s_size, 623 pk_x_ptr, pk_x_size, 624 pk_y_ptr, pk_y_size, 625 cid); 626 if (ret < 0) { 627 INFO("%s check param error %d\n", __func__, ret); 628 goto out; 629 } 630 631 if ((mmio_read_32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) { 632 INFO("%s busy\n", __func__); 633 ret = -EBUSY; 634 goto out; 635 } 636 637 /* Fill PKA RAM */ 638 /* With curve id values */ 639 ret = stm32_pka_ecdsa_verif_configure_curve(base, cid); 640 if (ret < 0) { 641 goto out; 642 } 643 644 /* With pubkey */ 645 ret = write_eo_data(base + _PKA_RAM_XQ, pk_x_ptr, pk_x_size, eo_nbw); 646 if (ret < 0) { 647 goto out; 648 } 649 650 ret = write_eo_data(base + _PKA_RAM_YQ, pk_y_ptr, pk_y_size, eo_nbw); 651 if (ret < 0) { 652 goto out; 653 } 654 655 /* With hash */ 656 ret = write_eo_data(base + _PKA_RAM_HASH_Z, hash, hash_size, eo_nbw); 657 if (ret < 0) { 658 goto out; 659 } 660 661 /* With signature */ 662 ret = write_eo_data(base + _PKA_RAM_SIGN_R, sig_r_ptr, sig_r_size, eo_nbw); 663 if (ret < 0) { 664 goto out; 665 } 666 667 ret = write_eo_data(base + _PKA_RAM_SIGN_S, sig_s_ptr, sig_s_size, eo_nbw); 668 if (ret < 0) { 669 goto out; 670 } 671 672 /* Set mode to ecdsa signature verification */ 673 ret = pka_enable(base, _PKA_CR_MODE_ECDSA_VERIF); 674 if (ret < 0) { 675 WARN("%s set mode pka error %d\n", __func__, ret); 676 goto out; 677 } 678 679 /* Start processing and wait end */ 680 ret = stm32_pka_process(base); 681 if (ret < 0) { 682 WARN("%s process error %d\n", __func__, ret); 683 goto out; 684 } 685 686 /* Check return status */ 687 ret = stm32_pka_ecdsa_verif_check_return(base); 688 689 /* Unset end proc */ 690 mmio_setbits_32(base + _PKA_CLRFR, _PKA_IT_PROCEND); 691 692 out: 693 /* Disable PKA (will stop all pending proccess and reset RAM) */ 694 pka_disable(base); 695 696 return ret; 697 } 698