Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

Commit

Permalink
crypto: ecc - make ecc into separate module
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
vt-alt authored and herbertx committed Apr 18, 2019
1 parent 3d6228a commit 4a2289d
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 23 deletions.
4 changes: 4 additions & 0 deletions crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 18 additions & 7 deletions crypto/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;

Expand All @@ -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)
Expand Down Expand Up @@ -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;

Expand All @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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)
{
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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 ------ */

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1036,10 +1043,11 @@ 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,
struct ecc_point *pk)
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];

Expand All @@ -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,
Expand Down Expand Up @@ -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 changes: 99 additions & 0 deletions crypto/ecc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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
15 changes: 0 additions & 15 deletions crypto/ecc_curve_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down

0 comments on commit 4a2289d

Please sign in to comment.