Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

πŸ› [BUG] - ACS Authentication (CMAC/HMAC) Unconditionally Calls gcry_mac_setiv, Which Those Algorithms Reject β€” Every Non-AEAD MAC Operation With a Non-Zero SA IV Fails Before the Tag Is Ever ComputedΒ #522

Copy link
Copy link

Description

@VissaMoutafis
Issue body actions

Description

Bug Report: ACS Authentication (CMAC/HMAC) Unconditionally Calls gcry_mac_setiv, Which Those Algorithms Reject β€” Every Non-AEAD MAC Operation With a Non-Zero SA IV Fails Before the Tag Is Ever Computed

Summary

Field Value
Product NASA CryptoLib (SDLS Protocol Implementation)
Version <=1.5.0
Component src/crypto/libgcrypt/cryptography_interface_libgcrypt.template.c β€” cryptography_authenticate, cryptography_validate_authentication
Issue Both functions unconditionally call gcry_mac_setiv() whenever the SA's iv_len > 0, but none of the three ACS algorithms CryptoLib actually maps to a libgcrypt MAC ID (CMAC-AES, HMAC-SHA256, HMAC-SHA512) accept an IV in libgcrypt β€” the call fails with GPG_ERR_INV_ARG before the MAC/tag is ever written or checked
Severity High
Impact Every non-AEAD authentication operation (cryptography_authenticate on encrypt, cryptography_validate_authentication on decrypt) β€” i.e. any SA_AUTHENTICATION or SA_AUTHENTICATED_ENCRYPTION SA using the ACS/CMAC-HMAC engine β€” fails outright whenever the SA is configured with iv_len > 0, which is a normal, unremarkable SA field. This makes the ACS authentication path functionally unusable for any SA that carries an IV, independent of whether the frame/MAC is otherwise valid.

Description

cryptography_authenticate (used by Crypto_TC_Encrypt/Crypto_TC_Do_Encrypt for SA_AUTHENTICATION) and cryptography_validate_authentication (used by Crypto_TC_Do_Decrypt for SA_AUTHENTICATION/SA_AUTHENTICATED_ENCRYPTION when the SA's cipher isn't AEAD) both contain the same pattern:

// If MAC needs IV, set it (only for certain ciphers)
if (iv_len > 0)
{
    gcry_error = gcry_mac_setiv(tmp_mac_hd, iv, iv_len);
    if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR)
    {
        printf(KRED "ERROR: gcry_mac_setiv error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK);
        printf(KRED "Failure: %s/%s\n", gcry_strsource(gcry_error), gcry_strerror(gcry_error));
        status = CRYPTO_LIB_ERROR;   // (CRYPTO_LIB_ERR_LIBGCRYPT_ERROR in the validate function)
        gcry_mac_close(tmp_mac_hd);
        return status;
    }
}

(cryptography_authenticate: src/crypto/libgcrypt/cryptography_interface_libgcrypt.template.c:172-184; cryptography_validate_authentication: :281-293)

The comment ("only for certain ciphers") shows the intent was to gate this on the specific MAC algorithm β€” but the code only checks iv_len > 0, never the algorithm itself. cryptography_get_acs_algo() (:950-973) maps CryptoLib's three supported AuthCipherSuite values to exactly these libgcrypt MAC IDs:

case CRYPTO_MAC_CMAC_AES256:  algo = GCRY_MAC_CMAC_AES;    break;  // libgcrypt ID 201
case CRYPTO_MAC_HMAC_SHA256:  algo = GCRY_MAC_HMAC_SHA256; break;  // libgcrypt ID 101
case CRYPTO_MAC_HMAC_SHA512:  algo = GCRY_MAC_HMAC_SHA512; break;  // libgcrypt ID 103

