.. | .. |
---|
26 | 26 | #ifndef _CRYPTO_ECC_H |
---|
27 | 27 | #define _CRYPTO_ECC_H |
---|
28 | 28 | |
---|
| 29 | +/* One digit is u64 qword. */ |
---|
29 | 30 | #define ECC_CURVE_NIST_P192_DIGITS 3 |
---|
30 | 31 | #define ECC_CURVE_NIST_P256_DIGITS 4 |
---|
31 | | -#define ECC_MAX_DIGITS ECC_CURVE_NIST_P256_DIGITS |
---|
| 32 | +#define ECC_MAX_DIGITS (512 / 64) |
---|
32 | 33 | |
---|
33 | 34 | #define ECC_DIGITS_TO_BYTES_SHIFT 3 |
---|
| 35 | + |
---|
| 36 | +/** |
---|
| 37 | + * struct ecc_point - elliptic curve point in affine coordinates |
---|
| 38 | + * |
---|
| 39 | + * @x: X coordinate in vli form. |
---|
| 40 | + * @y: Y coordinate in vli form. |
---|
| 41 | + * @ndigits: Length of vlis in u64 qwords. |
---|
| 42 | + */ |
---|
| 43 | +struct ecc_point { |
---|
| 44 | + u64 *x; |
---|
| 45 | + u64 *y; |
---|
| 46 | + u8 ndigits; |
---|
| 47 | +}; |
---|
| 48 | + |
---|
| 49 | +#define ECC_POINT_INIT(x, y, ndigits) (struct ecc_point) { x, y, ndigits } |
---|
| 50 | + |
---|
| 51 | +/** |
---|
| 52 | + * struct ecc_curve - definition of elliptic curve |
---|
| 53 | + * |
---|
| 54 | + * @name: Short name of the curve. |
---|
| 55 | + * @g: Generator point of the curve. |
---|
| 56 | + * @p: Prime number, if Barrett's reduction is used for this curve |
---|
| 57 | + * pre-calculated value 'mu' is appended to the @p after ndigits. |
---|
| 58 | + * Use of Barrett's reduction is heuristically determined in |
---|
| 59 | + * vli_mmod_fast(). |
---|
| 60 | + * @n: Order of the curve group. |
---|
| 61 | + * @a: Curve parameter a. |
---|
| 62 | + * @b: Curve parameter b. |
---|
| 63 | + */ |
---|
| 64 | +struct ecc_curve { |
---|
| 65 | + char *name; |
---|
| 66 | + struct ecc_point g; |
---|
| 67 | + u64 *p; |
---|
| 68 | + u64 *n; |
---|
| 69 | + u64 *a; |
---|
| 70 | + u64 *b; |
---|
| 71 | +}; |
---|
34 | 72 | |
---|
35 | 73 | /** |
---|
36 | 74 | * ecc_is_key_valid() - Validate a given ECDH private key |
---|
.. | .. |
---|
91 | 129 | int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, |
---|
92 | 130 | const u64 *private_key, const u64 *public_key, |
---|
93 | 131 | u64 *secret); |
---|
| 132 | + |
---|
| 133 | +/** |
---|
| 134 | + * ecc_is_pubkey_valid_partial() - Partial public key validation |
---|
| 135 | + * |
---|
| 136 | + * @curve: elliptic curve domain parameters |
---|
| 137 | + * @pk: public key as a point |
---|
| 138 | + * |
---|
| 139 | + * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial |
---|
| 140 | + * Public-Key Validation Routine. |
---|
| 141 | + * |
---|
| 142 | + * Note: There is no check that the public key is in the correct elliptic curve |
---|
| 143 | + * subgroup. |
---|
| 144 | + * |
---|
| 145 | + * Return: 0 if validation is successful, -EINVAL if validation is failed. |
---|
| 146 | + */ |
---|
| 147 | +int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve, |
---|
| 148 | + struct ecc_point *pk); |
---|
| 149 | + |
---|
| 150 | +/** |
---|
| 151 | + * ecc_is_pubkey_valid_full() - Full public key validation |
---|
| 152 | + * |
---|
| 153 | + * @curve: elliptic curve domain parameters |
---|
| 154 | + * @pk: public key as a point |
---|
| 155 | + * |
---|
| 156 | + * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full |
---|
| 157 | + * Public-Key Validation Routine. |
---|
| 158 | + * |
---|
| 159 | + * Return: 0 if validation is successful, -EINVAL if validation is failed. |
---|
| 160 | + */ |
---|
| 161 | +int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, |
---|
| 162 | + struct ecc_point *pk); |
---|
| 163 | + |
---|
| 164 | +/** |
---|
| 165 | + * vli_is_zero() - Determine is vli is zero |
---|
| 166 | + * |
---|
| 167 | + * @vli: vli to check. |
---|
| 168 | + * @ndigits: length of the @vli |
---|
| 169 | + */ |
---|
| 170 | +bool vli_is_zero(const u64 *vli, unsigned int ndigits); |
---|
| 171 | + |
---|
| 172 | +/** |
---|
| 173 | + * vli_cmp() - compare left and right vlis |
---|
| 174 | + * |
---|
| 175 | + * @left: vli |
---|
| 176 | + * @right: vli |
---|
| 177 | + * @ndigits: length of both vlis |
---|
| 178 | + * |
---|
| 179 | + * Returns sign of @left - @right, i.e. -1 if @left < @right, |
---|
| 180 | + * 0 if @left == @right, 1 if @left > @right. |
---|
| 181 | + */ |
---|
| 182 | +int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits); |
---|
| 183 | + |
---|
| 184 | +/** |
---|
| 185 | + * vli_sub() - Subtracts right from left |
---|
| 186 | + * |
---|
| 187 | + * @result: where to write result |
---|
| 188 | + * @left: vli |
---|
| 189 | + * @right vli |
---|
| 190 | + * @ndigits: length of all vlis |
---|
| 191 | + * |
---|
| 192 | + * Note: can modify in-place. |
---|
| 193 | + * |
---|
| 194 | + * Return: carry bit. |
---|
| 195 | + */ |
---|
| 196 | +u64 vli_sub(u64 *result, const u64 *left, const u64 *right, |
---|
| 197 | + unsigned int ndigits); |
---|
| 198 | + |
---|
| 199 | +/** |
---|
| 200 | + * vli_from_be64() - Load vli from big-endian u64 array |
---|
| 201 | + * |
---|
| 202 | + * @dest: destination vli |
---|
| 203 | + * @src: source array of u64 BE values |
---|
| 204 | + * @ndigits: length of both vli and array |
---|
| 205 | + */ |
---|
| 206 | +void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits); |
---|
| 207 | + |
---|
| 208 | +/** |
---|
| 209 | + * vli_from_le64() - Load vli from little-endian u64 array |
---|
| 210 | + * |
---|
| 211 | + * @dest: destination vli |
---|
| 212 | + * @src: source array of u64 LE values |
---|
| 213 | + * @ndigits: length of both vli and array |
---|
| 214 | + */ |
---|
| 215 | +void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits); |
---|
| 216 | + |
---|
| 217 | +/** |
---|
| 218 | + * vli_mod_inv() - Modular inversion |
---|
| 219 | + * |
---|
| 220 | + * @result: where to write vli number |
---|
| 221 | + * @input: vli value to operate on |
---|
| 222 | + * @mod: modulus |
---|
| 223 | + * @ndigits: length of all vlis |
---|
| 224 | + */ |
---|
| 225 | +void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod, |
---|
| 226 | + unsigned int ndigits); |
---|
| 227 | + |
---|
| 228 | +/** |
---|
| 229 | + * vli_mod_mult_slow() - Modular multiplication |
---|
| 230 | + * |
---|
| 231 | + * @result: where to write result value |
---|
| 232 | + * @left: vli number to multiply with @right |
---|
| 233 | + * @right: vli number to multiply with @left |
---|
| 234 | + * @mod: modulus |
---|
| 235 | + * @ndigits: length of all vlis |
---|
| 236 | + * |
---|
| 237 | + * Note: Assumes that mod is big enough curve order. |
---|
| 238 | + */ |
---|
| 239 | +void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right, |
---|
| 240 | + const u64 *mod, unsigned int ndigits); |
---|
| 241 | + |
---|
| 242 | +/** |
---|
| 243 | + * ecc_point_mult_shamir() - Add two points multiplied by scalars |
---|
| 244 | + * |
---|
| 245 | + * @result: resulting point |
---|
| 246 | + * @x: scalar to multiply with @p |
---|
| 247 | + * @p: point to multiply with @x |
---|
| 248 | + * @y: scalar to multiply with @q |
---|
| 249 | + * @q: point to multiply with @y |
---|
| 250 | + * @curve: curve |
---|
| 251 | + * |
---|
| 252 | + * Returns result = x * p + x * q over the curve. |
---|
| 253 | + * This works faster than two multiplications and addition. |
---|
| 254 | + */ |
---|
| 255 | +void ecc_point_mult_shamir(const struct ecc_point *result, |
---|
| 256 | + const u64 *x, const struct ecc_point *p, |
---|
| 257 | + const u64 *y, const struct ecc_point *q, |
---|
| 258 | + const struct ecc_curve *curve); |
---|
94 | 259 | #endif |
---|