matter_crypto.c
AES-128-CCM, the Matter nonce, and the key schedule.
Overview
AES-128-CCM, the Matter nonce, and the key schedule.
depends on aliro_hash.h matter_crypto.h
API
Cstruct cbc_mac
Streaming CBC-MAC state: no buffer proportional to the message.
Fstatic int mac_block(struct cbc_mac *m, const uint8_t b[AES_BLOCK])
XOR one 128-bit block into the CBC-MAC state and encrypt it with AES-ECB.
ccm_mac, mac_flush, mac_updateFstatic int mac_update(struct cbc_mac *m, const uint8_t *p, size_t len)
Update CBC-MAC state with input bytes: accumulate into partial blocks and process full 128-bit blocks through the cipher. Returns 0 on success or cipher error.
ccm_mac · calls mac_blockFstatic int mac_flush(struct cbc_mac *m)
Flush a partial block, zero-padded, as CCM requires at each section end.
ccm_mac · calls mac_blockFstatic void ctr_block(const uint8_t nonce[MATTER_NONCE_LEN], uint16_t i, uint8_t out[AES_BLOCK])
Counter block A_i, per RFC 3610: flags | nonce | i, with only L-1 in the flags because A blocks carry no Adata or tag-length fields.
ccm_ctr, ccm_tagFstatic int ccm_mac(const uint8_t key[MATTER_KEY_LEN], const uint8_t nonce[MATTER_NONCE_LEN], const uint8_t *aad, size_t aad_len, const uint8_t *pt, size_t pt_len, uint8_t t_out[AES_BLOCK])
Run the CBC-MAC over B0, the length-prefixed AAD, and the payload.
matter_aead_decrypt, matter_aead_encrypt · calls mac_block, mac_flush, mac_updateFstatic int ccm_ctr(const uint8_t key[MATTER_KEY_LEN], const uint8_t nonce[MATTER_NONCE_LEN], const uint8_t *in, size_t len, uint8_t *out)
XOR the CTR keystream over @p len bytes, starting at counter block 1.
matter_aead_decrypt, matter_aead_encrypt · calls ctr_blockFstatic int ccm_tag(const uint8_t key[MATTER_KEY_LEN], const uint8_t nonce[MATTER_NONCE_LEN], const uint8_t t[AES_BLOCK], uint8_t tag_out[MATTER_TAG_LEN])
Mask the raw CBC-MAC with S0 to produce the transmitted tag.
matter_aead_decrypt, matter_aead_encrypt · calls ctr_blockFstatic bool tag_equal(const uint8_t *a, const uint8_t *b, size_t len)
Constant time: a tag comparison must not leak how far it matched.
matter_aead_decryptFint matter_build_nonce(uint8_t security_flags, uint32_t message_counter, uint64_t node_id, uint8_t out[MATTER_NONCE_LEN])
Build an AES-CCM nonce from security flags, message counter, and node ID in little-endian form; returns MATTER_OK on success.
matter_crypto_open, matter_crypto_sealFint matter_derive_session_keys(const uint8_t *secret, size_t secret_len, const uint8_t *salt, size_t salt_len, bool resume, struct matter_session_keys *out)
Derive session keys from a shared secret using HKDF for Matter secure channel setup. Expands secret into i2r, r2i, and attestation_challenge keys using either normal or resume derivation context. Returns MATTER_E_INVAL if secret, out are NULL or secret_len is zero; returns MATTER_E_INVAL if salt_len is nonzero but salt is NULL; returns MATTER_E_STATE if HKDF fails.
Fint matter_aead_encrypt(const uint8_t key[MATTER_KEY_LEN], const uint8_t nonce[MATTER_NONCE_LEN], const uint8_t *aad, size_t aad_len, const uint8_t *pt, size_t pt_len, uint8_t *ct_out, uint8_t tag_out[MATTER_TAG_LEN])
Encrypt a plaintext with AES-CCM, optionally authenticated with AAD, by computing the CBC-MAC, generating the authentication tag, and encrypting the plaintext with CTR; returns MATTER_OK on success.
matter_crypto_seal · calls ccm_ctr, ccm_mac, ccm_tagFint matter_aead_decrypt(const uint8_t key[MATTER_KEY_LEN], const uint8_t nonce[MATTER_NONCE_LEN], const uint8_t *aad, size_t aad_len, const uint8_t *ct, size_t ct_len, const uint8_t tag[MATTER_TAG_LEN], uint8_t *pt_out)
Decrypt an AES-CCM ciphertext with an authentication tag and optional AAD, verifying the tag in constant time before returning plaintext; returns MATTER_OK on success or MATTER_E_TYPE if the tag does not verify.
matter_crypto_open · calls ccm_ctr, ccm_mac, ccm_tag, tag_equalFint matter_crypto_seal(const struct matter_msg_header *h, const uint8_t key[MATTER_KEY_LEN], uint64_t sender_node_id, const uint8_t *payload, size_t payload_len, uint8_t *out, size_t cap, size_t *out_len)
Encrypt and authenticate a Matter message: encode header into output buffer, build nonce from security flags and counter, and encrypt payload with AAD set to the encoded header bytes. Caller must ensure output capacity >= header length + payload length + MATTER_TAG_LEN. Returns MATTER_OK on success or encoding error.
matter_aead_encrypt, matter_build_nonceFint matter_crypto_open(const uint8_t *buf, size_t len, const uint8_t key[MATTER_KEY_LEN], uint64_t sender_node_id, struct matter_msg_header *h, uint8_t *pt_out, size_t pt_cap, size_t *pt_len)
Decrypt and verify a Matter message: decode header, extract ciphertext and authentication tag, build nonce from security flags and counter, and decrypt with AAD set to the message header. Returns MATTER_OK on successful decryption, MATTER_E_INVAL on bad parameters, MATTER_E_TRUNC if ciphertext too short for tag, MATTER_E_NOSPACE if plaintext exceeds output capacity.
matter_aead_decrypt, matter_build_nonce