Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a2289da authored by Vitaly Chikunov's avatar Vitaly Chikunov Committed by Herbert Xu
Browse files

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: default avatarVitaly Chikunov <vt@altlinux.org>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 3d6228a5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -248,8 +248,12 @@ config CRYPTO_DH
	help
	  Generic implementation of the Diffie-Hellman algorithm.

config CRYPTO_ECC
	tristate

config CRYPTO_ECDH
	tristate "ECDH algorithm"
	select CRYPTO_ECC
	select CRYPTO_KPP
	select CRYPTO_RNG_DEFAULT
	help
+1 −1
Original line number Diff line number Diff line
@@ -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_ZSTD) += zstd.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_helper.o
obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
+18 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/module.h>
#include <linux/random.h>
#include <linux/slab.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. */
static bool vli_is_zero(const u64 *vli, unsigned int ndigits)
bool vli_is_zero(const u64 *vli, unsigned int ndigits)
{
	int i;

@@ -123,6 +124,7 @@ static bool vli_is_zero(const u64 *vli, unsigned int ndigits)

	return true;
}
EXPORT_SYMBOL(vli_is_zero);

/* Returns nonzero if bit bit of vli is set. */
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. */
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;

@@ -184,6 +186,7 @@ static int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)

	return 0;
}
EXPORT_SYMBOL(vli_cmp);

/* Computes result = in << c, returning carry. Can modify in place
 * (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. */
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)
{
	u64 borrow = 0;
@@ -258,6 +261,7 @@ static u64 vli_sub(u64 *result, const u64 *left, const u64 *right,

	return borrow;
}
EXPORT_SYMBOL(vli_sub);

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"
 * 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)
{
	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);
}
EXPORT_SYMBOL(vli_mod_inv);

/* ------ 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);
}
EXPORT_SYMBOL(ecc_is_key_valid);

/*
 * 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;
}
EXPORT_SYMBOL(ecc_gen_privkey);

int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
		     const u64 *private_key, u64 *public_key)
@@ -1036,9 +1043,10 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
out:
	return ret;
}
EXPORT_SYMBOL(ecc_make_pub_key);

/* 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)
{
	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 0;

}
EXPORT_SYMBOL(ecc_is_pubkey_valid_partial);

int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
			      const u64 *private_key, const u64 *public_key,
@@ -1121,3 +1129,6 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
out:
	return ret;
}
EXPORT_SYMBOL(crypto_ecdh_shared_secret);

MODULE_LICENSE("Dual BSD/GPL");
+99 −0
Original line number Diff line number Diff line
@@ -32,6 +32,41 @@

#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
 *
@@ -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,
			      const u64 *private_key, const u64 *public_key,
			      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
+0 −15
Original line number Diff line number Diff line
@@ -2,21 +2,6 @@
#ifndef _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 */
static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
				0x188DA80EB03090F6ull };