Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions cuda_core/cuda/core/utils/_program_cache/_file_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,17 @@ def _path_for_key(self, key: object) -> Path:
k = _as_key_bytes(key)
# Hash the key to a fixed-length identifier so arbitrary-length user
# keys never exceed per-component filename limits (typically 255 on
# ext4 / NTFS). With a 256-bit blake2b digest, the cache relies on
# cryptographic collision resistance for key uniqueness -- two
# distinct keys hashing to the same path is astronomically unlikely
# (~2^-128 with the 32-byte digest in use here).
digest = hashlib.blake2b(k, digest_size=32).hexdigest()
# ext4 / NTFS).
#
# FIPS: must use a FIPS-approved hash algorithm. FIPS-enforcing
# systems can disable non-approved hashlib algorithms (for example
# blake2b) at the OpenSSL level. See #2043.
#
# With a 256-bit SHA-256 digest, the cache relies on collision
# resistance for key uniqueness -- two distinct keys hashing to the
# same path is astronomically unlikely (~2^128 practical collision
# work).
digest = hashlib.sha256(k, usedforsecurity=False).hexdigest()
return self._entries / digest[:2] / digest[2:]

# -- mapping API ---------------------------------------------------------
Expand Down
7 changes: 5 additions & 2 deletions cuda_core/cuda/core/utils/_program_cache/_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
)

# Bump when the key schema changes in a way that invalidates existing caches.
_KEY_SCHEMA_VERSION = 1
_KEY_SCHEMA_VERSION = 2

_VALID_CODE_TYPES = frozenset({"c++", "ptx", "nvvm"})
_VALID_TARGET_TYPES = frozenset({"ptx", "cubin", "ltoir"})
Expand Down Expand Up @@ -768,7 +768,10 @@ def make_program_cache_key(
option_bytes = backend.option_fingerprint(options, target_type)
name_tags = backend.encode_name_expressions(name_expressions)

hasher = hashlib.blake2b(digest_size=32)
# IMPORTANT: Must use a FIPS-approved hash algorithm (SHA-2 family).
# FIPS-enforcing systems can disable non-approved hashlib algorithms
# (for example blake2b) at the OpenSSL level. See #2043.
hasher = hashlib.sha256(usedforsecurity=False)

def _update(label: str, payload: bytes) -> None:
hasher.update(label.encode("ascii"))
Expand Down
2 changes: 1 addition & 1 deletion cuda_core/tests/test_program_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,7 @@ def test_filestream_cache_size_cap_counts_tmp_files(tmp_path):

def test_filestream_cache_handles_long_keys(tmp_path):
"""Arbitrary-length keys must not overflow per-component filename limits.
The filename is a fixed-length 256-bit blake2b digest; key uniqueness
The filename is a fixed-length 256-bit digest; key uniqueness
relies on the digest's collision resistance."""
from cuda.core.utils import FileStreamProgramCache

Expand Down
Loading