KEYCTL_DH_COMPUTE(2const)

✨ KEYCTL_DH_COMPUTE ✨

okay bestie, so this is a page from section 2const of the Linux manual β€” the keyctl operation ones β€” and it's genuinely one of the cuter syscall ops out there. she computes a Diffie-Hellman shared secret or public key, and she can even run a key derivation function (KDF) on the result afterwards. main character energy fr. πŸ”πŸ’–


πŸŽ€ NAME πŸŽ€

KEYCTL_DH_COMPUTE β€” compute a Diffie-Hellman shared secret or public key

πŸ“š LIBRARY πŸ“š

Standard C library (<lime>libc</lime>, -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 πŸ’…

So what she does is compute a Diffie-Hellman shared secret or public key, and if you want, she'll optionally apply a key derivation function (KDF) to the result. no cap.

The dh_params argument is a pointer to a little bundle of parameters holding serial numbers for three "user" keys used in the Diffie-Hellman calculation, packaged up in a structure that looks exactly like this:

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 those three keys has to grant the caller read permission, okurrr. Their payloads get used to calculate the Diffie-Hellman result like so:

base ^ private mod prime

If the base is the shared generator, the result is your local public key. If the base is the remote public key, the result is the shared secret. that's the whole vibe.

The buf argument points at a buffer where the result of the calculation gets dropped. Its size goes in n.

🚨 The buffer must be big enough to hold the output data, otherwise you get an error back. periodt.

If n is specified as zero, the buffer isn't used at all, and the operation returns the minimum required buffer size instead (i.e., the length of the prime). kinda iconic tbh, a little "how much room do u need bestie" call.

So like β€” Diffie-Hellman computations can genuinely be done in user space, but that requires a multiple-precision integer (MPI) library. Moving the implementation into the kernel gives you access to the kernel's MPI implementation, and also lets you reach secure or acceleration hardware. slay. ✨

Adding DH computation support to the keyctl() system call was considered a good fit because of the DH algorithm's use for deriving shared keys β€” and it also lets the key's type determine which DH implementation (software or hardware) is appropriate. iykyk.

If the kdf_params argument is NULL, then the DH result itself is returned. Otherwise (since Linux 4.12), it's a pointer to a structure that specifies the 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 specifying a hash name (available in the kernel's crypto API; the list of hashes available is rather tricky to observe β€” please go check the "Kernel Crypto API Architecture" documentation for the info on how hash names are constructed, and check your kernel's source and config for what ciphers and templates with type CRYPTO_ALG_TYPE_SHASH are available) to be applied to the DH result in the KDF operation. so real for that.

The otherinfo field is an OtherInfo data as described in SP800-56A section 5.8.1.2, and it's algorithm-specific. This data gets concatenated with the result of the DH operation and handed in as an input to the KDF operation. Its size goes in the otherinfolen field, and it's limited by the KEYCTL_KDF_MAX_OI_LEN constant 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 it should still be user-addressable since it is copied to the kernel), and it should contain zeros since Linux 4.13. don't get cute with it bestie.

The KDF implementation complies with SP800-56A as well as with SP800-108 (the counter KDF). a queen who follows the specs πŸ’œ

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, it returns 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. (sad girl hours 😭)


πŸ’€ 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 the kernel supports performing a KDF operation on the 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 the 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 the 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_dh_compute(3), keyctl_dh_compute_alloc(3), keyctl_dh_compute_kdf(3)


k that's the whole page bestie, go forth and compute ur shared secrets πŸ’–βœ¨

mwah πŸ’‹ β€” this lil rewrite brought to u by the Linux man-pages, version 6.20, dated 2026-02-08, straight out of the KEYCTL_DH_COMPUTE(2const) era. stan.

πŸ“¦ where this page comes from
  • arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • πŸ“œ the page's license: Linux-man-pages-copyleft
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms