summaryrefslogtreecommitdiff
path: root/crypto/dh_helper.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-09-15 20:50:42 +0200
committerThomas Gleixner <tglx@linutronix.de>2018-09-15 20:50:42 +0200
commitf4f1815d81195033eabb55651db2756b27cbaf0d (patch)
treee7667ecbd53d3985d294ea7ee64e33f9523cedff /crypto/dh_helper.c
parentea2d7a962774232c5ec13f85a399e7f2a7b6746e (diff)
parenta41bb691f04fcf6d3fa1f6e743d1520e305bc71d (diff)
downloadlinux-crypto-f4f1815d81195033eabb55651db2756b27cbaf0d.tar.gz
linux-crypto-f4f1815d81195033eabb55651db2756b27cbaf0d.zip
Merge tag 'y2038' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground into timers/core
Pull more y2038 work from Arnd Bergman: y2038: convert more syscalls Here is another set of system call changes to prepare the change over to 64-bit time_t. As before, the strategy is to change system calls that take a 'struct timespec' argument over to 'struct __kernel_timespec', which for now is defined to be the same but will get redefined to use a 64-bit time_t argument once we are ready to modify the system call tables. The major change from previous patches is that the plan is no longer to directly use the 'compat' system calls for providing compatibility with the existing 32-bit time_t based entry points. Instead, we rename the compat code to something that makes more sense on 32-bit architectures, e.g. compat_timespec becomes old_timespec32. With the renamed types in place, change over the 'stat' and 'utimes' families of system calls, sched_rr_get_interval, recvmmsg and rt_sigtimedwait. Another series for poll, select and io_pgetevents is currently being tested.
Diffstat (limited to 'crypto/dh_helper.c')
-rw-r--r--crypto/dh_helper.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/crypto/dh_helper.c b/crypto/dh_helper.c
index 24fdb2ec..edacda5f 100644
--- a/crypto/dh_helper.c
+++ b/crypto/dh_helper.c
@@ -14,10 +14,12 @@
#include <crypto/dh.h>
#include <crypto/kpp.h>
-#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 3 * sizeof(int))
+#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 4 * sizeof(int))
-static inline u8 *dh_pack_data(void *dst, const void *src, size_t size)
+static inline u8 *dh_pack_data(u8 *dst, u8 *end, const void *src, size_t size)
{
+ if (!dst || size > end - dst)
+ return NULL;
memcpy(dst, src, size);
return dst + size;
}
@@ -30,7 +32,7 @@ static inline const u8 *dh_unpack_data(void *dst, const void *src, size_t size)
static inline unsigned int dh_data_size(const struct dh *p)
{
- return p->key_size + p->p_size + p->g_size;
+ return p->key_size + p->p_size + p->q_size + p->g_size;
}
unsigned int crypto_dh_key_len(const struct dh *p)
@@ -42,25 +44,27 @@ EXPORT_SYMBOL_GPL(crypto_dh_key_len);
int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params)
{
u8 *ptr = buf;
+ u8 * const end = ptr + len;
struct kpp_secret secret = {
.type = CRYPTO_KPP_SECRET_TYPE_DH,
.len = len
};
- if (unlikely(!buf))
+ if (unlikely(!len))
return -EINVAL;
- if (len != crypto_dh_key_len(params))
+ ptr = dh_pack_data(ptr, end, &secret, sizeof(secret));
+ ptr = dh_pack_data(ptr, end, &params->key_size,
+ sizeof(params->key_size));
+ ptr = dh_pack_data(ptr, end, &params->p_size, sizeof(params->p_size));
+ ptr = dh_pack_data(ptr, end, &params->q_size, sizeof(params->q_size));
+ ptr = dh_pack_data(ptr, end, &params->g_size, sizeof(params->g_size));
+ ptr = dh_pack_data(ptr, end, params->key, params->key_size);
+ ptr = dh_pack_data(ptr, end, params->p, params->p_size);
+ ptr = dh_pack_data(ptr, end, params->q, params->q_size);
+ ptr = dh_pack_data(ptr, end, params->g, params->g_size);
+ if (ptr != end)
return -EINVAL;
-
- ptr = dh_pack_data(ptr, &secret, sizeof(secret));
- ptr = dh_pack_data(ptr, &params->key_size, sizeof(params->key_size));
- ptr = dh_pack_data(ptr, &params->p_size, sizeof(params->p_size));
- ptr = dh_pack_data(ptr, &params->g_size, sizeof(params->g_size));
- ptr = dh_pack_data(ptr, params->key, params->key_size);
- ptr = dh_pack_data(ptr, params->p, params->p_size);
- dh_pack_data(ptr, params->g, params->g_size);
-
return 0;
}
EXPORT_SYMBOL_GPL(crypto_dh_encode_key);
@@ -79,6 +83,7 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
ptr = dh_unpack_data(&params->key_size, ptr, sizeof(params->key_size));
ptr = dh_unpack_data(&params->p_size, ptr, sizeof(params->p_size));
+ ptr = dh_unpack_data(&params->q_size, ptr, sizeof(params->q_size));
ptr = dh_unpack_data(&params->g_size, ptr, sizeof(params->g_size));
if (secret.len != crypto_dh_key_len(params))
return -EINVAL;
@@ -88,7 +93,7 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
* some drivers assume otherwise.
*/
if (params->key_size > params->p_size ||
- params->g_size > params->p_size)
+ params->g_size > params->p_size || params->q_size > params->p_size)
return -EINVAL;
/* Don't allocate memory. Set pointers to data within
@@ -96,7 +101,9 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
*/
params->key = (void *)ptr;
params->p = (void *)(ptr + params->key_size);
- params->g = (void *)(ptr + params->key_size + params->p_size);
+ params->q = (void *)(ptr + params->key_size + params->p_size);
+ params->g = (void *)(ptr + params->key_size + params->p_size +
+ params->q_size);
/*
* Don't permit 'p' to be 0. It's not a prime number, and it's subject
@@ -106,6 +113,10 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
if (memchr_inv(params->p, 0, params->p_size) == NULL)
return -EINVAL;
+ /* It is permissible to not provide Q. */
+ if (params->q_size == 0)
+ params->q = NULL;
+
return 0;
}
EXPORT_SYMBOL_GPL(crypto_dh_decode_key);