Blame view

crypto/ecc.h 7.97 KB
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  /*
   * Copyright (c) 2013, Kenneth MacKay
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are
   * met:
   *  * Redistributions of source code must retain the above copyright
   *   notice, this list of conditions and the following disclaimer.
   *  * Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  #ifndef _CRYPTO_ECC_H
  #define _CRYPTO_ECC_H
0d7a78643   Vitaly Chikunov   crypto: ecrdsa - ...
28
  /* One digit is u64 qword. */
d5c3b1789   Kees Cook   crypto: ecc - Act...
29
30
  #define ECC_CURVE_NIST_P192_DIGITS  3
  #define ECC_CURVE_NIST_P256_DIGITS  4
0d7a78643   Vitaly Chikunov   crypto: ecrdsa - ...
31
  #define ECC_MAX_DIGITS             (512 / 64)
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
32
33
34
35
  
  #define ECC_DIGITS_TO_BYTES_SHIFT 3
  
  /**
4a2289dae   Vitaly Chikunov   crypto: ecc - mak...
36
37
38
39
40
41
42
43
44
45
46
   * struct ecc_point - elliptic curve point in affine coordinates
   *
   * @x:		X coordinate in vli form.
   * @y:		Y coordinate in vli form.
   * @ndigits:	Length of vlis in u64 qwords.
   */
  struct ecc_point {
  	u64 *x;
  	u64 *y;
  	u8 ndigits;
  };
0d7a78643   Vitaly Chikunov   crypto: ecrdsa - ...
47
  #define ECC_POINT_INIT(x, y, ndigits)	(struct ecc_point) { x, y, ndigits }
4a2289dae   Vitaly Chikunov   crypto: ecc - mak...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /**
   * struct ecc_curve - definition of elliptic curve
   *
   * @name:	Short name of the curve.
   * @g:		Generator point of the curve.
   * @p:		Prime number, if Barrett's reduction is used for this curve
   *		pre-calculated value 'mu' is appended to the @p after ndigits.
   *		Use of Barrett's reduction is heuristically determined in
   *		vli_mmod_fast().
   * @n:		Order of the curve group.
   * @a:		Curve parameter a.
   * @b:		Curve parameter b.
   */
  struct ecc_curve {
  	char *name;
  	struct ecc_point g;
  	u64 *p;
  	u64 *n;
  	u64 *a;
  	u64 *b;
  };
  
  /**
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
71
72
73
   * ecc_is_key_valid() - Validate a given ECDH private key
   *
   * @curve_id:		id representing the curve to use
c0ca1215d   Tudor-Dan Ambarus   crypto: kpp, (ec)...
74
   * @ndigits:		curve's number of digits
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
75
   * @private_key:	private key to be used for the given curve
c0ca1215d   Tudor-Dan Ambarus   crypto: kpp, (ec)...
76
   * @private_key_len:	private key length
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
77
78
79
80
   *
   * Returns 0 if the key is acceptable, a negative value otherwise
   */
  int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
ad2695971   Tudor-Dan Ambarus   crypto: ecc - rem...
81
  		     const u64 *private_key, unsigned int private_key_len);
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
82
83
  
  /**
6755fd269   Tudor-Dan Ambarus   crypto: ecdh - ad...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
   * ecc_gen_privkey() -  Generates an ECC private key.
   * The private key is a random integer in the range 0 < random < n, where n is a
   * prime that is the order of the cyclic subgroup generated by the distinguished
   * point G.
   * @curve_id:		id representing the curve to use
   * @ndigits:		curve number of digits
   * @private_key:	buffer for storing the generated private key
   *
   * Returns 0 if the private key was generated successfully, a negative value
   * if an error occurred.
   */
  int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey);
  
  /**
7380c56d2   Tudor-Dan Ambarus   crypto: ecc - ren...
98
   * ecc_make_pub_key() - Compute an ECC public key
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
99
100
   *
   * @curve_id:		id representing the curve to use
c0ca1215d   Tudor-Dan Ambarus   crypto: kpp, (ec)...
101
   * @ndigits:		curve's number of digits
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
102
   * @private_key:	pregenerated private key for the given curve
c0ca1215d   Tudor-Dan Ambarus   crypto: kpp, (ec)...
103
   * @public_key:		buffer for storing the generated public key
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
104
105
106
107
   *
   * Returns 0 if the public key was generated successfully, a negative value
   * if an error occurred.
   */
