xref: /linux/include/crypto/internal/ecc.h (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 /*
2  * Copyright (c) 2013, Kenneth MacKay
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *  * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #ifndef _CRYPTO_ECC_H
27 #define _CRYPTO_ECC_H
28 
29 #include <crypto/ecc_curve.h>
30 #include <linux/unaligned.h>
31 
32 /* One digit is u64 qword. */
33 #define ECC_CURVE_NIST_P192_DIGITS  3
34 #define ECC_CURVE_NIST_P256_DIGITS  4
35 #define ECC_CURVE_NIST_P384_DIGITS  6
36 #define ECC_CURVE_NIST_P521_DIGITS  9
37 #define ECC_MAX_DIGITS              DIV_ROUND_UP(521, 64) /* NIST P521 */
38 
39 #define ECC_DIGITS_TO_BYTES_SHIFT 3
40 
41 #define ECC_MAX_BYTES (ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT)
42 
43 #define ECC_POINT_INIT(x, y, ndigits)	(struct ecc_point) { x, y, ndigits }
44 
45 /*
46  * The integers r and s making up the signature are expected to be
47  * formatted as two consecutive u64 arrays of size ECC_MAX_BYTES.
48  * The bytes within each u64 digit are in native endianness,
49  * but the order of the u64 digits themselves is little endian.
50  * This format allows direct use by internal vli_*() functions.
51  */
52 struct ecdsa_raw_sig {
53 	u64 r[ECC_MAX_DIGITS];
54 	u64 s[ECC_MAX_DIGITS];
55 };
56 
57 /**
58  * ecc_swap_digits() - Copy ndigits from big endian array to native array
59  * @in:       Input array
60  * @out:      Output array
61  * @ndigits:  Number of digits to copy
62  */
63 static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigits)
64 {
65 	const __be64 *src = (__force __be64 *)in;
66 	int i;
67 
68 	for (i = 0; i < ndigits; i++)
69 		out[i] = get_unaligned_be64(&src[ndigits - 1 - i]);
70 }
71 
72 /**
73  * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array
74  * @in:       Input byte array
75  * @nbytes    Size of input byte array
76  * @out       Output digits array
77  * @ndigits:  Number of digits to create from byte array
78  *
79  * The first byte in the input byte array is expected to hold the most
80  * significant bits of the large integer.
81  */
82 void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
83 			   u64 *out, unsigned int ndigits);
84 
85 /**
86  * ecc_is_key_valid() - Validate a given ECDH private key
87  *
88  * @curve_id:		id representing the curve to use
89  * @ndigits:		curve's number of digits
90  * @private_key:	private key to be used for the given curve
91  * @private_key_len:	private key length
92  *
93  * Returns 0 if the key is acceptable, a negative value otherwise
94  */
95 int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
96 		     const u64 *private_key, unsigned int private_key_len);
97 
98 /**
99  * ecc_gen_privkey() -  Generates an ECC private key.
100  * The private key is a random integer in the range 0 < random < n, where n is a
101  * prime that is the order of the cyclic subgroup generated by the distinguished
102  * point G.
103  * @curve_id:		id representing the curve to use
104  * @ndigits:		curve number of digits
105  * @private_key:	buffer for storing the generated private key
106  *
107  * Returns 0 if the private key was generated successfully, a negative value
108  * if an error occurred.
109  */
110 int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits,
111 		    u64 *private_key);
112 
113 /**
114  * ecc_make_pub_key() - Compute an ECC public key
115  *
116  * @curve_id:		id representing the curve to use
117  * @ndigits:		curve's number of digits
118  * @private_key:	pregenerated private key for the given curve
119  * @public_key:		buffer for storing the generated public key
120  *
121  * Returns 0 if the public key was generated successfully, a negative value
122  * if an error occurred.
123  */
124 int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
125 		     const u64 *private_key, u64 *public_key);
126 
127 /**
128  * crypto_ecdh_shared_secret() - Compute a shared secret
129  *
130  * @curve_id:		id representing the curve to use
131  * @ndigits:		curve's number of digits
132  * @private_key:	private key of part A
133  * @public_key:		public key of counterpart B
134  * @secret:		buffer for storing the calculated shared secret
135  *
136  * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret
137  * before using it for symmetric encryption or HMAC.
138  *
139  * Returns 0 if the shared secret was generated successfully, a negative value
140  * if an error occurred.
141  */
142 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
143 			      const u64 *private_key, const u64 *public_key,
144 			      u64 *secret);
145 
146 /**
147  * ecc_is_pubkey_valid_partial() - Partial public key validation
148  *
149  * @curve:		elliptic curve domain parameters
150  * @pk:			public key as a point
151  *
152  * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial
153  * Public-Key Validation Routine.
154  *
155  * Note: There is no check that the public key is in the correct elliptic curve
156  * subgroup.
157  *
158  * Return: 0 if validation is successful, -EINVAL if validation is failed.
159  */
160 int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
161 				struct ecc_point *pk);
162 
163 /**
164  * ecc_is_pubkey_valid_full() - Full public key validation
165  *
166  * @curve:		elliptic curve domain parameters
167  * @pk:			public key as a point
168  *
169  * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full
170  * Public-Key Validation Routine.
171  *
172  * Return: 0 if validation is successful, -EINVAL if validation is failed.
173  */
174 int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
175 			     struct ecc_point *pk);
176 
177 /**
178  * vli_is_zero() - Determine is vli is zero
179  *
180  * @vli:		vli to check.
181  * @ndigits:		length of the @vli
182  */
183 bool vli_is_zero(const u64 *vli, unsigned int ndigits);
184 
185 /**
186  * vli_cmp() - compare left and right vlis
187  *
188  * @left:		vli
189  * @right:		vli
190  * @ndigits:		length of both vlis
191  *
192  * Returns sign of @left - @right, i.e. -1 if @left < @right,
193  * 0 if @left == @right, 1 if @left > @right.
194  */
195 int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits);
196 
197 /**
198  * vli_sub() - Subtracts right from left
199  *
200  * @result:		where to write result
201  * @left:		vli
202  * @right		vli
203  * @ndigits:		length of all vlis
204  *
205  * Note: can modify in-place.
206  *
207  * Return: carry bit.
208  */
209 u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
210 	    unsigned int ndigits);
211 
212 /**
213  * vli_from_be64() - Load vli from big-endian u64 array
214  *
215  * @dest:		destination vli
216  * @src:		source array of u64 BE values
217  * @ndigits:		length of both vli and array
218  */
219 void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits);
220 
221 /**
222  * vli_from_le64() - Load vli from little-endian u64 array
223  *
224  * @dest:		destination vli
225  * @src:		source array of u64 LE values
226  * @ndigits:		length of both vli and array
227  */
228 void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits);
229 
230 /**
231  * vli_mod_inv() - Modular inversion
232  *
233  * @result:		where to write vli number
234  * @input:		vli value to operate on
235  * @mod:		modulus
236  * @ndigits:		length of all vlis
237  */
238 void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
239 		 unsigned int ndigits);
240 
241 /**
242  * vli_mod_mult_slow() - Modular multiplication
243  *
244  * @result:		where to write result value
245  * @left:		vli number to multiply with @right
246  * @right:		vli number to multiply with @left
247  * @mod:		modulus
248  * @ndigits:		length of all vlis
249  *
250  * Note: Assumes that mod is big enough curve order.
251  */
252 void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right,
253 		       const u64 *mod, unsigned int ndigits);
254 
255 /**
256  * vli_num_bits() - Counts the number of bits required for vli.
257  *
258  * @vli:		vli to check.
259  * @ndigits:		Length of the @vli
260  *
261  * Return: The number of bits required to represent @vli.
262  */
263 unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits);
264 
265 /**
266  * ecc_aloc_point() - Allocate ECC point.
267  *
268  * @ndigits:		Length of vlis in u64 qwords.
269  *
270  * Return: Pointer to the allocated point or NULL if allocation failed.
271  */
272 struct ecc_point *ecc_alloc_point(unsigned int ndigits);
273 
274 /**
275  * ecc_free_point() - Free ECC point.
276  *
277  * @p:			The point to free.
278  */
279 void ecc_free_point(struct ecc_point *p);
280 
281 /**
282  * ecc_point_is_zero() - Check if point is zero.
283  *
284  * @p:			Point to check for zero.
285  *
286  * Return: true if point is the point at infinity, false otherwise.
287  */
288 bool ecc_point_is_zero(const struct ecc_point *point);
289 
290 /**
291  * ecc_point_mult_shamir() - Add two points multiplied by scalars
292  *
293  * @result:		resulting point
294  * @x:			scalar to multiply with @p
295  * @p:			point to multiply with @x
296  * @y:			scalar to multiply with @q
297  * @q:			point to multiply with @y
298  * @curve:		curve
299  *
300  * Returns result = x * p + x * q over the curve.
301  * This works faster than two multiplications and addition.
302  */
303 void ecc_point_mult_shamir(const struct ecc_point *result,
304 			   const u64 *x, const struct ecc_point *p,
305 			   const u64 *y, const struct ecc_point *q,
306 			   const struct ecc_curve *curve);
307 
308 extern struct crypto_template ecdsa_x962_tmpl;
309 extern struct crypto_template ecdsa_p1363_tmpl;
310 #endif
311