In libgcrypt, gcry_mac_setiv() is only meaningful for the GMAC family (GCRY_MAC_GMAC_*, IDs 4xx) and Poly1305 family (GCRY_MAC_POLY1305*, IDs 5xx) β€” algorithms that are keyed-nonce constructions. Plain HMAC (1xx) and CMAC (2xx) β€” the only algorithm families CryptoLib's ACS ever selects β€” take no IV at all; calling gcry_mac_setiv() on an HMAC or CMAC handle returns GPG_ERR_INV_ARG (libgcrypt error code 45). Since every CryptoLib SA carries an iv field and it is entirely normal for iv_len to be non-zero (e.g. for anti-replay/IV-tracking on the security header) regardless of which ACS algorithm is configured, this branch fires for essentially any real ACS-authenticated SA and aborts before gcry_mac_write/gcry_mac_read/gcry_mac_verify ever run β€” the actual MAC is never computed or checked.


Discovered using the StratoFuzz protocol fuzzing framework.

Branch Name

1.5.0

Reproduction steps

## Reproduction

Running a triage of a fuzz-generated packet sequence that triggers an `SA_AUTHENTICATED` SA rekey and start, then attempts to use it, produces the following logs:


~$ ./crypto_triage ~/BlindspotFuzz/fuzzer_output/dummy-test/mismatches/0:34:4:1717507963:0_MB_NC.pcap 
Key internal interface intialized 
Initializing Libgcrypt...
SA Written Successfully to file!
SA Written Successfully to file!
Crypto Lib Intialized.  Version 1.4.1.0
Extracted CCSDS Frame 1: 167 bytes
Extracted CCSDS Frame 2: 31 bytes
Extracted CCSDS Frame 3: 19 bytes
Extracted CCSDS Frame 4: 47 bytes
Processing packet 1/4 -> 002c10a6000000001104d0003f4c001001010c000000000000000000000000010200800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058f9

----- Crypto_TC_ProcessSecurity START -----
vcid = 4 
spi  = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 0 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 0 
         ek_ref     =  
         akid       = 0 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 0 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 0 
         ek_ref     =  
         akid       = 0 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
SA Index matches SPI
Processing a TC - CLEAR!
Crypto_Calc_FECF: 0x002c10a600, len_ingest = 165
0x002c10a6000000001104d0003f4c001001010c0000000000000000000000000102008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
In Crypto_Calc_FECF! fecf = 0x58f9
Received FECF is 0x58F9
Calculated FECF is 0x58F9
FECF was Calced over 165 bytes
Full IV Value from Frame and SADB (if applicable):

Full ARSN Value from Frame and SADB (if applicable):

TC PDU Calculated Length: 157 
Received SDLS command (No Packet Header or PUS): Current CCSDS in memory is: 
         Primary Header
                 pvn        = 0x0 
                 type       = 0x0 
                 shdr       = 0x0 
                 appID      = 0x000 
                 seq        = 0x0 
                 pktid      = 0x0000 
                 pkt_length = 0x3f4c 
         PUS Header
                 Config not configured for PUS Header, not printing
         TLV PDU 
                 type       = 0x0 
                 uf         = 0x0 
                 sg         = 0x1 
                 pid        = 0x1 
                 pdu_len    = 0x04d0 
                 data[0]    = 0x00 
                 data[1]    = 0x3f 
                 data[2]    = 0x4c 

SA Create
spi = 63 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 63 
         sa_state   = 0x0 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 63 
         ek_ref     =  
         akid       = 63 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
SA status: 
         spi   = 63 
         sa_state   = 0x1 
         est        = 0x0 
         ast        = 0x1 
         shivf_len  = 12 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 16 
         ecs_len    = 1 
         ecs[0]     = 0x01 
         ekid       = 63 
         ek_ref     =  
         akid       = 63 
         ak_ref     =  
         iv_len     = 12 
         iv[0]      = 0x00 
         iv[1]      = 0x00 
         iv[2]      = 0x00 
         iv[3]      = 0x00 
         iv[4]      = 0x00 
         iv[5]      = 0x00 
         iv[6]      = 0x00 
         iv[7]      = 0x00 
         iv[8]      = 0x00 
         iv[9]      = 0x00 
         iv[10]      = 0x00 
         iv[11]      = 0x00 
         acs_len    = 1 
         acs        = 0x02 
         abm_len    = 128 
         abm        = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
Status code: 0
Processing packet 2/4 -> 002c101e00000000160090003f00820082000000000000000000000000551f

----- Crypto_TC_ProcessSecurity START -----
vcid = 4 
spi  = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 0 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 0 
         ek_ref     =  
         akid       = 0 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 0 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 0 
         ek_ref     =  
         akid       = 0 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
SA Index matches SPI
Processing a TC - CLEAR!
Crypto_Calc_FECF: 0x002c101e00, len_ingest = 29
0x002c101e00000000160090003f00820082000000000000000000000000
In Crypto_Calc_FECF! fecf = 0x551f
Received FECF is 0x551F
Calculated FECF is 0x551F
FECF was Calced over 29 bytes
Full IV Value from Frame and SADB (if applicable):

Full ARSN Value from Frame and SADB (if applicable):

TC PDU Calculated Length: 21 
Received SDLS command (No Packet Header or PUS): Current CCSDS in memory is: 
         Primary Header
                 pvn        = 0x0 
                 type       = 0x0 
                 shdr       = 0x0 
                 appID      = 0x000 
                 seq        = 0x0 
                 pktid      = 0x0000 
                 pkt_length = 0x3f00 
         PUS Header
                 Config not configured for PUS Header, not printing
         TLV PDU 
                 type       = 0x0 
                 uf         = 0x0 
                 sg         = 0x1 
                 pid        = 0x6 
                 pdu_len    = 0x0090 
                 data[0]    = 0x00 
                 data[1]    = 0x3f 
                 data[2]    = 0x00 

SA Rekey
SPI 63 IV updated to: 0x000000000000000000000000
SPI 63 changed to KEYED state with encrypted Key ID 130. 
         spi  = 63 
         ekid = 130 
Status code: 0
Processing packet 3/4 -> 002c1012000000001b0030003f00002c040ac0

----- Crypto_TC_ProcessSecurity START -----
vcid = 4 
spi  = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 0 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 0 
         ek_ref     =  
         akid       = 0 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 0 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x0 
         shivf_len  = 0 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 0 
         ecs_len    = 0 
         ekid       = 0 
         ek_ref     =  
         akid       = 0 
         ak_ref     =  
         iv_len     = 0 
         iv        =  
         acs_len    = 0 
         acs        = 0x00 
         abm_len    = 0 
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
SA Index matches SPI
Processing a TC - CLEAR!
Crypto_Calc_FECF: 0x002c101200, len_ingest = 17
0x002c1012000000001b0030003f00002c04
In Crypto_Calc_FECF! fecf = 0x0ac0
Received FECF is 0x0AC0
Calculated FECF is 0x0AC0
FECF was Calced over 17 bytes
Full IV Value from Frame and SADB (if applicable):

Full ARSN Value from Frame and SADB (if applicable):

TC PDU Calculated Length: 9 
Received SDLS command (No Packet Header or PUS): Current CCSDS in memory is: 
         Primary Header
                 pvn        = 0x0 
                 type       = 0x0 
                 shdr       = 0x0 
                 appID      = 0x000 
                 seq        = 0x0 
                 pktid      = 0x0000 
                 pkt_length = 0x3f00 
         PUS Header
                 Config not configured for PUS Header, not printing
         TLV PDU 
                 type       = 0x0 
                 uf         = 0x0 
                 sg         = 0x1 
                 pid        = 0xb 
                 pdu_len    = 0x0030 
                 data[0]    = 0x00 
                 data[1]    = 0x3f 
                 data[2]    = 0x00 

SA Start

Parsed GVCID: 1
        MAPID: 4
SPI 63 changed to OPERATIONAL state. 
Type Unknown,   MAPID: 0
SPI 63 changed to OPERATIONAL state. 
Type TC,         spi = 63 
Status code: 0
Processing packet 4/4 -> 002c102e0000003f000000000000000000000000ff09c6bbf37c10202ea58487a7a07a5627dc54d1ebaaa0290dd7a1

