Sceawere
Vulnerability Detail
CVE-2026-15890UPDATED Verified Sceawere Triage Sources: NVD / CISA KEV
Zephyr ITS AEAD Nonce Race
Vulnerability Metadata
- Severity
- Medium
- Score / CVSS
- 5.3
- Creation Date
- 4h ago
- Vendor
- zephyrproject
- Product
- zephyr
- Attack Type
- crypto
- Vector String
- CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:N
- Attack Complexity
- HIGH
Narrative and Response
Description
The default AEAD nonce provider for the PSA Internal Trusted Storage transform module, secure_storage_its_transform_aead_get_nonce() in subsys/secure_storage/src/its/transform/aead_get.c, stores its nonce counter in unsynchronized function-local static variables (s_nonce and s_nonce_initialized). Every ITS write obtains its AES-GCM or ChaCha20-Poly1305 nonce here via secure_storage_its_transform_to_store(). Because the function held no lock, two threads calling it concurrently race on the shared statics: the initialization path (psa_generate_random() followed by memcpy()) and the non-atomic increment-then-copy path can each hand the same nonce value to two distinct encryption operations, and can lose increments so the counter repeats values it was designed never to repeat. The ITS layer (secure_storage_its_set() in subsys/secure_storage/src/its/implementation.c) performs no serialization of its own, so concurrent same-UID writes reach the racy provider directly. Reusing a nonce with the same key under AES-GCM or ChaCha20-Poly1305 is a catastrophic AEAD failure: it leaks the XOR of the two plaintexts (ITS routinely stores secrets, including PSA persistent keys) and, for GCM, exposes the authentication key, enabling forgery of stored entries. Because the AEAD key is derived per entry UID, the security-relevant collision is two concurrent writes to the same UID both receiving the same nonce; an adversary able to read the raw backing storage can then exploit the reuse. Both ITS store back-ends shipped with Zephyr, zms.c and the settings/NVS back-end in settings.c, are log-structured flash stores with deferred garbage collection, so an entry superseded by a rewrite remains physically present in the partition until its sector is reclaimed. Two same-UID writes that race therefore leave both ciphertexts readable in the raw image at once, which is the condition the nonce reuse needs to be exploitable. The trigger remains narrow: both built-in key providers (DEVICE_ID_HASH and ENTRY_UID_HASH) salt the derived key with the entry UID, so reuse across different UIDs is harmless, and the exposure requires an application that writes the same UID concurrently from two threads. The fix serializes the provider with a K_MUTEX_DEFINE(s_nonce_mutex) held for the duration of nonce generation.
Executive Summary
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Technical Details
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Mitigations
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
References
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Additional Metadata
{
"score": "5.3",
"pubDate": "2026-09-21T22:16:56.143Z",
"pubdate": "2026-09-21T22:16:56.143Z",
"executiveSummary": "A critical thread-safety vulnerability exists in the PSA Internal Trusted Storage (ITS) transform module of the Zephyr RTOS. The function secure_storage_its_transform_aead_get_nonce() utilizes unsynchronized static variables to manage nonce counters, leading to race conditions during concurrent ITS write operations.\nThis flaw enables nonce reuse for AES-GCM or ChaCha20-Poly1305 encryption when the same Unique Identifier (UID) is written to simultaneously from multiple threads. Nonce reuse in these AEAD algorithms constitutes a catastrophic security failure, potentially leading to plaintext recovery via XOR analysis and authentication key leakage.\nThe vulnerability affects Zephyr's ITS implementation, specifically within systems utilizing log-structured flash stores like zms.c or settings/NVS. Exploitation requires an attacker to trigger concurrent writes to the same UID. Successful exploitation allows for the compromise of sensitive persistent keys or data stored within the ITS partition. The risk is high for multi-threaded applications performing frequent updates to identical storage entries.",
"technicalDetails": "The root cause of the vulnerability is the lack of synchronization in the secure_storage_its_transform_aead_get_nonce() function located in subsys/secure_storage/src/its/transform/aead_get.c. The function relies on function-local static variables (s_nonce and s_nonce_initialized) to maintain state across successive calls. Because these variables are not protected by a mutex or semaphore, concurrent access from multiple threads results in race conditions.\nDuring the initialization path, two threads may execute psa_generate_random() and the subsequent memcpy() simultaneously, leading to redundant initialization. More critically, the non-atomic increment-and-copy sequence allows two threads to retrieve the same nonce value. Since the ITS layer (subsys/secure_storage/its/implementation.c) performs no serialization, concurrent calls to secure_storage_its_set() targeting the same UID propagate this race directly to the nonce provider.\nThe exploit relies on the nature of the storage back-ends (zms.c and NVS). These are log-structured and deferred garbage collection systems. When two same-UID writes occur, both ciphertexts are physically persisted in the flash memory simultaneously until garbage collection occurs. An attacker with access to the raw flash partition can observe both ciphertexts. Because the underlying AEAD construction uses the same derived key for a specific UID, the use of identical nonces enables the recovery of the XOR sum of the plaintexts.\nIn the case of AES-GCM, nonce reuse further exposes the internal authentication subkey, which allows an adversary to forge arbitrary entries in the ITS storage. While the vulnerability is limited by the fact that keys are salted with the UID (preventing cross-UID impacts), any application architecture that allows multi-threaded writes to the same storage handle is highly vulnerable. The lack of locking mechanisms in the ITS transform layer effectively breaks the cryptographic integrity guarantees expected of the PSA storage module, rendering the stored sensitive data susceptible to decryption and integrity compromise."
}