1 /*
2  * Copyright (c) 2024, The TrustedFirmware-M Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __CC3XX_EC_H__
9 #define __CC3XX_EC_H__
10 
11 #include <stdint.h>
12 #include <stddef.h>
13 
14 #include "cc3xx_error.h"
15 #include "cc3xx_pka.h"
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 /**
22  * @brief List of curve types
23  *
24  */
25 typedef enum {
26     CC3XX_EC_CURVE_TYPE_WEIERSTRASS,
27     CC3XX_EC_CURVE_TYPE_MONTGOMERY,
28     CC3XX_EC_CURVE_TYPE_TWISTED_EDWARDS,
29 } cc3xx_ec_curve_type_t;
30 
31 /**
32  * @brief List of curve identifiers
33  *
34  */
35 typedef enum {
36     CC3XX_EC_CURVE_SECP_192_R1,
37     CC3XX_EC_CURVE_SECP_224_R1,
38     CC3XX_EC_CURVE_SECP_256_R1,
39     CC3XX_EC_CURVE_SECP_384_R1,
40     CC3XX_EC_CURVE_SECP_521_R1,
41 
42     CC3XX_EC_CURVE_SECP_192_K1,
43     CC3XX_EC_CURVE_SECP_224_K1,
44     CC3XX_EC_CURVE_SECP_256_K1,
45 
46     CC3XX_EC_CURVE_BRAINPOOLP_192_R1,
47     CC3XX_EC_CURVE_BRAINPOOLP_224_R1,
48     CC3XX_EC_CURVE_BRAINPOOLP_256_R1,
49     CC3XX_EC_CURVE_BRAINPOOLP_320_R1,
50     CC3XX_EC_CURVE_BRAINPOOLP_384_R1,
51     CC3XX_EC_CURVE_BRAINPOOLP_512_R1,
52 
53     CC3XX_EC_CURVE_FRP_256_V1,
54 
55     CC3XX_EC_CURVE_25519,
56     CC3XX_EC_CURVE_448,
57 
58     CC3XX_EC_CURVE_ED25519,
59     CC3XX_EC_CURVE_ED448,
60     _CURVE_ID_MAX,
61     _CURVE_ID_SIZE_PAD = UINT32_MAX,
62 } cc3xx_ec_curve_id_t;
63 
64 /**
65  * @brief A representation of an EC point on the PKA engine
66  *        using affine coordinates
67  */
68 typedef struct {
69     cc3xx_pka_reg_id_t x;
70     cc3xx_pka_reg_id_t y;
71 } cc3xx_ec_point_affine;
72 
73 /**
74  * @brief A mapping of the curve parameters on the PKA engine
75  *
76  */
77 typedef struct {
78     cc3xx_ec_curve_id_t id;
79     size_t modulus_size;
80     cc3xx_ec_curve_type_t type;
81     cc3xx_pka_reg_id_t field_modulus;
82     cc3xx_pka_reg_id_t param_a;
83     cc3xx_pka_reg_id_t param_b;
84     cc3xx_ec_point_affine generator;
85     cc3xx_pka_reg_id_t order;
86     uint32_t cofactor;
87 } cc3xx_ec_curve_t;
88 
89 /**
90  * @brief                        Initialize an Elliptic Curve operation
91  *
92  * @param[in]  curve_id          The ID of the curve to use.
93  * @param[out] curve             An initialized curve object to use in future
94  *                               operations.
95  *
96  * @return                       CC3XX_ERR_SUCCESS on success, another
97  *                               cc3xx_err_t on error.
98  */
99 cc3xx_err_t cc3xx_lowlevel_ec_init(cc3xx_ec_curve_id_t id,
100                                    cc3xx_ec_curve_t *curve);
101 
102 /**
103  * @brief                        Allocate an affine point
104  *
105  * @return                       An initialized affine point object.
106  */
107 cc3xx_ec_point_affine cc3xx_lowlevel_ec_allocate_point(void);
108 
109 /**
110  * @brief                        Allocate an affine point and initialize it with
111  *                               a value
112  *
113  * @param[in]  curve             A pointer to an initialized curve object
114  * @param[in]  x                 The buffer to read the x coordinate from.
115  * @param[in]  x_len             The size of the x coordinate buffer.
116  * @param[in]  y                 The buffer to read the y coordinate from.
117  * @param[in]  y_len             The size of the y coordinate buffer.
118  * @param[out] res               A pointer to the affine point object to
119  *                               initialize with the value.
120  *
121  * @return                       CC3XX_ERR_SUCCESS on success, another
122  *                               cc3xx_err_t on error.
123  */
124 cc3xx_err_t cc3xx_lowlevel_ec_allocate_point_from_data(cc3xx_ec_curve_t *curve,
125                                                        const uint32_t *x,
126                                                        size_t x_len,
127                                                        const uint32_t *y,
128                                                        size_t y_len,
129                                                        cc3xx_ec_point_affine *res);
130 
131 /**
132  * @brief                        Free an affine point
133  *
134  * @param[in]  p                 The point to free.
135  */
136 void cc3xx_lowlevel_ec_free_point(cc3xx_ec_point_affine *p);
137 
138 /**
139  * @brief                        Add two affine points
140  *
141  * @param[in]  curve             A pointer to an initialized curve object
142  * @param[in]  p                 A pointer to the first affine point object to
143  *                               add.
144  * @param[in]  q                 A pointer to the secnd affine point object to
145  *                               add.
146  * @param[out] res               A pointer to the affine point object which the
147  *                               result will be written to.
148  *
149  * @return                       CC3XX_ERR_SUCCESS on success, another
150  *                               cc3xx_err_t on error.
151  */
152 cc3xx_err_t cc3xx_lowlevel_ec_add_points(cc3xx_ec_curve_t *curve,
153                                          cc3xx_ec_point_affine *p,
154                                          cc3xx_ec_point_affine *q,
155                                          cc3xx_ec_point_affine *res);
156 
157 /**
158  * @brief                        Double an affine point
159  *
160  * @param[in]  curve             A pointer to an initialized curve object
161  * @param[in]  p                 A pointer to the affine point object to double.
162  * @param[out] res               A pointer to the affine point object which the
163  *                               result will be written to.
164  *
165  * @return                       CC3XX_ERR_SUCCESS on success, another
166  *                               cc3xx_err_t on error.
167  */
168 cc3xx_err_t cc3xx_lowlevel_ec_double_point(cc3xx_ec_curve_t *curve,
169                                            cc3xx_ec_point_affine *p,
170                                            cc3xx_ec_point_affine *res);
171 
172 /**
173  * @brief                        Multiply an affine point by a scalar value
174  *
175  * @note                         This function is side-channel protected and
176  *                               may be used on secret values. By default it is
177  *                               protected against timing attacks, further
178  *                               mitigations can be enabled by config.
179  *
180  * @param[in]  curve             A pointer to an initialized curve object
181  * @param[in]  p                 A pointer to the affine point object to
182  *                               multiply.
183  * @param[in]  scalar            The scalar value to multiply the point by.
184  * @param[out] res               A pointer to the affine point object which the
185  *                               result will be written to.
186  *
187  * @return                       CC3XX_ERR_SUCCESS on success, another
188  *                               cc3xx_err_t on error.
189  */
190 cc3xx_err_t cc3xx_lowlevel_ec_multipy_point_by_scalar(cc3xx_ec_curve_t *curve,
191                                                       cc3xx_ec_point_affine *p,
192                                                       cc3xx_pka_reg_id_t scalar,
193                                                       cc3xx_ec_point_affine *res);
194 
195 /**
196  * @brief                        Multiply two scalars by two separate affine
197  *                               values, and then add the points. This function
198  *                               may use the Shamir trick, if it is enabled by
199  *                               config.
200  *
201  * @note                         This function must _not_ be used on secret
202  *                               values, in case the Shamir trick is used which
203  *                               is not side-channel protected.
204  *
205  * @param[in]  curve             A pointer to an initialized curve object
206  * @param[in]  p1                A pointer to the first affine point object to
207  *                               multiply.
208  * @param[in]  scalar1           The scalar value to multiply the first point
209  *                               by.
210  * @param[in]  p2                A pointer to the second affine point object to
211  *                               multiply.
212  * @param[in]  scalar2           The scalar value to multiply the second point
213  *                               by.
214  * @param[out] res               A pointer to the affine point object which the
215  *                               result will be written to.
216  *
217  * @return                       CC3XX_ERR_SUCCESS on success, another
218  *                               cc3xx_err_t on error.
219  */
220 cc3xx_err_t cc3xx_lowlevel_ec_shamir_multiply_points_by_scalars_and_add(
221                                              cc3xx_ec_curve_t *curve,
222                                              cc3xx_ec_point_affine *p1,
223                                              cc3xx_pka_reg_id_t    scalar1,
224                                              cc3xx_ec_point_affine *p2,
225                                              cc3xx_pka_reg_id_t    scalar2,
226                                              cc3xx_ec_point_affine *res);
227 
228 /**
229  * @brief Getter method to return the associated \a modulus_size from a curve.
230  *        Note that usually the implementation deals with 4-byte aligned sizes
231  *        so for, e.g. 521 bit curves this will be slightly greater than what
232  *        would be strictly required
233  *
234  * @param curve_id An ID of the curve to retrieve the modulus size
235  *
236  * @return size_t Size in bytes of the modulus
237  */
238 size_t cc3xx_lowlevel_ec_get_modulus_size_from_curve(cc3xx_ec_curve_id_t curve_id);
239 
240 /**
241  * @brief De-initializes the Elliptic Curve operation
242  *
243  */
244 void cc3xx_lowlevel_ec_uninit(void);
245 
246 #ifdef __cplusplus
247 }
248 #endif
249 
250 #endif /* __CC3XX_EC_H */
251