diff options
author | Vitaly Chikunov <vt@altlinux.org> | 2018-11-05 03:36:18 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2018-11-16 01:09:39 -0500 |
commit | 2eb4942b6609d35a4e835644a33203b0aef7443d (patch) | |
tree | f591a91748069d4db65aadc43858ba3651478647 | |
parent | 196ad6043e9fe93c4ae3dac02b5c8fd337f58c2d (diff) |
crypto: ecc - check for invalid values in the key verification test
Currently used scalar multiplication algorithm (Matthieu Rivain, 2011)
have invalid values for scalar == 1, n-1, and for regularized version
n-2, which was previously not checked. Verify that they are not used as
private keys.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/ecc.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/crypto/ecc.c b/crypto/ecc.c index 8facafd67802..9d24e6522730 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c | |||
@@ -904,30 +904,43 @@ static inline void ecc_swap_digits(const u64 *in, u64 *out, | |||
904 | out[i] = __swab64(in[ndigits - 1 - i]); | 904 | out[i] = __swab64(in[ndigits - 1 - i]); |
905 | } | 905 | } |
906 | 906 | ||
907 | int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, | 907 | static int __ecc_is_key_valid(const struct ecc_curve *curve, |
908 | const u64 *private_key, unsigned int private_key_len) | 908 | const u64 *private_key, unsigned int ndigits) |
909 | { | 909 | { |
910 | int nbytes; | 910 | u64 one[ECC_MAX_DIGITS] = { 1, }; |
911 | const struct ecc_curve *curve = ecc_get_curve(curve_id); | 911 | u64 res[ECC_MAX_DIGITS]; |
912 | 912 | ||
913 | if (!private_key) | 913 | if (!private_key) |
914 | return -EINVAL; | 914 | return -EINVAL; |
915 | 915 | ||
916 | nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; | 916 | if (curve->g.ndigits != ndigits) |
917 | |||
918 | if (private_key_len != nbytes) | ||
919 | return -EINVAL; | 917 | return -EINVAL; |
920 | 918 | ||
921 | if (vli_is_zero(private_key, ndigits)) | 919 | /* Make sure the private key is in the range [2, n-3]. */ |
920 | if (vli_cmp(one, private_key, ndigits) != -1) | ||
922 | return -EINVAL; | 921 | return -EINVAL; |
923 | 922 | vli_sub(res, curve->n, one, ndigits); | |
924 | /* Make sure the private key is in the range [1, n-1]. */ | 923 | vli_sub(res, res, one, ndigits); |
925 | if (vli_cmp(curve->n, private_key, ndigits) != 1) | 924 | if (vli_cmp(res, private_key, ndigits) != 1) |
926 | return -EINVAL; | 925 | return -EINVAL; |
927 | 926 | ||
928 | return 0; | 927 | return 0; |
929 | } | 928 | } |
930 | 929 | ||
930 | int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, | ||
931 | const u64 *private_key, unsigned int private_key_len) | ||
932 | { | ||
933 | int nbytes; | ||
934 | const struct ecc_curve *curve = ecc_get_curve(curve_id); | ||
935 | |||
936 | nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; | ||
937 | |||
938 | if (private_key_len != nbytes) | ||
939 | return -EINVAL; | ||
940 | |||
941 | return __ecc_is_key_valid(curve, private_key, ndigits); | ||
942 | } | ||
943 | |||
931 | /* | 944 | /* |
932 | * ECC private keys are generated using the method of extra random bits, | 945 | * ECC private keys are generated using the method of extra random bits, |
933 | * equivalent to that described in FIPS 186-4, Appendix B.4.1. | 946 | * equivalent to that described in FIPS 186-4, Appendix B.4.1. |
@@ -971,11 +984,8 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey) | |||
971 | if (err) | 984 | if (err) |
972 | return err; | 985 | return err; |
973 | 986 | ||
974 | if (vli_is_zero(priv, ndigits)) | 987 | /* Make sure the private key is in the valid range. */ |
975 | return -EINVAL; | 988 | if (__ecc_is_key_valid(curve, priv, ndigits)) |
976 | |||
977 | /* Make sure the private key is in the range [1, n-1]. */ | ||
978 | if (vli_cmp(curve->n, priv, ndigits) != 1) | ||
979 | return -EINVAL; | 989 | return -EINVAL; |
980 | 990 | ||
981 | ecc_swap_digits(priv, privkey, ndigits); | 991 | ecc_swap_digits(priv, privkey, ndigits); |