7380c56d2   Tudor-Dan Ambarus   crypto: ecc - ren...
108
109
  int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
  		     const u64 *private_key, u64 *public_key);
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
110
111
  
  /**
8f44df154   Stephen Rothwell   crypto: ecdh - ma...
112
   * crypto_ecdh_shared_secret() - Compute a shared secret
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
113
114
   *
   * @curve_id:		id representing the curve to use
c0ca1215d   Tudor-Dan Ambarus   crypto: kpp, (ec)...
115
   * @ndigits:		curve's number of digits
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
116
   * @private_key:	private key of part A
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
117
   * @public_key:		public key of counterpart B
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
118
   * @secret:		buffer for storing the calculated shared secret
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
119
   *
8f44df154   Stephen Rothwell   crypto: ecdh - ma...
120
   * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
121
122
123
124
125
   * before using it for symmetric encryption or HMAC.
   *
   * Returns 0 if the shared secret was generated successfully, a negative value
   * if an error occurred.
   */
8f44df154   Stephen Rothwell   crypto: ecdh - ma...
126
  int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
ad2695971   Tudor-Dan Ambarus   crypto: ecc - rem...
127
128
  			      const u64 *private_key, const u64 *public_key,
  			      u64 *secret);
4a2289dae   Vitaly Chikunov   crypto: ecc - mak...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  
  /**
   * ecc_is_pubkey_valid_partial() - Partial public key validation
   *
   * @curve:		elliptic curve domain parameters
   * @pk:			public key as a point
   *
   * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial
   * Public-Key Validation Routine.
   *
   * Note: There is no check that the public key is in the correct elliptic curve
   * subgroup.
   *
   * Return: 0 if validation is successful, -EINVAL if validation is failed.
   */
  int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
  				struct ecc_point *pk);
  
  /**
6914dd53e   Stephan Müller   crypto: ecc - SP8...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
   * ecc_is_pubkey_valid_full() - Full public key validation
   *
   * @curve:		elliptic curve domain parameters
   * @pk:			public key as a point
   *
   * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full
   * Public-Key Validation Routine.
   *
   * Return: 0 if validation is successful, -EINVAL if validation is failed.
   */
  int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
  			     struct ecc_point *pk);
  
  /**
4a2289dae   Vitaly Chikunov   crypto: ecc - mak...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
   * vli_is_zero() - Determine is vli is zero
   *
   * @vli:		vli to check.
   * @ndigits:		length of the @vli
   */
  bool vli_is_zero(const u64 *vli, unsigned int ndigits);
  
  /**
   * vli_cmp() - compare left and right vlis
   *
   * @left:		vli
   * @right:		vli
   * @ndigits:		length of both vlis
   *
   * Returns sign of @left - @right, i.e. -1 if @left < @right,
   * 0 if @left == @right, 1 if @left > @right.
   */
  int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits);
  
  /**
   * vli_sub() - Subtracts right from left
   *
   * @result:		where to write result
   * @left:		vli
   * @right		vli
   * @ndigits:		length of all vlis
   *
   * Note: can modify in-place.
   *
   * Return: carry bit.
   */
  u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
  	    unsigned int ndigits);
  
  /**
0d7a78643   Vitaly Chikunov   crypto: ecrdsa - ...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
   * vli_from_be64() - Load vli from big-endian u64 array
   *
   * @dest:		destination vli
   * @src:		source array of u64 BE values
   * @ndigits:		length of both vli and array
   */
  void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits);
  
  /**
   * vli_from_le64() - Load vli from little-endian u64 array
   *
   * @dest:		destination vli
   * @src:		source array of u64 LE values
   * @ndigits:		length of both vli and array
   */
  void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits);
  
  /**
4a2289dae   Vitaly Chikunov   crypto: ecc - mak...
215
216
217
218
219
220
221
222
223
   * vli_mod_inv() - Modular inversion
   *
   * @result:		where to write vli number
   * @input:		vli value to operate on
   * @mod:		modulus
   * @ndigits:		length of all vlis
   */
  void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
  		 unsigned int ndigits);
0d7a78643   Vitaly Chikunov   crypto: ecrdsa - ...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  /**
   * vli_mod_mult_slow() - Modular multiplication
   *
   * @result:		where to write result value
   * @left:		vli number to multiply with @right
   * @right:		vli number to multiply with @left
   * @mod:		modulus
   * @ndigits:		length of all vlis
   *
   * Note: Assumes that mod is big enough curve order.
   */
  void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right,
  		       const u64 *mod, unsigned int ndigits);
  
  /**
   * ecc_point_mult_shamir() - Add two points multiplied by scalars
   *
   * @result:		resulting point
   * @x:			scalar to multiply with @p
   * @p:			point to multiply with @x
   * @y:			scalar to multiply with @q
   * @q:			point to multiply with @y
   * @curve:		curve
   *
   * Returns result = x * p + x * q over the curve.
   * This works faster than two multiplications and addition.
   */
  void ecc_point_mult_shamir(const struct ecc_point *result,
  			   const u64 *x, const struct ecc_point *p,
  			   const u64 *y, const struct ecc_point *q,
  			   const struct ecc_curve *curve);
3c4b23901   Salvatore Benedetto   crypto: ecdh - Ad...
255
  #endif