| 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 |
|
| 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)
|
| 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 | * Validate 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 | * Validate 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 | * Returns: %true if vli == 0, %false otherwise.
|
| 184 |
|
| 185 | bool vli_is_zero(const u64 *vli, unsigned int ndigits);
|
| 186 |
|
| 187 | |
| 188 | * vli_cmp() - compare left and right vlis
|
| 189 | *
|
| 190 | * @left: vli
|
| 191 | * @right: vli
|
| 192 | * @ndigits: length of both vlis
|
| 193 | *
|
| 194 | * Returns: sign of @left - @right, i.e. -1 if @left < @right,
|
| 195 | * 0 if @left == @right, 1 if @left > @right.
|
| 196 |
|
| 197 | int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits);
|
| 198 |
|
| 199 | |
| 200 | * vli_sub() - Subtracts right from left
|
| 201 | *
|
| 202 | * @result: where to write result
|
| 203 | * @left: vli
|
| 204 | * @right: vli
|
| 205 | * @ndigits: length of all vlis
|
| 206 | *
|
| 207 | * Note: can modify in-place.
|
| 208 | *
|
| 209 | * Return: carry bit.
|
| 210 |
|
| 211 | u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
|
| 212 | unsigned int ndigits);
|
| 213 |
|
| 214 | |
| 215 | * vli_from_be64() - Load vli from big-endian u64 array
|
| 216 | *
|
| 217 | * @dest: destination vli
|
| 218 | * @src: source array of u64 BE values
|
| 219 | * @ndigits: length of both vli and array
|
| 220 |
|
| 221 | void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits);
|
| 222 |
|
| 223 | |
| 224 | * vli_from_le64() - Load vli from little-endian u64 array
|
| 225 | *
|
| 226 | * @dest: destination vli
|
| 227 | * @src: source array of u64 LE values
|
| 228 | * @ndigits: length of both vli and array
|
| 229 |
|
| 230 | void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits);
|
| 231 |
|
| 232 | |
| 233 | * vli_mod_inv() - Modular inversion
|
| 234 | *
|
| 235 | * @result: where to write vli number
|
| 236 | * @input: vli value to operate on
|
| 237 | * @mod: modulus
|
| 238 | * @ndigits: length of all vlis
|
| 239 |
|
| 240 | void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
|
| 241 | unsigned int ndigits);
|
| 242 |
|
| 243 | |
| 244 | * vli_mod_mult_slow() - Modular multiplication
|
| 245 | *
|
| 246 | * @result: where to write result value
|
| 247 | * @left: vli number to multiply with @right
|
| 248 | * @right: vli number to multiply with @left
|
| 249 | * @mod: modulus
|
| 250 | * @ndigits: length of all vlis
|
| 251 | *
|
| 252 | * Note: Assumes that mod is big enough curve order.
|
| 253 |
|
| 254 | void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right,
|
| 255 | const u64 *mod, unsigned int ndigits);
|
| 256 |
|
| 257 | |
| 258 | * vli_num_bits() - Counts the number of bits required for vli.
|
| 259 | *
|
| 260 | * @vli: vli to check.
|
| 261 | * @ndigits: Length of the @vli
|
| 262 | *
|
| 263 | * Return: The number of bits required to represent @vli.
|
| 264 |
|
| 265 | unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits);
|
| 266 |
|
| 267 | |
| 268 | * ecc_alloc_point() - Allocate ECC point.
|
| 269 | *
|
| 270 | * @ndigits: Length of vlis in u64 qwords.
|
| 271 | *
|
| 272 | * Return: Pointer to the allocated point or NULL if allocation failed.
|
| 273 |
|
| 274 | struct ecc_point *ecc_alloc_point(unsigned int ndigits);
|
| 275 |
|
| 276 | |
| 277 | * ecc_free_point() - Free ECC point.
|
| 278 | *
|
| 279 | * @p: The point to free.
|
| 280 |
|
| 281 | void ecc_free_point(struct ecc_point *p);
|
| 282 |
|
| 283 | |
| 284 | * ecc_point_is_zero() - Check if point is zero.
|
| 285 | *
|
| 286 | * @point: Point to check for zero.
|
| 287 | *
|
| 288 | * Return: true if point is the point at infinity, false otherwise.
|
| 289 |
|
| 290 | bool ecc_point_is_zero(const struct ecc_point *point);
|
| 291 |
|
| 292 | |
| 293 | * ecc_point_mult_shamir() - Add two points multiplied by scalars
|
| 294 | *
|
| 295 | * @result: resulting point
|
| 296 | * @x: scalar to multiply with @p
|
| 297 | * @p: point to multiply with @x
|
| 298 | * @y: scalar to multiply with @q
|
| 299 | * @q: point to multiply with @y
|
| 300 | * @curve: curve
|
| 301 | *
|
| 302 | * Returns result = x * p + x * q over the curve.
|
| 303 | * This works faster than two multiplications and addition.
|
| 304 |
|
| 305 | void ecc_point_mult_shamir(const struct ecc_point *result,
|
| 306 | const u64 *x, const struct ecc_point *p,
|
| 307 | const u64 *y, const struct ecc_point *q,
|
| 308 | const struct ecc_curve *curve);
|
| 309 |
|
| 310 | extern struct crypto_template ecdsa_x962_tmpl;
|
| 311 | extern struct crypto_template ecdsa_p1363_tmpl;
|
| 312 | #endif
|