hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/crypto/ecc.h
....@@ -26,11 +26,49 @@
2626 #ifndef _CRYPTO_ECC_H
2727 #define _CRYPTO_ECC_H
2828
29
+/* One digit is u64 qword. */
2930 #define ECC_CURVE_NIST_P192_DIGITS 3
3031 #define ECC_CURVE_NIST_P256_DIGITS 4
31
-#define ECC_MAX_DIGITS ECC_CURVE_NIST_P256_DIGITS
32
+#define ECC_MAX_DIGITS (512 / 64)
3233
3334 #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
+};
3472
3573 /**
3674 * ecc_is_key_valid() - Validate a given ECDH private key
....@@ -91,4 +129,131 @@
91129 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
92130 const u64 *private_key, const u64 *public_key,
93131 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);
94259 #endif