Commit f1c316a3 authored by Stephan Mueller's avatar Stephan Mueller Committed by David Howells
Browse files

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: default avatarStephan Mueller <smueller@chronox.de>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent f0df90cd
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -827,7 +827,7 @@ The keyctl syscall functions are:

       long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
		   char *buffer, size_t buflen,
		   void *reserved);
		   struct keyctl_kdf_params *kdf);

     The params struct contains serial numbers for three keys:

@@ -844,18 +844,36 @@ The keyctl syscall functions are:
     public key.  If the base is the remote public key, the result is
     the shared secret.

     The reserved argument must be set to NULL.
     If the parameter kdf is NULL, the following applies:

     The buffer length must be at least the length of the prime, or zero.
	 - The buffer length must be at least the length of the prime, or zero.

     If the buffer length is nonzero, the length of the result is
	 - If the buffer length is nonzero, the length of the result is
	   returned when it is successfully calculated and copied in to the
	   buffer. When the buffer length is zero, the minimum required
	   buffer length is returned.

     The kdf parameter allows the caller to apply a key derivation function
     (KDF) on the Diffie-Hellman computation where only the result
     of the KDF is returned to the caller. The KDF is characterized with
     struct keyctl_kdf_params as follows:

	 - char *hashname specifies the NUL terminated string identifying
	   the hash used from the kernel crypto API and applied for the KDF
	   operation. The KDF implemenation complies with SP800-56A as well
	   as with SP800-108 (the counter KDF).

	 - char *otherinfo specifies the OtherInfo data as documented in
	   SP800-56A section 5.8.1.2. The length of the buffer is given with
	   otherinfolen. The format of OtherInfo is defined by the caller.
	   The otherinfo pointer may be NULL if no OtherInfo shall be used.

     This function will return error EOPNOTSUPP if the key type is not
     supported, error ENOKEY if the key could not be found, or error
     EACCES if the key is not readable by the caller.
     EACCES if the key is not readable by the caller. In addition, the
     function will return EMSGSIZE when the parameter kdf is non-NULL
     and either the buffer length or the OtherInfo length exceeds the
     allowed length.

 (*) Restrict keyring linkage

+7 −0
Original line number Diff line number Diff line
@@ -295,6 +295,13 @@ struct compat_old_sigaction {
};
#endif

struct compat_keyctl_kdf_params {
	compat_uptr_t hashname;
	compat_uptr_t otherinfo;
	__u32 otherinfolen;
	__u32 __spare[8];
};

struct compat_statfs;
struct compat_statfs64;
struct compat_old_linux_dirent;
+7 −0
Original line number Diff line number Diff line
@@ -69,4 +69,11 @@ struct keyctl_dh_params {
	__s32 base;
};

struct keyctl_kdf_params {
	char *hashname;
	char *otherinfo;
	__u32 otherinfolen;
	__u32 __spare[8];
};

#endif /*  _LINUX_KEYCTL_H */
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ config KEY_DH_OPERATIONS
       bool "Diffie-Hellman operations on retained keys"
       depends on KEYS
       select MPILIB
       select CRYPTO_HASH
       help
	 This option provides support for calculating Diffie-Hellman
	 public keys and shared secrets using values stored as keys
+2 −1
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@ obj-y := \
	request_key.o \
	request_key_auth.o \
	user_defined.o
obj-$(CONFIG_KEYS_COMPAT) += compat.o
compat-obj-$(CONFIG_KEY_DH_OPERATIONS) += compat_dh.o
obj-$(CONFIG_KEYS_COMPAT) += compat.o $(compat-obj-y)
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSCTL) += sysctl.o
obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o
Loading