1 /* 2 * Copyright (c) 2023, The TrustedFirmware-M Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef CC3XX_PKA_H 9 #define CC3XX_PKA_H 10 11 #include <stdint.h> 12 #include <stddef.h> 13 #include <stdbool.h> 14 15 #include "cc3xx_error.h" 16 17 #define CC3XX_PKA_REG_N 0 18 #define CC3XX_PKA_REG_NP 1 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 typedef uint32_t cc3xx_pka_reg_id_t; 25 26 struct cc3xx_pka_state_t { 27 uint32_t reg_size; 28 uint32_t virt_reg_next_mapped; 29 }; 30 31 /** 32 * @brief Initialize the PKA engine. 33 * 34 * @param[in] size The size of operations the PKA engine will be 35 * performing, in bytes. This is a maximum, 36 * operations on values smaller than this size can 37 * be carried out. Larger size allocations may 38 * result in less registers being available. Note 39 * that register values can exceed this size, but 40 * operations on values larger than this may 41 * overflow and produce incorrect results. 42 * 43 */ 44 void cc3xx_lowlevel_pka_init(uint32_t size); 45 46 /** 47 * @brief Allocates a PKA register. 48 * 49 * @return A PKA register Identifier. Note that this 50 * function does not return an error code when 51 * allocation fails (but will fail an assertion), 52 * so the amount of registers used in a PKA 53 * session must be constant, otherwise non-debug 54 * builds will have silent allocation failures 55 * leading to unpredictable behaviour. 56 */ 57 cc3xx_pka_reg_id_t cc3xx_lowlevel_pka_allocate_reg(void); 58 59 /** 60 * @brief Unamp all mapped physical registers at once 61 * 62 */ 63 void cc3xx_lowlevel_pka_unmap_physical_registers(void); 64 65 /** 66 * @brief Free a PKA register, returning it to the pool 67 * so it can be reallocated. 68 * 69 * @param[in] id The register ID to be freed. 70 */ 71 void cc3xx_lowlevel_pka_free_reg(cc3xx_pka_reg_id_t reg_id); 72 73 /** 74 * @brief Write data into a PKA register. 75 * 76 * @param[in] id The register ID to write data into. 77 * @param[in] data The data to be written to the register. 78 * @param[in] len The size in bytes of the data. Must be a 79 * multiple of sizeof(uint32_t). Should be less 80 * than or equal to the operation size. 81 */ 82 void cc3xx_lowlevel_pka_write_reg(cc3xx_pka_reg_id_t reg_id, const uint32_t *data, size_t len); 83 /** 84 * @brief Write data into a PKA register, performing an 85 * endianness swap on each word. 86 * 87 * @param[in] id The register ID to write data into. 88 * @param[in] data The data to be written to the register. 89 * @param[in] len The size in bytes of the data. Must be a 90 * multiple of sizeof(uint32_t). Should be less 91 * than or equal to the operation size. 92 */ 93 void cc3xx_lowlevel_pka_write_reg_swap_endian(cc3xx_pka_reg_id_t reg_id, const uint32_t *data, size_t len); 94 95 /** 96 * @brief Read data from a PKA register. 97 * 98 * @param[in] id The register ID to write data into. 99 * @param[out] data Buffer the data will be written into. 100 * @param[in] len The size in bytes of the data to be read. Must 101 * be a multiple of sizeof(uint32_t). The buffer 102 * must be of at least this size. 103 */ 104 void cc3xx_lowlevel_pka_read_reg(cc3xx_pka_reg_id_t id, uint32_t *data, size_t len); 105 /** 106 * @brief Read data from a PKA register, performing an 107 * endianness swap on each word. 108 * 109 * @param[in] id The register ID to write data into. 110 * @param[out] data Buffer the data will be written into. 111 * @param[in] len The size in bytes of the data to be read. Must 112 * be a multiple of sizeof(uint32_t). The buffer 113 * must be of at least this size. 114 */ 115 void cc3xx_lowlevel_pka_read_reg_swap_endian(cc3xx_pka_reg_id_t id, uint32_t *data, size_t len); 116 117 /** 118 * @brief Set the modulus of a PKA session. This must be 119 * called before any pka_mod_* operations are used. 120 * For PKA sessions which do not use any of the 121 * pka_mod_* operations, this function does not 122 * need to be called. 123 * 124 * @param[in] modulus The register that will be used as the modulus. 125 * @param[in] calculate_tag Whether the barrett tag should be calculated. If 126 * this is set then the barrett_tag argument will 127 * be ignored. 128 * @param[in] barrett_tag The register that will be used as the barrett 129 * tag. 130 */ 131 void cc3xx_lowlevel_pka_set_modulus(cc3xx_pka_reg_id_t modulus, bool calculate_tag, 132 cc3xx_pka_reg_id_t barrett_tag); 133 134 /** 135 * @brief Get the state of the PKA engine, and save the 136 * contents of a selected subset of the PKA 137 * registers. 138 * 139 * @param[out] state A pointer to which the state of the PKA engine 140 * will be written 141 * @param[in] save_reg_am The amount of registers which will be saved. 142 * @param[in] save_reg_list A list of registers IDs which will be saved. 143 * Must be ``save_reg_am`` elements long. 144 * @param[in] save_reg_ptr_list A list of pointers to which the register 145 * contents will be written. The order must 146 * correspond to the order of ``save_reg_list``. 147 * Must be ``save_reg_am`` elements long. 148 * @param[in] save_reg_size_list A list of sizes of the registers which will be 149 * saved. Each buffer pointed to by 150 * ``save_reg_ptr_list`` must be at least the 151 * size of the corresponding element of this 152 * list. The order must correspond to the order 153 * of ``save_reg_list``. Must be ``save_reg_am`` 154 * elements long. 155 */ 156 void cc3xx_lowlevel_pka_get_state(struct cc3xx_pka_state_t *state, uint32_t save_reg_am, 157 cc3xx_pka_reg_id_t *save_reg_list, 158 uint32_t **save_reg_ptr_list, 159 const size_t *save_reg_size_list); 160 /** 161 * @brief Set the state of the PKA engine, and load the 162 * contents of a selected subset of the PKA 163 * registers. 164 * 165 * @param[out] state A pointer to which the state of the PKA engine 166 * will be read from 167 * @param[in] load_reg_am The amount of registers which will be loaded. 168 * @param[in] load_reg_list A list of registers IDs which will be loaded. 169 * Must be ``load_reg_am`` elements long. 170 * @param[in] load_reg_ptr_list A list of pointers from which the register 171 * contents will be read. The order must 172 * correspond to the order of ``load_reg_list``. 173 * Must be ``load_reg_am`` elements long. 174 * @param[in] load_reg_size_list A list of sizes of the registers which will be 175 * loaded. Each buffer pointed to by 176 * ``load_reg_ptr_list`` must be at least the 177 * size of the corresponding element of this 178 * list. The order must correspond to the order 179 * of ``load_reg_list``. Must be ``load_reg_am`` 180 * elements long. 181 * 182 * @note This function also initializes the PKA engine, 183 * so it can be used once this function has been 184 * called. 185 */ 186 void cc3xx_lowlevel_pka_set_state(const struct cc3xx_pka_state_t *state, 187 uint32_t load_reg_am, cc3xx_pka_reg_id_t *load_reg_list, 188 const uint32_t **load_reg_ptr_list, 189 const size_t *load_reg_size_list); 190 /** 191 * @brief Uninitialize the PKA engine. 192 */ 193 void cc3xx_lowlevel_pka_uninit(void); 194 195 /** 196 * @brief Get the size in bits of the contents of a 197 * register. 198 * 199 * @param[in] r0 The register ID to count the bits of. 200 * 201 * @note This does not return the register size, but the 202 * size of the number it contains. 203 * 204 * @return The number of bits. 205 */ 206 uint32_t cc3xx_lowlevel_pka_get_bit_size(cc3xx_pka_reg_id_t r0); 207 208 /** 209 * @brief Set a register to a power of 2. 210 * 211 * @param[in] r0 The register ID to set. 212 * @param[in] power The power to set the register to. 213 */ 214 void cc3xx_lowlevel_pka_set_to_power_of_two(cc3xx_pka_reg_id_t r0, uint32_t power); 215 216 /** 217 * @brief Set a register to a random value. All words in 218 * the register will be set to random values. 219 * 220 * @param[in] r0 The register ID to set. 221 * @param[in] bit_len Amount of bits of randomness to input. Must not 222 * be larger than the size the PKA operation was 223 * instanciated with. 224 * 225 * @return CC3XX_ERR_SUCCESS on success, another 226 * cc3xx_err_t on error. 227 */ 228 cc3xx_err_t cc3xx_lowlevel_pka_set_to_random(cc3xx_pka_reg_id_t r0, size_t bit_len); 229 230 /** 231 * @brief Set a register to a random value which is less 232 * than the modulus register. Will retry to avoid 233 * bias. 234 * 235 * @param[in] r0 The register ID to set. 236 * 237 * @return CC3XX_ERR_SUCCESS on success, another 238 * cc3xx_err_t on error. 239 */ 240 cc3xx_err_t cc3xx_lowlevel_pka_set_to_random_within_modulus(cc3xx_pka_reg_id_t r0); 241 242 /** 243 * @brief Add the values in two registers. res = r0 + r1. 244 * 245 * @param[in] r0 The register ID of the first operand. 246 * @param[in] r1 The register ID of the second operand. 247 * @param[out] res The register ID the result will be stored in. 248 * 249 * @note It is acceptable to have some or all of the 250 * register IDs be identical. 251 */ 252 void cc3xx_lowlevel_pka_add(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 253 /** 254 * @brief Add the values in a register with a signed 255 * immediate. res = r0 + imm. 256 * 257 * @param[in] r0 The register ID of the first operand. 258 * @param[in] imm The signed immediate, which must be in the range 259 * -16 to 15 inclusive. 260 * @param[out] res The register ID the result will be stored in. 261 * 262 * @note It is acceptable to have some or all of the 263 * register IDs be identical. 264 */ 265 void cc3xx_lowlevel_pka_add_si(cc3xx_pka_reg_id_t r0, int32_t imm, cc3xx_pka_reg_id_t res); 266 267 /** 268 * @brief Subtract the value in one register from the 269 * other. res = r0 - r1. 270 * 271 * @param[in] r0 The register ID of the first operand. 272 * @param[in] r1 The register ID of the second operand. 273 * @param[out] res The register ID the result will be stored in. 274 * 275 * @note It is acceptable to have some or all of the 276 * register IDs be identical. 277 */ 278 void cc3xx_lowlevel_pka_sub(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 279 /** 280 * @brief Subtract a signed immediate from the value in a 281 * register. res = r0 - imm. 282 * 283 * @param[in] r0 The register ID of the first operand. 284 * @param[in] imm The signed immediate, which must be in the range 285 * -16 to 15 inclusive. 286 * @param[out] res The register ID the result will be stored in. 287 * 288 * @note It is acceptable to have some or all of the 289 * register IDs be identical. 290 */ 291 void cc3xx_lowlevel_pka_sub_si(cc3xx_pka_reg_id_t r0, int32_t imm, cc3xx_pka_reg_id_t res); 292 293 /** 294 * @brief Negate the value in a register. res = 0 - r0. 295 * 296 * @param[in] r0 The register ID of the first operand. 297 * @param[out] res The register ID the result will be stored in. 298 * 299 * @note It is acceptable to have some or all of the 300 * register IDs be identical. 301 */ 302 void cc3xx_lowlevel_pka_neg(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t res); 303 304 /** 305 * @brief Add the values in two registers, and perform 306 * modular reduction. res = (r0 + r1) mod N. 307 * 308 * @param[in] r0 The register ID of the first operand. 309 * @param[in] r1 The register ID of the second operand. 310 * @param[out] res The register ID the result will be stored in. 311 * 312 * 313 * @note It is acceptable to have some or all of the 314 * register IDs be identical. 315 * 316 * @note r0 and r1 must be less than the modulus N. 317 */ 318 void cc3xx_lowlevel_pka_mod_add(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 319 /** 320 * @brief Add the values in a register with a signed 321 * immediate, and perform modular reduction. 322 * res = (r0 + imm) mod N. 323 * 324 * @param[in] r0 The register ID of the first operand. 325 * @param[in] imm The signed immediate, which must be in the range 326 * -16 to 15 inclusive. 327 * @param[out] res The register ID the result will be stored in. 328 * 329 * @note It is acceptable to have some or all of the 330 * register IDs be identical. 331 * 332 * @note r0 must be less than the modulus N. 333 */ 334 void cc3xx_lowlevel_pka_mod_add_si(cc3xx_pka_reg_id_t r0, int32_t imm, cc3xx_pka_reg_id_t res); 335 336 /** 337 * @brief Subtract the value in one register from the 338 * other, performing modular reduction. 339 * res = (r0 - r1) mod N. 340 * 341 * @param[in] r0 The register ID of the first operand. 342 * @param[in] r1 The register ID of the second operand. 343 * @param[out] res The register ID the result will be stored in. 344 * 345 * @note It is acceptable to have some or all of the 346 * register IDs be identical. 347 * 348 * @note r0 and r1 must be less than the modulus N. 349 */ 350 void cc3xx_lowlevel_pka_mod_sub(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 351 /** 352 * @brief Subtract a signed immediate from the value in a 353 * register, performing modular reduction. 354 * res = (r0 - imm) mod N. 355 * 356 * @param[in] r0 The register ID of the first operand. 357 * @param[in] imm The signed immediate, which must be in the range 358 * -16 to 15 inclusive. 359 * @param[out] res The register ID the result will be stored in. 360 * 361 * @note It is acceptable to have some or all of the 362 * register IDs be identical. 363 * 364 * @note r0 must be less than the modulus N. 365 */ 366 void cc3xx_lowlevel_pka_mod_sub_si(cc3xx_pka_reg_id_t r0, int32_t imm, cc3xx_pka_reg_id_t res); 367 368 /** 369 * @brief Negate the value in a register, and perform 370 * modular reduction. res = (0 - r0) mod N. 371 * 372 * @param[in] r0 The register ID of the first operand. 373 * @param[out] res The register ID the result will be stored in. 374 * 375 * @note It is acceptable to have some or all of the 376 * register IDs be identical. 377 * 378 * @note r0 must be less than the modulus N. 379 */ 380 void cc3xx_lowlevel_pka_mod_neg(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t res); 381 382 /** 383 * @brief Set the output register to the bitwise AND of 384 * two input registers. res = r0 & r1. 385 * 386 * @param[in] r0 The register ID of the first operand. 387 * @param[in] r1 The register ID of the second operand. 388 * @param[out] res The register ID the result will be stored in. 389 * 390 * @note It is acceptable to have some or all of the 391 * register IDs be identical. 392 */ 393 void cc3xx_lowlevel_pka_and(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 394 /** 395 * @brief Set the output register to the bitwise AND of 396 * a register and an unsigned mask. res = r0 & imm. 397 * 398 * @param[in] r0 The register ID of the first operand. 399 * @param[in] mask The unsigned mask, which must be in the range 400 * 0 to 32 inclusive. 401 * @param[out] res The register ID the result will be stored in. 402 * 403 * @note It is acceptable to have some or all of the 404 * register IDs be identical. 405 */ 406 void cc3xx_lowlevel_pka_and_si(cc3xx_pka_reg_id_t r0, uint32_t mask, cc3xx_pka_reg_id_t res); 407 408 /** 409 * @brief Check if a bits are set in a register. 410 * 411 * @param[in] r0 The register ID of the first operand. 412 * @param[in] idx The index of the bits to check. 413 * @param[in] bit_am The amount of bits to check. 414 * 415 * @return The bits requested. 416 */ 417 uint32_t cc3xx_lowlevel_pka_test_bits_ui(cc3xx_pka_reg_id_t r0, uint32_t idx, uint32_t bit_am); 418 419 /** 420 * @brief Clear a bit in a register. 421 * res = r0 & (1 << idx). 422 * 423 * @param[in] r0 The register ID of the first operand. 424 * @param[in] idx The index of the bit to be cleared. 425 * @param[out] res The register ID the result will be stored in. 426 */ 427 void cc3xx_lowlevel_pka_clear_bit(cc3xx_pka_reg_id_t r0, uint32_t idx, cc3xx_pka_reg_id_t res); 428 429 /** 430 * @brief Clear a register. r0 = 0. 431 * 432 * @param[in] r0 The register ID of the first operand. 433 */ 434 void cc3xx_lowlevel_pka_clear(cc3xx_pka_reg_id_t r0); 435 436 /** 437 * @brief Set the output register to the bitwise OR of 438 * two input registers. res = r0 | r1. 439 * 440 * @param[in] r0 The register ID of the first operand. 441 * @param[in] r1 The register ID of the second operand. 442 * @param[out] res The register ID the result will be stored in. 443 * 444 * @note It is acceptable to have some or all of the 445 * register IDs be identical. 446 */ 447 void cc3xx_lowlevel_pka_or(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 448 /** 449 * @brief Set the output register to the bitwise OR of 450 * a register and an unsigned mask. res = r0 | imm. 451 * 452 * @param[in] r0 The register ID of the first operand. 453 * @param[in] mask The unsigned mask, which must be in the range 454 * 0 to 32 inclusive. 455 * @param[out] res The register ID the result will be stored in. 456 * 457 * @note It is acceptable to have some or all of the 458 * register IDs be identical. 459 */ 460 void cc3xx_lowlevel_pka_or_si(cc3xx_pka_reg_id_t r0, uint32_t mask, cc3xx_pka_reg_id_t res); 461 462 /** 463 * @brief Copy a register into another one. res = r0. 464 * 465 * @param[in] r0 The register ID of the first operand. 466 * @param[out] res The register ID the result will be stored in. 467 * 468 * @note It is acceptable to have some or all of the 469 * register IDs be identical. 470 */ 471 void cc3xx_lowlevel_pka_copy(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t res); 472 473 /** 474 * @brief Set a bit in a register. 475 * res = r0 | (1 << idx). 476 * 477 * @param[in] r0 The register ID of the first operand. 478 * @param[in] idx The index of the bit to be set. 479 * @param[out] res The register ID the result will be stored in. 480 */ 481 void cc3xx_lowlevel_pka_set_bit(cc3xx_pka_reg_id_t r0, uint32_t idx, cc3xx_pka_reg_id_t res); 482 483 /** 484 * @brief Set the output register to the bitwise XOR of 485 * two input registers. res = r0 ^ r1. 486 * 487 * @param[in] r0 The register ID of the first operand. 488 * @param[in] r1 The register ID of the second operand. 489 * @param[out] res The register ID the result will be stored in. 490 * 491 * @note It is acceptable to have some or all of the 492 * register IDs be identical. 493 */ 494 void cc3xx_lowlevel_pka_xor(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 495 /** 496 * @brief Set the output register to the bitwise XOR of 497 * a register and an unsigned mask. res = r0 ^ imm. 498 * 499 * @param[in] r0 The register ID of the first operand. 500 * @param[in] mask The unsigned mask, which must be in the range 501 * 0 to 32 inclusive. 502 * @param[out] res The register ID the result will be stored in. 503 * 504 * @note It is acceptable to have some or all of the 505 * register IDs be identical. 506 */ 507 void cc3xx_lowlevel_pka_xor_si(cc3xx_pka_reg_id_t r0, uint32_t mask, cc3xx_pka_reg_id_t res); 508 509 /** 510 * @brief Flip a bit in a register. 511 * res = r0 ^ (1 << idx). 512 * 513 * @param[in] r0 The register ID of the first operand. 514 * @param[in] idx The index of the bit to be flipped. 515 * @param[out] res The register ID the result will be stored in. 516 */ 517 void cc3xx_lowlevel_pka_flip_bit(cc3xx_pka_reg_id_t r0, uint32_t idx, cc3xx_pka_reg_id_t res); 518 519 /** 520 * @brief Check if two registers are equal. 521 * retval = r0 == r1. 522 * 523 * @param[in] r0 The register ID of the first operand. 524 * @param[in] r1 The register ID of the second operand. 525 * 526 * @return true if registers are equal, false otherwise. 527 */ 528 bool cc3xx_lowlevel_pka_are_equal(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1); 529 /** 530 * @brief Check if a register is equal to n signed 531 * immediate. retval = r0 == imm. 532 * 533 * @param[in] r0 The register ID of the first operand. 534 * @param[in] imm The signed immediate, which must be in the range 535 * -16 to 15 inclusive. 536 * 537 * @return true if register and immediate are equal, false 538 * otherwise. 539 */ 540 bool cc3xx_lowlevel_pka_are_equal_si(cc3xx_pka_reg_id_t r0, int32_t imm); 541 542 /** 543 * @brief Check if a register is less than another 544 * register. retval = r0 < r1. 545 * 546 * @param[in] r0 The register ID of the first operand. 547 * @param[in] r1 The register ID of the second operand. 548 * 549 * @return true if r0 is less than r1, false otherwise. 550 */ 551 bool cc3xx_lowlevel_pka_less_than(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1); 552 /** 553 * @brief Check if a register is less than a signed 554 * immediate. retval = r0 < imm. 555 * 556 * @param[in] r0 The register ID of the first operand. 557 * @param[in] r1 The register ID of the second operand. 558 * 559 * @return true if r0 is less than imm, false otherwise. 560 */ 561 bool cc3xx_lowlevel_pka_less_than_si(cc3xx_pka_reg_id_t r0, int32_t imm); 562 563 /** 564 * @brief Check if a register is greater than another 565 * register. retval = r0 > r1. 566 * 567 * @param[in] r0 The register ID of the first operand. 568 * @param[in] r1 The register ID of the second operand. 569 * 570 * @return true if r0 is greater than r1, false otherwise. 571 */ 572 bool cc3xx_lowlevel_pka_greater_than(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1); 573 /** 574 * @brief Check if a register is greater than a signed 575 * immediate. retval = r0 > imm. 576 * 577 * @param[in] r0 The register ID of the first operand. 578 * @param[in] r1 The register ID of the second operand. 579 * 580 * @return true if r0 is greater than imm, false otherwise. 581 */ 582 bool cc3xx_lowlevel_pka_greater_than_si( cc3xx_pka_reg_id_t r0, int32_t imm); 583 584 /** 585 * @brief Shift a register to the right, and fill any new 586 * bits with zeros. res = r0 >> shift. 587 * 588 * @param[in] r0 The register ID of the first operand. 589 * @param[in] shift The amount the register should be shifted by. 590 * This must not be 0. 591 * @param[out] res The register ID the result will be stored in. 592 * 593 * @note It is acceptable to have some or all of the 594 * register IDs be identical. 595 */ 596 void cc3xx_lowlevel_pka_shift_right_fill_0_ui( cc3xx_pka_reg_id_t r0, uint32_t shift, cc3xx_pka_reg_id_t res); 597 /** 598 * @brief Shift a register to the right, and fill any new 599 * bits with ones. res = r0 >> shift. 600 * 601 * @param[in] r0 The register ID of the first operand. 602 * @param[in] shift The amount the register should be shifted by. 603 * This must not be 0. 604 * @param[out] res The register ID the result will be stored in. 605 * 606 * @note It is acceptable to have some or all of the 607 * register IDs be identical. 608 */ 609 void cc3xx_lowlevel_pka_shift_right_fill_1_ui( cc3xx_pka_reg_id_t r0, uint32_t shift, cc3xx_pka_reg_id_t res); 610 611 /** 612 * @brief Shift a register to the left, and fill any new 613 * bits with zeros. res = r0 << shift. 614 * 615 * @param[in] r0 The register ID of the first operand. 616 * @param[in] shift The amount the register should be shifted by. 617 * This must not be 0. 618 * @param[out] res The register ID the result will be stored in. 619 * 620 * @note It is acceptable to have some or all of the 621 * register IDs be identical. 622 */ 623 void cc3xx_lowlevel_pka_shift_left_fill_0_ui( cc3xx_pka_reg_id_t r0, uint32_t shift, cc3xx_pka_reg_id_t res); 624 /** 625 * @brief Shift a register to the left, and fill any new 626 * bits with ones. res = r0 << shift. 627 * 628 * @param[in] r0 The register ID of the first operand. 629 * @param[in] shift The amount the register should be shifted by. 630 * This must not be 0. 631 * @param[out] res The register ID the result will be stored in. 632 * 633 * @note It is acceptable to have some or all of the 634 * register IDs be identical. 635 */ 636 void cc3xx_lowlevel_pka_shift_left_fill_1_ui( cc3xx_pka_reg_id_t r0, uint32_t shift, cc3xx_pka_reg_id_t res); 637 638 /** 639 * @brief Set the output register low half of the result 640 * of the multiplication of the two input 641 * registers. res = (r0 * r1) & reg_size_mask. 642 * 643 * @param[in] r0 The register ID of the first operand. 644 * @param[in] r1 The register ID of the second operand. 645 * @param[out] res The register ID the result will be stored in. 646 * 647 * @note It is acceptable to have some or all of the 648 * register IDs be identical. 649 */ 650 void cc3xx_lowlevel_pka_mul_low_half(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 651 /** 652 * @brief Set the output register high half of the result 653 * of the multiplication of the two input 654 * registers. res = (r0 * r1) >> reg_size. 655 * 656 * @param[in] r0 The register ID of the first operand. 657 * @param[in] r1 The register ID of the second operand. 658 * @param[out] res The register ID the result will be stored in. 659 * 660 * @note It is acceptable to have some or all of the 661 * register IDs be identical. 662 */ 663 void cc3xx_lowlevel_pka_mul_high_half(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 664 665 /** 666 * @brief Set the quotient and remainder registers by 667 * dividing one input register by another. Division 668 * is integer division. quotient = r0 / r1. 669 * Remainder = r0 mod r1. 670 * 671 * @param[in] r0 The register ID of the first operand. 672 * @param[in] r1 The register ID of the second operand. 673 * @param[out] quotient The register ID the quotient will be stored in. 674 * @param[out] remainder The register ID the remainder will be stored in. 675 * 676 * @note It is acceptable to have some or all of the 677 * register IDs be identical. This function may 678 * perform transparent copying to achieve this. 679 */ 680 void cc3xx_lowlevel_pka_div(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t quotient, 681 cc3xx_pka_reg_id_t remainder); 682 683 /** 684 * @brief Perform multiplication of the input registers, 685 * and then modular reduction. 686 * res = (r0 * r1) mod N. 687 * 688 * @param[in] r0 The register ID of the first operand. 689 * @param[in] r1 The register ID of the second operand. 690 * @param[out] res The register ID the result will be stored in. 691 * 692 * @note It is acceptable to have some or all of the 693 * register IDs be identical. 694 */ 695 void cc3xx_lowlevel_pka_mod_mul(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 696 697 /** 698 * @brief Perform multiplication of the input register and 699 * a signed immediate, and then modular reduction. 700 * res = (r0 * imm) mod N. 701 * 702 * @param[in] r0 The register ID of the first operand. 703 * @param[in] imm The signed immediate, which must be in the range 704 * 0 to 15 inclusive. 705 * @param[out] res The register ID the result will be stored in. 706 * 707 * @note It is acceptable to have some or all of the 708 * register IDs be identical. 709 */ 710 void cc3xx_lowlevel_pka_mod_mul_si(cc3xx_pka_reg_id_t r0, int32_t imm, cc3xx_pka_reg_id_t res); 711 712 /** 713 * @brief Perform exponentiation and then modular 714 * reduction. res = (r0 ^ r1) mod N. 715 * 716 * @param[in] r0 The register ID of the first operand. 717 * @param[in] r1 The register ID of the second operand. 718 * @param[out] res The register ID the result will be stored in. 719 * 720 * @note It is acceptable to have some or all of the 721 * register IDs be identical. 722 */ 723 void cc3xx_lowlevel_pka_mod_exp(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t r1, cc3xx_pka_reg_id_t res); 724 /** 725 * @brief Perform exponentiation by a signed immediate and 726 * then modular reduction. res = (r0 ^ imm) mod N. 727 * 728 * @param[in] r0 The register ID of the first operand. 729 * @param[in] imm The signed immediate, which must be in the range 730 * 0 to 15 inclusive. 731 * @param[out] res The register ID the result will be stored in. 732 * 733 * @note It is acceptable to have some or all of the 734 * register IDs be identical. 735 */ 736 void cc3xx_lowlevel_pka_mod_exp_si(cc3xx_pka_reg_id_t r0, int32_t imm, cc3xx_pka_reg_id_t res); 737 738 /** 739 * @brief Perform modular inversion. 740 * res = x where (r0 * x mod N) == 1. 741 * 742 * @param[in] r0 The register ID of the first operand. 743 * @param[out] res The register ID the result will be stored in. 744 * 745 * @note It is acceptable to have some or all of the 746 * register IDs be identical. 747 */ 748 void cc3xx_lowlevel_pka_mod_inv(cc3xx_pka_reg_id_t r0, cc3xx_pka_reg_id_t res); 749 750 /** 751 * @brief Perform modular reduction. res = r0 mod N. 752 * 753 * @param[in/out] r0 The register ID of the first operand. 754 * 755 * @note It is acceptable to have some or all of the 756 * register IDs be identical. 757 */ 758 void cc3xx_lowlevel_pka_reduce(cc3xx_pka_reg_id_t r0); 759 760 #ifdef __cplusplus 761 } 762 #endif 763 764 #endif /* CC3XX_PKA_H */ 765