diff options
| author | Kees Cook <keescook@chromium.org> | 2018-03-08 16:57:02 -0500 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2018-03-16 11:35:53 -0400 |
| commit | 14de52112ee70ca289fa77bf2d9cbc79fd2c811f (patch) | |
| tree | aadb21d93cde2da9a059f4660d8c8376485526c2 /crypto | |
| parent | b698a9f4c5c52317db486b069190c7e3d2b97e7e (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.c | 23 |
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); |
| 1066 | err_alloc_product: | 1074 | err_alloc_product: |
| 1067 | ecc_free_point(pk); | 1075 | ecc_free_point(pk); |
| 1076 | kfree_out: | ||
| 1077 | kzfree(priv); | ||
| 1078 | kzfree(rand_z); | ||
| 1068 | out: | 1079 | out: |
| 1069 | return ret; | 1080 | return ret; |
| 1070 | } | 1081 | } |
