nasa / nasa/CryptoLib

🐛 [BUG] - SA Create Does Not Validate SA State (Conformance issue)

Open Beginner friendly
#507 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C
Stars
169
Forks
67
PR merge metrics
No merged PRs in 30d

Description

Description

Description

The sa_rekey() / SA-Create handler in
src/sa/internal/sa_interface_inmemory.template.c overwrites an existing Security
Association entry without first verifying that the target SPI is in SA_NONE state.
This means an operator can silently replace a live, operational SA — including its cryptographic
parameters — while the SA remains in service.

According to the CCSDS SDLS-EP standard (CCSDS 355.2-B-1, §3.3.1), the SA Create
procedure is only permitted when the target SPI is in the Unoccupied (NONE) state. All
other states must cause the command to be rejected.

Status on dev/main (as of 2026-03-31): The state-check guard (if (temp_sa->sa_state != SA_NONE) { return CRYPTO_LIB_ERROR; }) does not appear in
the current dev branch's sa_interface_inmemory.template.c. This issue should be
considered unpatched in the current dev branch.


Branch / Affected Version

  • Affected: v1.4.2 (src/sa/internal/sa_interface_inmemory.template.c, ~line 1453)
  • Latest tested dev commit: dev branch as of 2026-03-31

Reproduction Steps

Use the following packet sequence. Observe that Packet 3 (SA Create for SPI
20) succeeds unconditionally even if SPI 20 already exists in any state other than
SA_NONE.

Packet 1 – Key OTAR

002c104c000000000102000000000000000000000000000000719405af7fcd82f5c1073e5c81455b28e37b2e8b4cada60ec40bd3eea8585e2fb2e22726654fed87b83a4a912feffdf35b9c1422

Packet 2 – Key Activate

002c100e0000000002001000828a33

Packet 3 – SA Create (SPI 20) — send twice to demonstrate no state guard

002c1046000000001101d00014cc001001010c00000000000000000000000001010020000000000000000000000000000000000000000000000000000000000000000000002384
  1. Send Packet 1 and Packet 2 as prerequisites.
  2. Send Packet 3 the first time — SPI 20 is created successfully (sa_state = 0x1 UNKEYED).
  3. Advance SPI 20 to OPERATIONAL (Packets 4, 5 below).
  4. Send Packet 3 again — SPI 20 is overwritten without error. An operational SA is
    silently replaced.

Expected Behaviour

The second SA Create for SPI 20 (already in a non-NONE state) should be rejected with an
error code (e.g. CRYPTO_LIB_ERROR_SA) and the existing SA should be left untouched.

Actual Behaviour

The SA Create succeeds unconditionally, silently overwriting the live SA entry and resetting
all of its cryptographic parameters.


Logs

SA Create
spi = 20
SA status:
     spi        = 20
     sa_state   = 0x1      ← UNKEYED, regardless of prior state
     est        = 0x1
     ast        = 0x1
     shivf_len  = 12
     ...
Status code: 0             ← no error even when overwriting an operational SA

Proposed Fix

In src/sa/internal/sa_interface_inmemory.template.c, immediately after the lpid field
is populated (around line 1458 in v1.4.2, offsets may differ in dev), add a state-guard
block:

*** 1453,1458 ****
--- 1456,1470 ----
  // 5-8 : Procedure Identification Field (pid)
  temp_sa->lpid = (sdls_frame.tlv_pdu.hdr.type << 7) |
                  (sdls_frame.tlv_pdu.hdr.uf   << 6) |
                  (sdls_frame.tlv_pdu.hdr.sg   << 4) |
                   sdls_frame.tlv_pdu.hdr.pid;
+
+ // Check that the SA is in NONE state before creating
+ if (temp_sa->sa_state != SA_NONE)
+ {
+ #ifdef DEBUG
+     printf(KRED "ERROR: SPI %d is not in the NONE state.\n" RESET, spi);
+ #endif
+     return CRYPTO_LIB_ERROR_SA;
+ }
 
  // Write SA Configuration
  temp_sa->est = ...

References

  • CCSDS 355.2-B-1 – SDLS Extended Procedures, §3.3.1 (SA Create state machine
    requirements)
  • CCSDS 355.0-B-2 – Space Data Link Security Protocol, §4 (SA state transitions)

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
Use the following packet sequence. Observe that **Packet 3** (SA Create for SPI
20) succeeds unconditionally even if SPI 20 already exists in any state other than
`SA_NONE`.
 
**Packet 1 – Key OTAR**

002c104c000000000102000000000000000000000000000000719405af7fcd82f5c1073e5c81455b28e37b2e8b4cada60ec40bd3eea8585e2fb2e22726654fed87b83a4a912feffdf35b9c1422

**Packet 2 – Key Activate**

002c100e0000000002001000828a33

**Packet 3 – SA Create (SPI 20) — send twice to demonstrate no state guard**

002c1046000000001101d00014cc001001010c00000000000000000000000001010020000000000000000000000000000000000000000000000000000000000000000000002384

1. Send Packet 1 and Packet 2 as prerequisites.
2. Send Packet 3 the first time — SPI 20 is created successfully (`sa_state = 0x1 UNKEYED`).
3. Advance SPI 20 to `OPERATIONAL` (Packets 4, 5 below).
4. Send **Packet 3 again** — SPI 20 is overwritten without error. An operational SA is
   silently replaced.
Screenshots

Logs

OS

Linux

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/sa/internal/sa_interface_inmemory.template.c near the SA Create handler and the lpid assignment around line 1458. Reproduce the issue with the Packet 1–3 sequence, including a second SA Create for SPI 20 after it becomes operational. Done means a non-NONE target is rejected and the existing SA remains unchanged; no test file is named, so inspect the relevant SA tests or harness for coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.