mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
crypto: ecc - make ecc into separate module
ecc.c have algorithms that could be used togeter by ecdh and ecrdsa. Make it separate module. Add CRYPTO_ECC into Kconfig. EXPORT_SYMBOL and document to what seems appropriate. Move structs ecc_point and ecc_curve from ecc_curve_defs.h into ecc.h. No code changes. Signed-off-by: Vitaly Chikunov <vt@altlinux.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
3d6228a505
commit
4a2289dae0
@ -248,8 +248,12 @@ config CRYPTO_DH
|
|||||||
help
|
help
|
||||||
Generic implementation of the Diffie-Hellman algorithm.
|
Generic implementation of the Diffie-Hellman algorithm.
|
||||||
|
|
||||||
|
config CRYPTO_ECC
|
||||||
|
tristate
|
||||||
|
|
||||||
config CRYPTO_ECDH
|
config CRYPTO_ECDH
|
||||||
tristate "ECDH algorithm"
|
tristate "ECDH algorithm"
|
||||||
|
select CRYPTO_ECC
|
||||||
select CRYPTO_KPP
|
select CRYPTO_KPP
|
||||||
select CRYPTO_RNG_DEFAULT
|
select CRYPTO_RNG_DEFAULT
|
||||||
help
|
help
|
||||||
|
@ -147,8 +147,8 @@ obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o
|
|||||||
obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
|
obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
|
||||||
obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
|
obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
|
||||||
obj-$(CONFIG_CRYPTO_OFB) += ofb.o
|
obj-$(CONFIG_CRYPTO_OFB) += ofb.o
|
||||||
|
obj-$(CONFIG_CRYPTO_ECC) += ecc.o
|
||||||
|
|
||||||
ecdh_generic-y := ecc.o
|
|
||||||
ecdh_generic-y += ecdh.o
|
ecdh_generic-y += ecdh.o
|
||||||
ecdh_generic-y += ecdh_helper.o
|
ecdh_generic-y += ecdh_helper.o
|
||||||
obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
|
obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
|
||||||
|
25
crypto/ecc.c
25
crypto/ecc.c
@ -24,6 +24,7 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/swab.h>
|
#include <linux/swab.h>
|
||||||
@ -112,7 +113,7 @@ static void vli_clear(u64 *vli, unsigned int ndigits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if vli == 0, false otherwise. */
|
/* Returns true if vli == 0, false otherwise. */
|
||||||
static bool vli_is_zero(const u64 *vli, unsigned int ndigits)
|
bool vli_is_zero(const u64 *vli, unsigned int ndigits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -123,6 +124,7 @@ static bool vli_is_zero(const u64 *vli, unsigned int ndigits)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(vli_is_zero);
|
||||||
|
|
||||||
/* Returns nonzero if bit bit of vli is set. */
|
/* Returns nonzero if bit bit of vli is set. */
|
||||||
static u64 vli_test_bit(const u64 *vli, unsigned int bit)
|
static u64 vli_test_bit(const u64 *vli, unsigned int bit)
|
||||||
@ -171,7 +173,7 @@ static void vli_set(u64 *dest, const u64 *src, unsigned int ndigits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns sign of left - right. */
|
/* Returns sign of left - right. */
|
||||||
static int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
|
int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -184,6 +186,7 @@ static int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(vli_cmp);
|
||||||
|
|
||||||
/* Computes result = in << c, returning carry. Can modify in place
|
/* Computes result = in << c, returning carry. Can modify in place
|
||||||
* (if result == in). 0 < shift < 64.
|
* (if result == in). 0 < shift < 64.
|
||||||
@ -240,7 +243,7 @@ static u64 vli_add(u64 *result, const u64 *left, const u64 *right,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Computes result = left - right, returning borrow. Can modify in place. */
|
/* Computes result = left - right, returning borrow. Can modify in place. */
|
||||||
static u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
|
u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
|
||||||
unsigned int ndigits)
|
unsigned int ndigits)
|
||||||
{
|
{
|
||||||
u64 borrow = 0;
|
u64 borrow = 0;
|
||||||
@ -258,6 +261,7 @@ static u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
|
|||||||
|
|
||||||
return borrow;
|
return borrow;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(vli_sub);
|
||||||
|
|
||||||
static uint128_t mul_64_64(u64 left, u64 right)
|
static uint128_t mul_64_64(u64 left, u64 right)
|
||||||
{
|
{
|
||||||
@ -557,7 +561,7 @@ static void vli_mod_square_fast(u64 *result, const u64 *left,
|
|||||||
* See "From Euclid's GCD to Montgomery Multiplication to the Great Divide"
|
* See "From Euclid's GCD to Montgomery Multiplication to the Great Divide"
|
||||||
* https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf
|
* https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf
|
||||||
*/
|
*/
|
||||||
static void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
|
void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
|
||||||
unsigned int ndigits)
|
unsigned int ndigits)
|
||||||
{
|
{
|
||||||
u64 a[ECC_MAX_DIGITS], b[ECC_MAX_DIGITS];
|
u64 a[ECC_MAX_DIGITS], b[ECC_MAX_DIGITS];
|
||||||
@ -630,6 +634,7 @@ static void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
|
|||||||
|
|
||||||
vli_set(result, u, ndigits);
|
vli_set(result, u, ndigits);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(vli_mod_inv);
|
||||||
|
|
||||||
/* ------ Point operations ------ */
|
/* ------ Point operations ------ */
|
||||||
|
|
||||||
@ -948,6 +953,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
|
|||||||
|
|
||||||
return __ecc_is_key_valid(curve, private_key, ndigits);
|
return __ecc_is_key_valid(curve, private_key, ndigits);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(ecc_is_key_valid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ECC private keys are generated using the method of extra random bits,
|
* ECC private keys are generated using the method of extra random bits,
|
||||||
@ -1000,6 +1006,7 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(ecc_gen_privkey);
|
||||||
|
|
||||||
int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
|
int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
|
||||||
const u64 *private_key, u64 *public_key)
|
const u64 *private_key, u64 *public_key)
|
||||||
@ -1036,10 +1043,11 @@ err_free_point:
|
|||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(ecc_make_pub_key);
|
||||||
|
|
||||||
/* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
|
/* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
|
||||||
static int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
|
int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
|
||||||
struct ecc_point *pk)
|
struct ecc_point *pk)
|
||||||
{
|
{
|
||||||
u64 yy[ECC_MAX_DIGITS], xxx[ECC_MAX_DIGITS], w[ECC_MAX_DIGITS];
|
u64 yy[ECC_MAX_DIGITS], xxx[ECC_MAX_DIGITS], w[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
@ -1064,8 +1072,8 @@ static int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(ecc_is_pubkey_valid_partial);
|
||||||
|
|
||||||
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
|
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
|
||||||
const u64 *private_key, const u64 *public_key,
|
const u64 *private_key, const u64 *public_key,
|
||||||
@ -1121,3 +1129,6 @@ err_alloc_product:
|
|||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(crypto_ecdh_shared_secret);
|
||||||
|
|
||||||
|
MODULE_LICENSE("Dual BSD/GPL");
|
||||||
|
99
crypto/ecc.h
99
crypto/ecc.h
@ -32,6 +32,41 @@
|
|||||||
|
|
||||||
#define ECC_DIGITS_TO_BYTES_SHIFT 3
|
#define ECC_DIGITS_TO_BYTES_SHIFT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ecc_is_key_valid() - Validate a given ECDH private key
|
* ecc_is_key_valid() - Validate a given ECDH private key
|
||||||
*
|
*
|
||||||
@ -91,4 +126,68 @@ int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
|
|||||||
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
|
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
|
||||||
const u64 *private_key, const u64 *public_key,
|
const u64 *private_key, const u64 *public_key,
|
||||||
u64 *secret);
|
u64 *secret);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,21 +2,6 @@
|
|||||||
#ifndef _CRYTO_ECC_CURVE_DEFS_H
|
#ifndef _CRYTO_ECC_CURVE_DEFS_H
|
||||||
#define _CRYTO_ECC_CURVE_DEFS_H
|
#define _CRYTO_ECC_CURVE_DEFS_H
|
||||||
|
|
||||||
struct ecc_point {
|
|
||||||
u64 *x;
|
|
||||||
u64 *y;
|
|
||||||
u8 ndigits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ecc_curve {
|
|
||||||
char *name;
|
|
||||||
struct ecc_point g;
|
|
||||||
u64 *p;
|
|
||||||
u64 *n;
|
|
||||||
u64 *a;
|
|
||||||
u64 *b;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* NIST P-192: a = p - 3 */
|
/* NIST P-192: a = p - 3 */
|
||||||
static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
|
static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
|
||||||
0x188DA80EB03090F6ull };
|
0x188DA80EB03090F6ull };
|
||||||
|
Loading…
Reference in New Issue
Block a user