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