----- Crypto_TC_ProcessSecurity START -----
vcid = 4 
spi  = 63 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 63 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x1 
         shivf_len  = 12 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 16 
         ecs_len    = 1 
         ecs[0]     = 0x01 
         ekid       = 130 
         ek_ref     =  
         akid       = 130 
         ak_ref     =  
         iv_len     = 12 
         iv[0]      = 0x00 
         iv[1]      = 0x00 
         iv[2]      = 0x00 
         iv[3]      = 0x00 
         iv[4]      = 0x00 
         iv[5]      = 0x00 
         iv[6]      = 0x00 
         iv[7]      = 0x00 
         iv[8]      = 0x00 
         iv[9]      = 0x00 
         iv[10]      = 0x00 
         iv[11]      = 0x00 
         acs_len    = 1 
         acs        = 0x02 
         abm_len    = 128 
         abm        = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
DEBUG - Printing local copy of SA Entry for current SPI.
SA status: 
         spi   = 63 
         sa_state   = 0x3 
         est        = 0x0 
         ast        = 0x1 
         shivf_len  = 12 
         shsnf_len  = 0 
         shplf_len  = 0 
         stmacf_len = 16 
         ecs_len    = 1 
         ecs[0]     = 0x01 
         ekid       = 130 
         ek_ref     =  
         akid       = 130 
         ak_ref     =  
         iv_len     = 12 
         iv[0]      = 0x00 
         iv[1]      = 0x00 
         iv[2]      = 0x00 
         iv[3]      = 0x00 
         iv[4]      = 0x00 
         iv[5]      = 0x00 
         iv[6]      = 0x00 
         iv[7]      = 0x00 
         iv[8]      = 0x00 
         iv[9]      = 0x00 
         iv[10]      = 0x00 
         iv[11]      = 0x00 
         acs_len    = 1 
         acs        = 0x02 
         abm_len    = 128 
         abm        = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
         arsn_len    = 0 
         arsnw_len   = 0 
         arsnw       = 0 
SA Index matches SPI
CRYPTO IS AEAD? : TRUE
Processing a TC - AUTHENTICATED!
Crypto_Calc_FECF: 0x002c102e00, len_ingest = 45
0x002c102e0000003f000000000000000000000000ff09c6bbf37c10202ea58487a7a07a5627dc54d1ebaaa0290d
In Crypto_Calc_FECF! fecf = 0xd7a1
Received FECF is 0xD7A1
Calculated FECF is 0xD7A1
FECF was Calced over 45 bytes
Full IV Value from Frame and SADB (if applicable):
000000000000000000000000
Full ARSN Value from Frame and SADB (if applicable):

MAC Parsed from Frame:
a58487a7a07a5627dc54d1ebaaa0290d
AAD before ABM Bitmask:
        002c102e0000003f000000000000000000000000ff09c6bbf37c10202e
Preparing AAD:
        Using AAD Length of 29
        0000000000000000000000000000000000000000000000000000000000
TC PDU Calculated Length: 9 
Validate MAC Printing Key:
	FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210
ERROR: gcry_mac_setiv error code 45
Failure: gcrypt/Invalid argument
MC_Log: Error, [2026713,12:26:18], -1
Status code: -1


Frame 4's SA (SPI 63) is `est=0x0, ast=0x1, acs=0x02 (CRYPTO_MAC_HMAC_SHA256), ekid=akid=130, iv_len=12` β€” with the routing bug fixed, `cryptography_validate_authentication` is confirmed reached (the "Validate MAC Printing Key" trace only exists in that function) and picks the correct HMAC-SHA256 key. But it never gets as far as `gcry_mac_write`/`gcry_mac_verify`: `gcry_mac_setiv(tmp_mac_hd, iv, 12)` on an HMAC-SHA256 handle immediately fails with libgcrypt error code 45 (`GPG_ERR_INV_ARG`, "Invalid argument"), and the function returns `CRYPTO_LIB_ERROR` (-1) before the actual tag comparison ever happens.

Screenshots

Logs

OS

Linux

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.