diff options
author | Stephan Mueller <smueller@chronox.de> | 2016-08-19 20:39:09 +0200 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2017-04-04 22:33:38 +0100 |
commit | f1c316a3ab9d24df6022682422fe897492f2c0c8 (patch) | |
tree | 369b53c45d1f0c2bbd4c6f745cb9a694e1b28cbe /security/keys/internal.h | |
parent | f0df90cd7cf2f4a8195c3fff0d2f4c85088fd39c (diff) | |
download | linux-f1c316a3ab9d24df6022682422fe897492f2c0c8.tar.gz linux-f1c316a3ab9d24df6022682422fe897492f2c0c8.tar.bz2 linux-f1c316a3ab9d24df6022682422fe897492f2c0c8.zip |
KEYS: add SP800-56A KDF support for DH
SP800-56A defines the use of DH with key derivation function based on a
counter. The input to the KDF is defined as (DH shared secret || other
information). The value for the "other information" is to be provided by
the caller.
The KDF is implemented using the hash support from the kernel crypto API.
The implementation uses the symmetric hash support as the input to the
hash operation is usually very small. The caller is allowed to specify
the hash name that he wants to use to derive the key material allowing
the use of all supported hashes provided with the kernel crypto API.
As the KDF implements the proper truncation of the DH shared secret to
the requested size, this patch fills the caller buffer up to its size.
The patch is tested with a new test added to the keyutils user space
code which uses a CAVS test vector testing the compliance with
SP800-56A.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'security/keys/internal.h')
-rw-r--r-- | security/keys/internal.h | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index 6ce016314897..c0f8682eba69 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -18,6 +18,7 @@ #include <linux/task_work.h> #include <linux/keyctl.h> #include <linux/refcount.h> +#include <linux/compat.h> struct iovec; @@ -267,15 +268,34 @@ static inline long keyctl_get_persistent(uid_t uid, key_serial_t destring) #ifdef CONFIG_KEY_DH_OPERATIONS extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *, - size_t, void __user *); + size_t, struct keyctl_kdf_params __user *); +extern long __keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *, + size_t, struct keyctl_kdf_params *); +#ifdef CONFIG_KEYS_COMPAT +extern long compat_keyctl_dh_compute(struct keyctl_dh_params __user *params, + char __user *buffer, size_t buflen, + struct compat_keyctl_kdf_params __user *kdf); +#endif +#define KEYCTL_KDF_MAX_OUTPUT_LEN 1024 /* max length of KDF output */ +#define KEYCTL_KDF_MAX_OI_LEN 64 /* max length of otherinfo */ #else static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params, char __user *buffer, size_t buflen, - void __user *reserved) + struct keyctl_kdf_params __user *kdf) +{ + return -EOPNOTSUPP; +} + +#ifdef CONFIG_KEYS_COMPAT +static inline long compat_keyctl_dh_compute( + struct keyctl_dh_params __user *params, + char __user *buffer, size_t buflen, + struct keyctl_kdf_params __user *kdf) { return -EOPNOTSUPP; } #endif +#endif /* * Debugging key validation |