---
name: "keyctl_dh_compute"
section: "3"
platform: "linux"
package: "keyutils"
version: "1.6.3-4"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/keyctl_dh_compute"
---

# keyctl\_dh\_compute(3)

Compute a Diffie-Hellman shared secret or public key keyctl\_dh\_compute\_kdf - Derive key from a Diffie-Hellman shared secret

## NAME

keyctl\_dh\_compute - Compute a Diffie-Hellman shared secret or public key\
 keyctl\_dh\_compute\_kdf - Derive key from a Diffie-Hellman shared secret

## SYNOPSIS

```
#include <keyutils.h>

long keyctl_dh_compute(key_serial_t private, key_serial_t prime,
key_serial_t base, char *buffer, size_t buflen);

long keyctl_dh_compute_alloc(key_serial_t private,
key_serial_t prime, key_serial_t base, void **_buffer);

long keyctl_dh_compute_kdf(key_serial_t private, key_serial_t prime,
key_serial_t base, char *hashname, char *otherinfo,
size_t otherinfolen, char *buffer, size_t buflen);
```

## DESCRIPTION

**keyctl\_dh\_compute**() computes a Diffie-Hellman public key or shared secret.  That computation is:

-

  *base* ^ *private* ( mod *prime* )

When *base* is a key containing the shared generator value, the remote public key is computed.  When *base* is a key containing the remote public key, the shared secret is computed.

*base*, *private*, and *prime* must all refer to **user**-type keys containing the parameters for the computation.  Each of these keys must grant the caller **read** permission in order for them to be used.

*buffer* and *buflen* specify the buffer into which the computed result will be placed. *buflen* may be zero, in which case the buffer is not used and the minimum buffer length is fetched.

**keyctl\_dh\_compute\_alloc**() is similar to **keyctl\_dh\_compute**() except that it allocates a buffer big enough to hold the payload data and places the data in it.  If successful, a pointer to the buffer is placed in *\*\_buffer*. The caller must free the buffer.

**keyctl\_dh\_compute\_kdf**() derives a key from a Diffie-Hellman shared secret according to the protocol specified in SP800-56A. The Diffie-Hellman computation is based on the same primitives as discussed for **keyctl\_dh\_compute**().

To implement the protocol of SP800-56A *base* is a key containing the remote public key to compute the Diffie-Hellman shared secret. That shared secret is post-processed with a key derivation function.

The *hashname* specifies the Linux kernel crypto API name for a hash that shall be used for the key derivation function, such as sha256. The *hashname* must be a NULL terminated string.  See */proc/crypto* for available hashes on the system.

Following the specification of SP800-56A section 5.8.1.2 the *otherinfo* parameter may be provided. The format of the OtherInfo field is defined by the caller. The caller may also specify NULL as a valid argument when no OtherInfo data shall be processed. The length of the *otherinfo* parameter is specified with *otherinfolen* and is restricted to a maximum length by the kernel.

The KDF returns the requested number of bytes specified with the *genlen* or the *buflen* parameter depending on the invoked function.

*buffer* and *buflen* specify the buffer into which the computed result will be placed.

## RETURN VALUE

On success **keyctl\_dh\_compute**() returns the amount of data placed into the buffer when *buflen* is non-zero.  When *buflen* is zero, the minimum buffer length to hold the data is returned.

On success **keyctl\_dh\_compute\_alloc**() returns the amount of data in the buffer.

On error, both functions set errno to an appropriate code and return the value **-1**.

## ERRORS

- **ENOKEY**

  One of the keys specified is invalid or not readable.

- **EINVAL**

  The buffer pointer is invalid or buflen is too small.

- **EOPNOTSUPP**

  One of the keys was not a valid user key.

- **EMSGSIZE**

  When using **keyctl\_dh\_compute\_kdf**(), the size of either *otherinfolen* or *buflen* is too big.

## LINKING

This is a library function that can be found in *libkeyutils*. When linking, **-lkeyutils** should be specified to the linker.

## SEE ALSO

[**keyctl**(1)](/keyctl/1.md),\
 [**keyctl**(2)](/keyctl/2.md),\
 [**keyctl**(3)](/keyctl/3.md),\
 [**keyutils**(7)](/keyutils/7.md)
