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