crypto: dh - input validation fixes
Subsystems (3)
v2 cover crypto: dh - input validation fixes
This series fixes several corner cases in the Diffie-Hellman key exchange implementations:
1. With the software DH implementation, using a large buffer for 'g' caused a double free.
2. With CONFIG_DEBUG_SG=y and the software DH implementation, setting 'p' to 0 caused a BUG_ON().
3. With the QAT DH implementation, setting 'key' or 'g' larger than 'p' caused a buffer underflow.
Note that in kernels configured with CONFIG_KEY_DH_OPERATIONS=y, these bugs are reachable by unprivileged users via KEYCTL_DH_COMPUTE.
Patches 4 and 5 are cleanup only.
Eric Biggers (5):
crypto: dh - Fix double free of ctx->p
crypto: dh - Don't permit 'p' to be 0
crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
crypto: qat - Clean up error handling in qat_dh_set_secret()
crypto: dh - Remove pointless checks for NULL 'p' and 'g'
crypto/dh.c | 36 ++++++++++----------------- crypto/dh_helper.c | 16 ++++++++++++ drivers/crypto/qat/qat_common/qat_asym_algs.c | 18 ++++++-------- 3 files changed, 37 insertions(+), 33 deletions(-)
Signature · 1 line
2.15.0
PATCH v2 1/5 crypto: dh - Fix double free of ctx->p
From: Eric Biggers <[email protected]>
When setting the secret with the software Diffie-Hellman implementation, if allocating 'g' failed (e.g. if it was longer than MAX_EXTERN_MPI_BITS), then 'p' was freed twice: once immediately, and once later when the crypto_kpp tfm was destroyed.
Fix it by using dh_free_ctx() (renamed to dh_clear_ctx()) in the error paths, as that correctly sets the pointers to NULL.
KASAN report:
MPI: mpi too large (32760 bits)
=================================
BUG: KASAN: use-after-free in mpi_free+0x131/0x170
Read of size 4 at addr ffff88006c7cdf90 by task reproduce_doubl/367
CPU: 1 PID: 367 Comm: reproduce_doubl Not tainted 4.14.0-rc7-00040-g05298abde6fe #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
dump_stack+0xb3/0x10b
? mpi_free+0x131/0x170
print_address_description+0x79/0x2a0
? mpi_free+0x131/0x170
kasan_report+0x236/0x340
? akcipher_register_instance+0x90/0x90
__asan_report_load4_noabort+0x14/0x20
mpi_free+0x131/0x170
? akcipher_register_instance+0x90/0x90
dh_exit_tfm+0x3d/0x140
crypto_kpp_exit_tfm+0x52/0x70
crypto_destroy_tfm+0xb3/0x250
__keyctl_dh_compute+0x640/0xe90
? kasan_slab_free+0x12f/0x180
? dh_data_from_key+0x240/0x240
? key_create_or_update+0x1ee/0xb20
? key_instantiate_and_link+0x440/0x440
? lock_contended+0xee0/0xee0
? kfree+0xcf/0x210
? SyS_add_key+0x268/0x340
keyctl_dh_compute+0xb3/0xf1
? __keyctl_dh_compute+0xe90/0xe90
? SyS_add_key+0x26d/0x340
? entry_SYSCALL_64_fastpath+0x5/0xbe
? trace_hardirqs_on_caller+0x3f4/0x560
SyS_keyctl+0x72/0x2c0
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x43ccf9
RSP: 002b:00007ffeeec96158 EFLAGS: 00000246 ORIG_RAX: 00000000000000fa
RAX: ffffffffffffffda RBX: 000000000248b9b9 RCX: 000000000043ccf9
RDX: 00007ffeeec96170 RSI: 00007ffeeec96160 RDI: 0000000000000017
RBP: 0000000000000046 R08: 0000000000000000 R09: 0248b9b9143dc936
R10: 0000000000001000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000409670 R14: 0000000000409700 R15: 0000000000000000
Allocated by task 367:
save_stack_trace+0x16/0x20
kasan_kmalloc+0xeb/0x180
kmem_cache_alloc_trace+0x114/0x300
mpi_alloc+0x4b/0x230
mpi_read_raw_data+0xbe/0x360
dh_set_secret+0x1dc/0x460
__keyctl_dh_compute+0x623/0xe90
keyctl_dh_compute+0xb3/0xf1
SyS_keyctl+0x72/0x2c0
entry_SYSCALL_64_fastpath+0x1f/0xbe
Freed by task 367:
save_stack_trace+0x16/0x20
kasan_slab_free+0xab/0x180
kfree+0xb5/0x210
mpi_free+0xcb/0x170
dh_set_secret+0x2d7/0x460
__keyctl_dh_compute+0x623/0xe90
keyctl_dh_compute+0xb3/0xf1
SyS_keyctl+0x72/0x2c0
entry_SYSCALL_64_fastpath+0x1f/0xbe--- crypto/dh.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-)
crypto/dh.c +13 -20
@@ -21,19 +21,12 @@ struct dh_ctx {MPI xa; }; -static inline void dh_clear_params (struct dh_ctx *ctx) +static void dh_clear_ctx (struct dh_ctx *ctx) {mpi_free (ctx->p);mpi_free (ctx->g); - ctx->p =NULL ; - ctx->g =NULL ; -} - -static void dh_free_ctx (struct dh_ctx *ctx) -{ -dh_clear_params (ctx);mpi_free (ctx->xa); - ctx->xa =NULL ; +memset (ctx,0 ,sizeof (*ctx)); }/*
@@ -71,10 +64,8 @@ static int dh_set_params(struct dh_ctx *ctx, struct dh *params)return -EINVAL ; ctx->g =mpi_read_raw_data (params->g, params->g_size); -if (!ctx->g) { -mpi_free (ctx->p); +if (!ctx->g)return -EINVAL ; - }return 0 ; }
@@ -86,21 +77,23 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void *buf,struct dh params;/* Free the old MPI key if any */ -dh_free_ctx (ctx); +dh_clear_ctx (ctx);if (crypto_dh_decode_key (buf, len, ¶ms) <0 ) -return -EINVAL ; + goto err_clear_ctx;if (dh_set_params (ctx, ¶ms) <0 ) -return -EINVAL ; + goto err_clear_ctx; ctx->xa =mpi_read_raw_data (params.key, params.key_size); -if (!ctx->xa) { -dh_clear_params (ctx); -return -EINVAL ; - } +if (!ctx->xa) + goto err_clear_ctx;return 0 ; + +err_clear_ctx: +dh_clear_ctx (ctx); +return -EINVAL ; }static int dh_compute_value (struct kpp_request *req)
@@ -158,7 +151,7 @@ static void dh_exit_tfm(struct crypto_kpp *tfm) {struct dh_ctx *ctx =dh_get_ctx (tfm); -dh_free_ctx (ctx); +dh_clear_ctx (ctx); }static struct kpp_alg dh = {
Signature · 1 line
2.15.0
Re: [PATCH v2 1/5] crypto: dh - Fix double free of ctx->p
Quoted 78 lines · Eric Biggers
From: Eric Biggers <[email protected]>
When setting the secret with the software Diffie-Hellman implementation, if allocating 'g' failed (e.g. if it was longer than
MAX_EXTERN_MPI_BITS), then 'p' was freed twice: once immediately, and once later when thecrypto_kpptfm was destroyed.Fix it by using
dh_free_ctx()(renamed todh_clear_ctx()) in the error paths, as that correctly sets the pointers to NULL.KASAN report:
MPI: mpi too large (32760 bits) ================================= BUG: KASAN: use-after-free in mpi_free+0x131/0x170 Read of size 4 at addr ffff88006c7cdf90 by task reproduce_doubl/367 CPU: 1 PID: 367 Comm: reproduce_doubl Not tainted 4.14.0-rc7-00040-g05298abde6fe #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: dump_stack+0xb3/0x10b ? mpi_free+0x131/0x170 print_address_description+0x79/0x2a0 ? mpi_free+0x131/0x170 kasan_report+0x236/0x340 ? akcipher_register_instance+0x90/0x90 __asan_report_load4_noabort+0x14/0x20 mpi_free+0x131/0x170 ? akcipher_register_instance+0x90/0x90 dh_exit_tfm+0x3d/0x140 crypto_kpp_exit_tfm+0x52/0x70 crypto_destroy_tfm+0xb3/0x250 __keyctl_dh_compute+0x640/0xe90 ? kasan_slab_free+0x12f/0x180 ? dh_data_from_key+0x240/0x240 ? key_create_or_update+0x1ee/0xb20 ? key_instantiate_and_link+0x440/0x440 ? lock_contended+0xee0/0xee0 ? kfree+0xcf/0x210 ? SyS_add_key+0x268/0x340 keyctl_dh_compute+0xb3/0xf1 ? __keyctl_dh_compute+0xe90/0xe90 ? SyS_add_key+0x26d/0x340 ? entry_SYSCALL_64_fastpath+0x5/0xbe ? trace_hardirqs_on_caller+0x3f4/0x560 SyS_keyctl+0x72/0x2c0 entry_SYSCALL_64_fastpath+0x1f/0xbe RIP: 0033:0x43ccf9 RSP: 002b:00007ffeeec96158 EFLAGS: 00000246 ORIG_RAX: 00000000000000fa RAX: ffffffffffffffda RBX: 000000000248b9b9 RCX: 000000000043ccf9 RDX: 00007ffeeec96170 RSI: 00007ffeeec96160 RDI: 0000000000000017 RBP: 0000000000000046 R08: 0000000000000000 R09: 0248b9b9143dc936 R10: 0000000000001000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000409670 R14: 0000000000409700 R15: 0000000000000000 Allocated by task 367: save_stack_trace+0x16/0x20 kasan_kmalloc+0xeb/0x180 kmem_cache_alloc_trace+0x114/0x300 mpi_alloc+0x4b/0x230 mpi_read_raw_data+0xbe/0x360 dh_set_secret+0x1dc/0x460 __keyctl_dh_compute+0x623/0xe90 keyctl_dh_compute+0xb3/0xf1 SyS_keyctl+0x72/0x2c0 entry_SYSCALL_64_fastpath+0x1f/0xbe Freed by task 367: save_stack_trace+0x16/0x20 kasan_slab_free+0xab/0x180 kfree+0xb5/0x210 mpi_free+0xcb/0x170 dh_set_secret+0x2d7/0x460 __keyctl_dh_compute+0x623/0xe90 keyctl_dh_compute+0xb3/0xf1 SyS_keyctl+0x72/0x2c0 entry_SYSCALL_64_fastpath+0x1f/0xbe
Quoted 3 lines
Fixes 802c7f1c84e4 ("crypto: dh - Add DH software implementation")Cc <[email protected]> # v4.8+Signed-off-by Eric Biggers <[email protected]>
Quoted 83 lines
--- crypto/dh.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-)crypto/dh.c +13
-20@@ -21,19 +21,12 @@ struct dh_ctx {MPI xa; }; -static inline void dh_clear_params (struct dh_ctx *ctx) +static void dh_clear_ctx (struct dh_ctx *ctx) {mpi_free (ctx->p);mpi_free (ctx->g); - ctx->p =NULL ; - ctx->g =NULL ; -} - -static void dh_free_ctx (struct dh_ctx *ctx) -{ -dh_clear_params (ctx);mpi_free (ctx->xa); - ctx->xa =NULL ; +memset (ctx,0 ,sizeof (*ctx)); }/* @@ -71,10 +64,8 @@ static int dh_set_params(struct dh_ctx *ctx, struct dh *params)return -EINVAL ; ctx->g =mpi_read_raw_data (params->g, params->g_size); -if (!ctx->g) { -mpi_free (ctx->p); +if (!ctx->g)return -EINVAL ; - }return 0 ; }@@ -86,21 +77,23 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void *buf,struct dh params;/* Free the old MPI key if any */ -dh_free_ctx (ctx); +dh_clear_ctx (ctx);if (crypto_dh_decode_key (buf, len, ¶ms) <0 ) -return -EINVAL ; + goto err_clear_ctx;if (dh_set_params (ctx, ¶ms) <0 ) -return -EINVAL ; + goto err_clear_ctx; ctx->xa =mpi_read_raw_data (params.key, params.key_size); -if (!ctx->xa) { -dh_clear_params (ctx); -return -EINVAL ; - } +if (!ctx->xa) + goto err_clear_ctx;return 0 ; + +err_clear_ctx: +dh_clear_ctx (ctx); +return -EINVAL ; }static int dh_compute_value (struct kpp_request *req)@@ -158,7 +151,7 @@ static void dh_exit_tfm(struct crypto_kpp *tfm) {struct dh_ctx *ctx =dh_get_ctx (tfm); -dh_free_ctx (ctx); +dh_clear_ctx (ctx); }static struct kpp_alg dh = {
PATCH v2 2/5 crypto: dh - Don't permit 'p' to be 0
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
If 'p' is 0 for the software Diffie-Hellman implementation, then dh_max_size() returns 0. In the case of KEYCTL_DH_COMPUTE, this causes ZERO_SIZE_PTR to be passed to sg_init_one(), which with CONFIG_DEBUG_SG=y triggers the 'BUG_ON(!virt_addr_valid(buf));' in sg_set_buf().
Fix this by making crypto_dh_decode_key() reject 0 for 'p'. p=0 makes no sense for any DH implementation because 'p' is supposed to be a prime number. Moreover, 'mod 0' is not mathematically defined.
Bug report:
kernel BUG at ./include/linux/scatterlist.h:140!
invalid opcode: 0000 [#1] SMP KASAN
CPU: 0 PID: 27112 Comm: syz-executor2 Not tainted 4.14.0-rc7-00010-gf5dbb5d0ce32-dirty #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.3-20171021_125229-anatol 04/01/2014
task: ffff88006caac0c0 task.stack: ffff88006c7c8000
RIP: 0010:sg_set_buf include/linux/scatterlist.h:140 [inline]
RIP: 0010:sg_init_one+0x1b3/0x240 lib/scatterlist.c:156
RSP: 0018:ffff88006c7cfb08 EFLAGS: 00010216
RAX: 0000000000010000 RBX: ffff88006c7cfe30 RCX: 00000000000064ee
RDX: ffffffff81cf64c3 RSI: ffffc90000d72000 RDI: ffffffff92e937e0
RBP: ffff88006c7cfb30 R08: ffffed000d8f9fab R09: ffff88006c7cfd30
R10: 0000000000000005 R11: ffffed000d8f9faa R12: ffff88006c7cfd30
R13: 0000000000000000 R14: 0000000000000010 R15: ffff88006c7cfc50
FS: 00007fce190fa700(0000) GS:ffff88003ea00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fffc6b33db8 CR3: 000000003cf64000 CR4: 00000000000006f0
Call Trace:
__keyctl_dh_compute+0xa95/0x19b0 security/keys/dh.c:360
keyctl_dh_compute+0xac/0x100 security/keys/dh.c:434
SYSC_keyctl security/keys/keyctl.c:1745 [inline]
SyS_keyctl+0x72/0x2c0 security/keys/keyctl.c:1641
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x4585c9
RSP: 002b:00007fce190f9bd8 EFLAGS: 00000216 ORIG_RAX: 00000000000000fa
RAX: ffffffffffffffda RBX: 0000000000738020 RCX: 00000000004585c9
RDX: 000000002000d000 RSI: 0000000020000ff4 RDI: 0000000000000017
RBP: 0000000000000046 R08: 0000000020008000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000216 R12: 00007fff6e610cde
R13: 00007fff6e610cdf R14: 00007fce190fa700 R15: 0000000000000000
Code: 03 0f b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 04 84 d2 75 33 5b 45 89 6c 24 14 41 5c 41 5d 41 5e 41 5f 5d c3 e8 fd 8f 68 ff <0f> 0b e8 f6 8f 68 ff 0f 0b e8 ef 8f 68 ff 0f 0b e8 e8 8f 68 ff 20
RIP: sg_set_buf include/linux/scatterlist.h:140 [inline] RSP: ffff88006c7cfb08
RIP: sg_init_one+0x1b3/0x240 lib/scatterlist.c:156 RSP: ffff88006c7cfb08--- crypto/dh_helper.c | 8 ++++++++ 1 file changed, 8 insertions(+)
crypto/dh_helper.c +8 -0
@@ -90,6 +90,14 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params) params->p = (void *)(ptr + params->key_size); params->g = (void *)(ptr + params->key_size + params->p_size); +/* +* Don't permit 'p' to be 0. It's not a prime number, and it's subject +* to corner cases such as 'mod 0' being undefined or +* crypto_kpp_maxsize() returning 0. +*/ +if (memchr_inv (params->p,0 , params->p_size) =NULL ) +return -EINVAL ; +return 0 ; }EXPORT_SYMBOL_GPL (crypto_dh_decode_key);
Signature · 1 line
2.15.0
PATCH v2 3/5 crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
The "qat-dh" DH implementation assumes that 'key' and 'g' can be copied into a buffer with size 'p_size'. However it was never checked that that was actually the case, which most likely allowed users to cause a buffer underflow via KEYCTL_DH_COMPUTE.
Fix this by updating crypto_dh_decode_key() to verify this precondition for all DH implementations.
--- crypto/dh_helper.c | 8 ++++++++ 1 file changed, 8 insertions(+)
crypto/dh_helper.c +8 -0
@@ -83,6 +83,14 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)if (secret.len !=crypto_dh_key_len (params))return -EINVAL ; +/* +* Don't permit the buffer for 'key' or 'g' to be larger than 'p', since +* some drivers assume otherwise. +*/ +if (params->key_size > params->p_size || + params->g_size > params->p_size) +return -EINVAL ; +/* Don't allocate memory. Set pointers to data within * the given buffer */
Signature · 1 line
2.15.0
Re: [PATCH v2 3/5] crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
Quoted 7 lines · Eric Biggers
From: Eric Biggers <[email protected]>
The "qat-dh" DH implementation assumes that 'key' and 'g' can be copied into a buffer with size '
p_size'. However it was never checked that that was actually the case, which most likely allowed users to cause a buffer underflow viaKEYCTL_DH_COMPUTE.
Quoted 5 lines
Fix this by updating
crypto_dh_decode_key()to verify this precondition for all DH implementations.Fixes c9839143ebbf ("crypto: qat - Add DH support")Cc <[email protected]> # v4.8+
Quoted 25 lines
Signed-off-by Eric Biggers <[email protected]>--- crypto/dh_helper.c | 8 ++++++++ 1 file changed, 8 insertions(+)crypto/dh_helper.c +8
-0@@ -83,6 +83,14 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)if (secret.len !=crypto_dh_key_len (params))return -EINVAL ; +/* +* Don't permit the buffer for 'key' or 'g' to be larger than 'p', since +* some drivers assume otherwise. +*/ +if (params->key_size > params->p_size || + params->g_size > params->p_size) +return -EINVAL ; +/* Don't allocate memory. Set pointers to data within * the given buffer */
PATCH v2 4/5 crypto: qat - Clean up error handling in qat_dh_set_secret()
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
Update the error handling in qat_dh_set_secret() to mirror dh_set_secret(). The new version is less error-prone because freeing memory and setting the pointers to NULL is now only done in one place.
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/crypto/qat/qat_common/qat_asym_algs.c +8 -7
@@ -462,11 +462,8 @@ static int qat_dh_set_params(struct qat_dh_ctx *ctx, struct dh *params) } ctx->g =dma_zalloc_coherent (dev, ctx->p_size, &ctx->dma_g,GFP_KERNEL ); -if (!ctx->g) { -dma_free_coherent (dev, ctx->p_size, ctx->p, ctx->dma_p); - ctx->p =NULL ; +if (!ctx->g)return -ENOMEM ; - }memcpy (ctx->g + (ctx->p_size - params->g_size), params->g, params->g_size);
@@ -507,18 +504,22 @@ static int qat_dh_set_secret(struct crypto_kpp *tfm, const void *buf, ret =qat_dh_set_params (ctx, ¶ms);if (ret <0 ) -return ret; + goto err_clear_ctx; ctx->xa =dma_zalloc_coherent (dev, ctx->p_size, &ctx->dma_xa,GFP_KERNEL );if (!ctx->xa) { -qat_dh_clear_ctx (dev, ctx); -return -ENOMEM ; + ret = -ENOMEM ; + goto err_clear_ctx; }memcpy (ctx->xa + (ctx->p_size - params.key_size), params.key, params.key_size);return 0 ; + +err_clear_ctx: +qat_dh_clear_ctx (dev, ctx); +return ret; }static unsigned int qat_dh_max_size (struct crypto_kpp *tfm)
Signature · 1 line
2.15.0
PATCH v2 5/5 crypto: dh - Remove pointless checks for NULL 'p' and 'g'
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
Neither 'p' nor 'g' can be NULL, as they were unpacked using crypto_dh_decode_key(). And it makes no sense for them to be optional. So remove the NULL checks that were copy-and-pasted into both modules.
--- crypto/dh.c | 3 --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 3 --- 2 files changed, 6 deletions(-)
crypto/dh.c +0 -3
@@ -53,9 +53,6 @@ static int dh_check_params_length(unsigned int p_len)static int dh_set_params (struct dh_ctx *ctx,struct dh *params) { -if (unlikely (!params->p || !params->g)) -return -EINVAL ; -if (dh_check_params_length (params->p_size <<3 ))return -EINVAL ;
drivers/crypto/qat/qat_common/qat_asym_algs.c +0 -3
@@ -443,9 +443,6 @@ static int qat_dh_set_params(struct qat_dh_ctx *ctx, struct dh *params)struct qat_crypto_instance *inst = ctx->inst;struct device *dev = &GET_DEV (inst->accel_dev); -if (unlikely (!params->p || !params->g)) -return -EINVAL ; -if (qat_dh_check_params_length (params->p_size <<3 ))return -EINVAL ;
Signature · 1 line
2.15.0
Re: [PATCH v2 5/5] crypto: dh - Remove pointless checks for NULL 'p' and 'g'
Quoted 6 lines · Eric Biggers
From: Eric Biggers <[email protected]>
Neither 'p' nor 'g' can be NULL, as they were unpacked using
crypto_dh_decode_key(). And it makes no sense for them to be optional. So remove the NULL checks that were copy-and-pasted into both modules.
Quoted 35 lines
Signed-off-by Eric Biggers <[email protected]>--- crypto/dh.c | 3 --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 3 --- 2 files changed, 6 deletions(-)crypto/dh.c +0
-3@@ -53,9 +53,6 @@ static int dh_check_params_length(unsigned int p_len)static int dh_set_params (struct dh_ctx *ctx,struct dh *params) { -if (unlikely (!params->p || !params->g)) -return -EINVAL ; -if (dh_check_params_length (params->p_size <<3 ))return -EINVAL ;drivers/crypto/qat/qat_common/qat_asym_algs.c +0
-3@@ -443,9 +443,6 @@ static int qat_dh_set_params(struct qat_dh_ctx *ctx, struct dh *params)struct qat_crypto_instance *inst = ctx->inst;struct device *dev = &GET_DEV (inst->accel_dev); -if (unlikely (!params->p || !params->g)) -return -EINVAL ; -if (qat_dh_check_params_length (params->p_size <<3 ))return -EINVAL ;
Herbert Xu
maintainerQuoted 13 lines · Eric Biggers
This series fixes several corner cases in the Diffie-Hellman key exchange implementations:
1. With the software DH implementation, using a large buffer for 'g' caused a double free.
2. WithCONFIG_DEBUG_SG=yand the software DH implementation, setting 'p' to 0 caused aBUG_ON().
3. With the QAT DH implementation, setting 'key' or 'g' larger than 'p' caused a buffer underflow.Note that in kernels configured with
CONFIG_KEY_DH_OPERATIONS=y, these bugs are reachable by unprivileged users viaKEYCTL_DH_COMPUTE.
Quoted 8 lines
Patches 4 and 5 are cleanup only.
Eric Biggers (5):
crypto: dh - Fix double free ofctx->p
crypto: dh - Don't permit 'p' to be 0
crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
crypto: qat - Clean up error handling inqat_dh_set_secret()
crypto: dh - Remove pointless checks for NULL 'p' and 'g'
All applied. Thanks.
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt