Skip to content

🐛 [BUG] - v1.4.2 - OTAR Does Not Set Key Length Properly #506

@VissaMoutafis

Description

@VissaMoutafis

Description

During the OTAR (Over-The-Air Rekeying) process in Crypto_Key_OTAR(), the code decrypts
and stores each incoming key into the key ring, but never initialises or increments
ekp->key_len
. The field is left at whatever value was already in memory. Any downstream
consumer that relies on key_len to determine the byte-length of a key ring entry, for
example size validation or GCM tag-length derivation, will therefore operate on
garbage/stale data, which can cause incorrect decryption, silent authentication failures, or
a crash.

This issue is present in src/core/crypto_key_mgmt.c in the Crypto_Key_OTAR() function,
around the key-copy loop (line ~193–210 in v1.4.2). The patch adds ekp->key_len = 0;
before the loop and ekp->key_len++; inside the loop so that the length counter accurately
reflects the number of bytes written.

Status on dev/main (as of 2026-03-31): This class of bug was partially addressed in
v1.3.2 (see CVE-2025-46672) for earlier branches, but the fix does not appear to have
been forward-ported into the v1.4.x line. The dev branch does not contain the
ekp->key_len initialisation + increment pattern described below. This issue should be
considered unpatched in the current dev branch.


Branch / Affected Version

  • Affected: v1.4.2 (src/core/crypto_key_mgmt.c)
  • Latest tested dev commit: dev branch as of 2026-03-31

Reproduction Steps

Execute the following six-packet sequence against a CryptoLib v1.4.2 instance built with
TC_PROCESS_SDLS_PDUS_TRUE and internal key/SA storage. The raw TC frames (hex) are listed
before each step.

Packet 1 – Key OTAR (deliver key ID 130 via master key 0)

002c104c000000000102000000000000000000000000000000719405af7fcd82f5c1073e5c81455b28e37b2e8b4cada60ec40bd3eea8585e2fb2e22726654fed87b83a4a912feffdf35b9c1422
  1. Send Packet 1. Observe Received 1 keys via master key 0 — key ID 130 written to key
    ring. At this point ekp->key_len is 0 (uninitialised / stale).

Packet 2 – Key Activate (activate key ID 130)

002c100e0000000002001000828a33
  1. Send Packet 2. Key 130 transitions to ACTIVE.

Packet 3 – SA Create (create SPI 20 with AES-GCM, ekid=20, akid=20)

002c1046000000001101d00014cc001001010c00000000000000000000000001010020000000000000000000000000000000000000000000000000000000000000000000002384
  1. Send Packet 3. SPI 20 is created in UNKEYED state with iv_len=0.

Packet 4 – SA Rekey (rekey SPI 20 with encrypted key ID 130)

002c101e00000000160090001400820082000000000000000000000000df2b
  1. Send Packet 4. SPI 20 transitions to KEYED, ekid=130.

Packet 5 – SA Start (set SPI 20 OPERATIONAL)

002c1011000000001b00280014002c04dfc1
  1. Send Packet 5. SPI 20 transitions to OPERATIONAL.

Packet 6 – Encrypted TC using SPI 20

002c106800000014000000000000000000000000caf032aed81de3019156893e1cf8f3a9124278c02835e95bc5624095ce79f69286ab5684a697900b06e35b286440bd99e7af8701426243de674411ea1c57379ff7d66b5cb3e53222b27350b505450fba4b2d47e2c1
  1. Send Packet 6 (AES-GCM encrypted TC). Observe the key_len was never set, causing the cryptography backend to reject or
    mishandle the key material.
Image

Expected Behaviour

ekp->key_len should equal SDLS_KEY_LEN (32) after the OTAR loop, and Packet 6 should
decrypt successfully with status code 0.


Actual Behaviour

ekp->key_len remains 0 (or stale).


Proposed Fix

In src/core/crypto_key_mgmt.c, inside Crypto_Key_OTAR(), locate the key-copy loop and
apply the following patch:

*** 193,199 ****
  count = count + 2;
  #ifdef DEBUG
  printf("\t Key %d = %d\n", x, packet.EKB[x].ekid);
! #endif
  for (y = count; y < (SDLS_KEY_LEN + count); y++)
--- 193,200 ----
  count = count + 2;
  #ifdef DEBUG
  printf("\t Key %d = %d\n", x, packet.EKB[x].ekid);
! #endif
! ekp->key_len = 0;
  for (y = count; y < (SDLS_KEY_LEN + count); y++)

*** 203,208 ****
--- 204,211 ----
  #endif
  // Setup Key Ring
  ekp->value[y - count] = sdls_frame.tlv_pdu.data[y];
+
+ ekp->key_len++;
  }
  count = count + SDLS_KEY_LEN;

References

  • CCSDS 355.0-B-2 – Space Data Link Security (SDLS) Protocol, Section 5 (Key Management)
  • CCSDS 355.2-B-1 – SDLS Extended Procedures, Section 3.2 (OTAR Procedure)

Environment

  • OS: Linux (Ubuntu 22.04 / tested in Docker)
  • CryptoLib version: v1.4.2
  • Crypto backend: LibGcrypt 1.4.1 (internal SA/Key)
  • Build flags: TC_PROCESS_SDLS_PDUS_TRUE, CRYPTO_EPROC=1

Branch Name

v1.4.2 and dev

Reproduction steps

Execute the following six-packet sequence against a CryptoLib v1.4.2 instance built with
`TC_PROCESS_SDLS_PDUS_TRUE` and internal key/SA storage. The raw TC frames (hex) are listed
before each step.

**Packet 1 – Key OTAR (deliver key ID 130 via master key 0)**

002c104c000000000102000000000000000000000000000000719405af7fcd82f5c1073e5c81455b28e37b2e8b4cada60ec40bd3eea8585e2fb2e22726654fed87b83a4a912feffdf35b9c1422

1. Send Packet 1. Observe `Received 1 keys via master key 0` — key ID 130 written to key
   ring.  At this point `ekp->key_len` is **0** (uninitialised / stale).

**Packet 2 – Key Activate (activate key ID 130)**

002c100e0000000002001000828a33

2. Send Packet 2. Key 130 transitions to `ACTIVE`.

**Packet 3 – SA Create (create SPI 20 with AES-GCM, ekid=20, akid=20)**

002c1046000000001101d00014cc001001010c00000000000000000000000001010020000000000000000000000000000000000000000000000000000000000000000000002384

3. Send Packet 3. SPI 20 is created in `UNKEYED` state with `iv_len=0`.

**Packet 4 – SA Rekey (rekey SPI 20 with encrypted key ID 130)**

002c101e00000000160090001400820082000000000000000000000000df2b

4. Send Packet 4. SPI 20 transitions to `KEYED`, `ekid=130`.

**Packet 5 – SA Start (set SPI 20 OPERATIONAL)**

002c1011000000001b00280014002c04dfc1

5. Send Packet 5. SPI 20 transitions to `OPERATIONAL`.

Screenshots

Logs

OS

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions