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