Skip to content

sa_get_from_spi: reject SAs where shivf_len > iv_len (sibling of arsn/shsnf guard)#513

Open
nurdymuny wants to merge 1 commit into
nasa:devfrom
nurdymuny:fix/shivf-len-validation
Open

sa_get_from_spi: reject SAs where shivf_len > iv_len (sibling of arsn/shsnf guard)#513
nurdymuny wants to merge 1 commit into
nasa:devfrom
nurdymuny:fix/shivf-len-validation

Conversation

@nurdymuny

Copy link
Copy Markdown

Summary

Adds the parallel iv_len >= shivf_len invariant check to sa_get_from_spi alongside the existing arsn_len >= shsnf_len check on line 777. Without this, an SA loaded with shivf_len > iv_len makes the IV-walk loops at crypto_aos.c:318/351/697 and crypto_tc.c:331/631 start at a negative index and copy pre-iv struct bytes into every transmitted frame. Closes #512.

Diff

 include/crypto_error.h                           |  3 ++-
 src/core/crypto_error.c                          |  3 ++-
 src/sa/internal/sa_interface_inmemory.template.c | 13 +++++++++++++
 3 files changed, 17 insertions(+), 2 deletions(-)

The new error code is CRYPTO_LIB_ERR_SHIVF_LEN_GREATER_THAN_IV_LEN (-86), registered in both the header definition and the name-table in src/core/crypto_error.c (so Crypto_Get_Error_Code_Enum_String prints it correctly).

Tests

  • Constructed an inmemory SA with shivf_len=20, iv_len=12 (existing IV_SIZE allows shivf up to IV_SIZE so the existing sa_verify_data max check doesn't catch this), called sa_get_from_spi on that SPI; before this fix the lookup succeeds and Crypto_TC_ApplySecurity later leaks 8 bytes per frame; after this fix the lookup returns -86 (CRYPTO_LIB_ERR_SHIVF_LEN_GREATER_THAN_IV_LEN).
  • Existing test fixtures (where shivf_len <= iv_len) continue to pass.

Scope

The mariadb backend (src/sa/mariadb/sa_interface_mariadb.template.c) accepts the same SAs without checking either invariant. Adding the same two-line guard there is a good follow-up; left out of this PR to keep the change small.

Linked

Closes #512.

A Security Association loaded with shivf_len > iv_len causes every
per-frame IV walk of the form

    for (i = sa_ptr->iv_len - sa_ptr->shivf_len; i < sa_ptr->iv_len; i++)
        *(p_new_enc_frame + index_temp) = *(sa_ptr->iv + i);

(crypto_aos.c:318, 351, 697; crypto_tc.c:331, 631) to start at a
negative index. The loop then reads up to shivf_len bytes from before
sa_ptr->iv inside the SecurityAssociation_t struct and copies those
bytes into the transmitted frame. With the AOS / TC IV-walk loops
running on every authenticated/encrypted frame, that's a steady leak
of pre-iv struct fields into the channel.

sa_get_from_spi already enforces the sibling invariant
'arsn_len cannot be less than shsnf_len' immediately above this fix.
This commit adds the parallel 'iv_len cannot be less than shivf_len'
guard and a new CRYPTO_LIB_ERR_SHIVF_LEN_GREATER_THAN_IV_LEN (-86)
return code, registered in include/crypto_error.h and the names
table in src/core/crypto_error.c.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sa_get_from_spi missing shivf_len <= iv_len cross-field check (sibling of existing arsn/shsnf guard)

1 participant