🐛 [BUG] - Implementation detail - SA setARSN and setARSNW Never Verify the Target SPI Was Actually Created (Only That It's In-Bounds)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 169
- Forks
- 67
- PR merge metrics
- No merged PRs in 30d
Description
Description
Bug Report: SA setARSN and setARSNW Never Verify the Target SPI Was Actually Created (Only That It's In-Bounds)
Summary
| Field | Value |
|---|---|
| Product | NASA CryptoLib (SDLS Protocol Implementation) |
| Version | 1.4.2 & dev - details are specific to v1.4.2 |
| Component | src/sa/internal/sa_interface_inmemory.template.c — sa_setARSN, sa_setARSNW |
| Issue | Both functions' only "does this SA exist" check is spi < NUM_SA — an array-bounds check, not an existence check — and neither ever consults sa[spi].sa_state, unlike every other SA-management operation in this file |
| Bug Type | Conformance |
| Severity | Minor |
| Impact | An ARSN/ARSNW update against an SPI that was never created (sa_create never called for it) is indistinguishable, from CryptoLib's perspective, from one against a genuinely-provisioned SA — and even for genuinely-provisioned SAs, no operational-state precondition is ever enforced, unlike sa_start/sa_stop/sa_rekey/sa_expire/sa_create, which all gate on sa_state |
Description
sa[] is a fixed-size, dense array (static SecurityAssociation_t sa[NUM_SA]) — every index
from 0 to NUM_SA-1 always physically "exists" as a struct, whether or not sa_create was
ever called for it. sa_setARSN/sa_setARSNW's only gate is spi < NUM_SA, an array-bounds
check. This conflates a condition in which an SPI inside the valid range whose slot was simply never provisioned to be able to complete this command.
Affected Code
sa_setARSN (src/sa/internal/sa_interface_inmemory.template.c:1667-1724)
// TODO: Add more checks on bounds <- CryptoLib's own comment acknowledging this gap
// Check SPI exists
if (spi < NUM_SA) // bounds check only, not an existence check
{
if ((sa[spi].est == 1 && sa[spi].ast == 1) || sa[spi].ast == 1)
{ /* ... no sa_state read anywhere in this function ... */ }
else { /* ... */ }
}
else { printf("sa_setARSN ERROR: SPI %d does not exist.\n", spi); }
return CRYPTO_LIB_SUCCESS;
sa_setARSNW (src/sa/internal/sa_interface_inmemory.template.c:1730-1775)
// Check SPI exists
if (spi < NUM_SA) // same bounds-only check
{
/* ... no sa_state read anywhere in this function ... */
}
else { printf("sa_setARSNW ERROR: SPI %d does not exist.\n", spi); }
return CRYPTO_LIB_SUCCESS;
Reproduction Sequence (from the fuzzing logs)
SPI in-bounds (63) but never actually created — CryptoLib treats this
identically to a legitimately-created-but-non-auth SA, because it has no sa_state/existence
check to tell the difference. Single frame, no prior SA Create in the sequence:
| # | Direction | Hex | Meaning |
|---|---|---|---|
| 1 | ground → flight | 002c100e000000001a0010003ffa32 |
TC frame, sg=0x1, pid=0xa (SA SetARSN), SPI 63, no prior SA Create for SPI 63 anywhere in this sequence |
TLV PDU
sg = 0x1
pid = 0xa
SA SetARSN
Failed setARSN on SPI 63, ECS 0, ACS 0
Status code: 0
| # | Direction | Hex | Meaning |
|---|---|---|---|
| 1 | ground → flight | 002c100e00000000150010003f9fcb |
TC frame, sg=0x1, pid=0x5 (SA SetARSNW), SPI 63, no prior SA Create for SPI 63 |
TLV PDU
sg = 0x1
pid = 0x5
SA setARSNW
spi = 63
ARSN set to: 0
Status code: 0
Discovered using the StratoFuzz protocol fuzzing framework.
Branch Name
dev
Reproduction steps
## Reproduction Sequence (from the fuzzing logs)
**SPI in-bounds (63) but never actually created** — CryptoLib treats this
identically to a legitimately-created-but-non-auth SA, because it has no `sa_state`/existence
check to tell the difference. Single frame, no prior `SA Create` in the sequence:
| # | Direction | Hex | Meaning |
|---|-----------|-----|---------|
| 1 | ground → flight | `002c100e000000001a0010003ffa32` | TC frame, `sg=0x1, pid=0xa` (SA SetARSN), SPI 63, no prior `SA Create` for SPI 63 anywhere in this sequence |
TLV PDU
sg = 0x1
pid = 0xa
SA SetARSN
Failed setARSN on SPI 63, ECS 0, ACS 0
Status code: 0
| # | Direction | Hex | Meaning |
|---|-----------|-----|---------|
| 1 | ground → flight | `002c100e00000000150010003f9fcb` | TC frame, `sg=0x1, pid=0x5` (SA SetARSNW), SPI 63, no prior `SA Create` for SPI 63 |
TLV PDU
sg = 0x1
pid = 0x5
SA setARSNW
spi = 63
ARSN set to: 0
Status code: 0
Screenshots
Logs
OS
Linux
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/sa/internal/sa_interface_inmemory.template.c at sa_setARSN and sa_setARSNW, then compare their checks with the neighboring SA-management operations that read sa_state. Reproduce the supplied SPI 63 sequences and inspect the resulting status codes. Done means an in-range SPI that was never created is distinguished from a provisioned SA and handled according to the existing SA-state rules.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100