From 305fe835d4c704e5b279ec49288fd3d03ec85933 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 5 Jan 2013 20:59:46 +0200 Subject: [PATCH] Add more crypto_bignum_*() wrappers These operations will be needed for SAE FCC group operations. Signed-hostap: Jouni Malinen --- src/crypto/crypto.h | 69 ++++++++++++++++++++++++++++ src/crypto/crypto_openssl.c | 92 +++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 950cd9e43..7c19d2b81 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -520,6 +520,75 @@ int crypto_bignum_mod(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c); +/** + * crypto_bignum_exptmod - Modular exponentiation: d = a^b (mod c) + * @a: Bignum; base + * @b: Bignum; exponent + * @c: Bignum; modulus + * @d: Bignum; used to store the result of a^b (mod c) + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_exptmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); + +/** + * crypto_bignum_rshift - b = a >> n + * @a: Bignum + * @n: Number of bits to shift + * @b: Bignum; used to store the result of a >> n + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_rshift(const struct crypto_bignum *a, int n, + struct crypto_bignum *b); + +/** + * crypto_bignum_inverse - Inverse a bignum so that a * c = 1 (mod b) + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_inverse(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_sub - c = a - b + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a - b + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_sub(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_div - c = a / b + * @a: Bignum + * @b: Bignum + * @c: Bignum; used to store the result of a / b + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_div(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_mulmod - d = a * b (mod c) + * @a: Bignum + * @b: Bignum + * @c: Bignum + * @d: Bignum; used to store the result of (a * b) % c + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_mulmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); + /** * struct crypto_ec - Elliptic curve context * diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 593cf6f2d..80bc50fab 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -895,6 +895,98 @@ int crypto_bignum_mod(const struct crypto_bignum *a, } +int crypto_bignum_exptmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d) +{ + int res; + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + if (bnctx == NULL) + return -1; + res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b, + (const BIGNUM *) c, bnctx); + BN_CTX_free(bnctx); + + return res ? 0 : -1; +} + + +int crypto_bignum_rshift(const struct crypto_bignum *a, int n, + struct crypto_bignum *b) +{ + return BN_rshift((BIGNUM *) b, (const BIGNUM *) a, n) ? 0 : -1; +} + + +int crypto_bignum_inverse(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c) +{ + BIGNUM *res; + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + if (bnctx == NULL) + return -1; + res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a, + (const BIGNUM *) b, bnctx); + BN_CTX_free(bnctx); + + return res ? 0 : -1; +} + + +int crypto_bignum_sub(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c) +{ + return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ? + 0 : -1; +} + + +int crypto_bignum_div(const struct crypto_bignum *a, + const struct crypto_bignum *b, + struct crypto_bignum *c) +{ + int res; + + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + if (bnctx == NULL) + return -1; + res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a, + (const BIGNUM *) b, bnctx); + BN_CTX_free(bnctx); + + return res ? 0 : -1; +} + + +int crypto_bignum_mulmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d) +{ + int res; + + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + if (bnctx == NULL) + return -1; + res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b, + (const BIGNUM *) c, bnctx); + BN_CTX_free(bnctx); + + return res ? 0 : -1; +} + + #ifdef CONFIG_ECC struct crypto_ec {