Changelog¶
Version 2.0.2¶
- Date:
August 7, 2026
@kamil-kielbasa : message 1 no longer turns a label-only EAD_1 item into one carrying an empty byte string. The presence of the optional value is now derived from the value pointer, as messages 2 to 4 already did.
Version 2.0.1¶
- Date:
August 5, 2026
@kamil-kielbasa : CI: publishing a release no longer leaves the version badge stale. It starts two runs of the documentation job —
releaseand a tagpush— sharing onegithub.ref, and the concurrency key ignored the event name, so the tag run cancelled the release run, the only one that deploys. The key now includes it. No library code changed.
Version 2.0.0¶
- Date:
August 4, 2026
Breaking release. Every application interface changed: the crypto and key
interfaces were merged and rebuilt around key handles, credentials and
connection identifiers were remodelled, the context became opaque and all
headers moved. Code written against 1.x needs porting throughout; the
highlights explain why, the breaking changes list what to change.
Highlights¶
Secrets are key handles, not bytes.
struct edhoc_keysis gone: the library no longer hands raw key material to the application to import. Every long-lived secret is produced directly as an opaque handle into the backend key store, so it can stay in a PSA slot, the secure world or a secure element for the whole handshake. The exporters gained handle-returning forms, so even the OSCORE Master Secret can be taken out without the application ever seeing the bytes.The ephemeral key exchange is a KEM.
encapsulate/decapsulatemodel the exchange and a classical Diffie-Hellman suite implements them as a thin NIKE-as-KEM shim. Nothing changes on the wire and a post-quantum KEM drops in behind the same interface.Cipher suites are part of the library, including post-quantum suite 1 (ML-KEM-512 / ML-DSA-44 / AES-CCM-16-128-128 / SHAKE256), which no longer needs its own vtable or an experimental build flag.
<edhoc/cipher_suite.h>holds the parameters, the identifiers and the getters; each suite has a Kconfig gate and a disabled one is not compiled in.Authentication credentials are enforced, not merely documented. Selecting the local credential and authenticating the peer’s use separate types, CRED lives in the variant that owns it, a missing label is rejected, and what the credentials and EAD callbacks return is validated before it reaches the encoder.
Compact byte strings are handled once, by the library. A connection identifier and a COSE
kidare byte strings everywhere in the API, in both directions. The compact CBOR integer encoding of RFC 9528: 3.3.2 is applied and undone inside the library, so an application no longer has to know that a short identifier travels as a bare integer, nor translate it back before matching its own records. In1.xthat encoding leaked into the API and was implemented inconsistently across the call sites that touched it, which produced identifiers that no other implementation could read.The context is opaque. Its layout, the state machine and the key schedule are no longer part of the API, and internally it is grouped by concern — negotiation, state, key slots, interfaces — instead of one flat structure.
Hashing is multi-part.
hash_init/hash_update/hash_finishfeed a transcript hash in chunks instead of assembling it into one buffer, which removes the largest working allocation of the handshake.Headers relocated, documentation unified. Every public header lives under
include/edhoc/with one include convention and one documentation style;<edhoc/edhoc.h>is an umbrella over all of them.Tests rebuilt around matrices. Linux and Zephyr have separate trees and the Linux one is split by purpose — integration, robustness, RFC 9529, unit, fuzz — with shared drivers, so a scenario scales across every cipher suite, method, memory backend and a range of build configurations.
Toolchain refresh: mbedTLS 4.1 with TF-PSA-Crypto, and Zephyr 4.4.
Breaking changes¶
Key interface removed.
edhoc_bind_keys(),struct edhoc_keys,enum edhoc_key_typeand theEDHOC_KT_*values are gone. Key creation and destruction moved intostruct edhoc_crypto, which now produces handles itself; there is nothing left for the application to import.Crypto vtable rebuilt.
make_key_pairbecamegenerate_key_pair,signaturebecamesign,encrypt/decryptbecameaead_encrypt/aead_decrypt, and the one-shothashbecamehash_init/hash_update/hash_finish/hash_abort. New entries:encapsulate,decapsulate,expand_rawanddestroy_key. Every entry is mandatory; a suite that cannot perform an operation supplies it and fails withEDHOC_ERROR_NOT_SUPPORTED.Context opaque.
struct edhoc_contexthas no public layout andEDHOC_PRIVATE()is removed; allocateedhoc_context_size()bytes, then calledhoc_context_init().enum edhoc_state_machine,enum edhoc_prk_state,enum edhoc_th_stateand their values are no longer public.Platform binding (new, mandatory). Bind a
struct edhoc_platformwith a non-elidablezeroizethroughedhoc_bind_platform(); message processing refuses to run until it is bound.Credentials.
fetch/verifybecomeselect_local/authenticate_peer. What the application receives and what it returns are now separate types instead of onestruct edhoc_auth_credsserving as both, and a zeroed structure is rejected rather than read as a valid choice. Buffers handed toauthenticate_peerare views into the message being processed and stop being valid once the call returns.EDHOC_COSE_ANY, the only way to pass a pre-encoded ID_CRED, is removed with no replacement; the supported labels arekid,x5chainandx5t.Connection identifiers are byte strings.
struct edhoc_connection_idandenum edhoc_connection_id_type(EDHOC_CID_TYPE_*) are removed;edhoc_set_connection_id()and the CoAP helpers takeconst struct edhoc_buffer *. Pass the identifier itself, as the bytes it is made of; the CBOR encoding of RFC 9528: 3.3.2 is no longer the application’s concern.CoAP helpers.
edhoc_helpers.his replaced by<edhoc/coap.h>and every function gained anedhoc_coap_prefix. The working buffers now count progress (buffer/capacity/lengthandbuffer/length/consumed), so prepend and extract calls compose instead of overwriting each other;edhoc_message_ptr,edhoc_message_sizeandedhoc_prepend_recalculate_size()are gone.Exporters take a context, and come in two forms.
edhoc_export_prk_exporter()becomesedhoc_export_raw()andedhoc_export_oscore_session()becomesedhoc_export_oscore_context_raw();edhoc_export()andedhoc_export_oscore_context()are the new handle-returning forms. The exporter now takes thecontextargument that EDHOC_Exporter is defined with (RFC 9528: 4.2.1) and that1.xomitted entirely, so application keying material can finally be bound to something other than the label.edhoc_export_key_update()takes the same kind of context byte string in place of theentropyit used to demand.OSCORE export is single-use and rejects colliding identifiers. A session yields one security context; a further export returns
EDHOC_ERROR_BAD_STATEuntiledhoc_export_key_update()rotates PRK_out. A session whose C_I equals C_R is refused withEDHOC_ERROR_NOT_PERMITTED, because the two become the OSCORE Recipient IDs and RFC 9528: 3.3.3 forbids them being equal.Callback context and EAD. New
struct edhoc_call_contextcarries the role, method, selected cipher suite and message;edhoc_ead.compose/.processtake it in place ofenum edhoc_messageand both are mandatory when EAD is bound.struct edhoc_ead_tokenuses a singlestruct edhoc_buffer value.Cipher suite parameters.
struct edhoc_cipher_suitemoved to<edhoc/cipher_suite.h>;ecc_key_lengthandecc_sign_lengthare replaced bykem_encapsulation_key_length,kem_ciphertext_length,nike_key_length,sign_lengthandsupports_dh_nike. The per-suite helpers moved into the library, soedhoc_cipher_suite_N_get_keys()is gone along with the experimentaledhoc_exp_pqc_cipher_suite_1_*API,struct edhoc_crypto_pqcandstruct edhoc_cipher_suite_pqc. New gettersedhoc_cipher_suite_get_params()/edhoc_cipher_suite_get_crypto()are keyed byenum edhoc_cipher_suite_id.Types and names.
EDHOC_INITIATOR/EDHOC_RESPONDERbecomeEDHOC_ROLE_INITIATOR/EDHOC_ROLE_RESPONDER,EDHOC_MSG_1..4becomeEDHOC_MESSAGE_1..4, andEDHOC_ENCODE_TYPE_BYTE_STRINGbecomesEDHOC_ENCODE_TYPE_STRING.EDHOC_METHOD_MAXis removed andedhoc_set_methods()rejects a value outside 0..3.edhoc_set_user_context()accepts NULL, which clears the context. The misspelledEDHOC_SM_RECEVIED_M4alias is gone with the state enum.Error codes.
EDHOC_ERROR_EPHEMERAL_DIFFIE_HELLMAN_FAILUREbecomesEDHOC_ERROR_EPHEMERAL_KEY_EXCHANGE_FAILURE.EDHOC_ERROR_INVALID_MAC_2/_3are removed: a failed authentication has always beenEDHOC_ERROR_INVALID_SIGN_OR_MAC_2/_3, which is also what RFC 9528 calls the field. Malformed input now consistently yieldsEDHOC_ERROR_CBOR_FAILURE, whileEDHOC_ERROR_MSG_x_PROCESS_FAILUREmeans the message decoded but its content was rejected. A missing callback in a bound interface, and a list longer than the configured capacity, reportEDHOC_ERROR_INVALID_ARGUMENTinstead ofEDHOC_ERROR_BAD_STATE.Private headers.
edhoc_context.h,edhoc_common.handedhoc_macros.hare no longer installed, so theedhoc_comp_*/edhoc_verify_sign_or_mac()helpers, theedhoc_cbor_*_oh()sizing helpers and theEDHOC_EXTRACT_PRK_INFO_LABEL_*labels are internal.Configuration.
CONFIG_LIBEDHOC_MAX_LEN_OF_ECC_KEYis replaced byCONFIG_LIBEDHOC_MAX_LEN_OF_KEM_ENCAPSULATION_KEYandCONFIG_LIBEDHOC_MAX_LEN_OF_KEM_CIPHERTEXT, andCONFIG_LIBEDHOC_MAX_LEN_OF_HASH_ALGby the fixedEDHOC_CREDENTIAL_X5T_ALGORITHM_MAX_LEN(32). New:CONFIG_LIBEDHOC_MAX_NR_OF_METHODS, which sizes the method list, andCONFIG_LIBEDHOC_CIPHER_SUITE_{0,2,4,24,PQC_1}_ENABLE. The limits the CBOR backend caps are checked with_Static_assert, so the standalone build no longer truncates silently.API version.
EDHOC_API_VERSION_MAJORis2,_MINORis0and a newEDHOC_API_VERSION_PATCHcompletes the triplet.
Hardening¶
Malformed input is now rejected where it used to be processed. Two of these are reachable before authentication, from any peer that can deliver a message.
edhoc_message_1_process()rejects a message that fails CBOR decoding; it used to keep processing it against a zeroed structure.edhoc_message_error_process()rejects anERR_INFOwhose variant does not matchERR_CODE(RFC 9528: 6); the mismatch used to read a union as a byte string and copy out of bounds.edhoc_message_3_process()rejects aCIPHERTEXT_3no longer than the AEAD tag, which is malformed and formed a zero-length VLA in the stack memory backend.A
kidreceived as a CBOR integer outside the one-byte range -24..23 stands for no byte string at all and is rejected.What
edhoc_ead.composereturns is validated before it reaches the CBOR encoder, which cannot tell a missing buffer from an empty one.
Version 1.15.1¶
- Date:
July 9, 2026
@kamil-kielbasa : CI: the Valgrind job no longer builds the experimental PQC cipher suite. liboqs dispatches hand-written AVX2/AVX-512 ML-KEM code at runtime and Valgrind cannot decode some of those opcodes, which aborted the run with SIGILL on AVX-512-capable runners. No library code changed.
Version 1.15.0¶
- Date:
July 8, 2026
@kamil-kielbasa : Cipher suites:
Added cipher suite 4 (ChaCha20/Poly1305, SHA-256, X25519, EdDSA) as a ready-to-use helper.
Version 1.14.1¶
- Date:
July 1, 2026
@kamil-kielbasa : Experimental PQC cipher suite 1:
Fixed
EDHOC_Extract/EDHOC_Expand: KMAC256 (RFC 9528 Section 4.1) is now computed by XKCP and conforms to NIST SP 800-185, so the suite derives correct keys. Verified against the published NIST KMAC256 known-answer vector.Enabling
LIBEDHOC_ENABLE_EXPERIMENTAL_PQCnow also builds XKCP and requiresxsltprocon the host.
Version 1.14.0¶
- Date:
June 17, 2026
@kamil-kielbasa : PQC:
Added experimental PQC cipher suite 1 helper (draft TBD1) for draft-spm-lake-pqsuites-02: ML-KEM-512 key exchange, ML-DSA-44 signatures, AES-CCM-16-128-128 AEAD, SHAKE256 hash, and KMAC256 extract/expand (RFC 9528 Section 4.1).
Introduced
struct edhoc_crypto_pqcandstruct edhoc_cipher_suite_pqcinhelpers/include/edhoc_exp_pqc_cipher_suite_1.h(KEM-shaped crypto vtable;encapsulate/decapsulatereplacekey_agreement).Key import uses
PSA_KEY_TYPE_RAW_DATAfor ML-KEM / ML-DSA material; ephemeral ML-KEM keys use static slots simulating PSA key identifiers.
@kamil-kielbasa : Build:
Added
externals/liboqsgit submodule pinned to tag 0.15.0 and west projectmodules/lib/liboqs.New CMake option
LIBEDHOC_ENABLE_EXPERIMENTAL_PQC(default OFF) builds liboqs withKEM_ml_kem_512andSIG_ml_dsa_44only.Renamed
LIBEDHOC_ENABLE_MODULE_TESTStoLIBEDHOC_ENABLE_TESTS.
@kamil-kielbasa : Tests:
Added Unity group
cipher_suite_exp_pqc_1(ML-KEM, ML-DSA, hash, KMAC, AES-CCM round-trips on Linux).
@kamil-kielbasa : Coverage / docs:
New guide
guide/pqc(experimental PQC cipher suite 1), README experimental cipher-suite section, and helpers.rst section for experimental PQC cipher suite 1.
Version 1.13.0¶
- Date:
June 17, 2026
@kamil-kielbasa : API:
Removed callback
typedefs from the public headers and inlined the function pointers directly into their binding structs (struct edhoc_credentials,struct edhoc_keys,struct edhoc_crypto,struct edhoc_ead), Zephyr-style. The associated Doxygen was moved onto each struct member. No function signatures, struct names, struct layouts or behavior change; ABI is unchanged. Existing code that supplies callbacks via designated initializers requires no changes. Only code that referenced the removededhoc_*_ttype names directly is affected.
Version 1.12.7¶
- Date:
June 16, 2026
@kamil-kielbasa : CBOR:
Removed duplicate
cbor_bstr_overheadhelpers from message 4 and the exporter; all byte-string buffer sizing now usesedhoc_cbor_bstr_oh.edhoc_cbor_bstr_ohreturns the canonical 1-byte header for lengths ≤ 23 (removed legacy zcbor padding).Dropped redundant literal
+1header counts incomp_cid_len,compute_plaintext_4_len, exporter empty-bstr sizing, and message 2 signature encode buffers.
Version 1.12.6¶
- Date:
June 16, 2026
@kamil-kielbasa : Build:
Centralized warning flags in
cmake/warnings.cmake(libedhoc_target_warnings(STRICT|TEST)) for library, tests, and fuzz.Unified zcbor compile definitions via
LIBEDHOC_ZCBOR_COMPILE_DEFINITIONS; removed unusedCONFIG_ZCBOR;ZCBOR_CANONICALconsistentlyPRIVATE.Fixed
CMakePresets.jsonschema version (6 → 3) to matchcmake_minimum_required3.21.Install of generated
edhoc_config.husesLIBEDHOC_GENERATED_DIRinstead of a hardcoded path.
Version 1.12.5¶
- Date:
June 16, 2026
@kamil-kielbasa : Tests:
Assert specific
EDHOC_ERROR_*return codes instead of generic success/failure checks across integration and unit tests.Removed
goto-based cleanup from integration test helpers; use structured early returns instead.Strengthened integration tests:
psa_crypto_init()checks in setup,edhoc_context_deinit()asserts in teardown, and directedhoc_cipher_suite_N_get_suite()/_get_keys()getter calls where a cached pointer added no value.Added
get_cipher_suite_descriptorstest intests/unit/api/test_api.cfor cipher suite 0, 2, and 24 getters.Documented test quality standards in
doc/project/testing.rst.Added
coverage_sweep.handtest_coverage_sweep_validate.c: per-fail_ptexpected outcomes for mock sweeps viacoverage_assert_sweep_result().Extended mock full-handshake coverage tests to message 4; hardened
coverage_common.csetup.
Version 1.12.4¶
- Date:
June 16, 2026
@kamil-kielbasa : Tests:
Split
test_coverage.c(142 cases) into eight topic files undertests/unit/coverage/with sharedcoverage_common.c.Split
test_internals.c(232 cases) into nine topic files undertests/unit/internals/with sharedinternals_common.c.Removed
@scenario/@env/@action/@expectedcomment blocks; test names are self-describing.Renamed
TEST_GROUPidentifiers to match file topics (e.g.coverage_msg1,internals_mac).Added
edhoc_macros.htotest_common.hforARRAY_SIZE.Renamed compile definition
EDHOC_MODULE_TESTStoLIBEDHOC_MODULE_TESTS.
Version 1.12.3¶
- Date:
June 15, 2026
@kamil-kielbasa : Tests:
Replaced
LIBEDHOC_TEST_HOOKS/edhoc_test_*wrappers with aSTATIClinkage macro ininclude/edhoc_macros.h, enabled byEDHOC_MODULE_TESTSwhen module tests are built.Reorganised unit tests into topic subdirectories under
tests/unit/(api/,cipher_suites/,coverage/,internals/, etc.).
Version 1.12.2¶
- Date:
June 15, 2026
@kamil-kielbasa : Build system:
The CMake setup was reorganised around namespaced targets (
libedhoc::edhoc,libedhoc::api,libedhoc::helpers,libedhoc::backend_*). Plain target names are kept for backward compatibility, andEXPORT_NAMEmakesfind_package()andadd_subdirectory()consumers use identical names.Backends are now linked
PRIVATEon the core, so their ~40 headers no longer leak onto a consumer’s include path. Consumers that compile the helper sources themselves linklibedhoc::helpers(which carries the helper, CBOR and log include paths).A single source-of-truth list (
cmake/sources.cmake) feeds both the standalone and the Zephyr builds, andzephyr/CMakeLists.txtis now the only Zephyr-aware file — the rest of the tree has noif(TARGET zephyr_interface)branches.A generated
edhoc_config.h(fromcmake/edhoc_config.h.in) guarantees every translation unit — and every installed consumer — sees the same build-time configuration, removing a silent cross-TU mismatch ofCONFIG_LIBEDHOC_MEM_BACKEND. On Zephyr the values still come from Kconfig (the include is guarded by__ZEPHYR__).Packaging was hardened:
find_dependency(zcbor)in the package config, a generated package-version file, namespaced exported targets, and the convenience helper sources installed undershare/instead of the CMake-package directory.Added
CMakePresets.json(gcc/clang/coverage/sanitizers/fuzz). The minimum CMake version is now 3.21.This is a build-system change only: the public API, headers and runtime behaviour are unchanged.
Version 1.12.1¶
- Date:
June 12, 2026
@kamil-kielbasa : Logging backend:
The logging facility moved into a single, pluggable backend header,
backends/log/include/edhoc_backend_log.h. The previousinclude/edhoc_log.hand the entireport/logdirectory (with its separate Linux and Zephyr backend files) have been removed.The Linux/Zephyr split is now resolved entirely by the preprocessor (
__ZEPHYR__) inside that one header, instead of by selecting a different include directory per platform from CMake.The compile-time level gating that previously lived in
include/edhoc_log.hwas folded into the backend header, and the one-time ZephyrLOG_MODULE_REGISTERis now hosted directly inlibrary/edhoc.c.This is purely an internal reorganisation: the
EDHOC_LOG_*macros, the log levels andCONFIG_LIBEDHOC_LOG_LEVELbehave exactly as before.
Version 1.12.0¶
- Date:
June 12, 2026
@kamil-kielbasa : Memory backend:
The library can now obtain its internal working buffers from one of three interchangeable memory backends, chosen at build time. The default keeps the previous behaviour, so existing integrations are unaffected:
Stack (default) — buffers live on the call stack, exactly as before.
Heap — buffers come from the system heap (
callocon hosted builds,k_callocon Zephyr), removing the deep per-handshake stack usage on constrained targets.Custom — the application provides its own
edhoc_mem_alloc/edhoc_mem_freeat link time, e.g. to serve buffers from a dedicated pool.
The backend is chosen by the integer
CONFIG_LIBEDHOC_MEM_BACKEND: on Zephyr it is derived from theLIBEDHOC_MEM_BACKEND_CHOICEKconfig choice, and on every other build it is passed directly (-DCONFIG_LIBEDHOC_MEM_BACKEND=N, where N is 0 stack, 1 heap or 2 custom; default 0).Out-of-memory conditions are now reported to the caller. The new
EDHOC_ERROR_NOT_ENOUGH_MEMORY(-106) error code is returned by the affected message and exporter APIs when a non-stack backend cannot satisfy an allocation, and the failing call leaves no buffers leaked behind.Working buffers handed to the library are guaranteed to be zero-initialised on every backend.
The behaviour is verified for all three backends, including a tracking, fault-injecting custom allocator that exercises every out-of-memory path, and the heap backend additionally under ASan/LSan.
@kamil-kielbasa : Fix:
Message 1 processing now rejects an empty peer cipher suite list (
SUITES_I). The responder previously read the list’s last entry atcount - 1; for an empty list that index underflowed toSIZE_MAXand caused an out-of-bounds read. An empty list is now reported as a wrong selected cipher suite error.
Version 1.11.2¶
- Date:
June 11, 2026
@kamil-kielbasa : Docs:
Removed the stale hardcoded “Release” admonition from
doc/index.rst; the project version is maintained indoc/conf.py.
Version 1.11.1¶
- Date:
June 11, 2026
@kamil-kielbasa : CI:
Added a reusable
.github/actions/retrycomposite action and wrapped the submodule checkout. Transient GitHub network failures are retried instead of failing the job.
@kamil-kielbasa : Fix:
Replaced the dynamic shields.io release badge in
README.mdwith a GitHub Pages-hosted endpoint badge, so it no longer renders “Unable to select next GitHub token from pool” when the shields.io GitHub token pool is exhausted.
Version 1.11.0¶
- Date:
June 10, 2026
@kamil-kielbasa : Helpers / cipher suites:
Added the cipher suite 24 reference helper: A256GCM, SHA-384, P-384 (secp384r1) and ES384.
Added
tests/unit/test_cipher_suite_24.ccovering the full crypto surface.Documented cipher suite 24.
Moved the suite length macros (
EDHOC_CIPHER_SUITE_<n>_*, suites 0/2/24) out of the public headers into eachedhoc_cipher_suite_<n>.c, where they seed the descriptor.Renamed
test_crypto_suite{0,2}.ctotest_cipher_suite_{0,2}.c(groupscipher_suite_{0,2}) and sized their buffers from the_get_suite()descriptors.Extended
tests/unit/test_cipher_suite_{0,2}.cwith signature/AEAD tamper-detection and an additional HKDF-SHA-256 KAT.Removed the per-test descriptive comments across
tests/unit/test_cipher_suite_{0,2,24}.cin favour of self-descriptive test names.Hardened
tests/unit/test_cipher_suite_{0,2,24}.c.
@kamil-kielbasa : Tests / integration:
Added
tests/integration/test_handshake_x5chain_sig_suite24.c— a full EDHOC handshake over an X.509 certificate chain using cipher suite 24 (P-384 / ES384), with the P-384 test vectortests/include/test_vector_x5chain_sign_keys_suite_24.h.Raised
CONFIG_LIBEDHOC_MAX_LEN_OF_ECC_KEYandCONFIG_LIBEDHOC_MAX_LEN_OF_MACto 48 inscripts/ci.shso the shared test build accommodates P-384 keys and SHA-384 transcript hashes.Relaxed the X25519
make_key_pairbuffer-size check inedhoc_cipher_suite_0.cto accept context buffers larger than the key (only undersized buffers are rejected).Updated the
coveragemock crypto intests/unit/test_coverage.cto report fixed cipher suite 2 key/hash lengths (32) regardless of the buffer size.Fixed the message 2 ECDH-secret known-answer checks in
tests/integration/test_rfc9529_chapter{2,3}.cto comparedh_secret_lenbytes instead of the whole buffer (sizeof).
@kamil-kielbasa : Fix:
Helpers: corrected the cipher suite 2 descriptor MAC length (Static DH) from 32 to 8 bytes to match RFC 9528 (
edhoc_cipher_suite_2_get_suite).
Version 1.10.3¶
- Date:
June 5, 2026
@orbisai0security : Security:
Helpers: fixed buffer overread in P-256 public-key decompression — an oversized compressed peer key could write past the decompressed-key buffer; keys longer than the curve field size are now rejected before copying (V-001).
@kamil-kielbasa : Coverage / docs:
Helpers: documented the P-256 decompression bounds check as defensive and unreachable through the public API.
Tests: clarified that
key_agreement_peer_key_oversized_33exercises thekey_agreementlength guard rather than thembedtls_ecp_decompressbounds check.
Version 1.10.2¶
- Date:
June 2, 2026
@kamil-kielbasa : CI / contributing:
Added the
CI / FormatGitHub Actions workflow that runsclang-format --dry-run --Werrorover every tracked*.c/*.hfile (excluding the zcbor-generatedbackends/cbor/tree).Reformatted to satisfy the new check.
Documented in
CONTRIBUTING.mdthat every PR must updateCHANGELOG.rstwith a matching entry.
Version 1.10.1¶
- Date:
June 2, 2026
@kamil-kielbasa : Library:
Added
edhoc_cipher_suite_0_get_suite()andedhoc_cipher_suite_2_get_suite()returning a pointer to a pre-initialized canonicalstruct edhoc_cipher_suite(mirrors the existing_get_keys/_get_cryptogetters).Migrated all callers to the new getters and removed the now-redundant
tests/common/{include,src}/test_cipher_suites.{h,c}(and their CMake entries).
@kamil-kielbasa : Doxygen cleanup:
Removed stale
\versionand\datetags from all library, helper, port, sample and test file headers.
Version 1.10.0¶
- Date:
June 2, 2026
@kamil-kielbasa : Documentation overhaul:
Restructured Sphinx docs into
getting_started/,guide/,api/,reference/andproject/sections; switched to the Furo theme.Split the monolithic API page into per-topic pages (context, messages, credentials, crypto, exporters, EAD, helpers, internals).
Added a glossary, an error-code reference, a values reference and a links page.
Refreshed
README.md(two-row badge layout) and rewroteCONTRIBUTING.mdwith the unifiedscripts/ci.shworkflow and shallowwest update.
Version 1.9.0¶
- Date:
June 1, 2026
@kamil-kielbasa : Library / helpers (log footprint):
Shortened
EDHOC_LOG_*message literals acrosslibrary/*.candhelpers/src/*.cto reduce flash footprint when logging is enabled.
Version 1.8.0¶
- Date:
June 1, 2026
@kamil-kielbasa : Library (
edhoc_macros.h):Added
EDHOC_ASSERT_FREE_STACK_SIZE: on Zephyr expands to a runtime free-stack check viak_thread_stack_space_get+__ASSERT, otherwise no-op.VLA_ALLOCnow callsEDHOC_ASSERT_FREE_STACK_SIZEon Linux/Zephyr.Reorganized Doxygen for platform-dependent macros using the
__DOXYGEN__stub pattern.
Version 1.7.1¶
- Date:
March 23, 2026
@kamil-kielbasa : Testing:
Cipher suite 2 (
tests/unit/test_crypto_suite2.c): invalid key material for import; HKDF extract/expand whenpsa_key_derivation_set_capacityrejects oversized output; AEAD encrypt/decrypt with zero-length plaintext (null message buffers where PSA allows for AES-CCM).
@kamil-kielbasa : Documentation:
Updated Sphinx
conf.pyversion to v1.7.1.
Version 1.7.0¶
- Date:
March 20, 2026
@kamil-kielbasa : Cipher suite 2 reference helper (
helpers/src/edhoc_cipher_suite_2.c):ES256:
edhoc_cipher_suite_2_hashthenpsa_sign_hash/psa_verify_hash(waspsa_sign_message/psa_verify_message); equivalent toPSA_ALG_ECDSA(PSA_ALG_SHA_256)on the full message.Hash-then-sign lowers I/O for large sign payloads (e.g. secure elements). Callback
inputis unchanged: full byte string from the library.
@kamil-kielbasa : Documentation:
Cipher suite 2 Doxygen and
api.rstnote.Updated Sphinx
conf.pyversion to v1.7.0.
@kamil-kielbasa : Library (volatile key handles):
memsetlocalkey_idafterdestroy_keyinedhoc_message_{1,2,3}.c(aligned with the rest of the library).
Version 1.6.0¶
- Date:
March 1, 2026
@kamil-kielbasa : API symbol corrections (deprecated aliases preserved):
Renamed
EDHOC_SM_RECEVIED_M4→EDHOC_SM_RECEIVED_M4.Renamed
EDHOC_EXTRACT_PRK_INFO_LABEL_KEYSTERAM_2→EDHOC_EXTRACT_PRK_INFO_LABEL_KEYSTREAM_2.
@kamil-kielbasa : API documentation audit:
Standardized all
\retvaldescriptions inedhoc.hfor clarity and consistency.Added missing
\retval #EDHOC_ERROR_BUFFER_TOO_SMALLforedhoc_message_1_composeandedhoc_export_oscore_session.Corrected
\paramdirections and descriptions inedhoc_crypto.h(e.g.public_key_length,hashoutput direction).Fixed process function
message_N_lengthdescriptions (length of message, not buffer size).Fixed grammar and CBOR capitalization in
edhoc_credentials.handedhoc_context.h.Added comprehensive Doxygen for all macros in
edhoc_macros.h(\defgroup edhoc-macros).Added
\authortoedhoc_test_hooks.h.Fixed duplicate
\defgroupinedhoc_helpers.h.Unified
\return/\retvalstyle across all callback typedefs and internal functions.Corrected
\ref→\seefor external URLs in Doxygen.Fixed
#errormessage forCONFIG_LIBEDHOC_MAX_LEN_OF_MAC.
@kamil-kielbasa : Spelling corrections across all headers:
psuedorandom→pseudorandom,crypographics→cryptographic.Diffie-Helmann→Diffie-Hellman,registery→registry.conatins→contains,definitiones→definitions.identifer→identifier,buffor→buffer.Renamed
psuedo_random_key→pseudo_random_keyin cipher suite header declarations.Corrected
\filetag in Zephyr log backend to match actual filename.
@kamil-kielbasa : Added Doxygen for internal modules:
Added
\defgroup edhoc-logwith documentation for all log levels and log macros.Added Doxygen for Linux log backend:
edhoc_log_get_timestamp,edhoc_log_hexdump_impl, ANSI color defines.Added Doxygen for Zephyr log backend macro wrappers.
Added
\defgroup edhoc-test-hookswith\brieffor all 40+ test hook functions.
@kamil-kielbasa : Documentation improvements:
Added “Lifecycle” section to
api.rstwith context initialization call order and code examples.Added “Error handling” section to
api.rstwith error code retrieval guidance.Fixed
edhoc_set_conn_id()→edhoc_set_connection_id()in API flow diagram.Fixed cipher suite 0 algorithm description: ECDSA → EdDSA in
testing.rst.Fixed west build path for benchmark sample in
configuration.rst.Updated Sphinx
conf.pyversion to v1.6.0.
Version 1.5.0¶
- Date:
February 27, 2026
@kamil-kielbasa : CI/CD pipeline overhaul:
Consolidated all CI logic into a single
scripts/ci.shentry point for local reproducibility.Added code coverage measurement with gcov/lcov and Codecov integration.
Added ASan + UBSan sanitizer CI job (GCC).
Added LibFuzzer-based fuzz testing CI job (Clang).
Added weekly scheduled CI workflow with extended fuzzing.
@kamil-kielbasa : Compiler flags hardening:
Unified GCC and Clang warning flags (~25 shared flags).
Added GCC-specific warnings:
-Wformat-overflow=2,-Wformat-truncation=2,-Wswitch-enum,-Wjump-misses-init,-Wduplicated-cond,-Wduplicated-branches,-Wlogical-op.Added
-fstack-protector-strongfor non-sanitizer builds.
@kamil-kielbasa : Resolved all 538 clang-tidy warnings across the library.
@kamil-kielbasa : Zephyr benchmark application (
sample/benchmark/):Full EDHOC handshake benchmark for
native_sim(cipher suite 2, P-256/ES256, X.509 chain).Per-phase handshake timing with JSON output.
Library flash footprint analysis (~20 KiB).
NSI two-stage linking solved by providing mbedTLS archives to
RUNNER_LINK_LIBRARIES.CI uploads
flash_report.txtandbenchmark_timing.jsonas artifacts.
@kamil-kielbasa : Test improvements:
Restructured tests into 3-tier architecture: unit, integration, and fuzz.
Extracted shared test helpers (
test_cipher_suites,test_credentials,test_ead).Added negative test scenarios for
edhoc_export_oscore_sessionandedhoc_message_1_compose/process.Added mock-based failure injection tests for internal error paths.
Consolidated fuzz targets from
fuzz/intotests/fuzz/.Achieved 92.8% line coverage and 100% function coverage (635+ tests).
@kamil-kielbasa : Bug fixes:
Fixed out-of-bounds write in
test_internals.c(alg_bstrarray).Fixed GCC extension usage (non-constant struct initializers) for Clang compatibility.
Fixed
-Wformat-truncationin log backend timestamp formatting.Fixed
-gdwarf-4for Valgrind compatibility with GCC 11+.
Version 1.4.2¶
- Date:
January 30, 2026
@kamil-kielbasa : Documentation improvements and updates.
Version 1.4.1¶
- Date:
January 30, 2026
@tgujda : Added log module declaration for EDHOC helpers.
Version 1.4.0¶
- Date:
January 30, 2026
@tgujda : Added cmake install target for library installation.
@magdalena-szumny : Added extra logs for EDHOC helpers module
Version 1.3.0¶
- Date:
January 27, 2026
-
Added EDHOC helpers module with connection ID and buffer utilities.
Renamed cipher suite files and functions to edhoc_cipher_suite_X for consistency.
Refactored cipher suite implementations to expose struct edhoc_crypto and struct edhoc_keys.
@kamil-kielbasa : Fixed Zephyr logging backend.
Version 1.2.0¶
- Date:
January 27, 2026
@kamil-kielbasa : Added new logging module:
Logging module has the same signatures to the Zephyr logging module.
Added logging backends for Linux and Zephyr platforms.
Added EDHOC_LOG_ERR for the entire library.
Replaced context.logger with new logging hexdump functionlike-macros.
Version 1.1.1¶
- Date:
January 8, 2026
@kamil-kielbasa : Fixed Zephyr build github workflow.
Version 1.1.0¶
- Date:
January 7, 2026
@magdalena-szumny : Added Zephyr build system support.
@magdalena-szumny : Added Zephyr sample application for build verification (native_sim).
@magdalena-szumny : Added west manifest (west.yml) for Zephyr workspace initialization.
Version 1.0.0¶
- Date:
April 14, 2025
@marek-serafin : Fixed some minor issues with sizes.
@kamil-kielbasa : Added module tests for public API.
@kamil-kielbasa : Added peer cipher suites caching for message 1 process.
@kamil-kielbasa : Refactored cipher suites negotiation module tests.
@kamil-kielbasa : Updated readme.
@kamil-kielbasa : Refactored Kconfig:
Moved hardcoded values from cmake to build script.
Renamed two variables according to style.
Zephyr environment variable in cmake.
@kamil-kielbasa : Cleaned up cppcheck warnings in module tests.
Version 0.6.0¶
- Date:
October 31, 2024
@kamil-kielbasa : Added C unit test framework - Unity.
@kamil-kielbasa : Migrated all module tests to Unity framework.
@kamil-kielbasa : Added documentation for:
Library configuration.
Module tests scenarios.
@kamil-kielbasa : Added missing doxygen for API.
@kamil-kielbasa : Update zcbor from v0.7.0 to v0.8.1.
Version 0.5.0¶
- Date:
August 5, 2024
@kamil-kielbasa : Changed build system from Make to CMake.
@kamil-kielbasa : Added building library code with clang compiler.
@kamil-kielbasa : Added new module test for scenario:
X.509 chain, cipher suite 2, static DH keys, single EAD token.
@marek-serafin : Fixed setting correct cases for static dh methods.
@kamil-kielbasa : Refactored message_2 and message_3 for common code:
CBOR utilities.
MAC 2/3 context generation.
MAC 2/3 computation.
Signature_or_MAC 2/3 computation and verification.
@kamil-kielbasa : Fixed setting correct cases for methods for message_3.
@kamil-kielbasa : Added any cborised authentication credentials option.
@kamil-kielbasa : Fixed end entity certificate according to COSE X.509 chain.
@kamil-kielbasa : Fixed wrong MAC length for static DH in test suite.
@kamil-kielbasa : Refactored EDHOC API and EDHOC interfaces.
@kamil-kielbasa : Added library zephyrization.
@kamil-kielbasa : Refactored function edhoc_set_methods for more flexibility.
@kamil-kielbasa : Added support for MSVC _alloca (lack of VLA).
Version 0.4.0¶
- Date:
July 5, 2024
@marek-serafin : Fixed typo in setting peer_cid while processing message 1.
@marek-serafin : Fixed zcbor. Added a method to avoid generation of duplicated types.
@kamil-kielbasa : Added EDHOC error message compose & process with unit tests.
@kamil-kielbasa : Added EDHOC PRK exporter with unit test.
@kamil-kielbasa : Fixed CDDL models for COSE X.509 chain and COSE X.509 hash.
added unit test with two certificates for X.509 chain for cipher suite 0.
added unit test with one certificate for X.509 chain for cipher suite 2 with multiple EAD tokens.
added unit test for X.509 hash for cipher suite 2 with single EAD token.
@kamil-kielbasa : Changed licence from GPL-2.0 to MIT.
@kamil-kielbasa : Forbidden passing empty byte string for connection identifier.
@kamil-kielbasa : Added EDHOC error getters for: error code and cipher suites.
added test scenarios according to RFC 9528: 6.3.2. Examples. Covered figures 8 and 9.
Version 0.3.0¶
- Date:
May 20, 2024
@kamil-kielbasa : Full support of RFC 9528 (EDHOC).
add missing static diffie hellman keys authentication method.
@kamil-kielbasa : Implementation is verified with RFC 9529 (EDHOC traces) for chapter 3.
@kamil-kielbasa : Create documentation for sphinx including:
move README to sphinx.
move ChangeLog to sphinx.
create API documentation and fix header files.
@kamil-kielbasa : Add documentation deployment step for github actions.
Version 0.2.0¶
- Date:
April 28, 2024
@kamil-kielbasa : Update implementation for RFC 9528 (EDHOC) including:
external authorization data aligned with RFC.
add message 4 compose & process.
keyUpdate method.
@kamil-kielbasa : Separate interface for EAD.
@kamil-kielbasa : Implementation is verified with RFC 9529 (EDHOC traces) for chapter 2.
extended unit tests with EAD single/multiple tokens.
used RFC 9529 certificates to verify authentication identified by ‘x5chain’.
@kamil-kielbasa : Example implementation of cipher suite 2.
@kamil-kielbasa : EDHOC context structure with private members.
@kamil-kielbasa : Fix connection identifiers encoding option.
@kamil-kielbasa : Fix authentication credentials encoding option.
@kamil-kielbasa : Fix CBOR memory requirements for integer, byte string and text string.
@kamil-kielbasa : Add build, run unit tests and verification by cppcheck and valgrind for github actions.
@kamil-kielbasa : Update README.
Version 0.1.0¶
- Date:
April 01, 2024
@kamil-kielbasa : EDHOC implementation for version 16:
limited support for authentication methods only via signatures.
support EAD encoded as byte string.
support authentication identified by: ‘kid’, ‘x5chain’, ‘x5t’.
@kamil-kielbasa : CoAP friendly EDHOC API.
@kamil-kielbasa : Separate interfaces for:
cryptographics keys.
cryptographics operations.
authentication credentials.
@kamil-kielbasa : Authentication credentials fetch callback accept only private key identifier.
@kamil-kielbasa : Example implementation of cipher suite 0 with PSA.
@kamil-kielbasa : Unit test with test vectors for authentication with signatures, X.509 identified by ‘kid’, ‘x5chain’ and ‘x5t’.