# KEYCTL_DH_COMPUTE

## NAME



           KEYCTL_DH_COMPUTE - compute a Diffie-Hellman shared secret or
           public key
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#include <linux/keyctl.h>  **/* Definition of **KEY*** constants */
           **#include <sys/syscall.h>   **/* Definition of **SYS_*** constants */
           **#include <unistd.h>**
    
           **long syscall(** size_t n;
                        **SYS_keyctl, KEYCTL_DH_COMPUTE,**
                        **struct keyctl_dh_params ***_dh_params_**,**
                        **char** _buf_**[**_n_**], size_t** _n_**,**
                        **struct keyctl_kdf_params *_Nullable** _kdf_params_**);**
    


## DESCRIPTION



           Compute a Diffie-Hellman shared secret or public key, optionally
           applying key derivation function (KDF) to the result.
    
           The _dh_params_ argument is a pointer to a set of parameters
           containing serial numbers for three _"user"_ keys used in the
           Diffie-Hellman calculation, packaged in a structure of the
           following form:
    
               struct keyctl_dh_params {
                   int32_t private; /* The local private key */
                   int32_t prime; /* The prime, known to both parties */
                   int32_t base;  /* The base integer: either a shared
                                     generator or the remote public key */
               };
    
           Each of the three keys specified in this structure must grant the
           caller _read_ permission.  The payloads of these keys are used to
           calculate the Diffie-Hellman result as:
    
               base ^ private mod prime
    
           If the base is the shared generator, the result is the local
           public key.  If the base is the remote public key, the result is
           the shared secret.
    
           The _buf_ argument points to a buffer where the result of the
           calculation is placed.  The size of that buffer is specified in _n_.
    
           The buffer must be large enough to accommodate the output data,
           otherwise an error is returned.  If _n_ is specified zero, in which
           case the buffer is not used and the operation returns the minimum
           required buffer size (i.e., the length of the prime).
    
           Diffie-Hellman computations can be performed in user space, but
           require a multiple-precision integer (MPI) library.  Moving the
           implementation into the kernel gives access to the kernel MPI
           implementation, and allows access to secure or acceleration
           hardware.
    
           Adding support for DH computation to the **keyctl**() system call was
           considered a good fit due to the DH algorithm's use for deriving
           shared keys; it also allows the type of the key to determine which
           DH implementation (software or hardware) is appropriate.
    
           If the _kdf_params_ argument is **NULL** , then the DH result itself is
           returned.  Otherwise (since Linux 4.12), it is a pointer to a
           structure which specifies parameters of the KDF operation to be
           applied:
    
               struct keyctl_kdf_params {
                   char *hashname;     /* Hash algorithm name */
                   char *otherinfo;    /* SP800-56A OtherInfo */
                   __u32 otherinfolen; /* Length of otherinfo data */
                   __u32 __spare[8];   /* Reserved */
               };
    
           The _hashname_ field is a null-terminated string which specifies a
           hash name (available in the kernel's crypto API; the list of the
           hashes available is rather tricky to observe; please refer to the
           "Kernel Crypto API Architecture" 
           ⟨https://www.kernel.org/doc/html/latest/crypto/architecture.html⟩
           documentation for the information regarding how hash names are
           constructed and your kernel's source and configuration regarding
           what ciphers and templates with type **CRYPTO_ALG_TYPE_SHASH** are
           available) to be applied to DH result in KDF operation.
    
           The _otherinfo_ field is an _OtherInfo_ data as described in SP800-56A
           section 5.8.1.2 and is algorithm-specific.  This data is
           concatenated with the result of DH operation and is provided as an
           input to the KDF operation.  Its size is provided in the
           _otherinfolen_ field and is limited by **KEYCTL_KDF_MAX_OI_LEN**
           constant that defined in _security/keys/internal.h_ to a value of
           64.
    
           The **__spare** field is currently unused.  It was ignored until Linux
           4.13 (but still should be user-addressable since it is copied to
           the kernel), and should contain zeros since Linux 4.13.
    
           The KDF implementation complies with SP800-56A as well as with
           SP800-108 (the counter KDF).
    
           This operation is exposed by _libkeyutils_ (from _libkeyutils_ 1.5.10
           onwards) via the functions keyctl_dh_compute(3) and
           **keyctl_dh_compute_alloc**(3).
    


## RETURN VALUE



           On success, the number of bytes copied to the buffer, or, if _n_ is
           0, the required buffer size.
    
           On error, -1 is returned, and _errno_ is set to indicate the error.
    


## ERRORS



           **EAGAIN** There was an error during crypto module initialization.
    
           **EFAULT** One of the following has failed:
    
                  •  copying of the _struct keyctl_dh_params_ , provided in the
                     _dh_params_ argument, from user space;
    
                  •  copying of the _struct keyctl_kdf_params_ , provided in the
                     non-NULL _kdf_params_ argument, from user space (in case
                     kernel supports performing KDF operation on DH operation
                     result);
    
                  •  copying of data pointed by the _hashname_ field of the
                     _struct keyctl_kdf_params_ from user space;
    
                  •  copying of data pointed by the _otherinfo_ field of the
                     _struct keyctl_kdf_params_ from user space if the
                     _otherinfolen_ field was nonzero;
    
                  •  copying of the result to user space.
    
           **EINVAL**(before Linux 4.12)
                  Argument _kdf_params_ was non-NULL.
    
           **EINVAL** The digest size of the hashing algorithm supplied is zero.
    
           **EINVAL** The buffer size provided is not enough to hold the result.
                  Provide 0 as a buffer size in order to obtain the minimum
                  buffer size.
    
           **EINVAL** The hash name provided in the _hashname_ field of the _struct_
                  _keyctl_kdf_params_ pointed by _kdf_params_ argument is too big
                  (the limit is implementation-specific and varies between
                  kernel versions, but it is deemed big enough for all valid
                  algorithm names).
    
           **EINVAL** The ___spare_ field of the _struct keyctl_kdf_params_ provided
                  in the _kdf_params_ argument contains nonzero values.
    
           **EMSGSIZE**
                  The buffer length exceeds **KEYCTL_KDF_MAX_OUTPUT_LEN**(which
                  is 1024 currently) or the _otherinfolen_ field of the _struct_
                  _keyctl_kdf_parms_ passed in _kdf_params_ exceeds
                  **KEYCTL_KDF_MAX_OI_LEN**(which is 64 currently).
    
           **ENOENT** The hashing algorithm specified in the _hashname_ field of
                  the _struct keyctl_kdf_params_ pointed by _kdf_params_ argument
                  hasn't been found.
    
           **ETIMEDOUT**
                  The initialization of crypto modules has timed out.
    


## STANDARDS



           Linux.
    


* * *