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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions