Skip to content

prototype(azure_execution_binding): bind HCLAkPub exponent e and key size, reject duplicate JSON keys, and harden _secure_boot_state and authenticode_sha256 #613

Open

Description

@drk-ram

What is wrong

At main (a8e3559), prototype/azure_execution_binding.py has four security and input-validation bugs:

  1. authenticate_ak checks only the RSA modulus n of HCLAkPub and ignores kty, e, and key size (GHSA-vwq2 exponent-mismatch class):

    • In prototype/azure_execution_binding.py:466-492, authenticate_ak reads keys[0]["n"] from HCLAkPub, compares if modulus != ak.public_numbers().n: raise ExecutionDenied("ak_not_hcl_bound"), and returns ak (loaded from attacker-supplied packet["ak_pem"]).
    • It never checks keys[0].get("kty") == "RSA", never decodes or validates keys[0]["e"] as a canonical Base64urlUInt, never requires exponent == 65537 and modulus.bit_length() >= 2048, and never checks ak.public_numbers().e == exponent.
    • Supplying an ak_pem with the same modulus n as HCLAkPub and a different public exponent e (e.g., e=3), or an HCLAkPub with a non-RSA kty, weak exponent, or < 2048-bit modulus, passes authenticate_ak.
  2. authenticate_ak and _runtime_claims accept duplicate JSON object keys in HCL runtime JSON:

    • authenticate_ak (line 467) and _runtime_claims (line 512) call json.loads(...) without an object_pairs_hook to reject duplicate keys, unlike execution_appraisal.py, tdx_collateral.py, and verifier_token.py.
  3. _secure_boot_state leaks struct.error / UnicodeDecodeError and accepts truncated variable payloads:

    • In prototype/azure_execution_binding.py:207-218, _secure_boot_state calls name_len, data_len = struct.unpack_from("<QQ", event.data, 16) and event.data[32 : 32 + 2 * name_len].decode("utf-16-le") without checking len(event.data) >= 32 or 32 + 2 * name_len + data_len <= len(event.data) and without catching (struct.error, UnicodeDecodeError) as ExecutionDenied. When data_len exceeds the remaining bytes and 1 byte \x01 follows SecureBoot, Python's slice event.data[32 + 2 * name_len : 32 + 2 * name_len + data_len] silently truncates to b"\x01" and returns True.
  4. authenticode_sha256 leaks struct.error / TypeError on non-bytes or truncated PE images instead of raising ValueError.

Reproduction on a8e3559:

import hashlib, struct
from prototype import azure_execution_binding as aeb

# 1. Truncated SecureBoot UEFI variable event with data_len=9999 and 1 trailing byte b'\x01' passes:
name_utf16 = "SecureBoot".encode("utf-16-le")
data = b"\x00" * 16 + struct.pack("<QQ", len("SecureBoot"), 9999) + name_utf16 + b"\x01"
ev = aeb.UefiEvent(pcr=7, event_type=aeb.EV_EFI_VARIABLE_DRIVER_CONFIG, sha256=hashlib.sha256(data).digest(), data=data)
assert aeb._secure_boot_state([ev]) is True

# 2. Short event data (< 32 bytes) raises raw struct.error instead of ExecutionDenied:
bad_data = b"\x00" * 20
bad_ev = aeb.UefiEvent(pcr=7, event_type=aeb.EV_EFI_VARIABLE_DRIVER_CONFIG, sha256=hashlib.sha256(bad_data).digest(), data=bad_data)
aeb._secure_boot_state([bad_ev])  # raises struct.error

Spec section or file

  • prototype/azure_execution_binding.py (authenticate_ak, _runtime_claims, _secure_boot_state, authenticode_sha256)

Expected behavior

  1. authenticate_ak requires keys[0].get("kty") == "RSA", decodes keys[0]["e"] as a canonical Base64urlUInt, requires exponent == 65537 and modulus.bit_length() >= 2048, and verifies (ak.public_numbers().n, ak.public_numbers().e) == (modulus, exponent).
  2. authenticate_ak and _runtime_claims reject duplicate JSON object keys in HCL runtime JSON with ExecutionDenied.
  3. _secure_boot_state validates len(event.data) >= 32 and 32 + 2 * name_len + data_len <= len(event.data) (requiring exact data_len bytes) and catches (struct.error, UnicodeDecodeError) as ExecutionDenied("secure_boot_state").
  4. authenticode_sha256 validates isinstance(image, bytes) and PE header/section bounds, raising ValueError on malformed inputs.

Impact

An attacker-supplied ak_pem with a mismatched public exponent e (or a truncated PCR 7 SecureBoot variable event) is accepted by azure_execution_binding.

Activity

  1. github-actions commented on Oct 23, 2026

    @github-actions
    Contributor

    🟡 Contributor Check: MEDIUM

    Check Result
    Profile MEDIUM
    Credential LOW
    Overall MEDIUM

    Automated check by AgenTrust Contributor Check.

  2. added 3 commits that reference this issue on Oct 24, 2026
    d33ab87
    abcb526
    5ab7fbc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions