aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2018-03-08 16:57:02 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2018-03-16 11:35:53 -0400
commit14de52112ee70ca289fa77bf2d9cbc79fd2c811f (patch)
treeaadb21d93cde2da9a059f4660d8c8376485526c2 /crypto
parentb698a9f4c5c52317db486b069190c7e3d2b97e7e (diff)
crypto: ecc - Remove stack VLA usage
On the quest to remove all VLAs from the kernel[1], this switches to a pair of kmalloc regions instead of using the stack. This also moves the get_random_bytes() after all allocations (and drops the needless "nbytes" variable). [1] https://lkml.org/lkml/2018/3/7/621 Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/ecc.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/crypto/ecc.c b/crypto/ecc.c
index 18f32f2a5e1c..9c066b5ac12d 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -1025,9 +1025,7 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
1025{ 1025{
1026 int ret = 0; 1026 int ret = 0;
1027 struct ecc_point *product, *pk; 1027 struct ecc_point *product, *pk;
1028 u64 priv[ndigits]; 1028 u64 *priv, *rand_z;
1029 u64 rand_z[ndigits];
1030 unsigned int nbytes;
1031 const struct ecc_curve *curve = ecc_get_curve(curve_id); 1029 const struct ecc_curve *curve = ecc_get_curve(curve_id);
1032 1030
1033 if (!private_key || !public_key || !curve) { 1031 if (!private_key || !public_key || !curve) {
@@ -1035,14 +1033,22 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
1035 goto out; 1033 goto out;
1036 } 1034 }
1037 1035
1038 nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; 1036 priv = kmalloc_array(ndigits, sizeof(*priv), GFP_KERNEL);
1037 if (!priv) {
1038 ret = -ENOMEM;
1039 goto out;
1040 }
1039 1041
1040 get_random_bytes(rand_z, nbytes); 1042 rand_z = kmalloc_array(ndigits, sizeof(*rand_z), GFP_KERNEL);
1043 if (!rand_z) {
1044 ret = -ENOMEM;
1045 goto kfree_out;
1046 }
1041 1047
1042 pk = ecc_alloc_point(ndigits); 1048 pk = ecc_alloc_point(ndigits);
1043 if (!pk) { 1049 if (!pk) {
1044 ret = -ENOMEM; 1050 ret = -ENOMEM;
1045 goto out; 1051 goto kfree_out;
1046 } 1052 }
1047 1053
1048 product = ecc_alloc_point(ndigits); 1054 product = ecc_alloc_point(ndigits);
@@ -1051,6 +1057,8 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
1051 goto err_alloc_product; 1057 goto err_alloc_product;
1052 } 1058 }
1053 1059
1060 get_random_bytes(rand_z, ndigits << ECC_DIGITS_TO_BYTES_SHIFT);
1061
1054 ecc_swap_digits(public_key, pk->x, ndigits); 1062 ecc_swap_digits(public_key, pk->x, ndigits);
1055 ecc_swap_digits(&public_key[ndigits], pk->y, ndigits); 1063 ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
1056 ecc_swap_digits(private_key, priv, ndigits); 1064 ecc_swap_digits(private_key, priv, ndigits);
@@ -1065,6 +1073,9 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
1065 ecc_free_point(product); 1073 ecc_free_point(product);
1066err_alloc_product: 1074err_alloc_product:
1067 ecc_free_point(pk); 1075 ecc_free_point(pk);
1076kfree_out:
1077 kzfree(priv);
1078 kzfree(rand_z);
1068out: 1079out:
1069 return ret; 1080 return ret;
1070} 1081}