---
name: "KEYCTL_DH_COMPUTE"
section: "2const"
platform: "linux"
package: "man-pages"
version: "6.19-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/KEYCTL_DH_COMPUTE"
---

# KEYCTL\_DH\_COMPUTE(2const)

compute a Diffie-Hellman shared secret or public key

## 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)](/keyctl_dh_compute/3.md) and [**keyctl\_dh\_compute\_alloc**(3)](/keyctl_dh_compute_alloc/3.md).

## 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.

## HISTORY

Linux 4.7.

## SEE ALSO

[**keyctl**(2)](/keyctl/2.md), [**keyctl\_dh\_compute**(3)](/keyctl_dh_compute/3.md), [**keyctl\_dh\_compute\_alloc**(3)](/keyctl_dh_compute_alloc/3.md), [**keyctl\_dh\_compute\_kdf**(3)](/keyctl_dh_compute_kdf/3.md)
