|
| static void | put_be32 (uint8_t *out, uint32_t v) |
| | Store v big-endian into out (4 bytes).
|
| |
| static uint32_t | get_be32 (const uint8_t *in) |
| | Load a big-endian uint32 from in (4 bytes).
|
| |
| static void | xor_bytes (uint8_t *out, const uint8_t *a, const uint8_t *b, size_t n) |
| | XOR n bytes: out = a ^ b (out may alias a).
|
| |
| static uint8_t | block_lshift1 (const uint8_t in[AES_BLOCK_LEN], uint8_t out[AES_BLOCK_LEN]) |
| | One-bit left shift of a 128-bit big-endian block.
|
| |
| static void | cmac_subkey (const uint8_t l[AES_BLOCK_LEN], uint8_t out[AES_BLOCK_LEN]) |
| | CMAC subkey derivation: K = (L << 1), XOR Rb if the top bit was set.
|
| |
| int | ccc_aes_cmac (const uint8_t *key, size_t key_bits, const uint8_t *msg, size_t msg_len, uint8_t tag[CCC_CMAC_TAG_LEN]) |
| | AES-CMAC authentication tag over message.
|
| |
| static int | kdf108_block (const uint8_t *kdk, size_t kdk_bits, uint32_t counter, const uint8_t *label, size_t label_len, const uint8_t *context, size_t ctx_len, uint32_t l_bits, uint8_t out[AES_BLOCK_LEN]) |
| | One counter-mode CMAC block: CMAC(kdk, counter || label || 0x00 || context || l_bits).
|
| |
| int | ccc_derive_mupsk1 (const uint8_t ursk[CCC_URSK_LEN], uint8_t out[CCC_MUPSK1_LEN]) |
| | Derive mUPSK1, the SP0 Pre-POLL AES-CCM* key.
|
| |
| int | ccc_derive_mupsk2 (const uint8_t ursk[CCC_URSK_LEN], uint8_t out[CCC_MUPSK2_LEN]) |
| | Derive mUPSK2, the seed for the UWB-address KDF.
|
| |
| int | ccc_derive_mursk (const uint8_t ursk[CCC_URSK_LEN], uint8_t out[CCC_MURSK_LEN]) |
| | Derive mURSK, the ranging-key seed feeding URSK_KT.
|
| |
|
int | ccc_derive_salted_hash (const uint8_t ursk[CCC_URSK_LEN], const uint8_t *ranging_config, size_t rc_len, uint8_t out[CCC_SALTED_HASH_LEN]) |
| | Derive SaltedHash from the serialized ranging configuration.
|
| |
| int | ccc_derive_ursk_kt (const uint8_t mursk[CCC_MURSK_LEN], uint32_t sts_index, uint8_t out[CCC_URSK_KT_LEN]) |
| | Derive URSK_KT, generated once per ranging cycle and keyed by the STS index.
|
| |
| static int | derive_dkey (const uint8_t ursk_kt[CCC_URSK_KT_LEN], const uint8_t label[4], const uint8_t salted_hash[CCC_SALTED_HASH_LEN], uint8_t out[CCC_DURSK_LEN]) |
| | Shared dURSK/dUDSK derivation body: CMAC(URSK_KT, ctr1 || label || 0x00 || SaltedHash || 0x000000 || 0x80).
|
| |
| int | ccc_derive_dursk (const uint8_t ursk_kt[CCC_URSK_KT_LEN], const uint8_t salted_hash[CCC_SALTED_HASH_LEN], uint8_t out[CCC_DURSK_LEN]) |
| | Derive dURSK, per-cycle STS key material.
|
| |
| int | ccc_derive_dudsk (const uint8_t ursk_kt[CCC_URSK_KT_LEN], const uint8_t salted_hash[CCC_SALTED_HASH_LEN], uint8_t out[CCC_DUDSK_LEN]) |
| | Derive dUDSK, per-cycle SP0 timestamp-frame key.
|
| |
| int | ccc_derive_sts_v (const uint8_t salted_hash[CCC_SALTED_HASH_LEN], uint32_t sts_index, uint8_t out[CCC_STS_V_LEN]) |
| | Derive STS-V (phyHrpUwbStsV), the per-PPDU STS IV for the DW3000.
|
| |
| int | ccc_derive_uad (const uint8_t mupsk2[CCC_MUPSK2_LEN], uint32_t sts_index0, uint8_t out[CCC_UAD_LEN]) |
| | Derive UAD, the raw UWB-address derivation output.
|
| |
| static void | remap_if_reserved (uint8_t *addr, size_t len) |
| | If addr is a reserved all-ones value (0xFFFF/0xFFFE for 2 bytes, 0xFF..FF for other lengths), clear its top bit.
|
| |
| int | ccc_uad_addresses (const uint8_t uad[CCC_UAD_LEN], uint8_t keysource[CCC_KEYSOURCE_LEN], uint8_t dest_short_addr[CCC_DEST_SHORT_ADDR_LEN], uint8_t src_long_addr[CCC_SRC_LONG_ADDR_LEN]) |
| | Split UAD into the UWB addresses (KeySource, destination short address, source long address).
|
| |
| static void | sp0_nonce (uint8_t nonce[CCC_SP0_NONCE_LEN], const uint8_t src_long_addr[CCC_SRC_LONG_ADDR_LEN], uint32_t frame_counter) |
| | Build the SP0 CCM* nonce: SrcLongAddr || FrameCounter(BE) || SecLevel.
|
| |
| static int | sp0_cbc_mac (const uint8_t key[CCC_MUPSK1_LEN], const uint8_t nonce[CCC_SP0_NONCE_LEN], const uint8_t *mhr, size_t mhr_len, const uint8_t *payload, size_t payload_len, uint8_t tag[AES_BLOCK_LEN]) |
| | Compute the CCM* CBC-MAC over B0 || l(a)||MHR || payload, zero-padded per block.
|
| |
| static int | sp0_ctr (const uint8_t key[CCC_MUPSK1_LEN], const uint8_t nonce[CCC_SP0_NONCE_LEN], const uint8_t *in, size_t len, uint8_t *out, uint8_t s0[AES_BLOCK_LEN]) |
| | Apply CCM* CTR mode: emit the S0 keystream block, then XOR keystream S1.
|
| |
|
static int | sp0_ct_diff (const uint8_t *a, const uint8_t *b, size_t n) |
| | Constant-time inequality: 0 iff the n bytes are equal.
|
| |
|
int | ccc_sp0_encrypt (const uint8_t key[CCC_MUPSK1_LEN], const uint8_t src_long_addr[CCC_SRC_LONG_ADDR_LEN], uint32_t frame_counter, const uint8_t *mhr, size_t mhr_len, const uint8_t *payload, size_t payload_len, uint8_t *ciphertext_out, uint8_t mic_out[CCC_SP0_MIC_LEN]) |
| | Encrypt + authenticate an SP0 data frame (AES-CCM*, ENC-MIC-64).
|
| |
|
int | ccc_sp0_decrypt (const uint8_t key[CCC_MUPSK1_LEN], const uint8_t src_long_addr[CCC_SRC_LONG_ADDR_LEN], uint32_t frame_counter, const uint8_t *mhr, size_t mhr_len, const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t mic[CCC_SP0_MIC_LEN], uint8_t *payload_out) |
| | Decrypt + verify an SP0 data frame; zeroes plaintext and returns -EBADMSG on MIC failure.
|
| |
|
|
static const uint8_t | LBL_UPSK [4] = {0x55, 0x50, 0x53, 0x4B} |
| | Label "UPSK" (0x5550534B).
|
| |
|
static const uint8_t | LBL_URSK [4] = {0x55, 0x52, 0x53, 0x4B} |
| | Label "URSK" (0x5552534B).
|
| |
|
static const uint8_t | LBL_UDSK [4] = {0x55, 0x44, 0x53, 0x4B} |
| | Label "UDSK" (0x5544534B).
|
| |
|
static const uint8_t | LBL_SALT [4] = {0x53, 0x41, 0x4C, 0x54} |
| | Label "SALT" (0x53414C54).
|
| |
|
static const uint8_t | LBL_URSK_KT [7] = {0x55, 0x52, 0x53, 0x4B, 0x5F, 0x4B, 0x54} |
| | Label "URSK_KT" (0x5552534B5F4B54).
|
| |
|
static const uint8_t | LBL_UAD [3] = {0x55, 0x41, 0x44} |
| | Label "UAD" (0x554144).
|
| |
|
static const uint8_t | CTX_ZERO3 [3] = {0x00, 0x00, 0x00} |
| | 3-byte zero context tail carried by mUPSK/Salt/mURSK/dURSK/dUDSK.
|
| |
— UWB key schedule + SP0 Pre-POLL frame codec.