crypto: hisilicon/sec - Supply missing description for 'sec_queue_empty()'s 'queue...
[linux-2.6-microblaze.git] / crypto / ecc.h
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
31 /* One digit is u64 qword. */
32 #define ECC_CURVE_NIST_P192_DIGITS  3
33 #define ECC_CURVE_NIST_P256_DIGITS  4
34 #define ECC_CURVE_NIST_P384_DIGITS  6
35 #define ECC_MAX_DIGITS              (512 / 64) /* due to ecrdsa */
36
37 #define ECC_DIGITS_TO_BYTES_SHIFT 3
38
39 #define ECC_MAX_BYTES (ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT)
40
41 #define ECC_POINT_INIT(x, y, ndigits)   (struct ecc_point) { x, y, ndigits }
42
43 /**
44  * ecc_swap_digits() - Copy ndigits from big endian array to native array
45  * @in:       Input array
46  * @out:      Output array
47  * @ndigits:  Number of digits to copy
48  */
49 static inline void ecc_swap_digits(const u64 *in, u64 *out, unsigned int ndigits)
50 {
51         const __be64 *src = (__force __be64 *)in;
52         int i;
53
54         for (i = 0; i < ndigits; i++)
55                 out[i] = be64_to_cpu(src[ndigits - 1 - i]);
56 }
57
58 /**
59  * ecc_get_curve()  - Get a curve given its curve_id
60  * @curve_id:  Id of the curve
61  *
62  * Returns pointer to the curve data, NULL if curve is not available
63  */
64 const struct ecc_curve *ecc_get_curve(unsigned int curve_id);
65
66 /**
67  * ecc_is_key_valid() - Validate a given ECDH private key
68  *
69  * @curve_id:           id representing the curve to use
70  * @ndigits:            curve's number of digits
71  * @private_key:        private key to be used for the given curve
72  * @private_key_len:    private key length
73  *
74  * Returns 0 if the key is acceptable, a negative value otherwise
75  */
76 int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
77                      const u64 *private_key, unsigned int private_key_len);
78
79 /**
80  * ecc_gen_privkey() -  Generates an ECC private key.
81  * The private key is a random integer in the range 0 < random < n, where n is a
82  * prime that is the order of the cyclic subgroup generated by the distinguished
83  * point G.
84  * @curve_id:           id representing the curve to use
85  * @ndigits:            curve number of digits
86  * @private_key:        buffer for storing the generated private key
87  *
88  * Returns 0 if the private key was generated successfully, a negative value
89  * if an error occurred.
90  */
91 int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey);
92
93 /**
94  * ecc_make_pub_key() - Compute an ECC public key
95  *
96  * @curve_id:           id representing the curve to use
97  * @ndigits:            curve's number of digits
98  * @private_key:        pregenerated private key for the given curve
99  * @public_key:         buffer for storing the generated public key
100  *
101  * Returns 0 if the public key was generated successfully, a negative value
102  * if an error occurred.
103  */
104 int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
105                      const u64 *private_key, u64 *public_key);
106
107 /**
108  * crypto_ecdh_shared_secret() - Compute a shared secret
109  *
110  * @curve_id:           id representing the curve to use
111  * @ndigits:            curve's number of digits
112  * @private_key:        private key of part A
113  * @public_key:         public key of counterpart B
114  * @secret:             buffer for storing the calculated shared secret
115  *
116  * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret
117  * before using it for symmetric encryption or HMAC.
118  *
119  * Returns 0 if the shared secret was generated successfully, a negative value
120  * if an error occurred.
121  */
122 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
123                               const u64 *private_key, const u64 *public_key,
124                               u64 *secret);
125
126 /**
127  * ecc_is_pubkey_valid_partial() - Partial public key validation
128  *
129  * @curve:              elliptic curve domain parameters
130  * @pk:                 public key as a point
131  *
132  * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial
133  * Public-Key Validation Routine.
134  *
135  * Note: There is no check that the public key is in the correct elliptic curve
136  * subgroup.
137  *
138  * Return: 0 if validation is successful, -EINVAL if validation is failed.
139  */
140 int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
141                                 struct ecc_point *pk);
142
143 /**
144  * ecc_is_pubkey_valid_full() - Full public key validation
145  *
146  * @curve:              elliptic curve domain parameters
147  * @pk:                 public key as a point
148  *
149  * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full
150  * Public-Key Validation Routine.
151  *
152  * Return: 0 if validation is successful, -EINVAL if validation is failed.
153  */
154 int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
155                              struct ecc_point *pk);
156
157 /**
158  * vli_is_zero() - Determine is vli is zero
159  *
160  * @vli:                vli to check.
161  * @ndigits:            length of the @vli
162  */
163 bool vli_is_zero(const u64 *vli, unsigned int ndigits);
164
165 /**
166  * vli_cmp() - compare left and right vlis
167  *
168  * @left:               vli
169  * @right:              vli
170  * @ndigits:            length of both vlis
171  *
172  * Returns sign of @left - @right, i.e. -1 if @left < @right,
173  * 0 if @left == @right, 1 if @left > @right.
174  */
175 int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits);
176
177 /**
178  * vli_sub() - Subtracts right from left
179  *
180  * @result:             where to write result
181  * @left:               vli
182  * @right               vli
183  * @ndigits:            length of all vlis
184  *
185  * Note: can modify in-place.
186  *
187  * Return: carry bit.
188  */
189 u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
190             unsigned int ndigits);
191
192 /**
193  * vli_from_be64() - Load vli from big-endian u64 array
194  *
195  * @dest:               destination vli
196  * @src:                source array of u64 BE values
197  * @ndigits:            length of both vli and array
198  */
199 void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits);
200
201 /**
202  * vli_from_le64() - Load vli from little-endian u64 array
203  *
204  * @dest:               destination vli
205  * @src:                source array of u64 LE values
206  * @ndigits:            length of both vli and array
207  */
208 void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits);
209
210 /**
211  * vli_mod_inv() - Modular inversion
212  *
213  * @result:             where to write vli number
214  * @input:              vli value to operate on
215  * @mod:                modulus
216  * @ndigits:            length of all vlis
217  */
218 void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
219                  unsigned int ndigits);
220
221 /**
222  * vli_mod_mult_slow() - Modular multiplication
223  *
224  * @result:             where to write result value
225  * @left:               vli number to multiply with @right
226  * @right:              vli number to multiply with @left
227  * @mod:                modulus
228  * @ndigits:            length of all vlis
229  *
230  * Note: Assumes that mod is big enough curve order.
231  */
232 void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right,
233                        const u64 *mod, unsigned int ndigits);
234
235 /**
236  * ecc_point_mult_shamir() - Add two points multiplied by scalars
237  *
238  * @result:             resulting point
239  * @x:                  scalar to multiply with @p
240  * @p:                  point to multiply with @x
241  * @y:                  scalar to multiply with @q
242  * @q:                  point to multiply with @y
243  * @curve:              curve
244  *
245  * Returns result = x * p + x * q over the curve.
246  * This works faster than two multiplications and addition.
247  */
248 void ecc_point_mult_shamir(const struct ecc_point *result,
249                            const u64 *x, const struct ecc_point *p,
250                            const u64 *y, const struct ecc_point *q,
251                            const struct ecc_curve *curve);
252 #endif