Cryptographic Interface¶
libedhoc computes no cryptography itself: every primitive is reached through a single user-supplied callback interface, the operations interface:
Ephemeral key exchange — a KEM:
generate_key_pair/encapsulate/decapsulate.Static Diffie-Hellman —
key_agreement(NIKE suites, methods 1/2/3).AEAD —
aead_encrypt/aead_decrypt.Hash — multipart
hash_init/hash_update/hash_finish.Key derivation — HKDF
extract/expand(handle and raw forms).Signature —
sign/verify.
Keys never cross the boundary as raw bytes: they live in the backend key store and are passed by opaque handle only, and each derived handle carries the key-usage policy it will serve.
Ready-made, production-ready bindings for every supported suite live under
library/cipher_suites/; see Cipher Suites.
include/edhoc/crypto.hKey usage¶
- group EDHOC interface for cryptographic key usage
Enums
-
enum edhoc_key_usage¶
Policy of a key handle produced by edhoc_crypto::expand.
Values:
-
enumerator EDHOC_KEY_USAGE_KDF¶
Key used as input to key derivation (EDHOC_Extract / EDHOC_Expand).
-
enumerator EDHOC_KEY_USAGE_AEAD¶
Key used for AEAD encryption and decryption.
-
enumerator EDHOC_KEY_USAGE_KDF¶
-
enum edhoc_key_usage¶
Operations¶
- group EDHOC interface for cryptographic operations
-
struct edhoc_crypto¶
- #include <crypto.h>
Cryptographic operations vtable (handle-based).
- Every entry is mandatory; \ref edhoc_bind_crypto rejects a vtable with a missing one. A suite that cannot perform an operation still supplies the entry and fails it with #EDHOC_ERROR_NOT_SUPPORTED. - Every long-lived secret is an opaque handle into the backend key store (a software PSA slot, the TrustZone secure world or a secure element); it is never serialized into \ref edhoc_context or onto the stack. - Peer public keys enter as raw bytes; one-shot public outputs (keystreams, IVs, MACs) leave as raw bytes. - The ephemeral key exchange is modelled as a KEM; a classical Diffie-Hellman suite implements it as a thin NIKE-as-KEM shim (\c G_X carries the encapsulation key, \c G_Y the ciphertext), so ML-KEM drops in behind the same interface with the wire unchanged.
Public Members
-
int (*destroy_key)(void *user_context, void *key_id)¶
Destroy a key handle and free its key-store slot.
Destroying a zeroed / no-key handle is a successful no-op, so \ref edhoc_context_deinit may re-destroy already-freed slots.
- Param user_context:
[in] User context.
- Param key_id:
[inout] Key identifier to destroy.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*generate_key_pair)(void *user_context, void *decapsulation_key_id, uint8_t *encapsulation_key, size_t encapsulation_key_size, size_t *encapsulation_key_length)¶
Generate an ephemeral key pair (Initiator, message_1).
The decapsulation (private) key stays in the key store as a handle; only the encapsulation (public) key leaves, to be sent in \c G_X. The handle is retained for \ref decapsulate and, on a NIKE suite, for the static-DH \c G_RX agreement in message_2 (methods 1 and 3).
- Param user_context:
[in] User context.
- Param decapsulation_key_id:
[out] Handle of the generated private key.
- Param encapsulation_key:
[out] Public key, sent in
G_X.- Param encapsulation_key_size:
Size of the
encapsulation_keybuffer in bytes.- Param encapsulation_key_length:
[out] On success, the number of bytes that make up the encapsulation key.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*encapsulate)(void *user_context, const uint8_t *encapsulation_key, size_t encapsulation_key_length, void *decapsulation_key_id, void *shared_secret_key_id, uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)¶
Encapsulate to a peer’s ephemeral public key (Responder, message_2).
KEM suite: encapsulate against
encapsulation_key(G_X), yielding the shared-secret handle and theciphertext(G_Y).NIKE (classical Diffie-Hellman) suite: the backend generates its own ephemeral key pair, runs the key agreement against
encapsulation_key, and returns its own ephemeral public key as theciphertext(G_Y).
decapsulation_key_idreturns the Responder’s ephemeral private key so it can be reused for the static-DHG_IYagreement in message_3 (methods 2 and 3); a KEM without static-DH support leaves it a null handle.- Param user_context:
[in] User context.
- Param encapsulation_key:
[in] Peer public key from
G_X.- Param encapsulation_key_length:
Size of the
encapsulation_keybuffer in bytes.- Param decapsulation_key_id:
[out] Handle of the retained ephemeral private key. A KEM without static-DH support leaves it a null handle.
- Param shared_secret_key_id:
[out] Handle of the shared secret (
G_XY).- Param ciphertext:
[out] KEM ciphertext, sent in
G_Y.- Param ciphertext_size:
Size of the
ciphertextbuffer in bytes.- Param ciphertext_length:
[out] On success, the number of bytes that make up the ciphertext.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*decapsulate)(void *user_context, const void *decapsulation_key_id, const uint8_t *ciphertext, size_t ciphertext_length, void *shared_secret_key_id)¶
Decapsulate a ciphertext (Initiator, after message_2).
- Param user_context:
[in] User context.
- Param decapsulation_key_id:
[in] Handle of the private key from generate_key_pair.
- Param ciphertext:
[in] KEM ciphertext from
G_Y.- Param ciphertext_length:
Size of the
ciphertextbuffer in bytes.- Param shared_secret_key_id:
[out] Handle of the shared secret (
G_XY).- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*key_agreement)(void *user_context, const void *private_key_id, const uint8_t *peer_public_key, size_t peer_public_key_length, void *shared_secret_key_id)¶
Compute a static Diffie-Hellman shared secret (methods 1/2/3).
Used only for static-DH authentication: \c G_RX in message_2 and \c G_IY in message_3. Each agreement pairs one party's static authentication key with the other's ephemeral key, so which of the two arguments is the static one depends on the local role. A suite without static-DH support fails with #EDHOC_ERROR_NOT_SUPPORTED.
- Param user_context:
[in] User context.
- Param private_key_id:
[in] Handle of the local private key, static or ephemeral.
- Param peer_public_key:
[in] Peer public key (raw bytes), ephemeral or static.
- Param peer_public_key_length:
Size of the
peer_public_keybuffer in bytes.- Param shared_secret_key_id:
[out] Handle of the shared secret.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*sign)(void *user_context, const void *private_key_id, const uint8_t *input, size_t input_length, uint8_t *signature, size_t signature_size, size_t *signature_length)¶
Generate a digital signature.
- Param user_context:
[in] User context.
- Param private_key_id:
[in] Handle of the signing key.
- Param input:
[in] Full message to sign (not a digest).
- Param input_length:
Size of the
inputbuffer in bytes.- Param signature:
[out] Buffer where the signature is to be written.
- Param signature_size:
Size of the
signaturebuffer in bytes.- Param signature_length:
[out] On success, the number of bytes that make up the signature.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*verify)(void *user_context, const uint8_t *public_key, size_t public_key_length, const uint8_t *input, size_t input_length, const uint8_t *signature, size_t signature_length)¶
Verify a digital signature against a raw peer public key.
- Param user_context:
[in] User context.
- Param public_key:
[in] Peer public key (raw bytes).
- Param public_key_length:
Size of the
public_keybuffer in bytes.- Param input:
[in] Full signed message (not a digest).
- Param input_length:
Size of the
inputbuffer in bytes.- Param signature:
[in] Buffer containing the signature to verify.
- Param signature_length:
Size of the
signaturebuffer in bytes.- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*extract)(void *user_context, const void *ikm_key_id, const uint8_t *salt, size_t salt_length, void *prk_key_id)¶
EDHOC_Extract: derive a pseudorandom key handle from a salt.
- Param user_context:
[in] User context.
- Param ikm_key_id:
[in] Input keying material handle.
- Param salt:
[in] Raw salt.
- Param salt_length:
Size of the
saltbuffer in bytes.- Param prk_key_id:
[out] Output pseudorandom key handle.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*expand)(void *user_context, const void *prk_key_id, const uint8_t *info, size_t info_length, enum edhoc_key_usage usage, void *output_key_id)¶
EDHOC_Expand producing a key handle (handle space).
The \p usage selects the policy of the created key, since a PSA / secure-element key must receive its policy at creation.
- Param user_context:
[in] User context.
- Param prk_key_id:
[in] Pseudorandom key handle.
- Param info:
[in] CBOR-encoded info.
- Param info_length:
Size of the
infobuffer in bytes.- Param usage:
Policy of the produced key.
- Param output_key_id:
[out] Output key handle.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*expand_raw)(void *user_context, const void *prk_key_id, const uint8_t *info, size_t info_length, uint8_t *output, size_t output_length)¶
EDHOC_Expand producing raw output (keystream, IV, MAC, exporter).
- Param user_context:
[in] User context.
- Param prk_key_id:
[in] Pseudorandom key handle.
- Param info:
[in] CBOR-encoded info.
- Param info_length:
Size of the
infobuffer in bytes.- Param output:
[out] Raw output keying material.
- Param output_length:
Requested output length in bytes.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*aead_encrypt)(void *user_context, const void *key_id, const uint8_t *nonce, size_t nonce_length, const uint8_t *additional_data, size_t additional_data_length, const uint8_t *plaintext, size_t plaintext_length, uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)¶
Encrypt with an AEAD.
- Param user_context:
[in] User context.
- Param key_id:
[in] AEAD key handle.
- Param nonce:
[in] Nonce or IV to use.
- Param nonce_length:
Size of the
noncebuffer in bytes.- Param additional_data:
[in] Additional data that will be authenticated but not encrypted.
- Param additional_data_length:
Size of the
additional_databuffer in bytes.- Param plaintext:
[in] Data that will be authenticated and encrypted.
- Param plaintext_length:
Size of the
plaintextbuffer in bytes.- Param ciphertext:
[out] Buffer where the authenticated and encrypted data is to be written.
- Param ciphertext_size:
Size of the
ciphertextbuffer in bytes.- Param ciphertext_length:
[out] On success, the number of bytes that make up the ciphertext.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*aead_decrypt)(void *user_context, const void *key_id, const uint8_t *nonce, size_t nonce_length, const uint8_t *additional_data, size_t additional_data_length, const uint8_t *ciphertext, size_t ciphertext_length, uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)¶
Decrypt with an AEAD.
- Param user_context:
[in] User context.
- Param key_id:
[in] AEAD key handle.
- Param nonce:
[in] Nonce or IV to use.
- Param nonce_length:
Size of the
noncebuffer in bytes.- Param additional_data:
[in] Additional data that will be authenticated but not encrypted.
- Param additional_data_length:
Size of the
additional_databuffer in bytes.- Param ciphertext:
[in] Buffer containing the authenticated and encrypted data.
- Param ciphertext_length:
Size of the
ciphertextbuffer in bytes.- Param plaintext:
[out] Buffer where the decrypted data is to be written.
- Param plaintext_size:
Size of the
plaintextbuffer in bytes.- Param plaintext_length:
[out] On success, the number of bytes that make up the plaintext.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*hash_init)(void *user_context, void **operation)¶
Begin a multipart hash operation.
The operation object is owned by the backend and released by \ref hash_finish or \ref hash_abort.
- Param user_context:
[in] User context.
- Param operation:
[out] On success, backend hash operation.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*hash_update)(void *user_context, void *operation, const uint8_t *input, size_t input_length)¶
Add input to a multipart hash operation.
- Param user_context:
[in] User context.
- Param operation:
[in] Backend hash operation.
- Param input:
[in] Input message chunk to hash.
- Param input_length:
Size of the
inputbuffer in bytes.- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*hash_finish)(void *user_context, void *operation, uint8_t *hash, size_t hash_size, size_t *hash_length)¶
Finish a multipart hash operation and release it.
- Param user_context:
[in] User context.
- Param operation:
[in] Backend hash operation.
- Param hash:
[out] Buffer where the hash is to be written.
- Param hash_size:
Size of the
hashbuffer in bytes.- Param hash_length:
[out] On success, the number of bytes that make up the hash.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*hash_abort)(void *user_context, void *operation)¶
Abort a multipart hash operation and release it.
- Param user_context:
[in] User context.
- Param operation:
[in] Backend hash operation.
- Retval EDHOC_SUCCESS:
Success.
- Return:
Negative error code on failure (EDHOC error codes).
-
int (*destroy_key)(void *user_context, void *key_id)¶
-
struct edhoc_crypto¶