[rlc-10/6.12.0-211.47.1.el10_2] Multiple patches tested (26 commits) - #1556
Open
ciq-kernel-automation[bot] wants to merge 26 commits into
Open
Conversation
commit - commit-source https://build.opensuse.org/public/source/SUSE:SLE-15-SP6:GA/kernel-source/patches.suse.tar.bz2 commit-patch-path patches.suse/crypto-ecdh-implement-FIPS-PCT.patch SP800-56Arev3, 5.6.2.1.4 ("Owner Assurance of Pair-wise Consistency") requires that a pair-wise consistency check needs to be conducted on a keypair. A pair-wise consistency test (PCT) is meant to ensure that a some provided public key is indeed associated with the given private one. As the kernel's ECDH implementation always computes the public key from the private one, this is guaranteed already as per the API. However, in the course of the certification process, there had been a lengthy discussion regarding this topic, with the result that a PCT is nonetheless mandatory. As the only user of the in-kernel ECDH is bluetooth, performance certainly isn't super critical. Simply implement a PCT for ECDH and move on. As mandated by SP800-56Arev3, 5.6.2.1.4, the PCT involves recomputing the public key and comparing it against the one under test. Signed-off-by: Nicolai Stange <nstange@suse.de> Signed-off-by: Jeremy Allison <jallison@ciq.com>
In essiv_aead_setkey(), use the same logic as crypto_authenc_esn_setkey() to zeroize keys on exit. [Sultan: touched up commit message] Signed-off-by: Jason Rodriguez <jrodriguez@ciq.com>
None of the ciphers used by the DRBG have an alignment requirement; thus, they all return 0 from .crypto_init, resulting in inconsistent alignment across all buffers. Align all buffers to at least a cache line to improve performance. This is especially useful when multiple DRBG instances are used, since it prevents false sharing of cache lines between the different instances. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Like pin_user_pages_fast(), but with the internal-only FOLL_FAST_ONLY flag. This complements the get_user_pages*() API, which already has get_user_pages_fast_only(). Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
There is no reason this refcount should be a signed int. Convert it to an unsigned int, thereby also making it less likely to ever overflow. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Since crypto_devrandom_read_iter() is invoked directly by user tasks and is accessible by every task in the system, there are glaring priority inversions on crypto_reseed_rng_lock and crypto_default_rng_lock. Tasks of arbitrary scheduling priority access crypto_devrandom_read_iter(). When a low-priority task owns one of the mutex locks, higher-priority tasks waiting on that mutex lock are stalled until the low-priority task is done. Fix the priority inversions by converting the mutex locks into rt_mutex locks which have PI support. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
The kernel has two SHA-1 code paths: the crypto API (crypto/sha1_generic.c), which is covered by testmgr's FIPS self-tests at algorithm registration time, and the library implementation (lib/crypto/sha1.c), which provides sha1_init() and sha1_transform() directly to in-kernel callers that bypass the crypto API entirely. When booting with fips=1, the library path was not independently validated, meaning any corruption or miscompilation of the lib/crypto SHA-1 code would go undetected. This is a gap in FIPS 140 coverage since several subsystems use the library functions directly. Add a known answer test that runs at subsys_initcall time when CONFIG_CRYPTO_FIPS is enabled and fips_enabled is set. The test computes SHA-1 over the NIST one-block test message "abc" (pre-padded to a full 64-byte SHA-1 input block) using the library's own sha1_init() and sha1_transform() functions, and compares the result against the known digest a9993e364706816aba3e25717850c26c9cd0d89d. On mismatch the kernel panics, consistent with FIPS 140 self-test failure handling elsewhere in the tree (e.g. the 6.18 HMAC-SHA-1 KAT in the same file and DRBG self-tests in crypto/). The test vector data and expected digest are marked __initconst so they are freed after boot, and the workspace buffer is scrubbed with memzero_explicit() after use. No header, Kconfig, or Makefile changes are required: SHA1_BLOCK_SIZE, SHA1_DIGEST_WORDS, and SHA1_WORKSPACE_WORDS are already provided by include/crypto/sha1.h, and CONFIG_CRYPTO_FIPS already exists in crypto/Kconfig. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The kernel has two SHA-256 code paths: the crypto API (crypto/sha256_generic.c), which is covered by testmgr's FIPS self-tests at algorithm registration time, and the library implementation (lib/crypto/sha256.c), which provides sha256_init(), sha256_update(), sha256_final(), and the sha256() one-shot function directly to in-kernel callers that bypass the crypto API entirely. When booting with fips=1, the library path was not independently validated, meaning any corruption or miscompilation of the lib/crypto SHA-256 code would go undetected. This is a gap in FIPS 140 coverage since several subsystems use the library functions directly. Add a known answer test that runs at subsys_initcall time when CONFIG_CRYPTO_FIPS is enabled and fips_enabled is set. The test uses the sha256() one-shot function to hash the NIST one-block test message "abc", exercising the full sha256_init/update/final path including the underlying sha256_transform compression function. The result is compared against the known digest ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad. On mismatch the kernel panics, consistent with FIPS 140 self-test failure handling elsewhere in the tree. Unlike the SHA-1 library KAT (which could only test the raw transform since the 6.12 lib/crypto/sha1.c lacks update/final), this test covers the complete hash pipeline including padding and finalization logic. The test vector data and expected digest are marked __initconst so they are freed after boot. No header, Kconfig, or Makefile changes are required. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
commit-author Joachim Vandersmissen <git@jvdsn.com> commit - commit-source https://lore.kernel.org/linux-crypto/20260303060509.246038-1-git@jvdsn.com/ xxhash64 is not a cryptographic hash algorithm, but is offered in the same API (shash) as actual cryptographic hash algorithms such as SHA-256. The Cryptographic Module Validation Program (CMVP), managing FIPS certification, believes that this could cause confusion. xxhash64 must therefore be blocked in FIPS mode. The only usage of xxhash64 in the kernel is btrfs. Commit fe11ac1 ("btrfs: switch to library APIs for checksums") recently modified the btrfs code to use the lib/crypto API, avoiding the Kernel Cryptographic API. Consequently, the removal of xxhash64 from the Crypto API in FIPS mode should now have no impact on btrfs usage. Signed-off-by: Joachim Vandersmissen <git@jvdsn.com> Signed-off-by: Jeremy Allison <jallison@ciq.com>
Requested by the lab. Signed-off-by: Jeremy Allison <jallison@ciq.com>
Requested by the lab. Signed-off-by: Jeremy Allison <jallison@ciq.com>
…the digest to be generated - it must be at least 112 bits. Requested by the lab. Signed-off-by: Jeremy Allison <jallison@ciq.com>
When FIPS mode is enabled (via fips=1), there is an absolute need for the
DRBG to be available. This is at odds with the fact that the DRBG can be
built as a module when in FIPS mode, leaving critical RNG functionality at
the whims of userspace.
Userspace could simply rmmod the DRBG module, or not provide it at all and
thus a different stdrng algorithm could be used without anyone noticing.
Additionally, when running a FIPS-enabled userspace, modprobe itself may
perform a getrandom() syscall _before_ loading a given module. As a result,
there's a possible deadlock scenario where the RNG core (crypto/rng.c)
initializes _before_ the DRBG, thereby installing its getrandom() override
without having an stdrng algorithm available. Then, when userspace calls
getrandom() which redirects to the override in crypto/rng.c,
crypto_alloc_rng("stdrng") invokes the UMH (modprobe) to load the DRBG
(which is aliased to stdrng). And *then* that modprobe invocation gets
stuck at getrandom() because there's no stdrng algorithm available!
There are too many risks that come with allowing the DRBG and RNG core to
be modular for FIPS mode. Therefore, make CRYPTO_FIPS require the DRBG to
be built-in, which in turn makes the DRBG require the RNG core to be
built-in. That way, it's guaranteed for these drivers to be built-in when
running in FIPS mode.
Also clean up the CRYPTO_FIPS option name and remove the CRYPTO_ANSI_CPRNG
dependency since it's obsolete for FIPS now.
Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
Signed-off-by: Jeremy Allison <jallison@ciq.com>
commit c0d3672 upstream. Ensure that set_ent is always set since only drbg provides it. Fixes: 77ebdab ("crypto: af_alg - add extra parameters for DRBG interface") Reported-by: Yiqi Sun <sunyiqixm@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
commit-author Herbert Xu <herbert.xu@redhat.com> commit 8b0beca705b3877e24cccdd672422c66bbd75635 commit-source https://gitlab.com/cki-project/kernel-ark Upstream Status: RHEL only Restore the changes to use the crypto RNG in drivers/char/random which were reverted after 5.18. This reverts commit 297bcb88233101e8d5062729ff3a5f989bad1c3b. This also brings the code up-to-date with respect to centos-stream commit 9de3a73 so that changes that were made after the kernel-ark revert have been brought in. Signed-off-by: Herbert Xu <herbert.xu@redhat.com> Signed-off-by: Jeremy Allison <jallison@ciq.com>
When the kernel is booted with fips=1, the RNG exposed to userspace is hijacked away from the CRNG and redirects to crypto_devrandom_read_iter(), which utilizes the DRBG. Notably, crypto_devrandom_read_iter() maintains just two global DRBG instances _for the entire system_, and the two instances serve separate request types: one instance for GRND_RANDOM requests (crypto_reseed_rng), and one instance for non-GRND_RANDOM requests (crypto_default_rng). So in essence, for requests of a single type, there is just one global RNG for all CPUs in the entire system, which scales _very_ poorly. To make matters worse, the temporary buffer used to ferry data between the DRBG and userspace is woefully small at only 256 bytes, which doesn't do a good job of maximizing throughput from the DRBG. This results in lost performance when userspace requests >256 bytes; it is observed that DRBG throughput improves by 70% on an i9-13900H when the buffer size is increased to 4096 bytes (one page). Going beyond the size of one page up to the DRBG maximum request limit of 65536 bytes produces diminishing returns of only 3% improved throughput in comparison. And going below the size of one page produces progressively less throughput at each power of 2: there's a 5% loss going from 4096 bytes to 2048 bytes and a 9% loss going from 2048 bytes to 1024 bytes. Thus, this implements per-CPU DRBG instances utilizing a page-sized buffer for each CPU to utilize the DRBG itself more effectively. On top of that, for non-GRND_RANDOM requests, the DRBG's operations now occur under a local lock that disables preemption on non-PREEMPT_RT kernels, which not only keeps each CPU's DRBG instance isolated from another, but also improves temporal cache locality while the DRBG actively generates a new string of random bytes. Prefaulting one user destination page at a time is also employed to prevent a DRBG instance from getting blocked on page faults, thereby maximizing the use of the DRBG so that the only bottleneck is the DRBG itself. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
It is technically a risk to permit extrng registration by modules after kernel init completes. Since there is only one user of the extrng interface and it is imperative that it is the _only_ registered extrng for FIPS compliance, restrict the extrng registration interface to only permit registration during kernel init and only from built-in drivers. This also eliminates the risks associated with the extrng interface itself being designed to solely accommodate a single registration, which would therefore permit the registered extrng to be overridden or even removed by an unrelated module. Signed-off-by: Sultan Alsawaf <sultan@ciq.com> Signed-off-by: Jonathan Maple <jmaple@ciq.com>
In FIPS mode, the DRBG must take precedence over all stdrng algorithms. The only problem standing in the way of this is that a different stdrng algorithm could get registered and utilized before the DRBG is registered, and since crypto_alloc_rng() only allocates an stdrng algorithm when there's no existing allocation, this means that it's possible for the wrong stdrng algorithm to remain in use indefinitely. This issue is also often impossible to observe from userspace; an RNG other than the DRBG could be used somewhere in the kernel and userspace would be none the wiser. To ensure this can never happen, only allow stdrng instances from the DRBG to be registered when running in FIPS mode. This works since the previous commit forces the DRBG to be built into the kernel when CONFIG_CRYPTO_FIPS is enabled, so the DRBG's presence is guaranteed when fips_enabled is true. Signed-off-by: Sultan Alsawaf <sultan@ciq.com> Signed-off-by: Jonathan Maple <jmaple@ciq.com>
The 6.18.y version of "crypto: rng - Implement fast per-CPU DRBG instances" picked up a few spots that use spaces where the ciqlts9_6 tree's version [1] uses tabs: the lock_default_rng() comment's numbered list, the line continuations in the unlock_local_rng() macro, and a brace in crypto_devrandom_read_iter(). A nearby block comment was also missing the space before its '*'. Fix them up. [1] b0c560a Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
The per-CPU DRBG instances used to be torn down by crypto_del_default_rng() under del_pcpu_rwsem, and the read path took that rwsem as a reader to keep an instance from being freed out from under it. That machinery only made sense back when the extrng override could be unregistered and the DRBG could be built as a module. That's no longer the case. extrng registration is now restricted to init time from built-in drivers, and FIPS mode requires the DRBG to be built-in, so the registered DRBG can't be unregistered or swapped out. As such, the per-CPU instances are never torn down, and the deletion rwsem just adds a lock to the hot read path for no reason. Drop the deletion rwsem and crypto_del_pcpu_rng(), and stop freeing the per-CPU instances in crypto_del_default_rng(). Since the instances are permanent now, allocate their pages once at init time with __GFP_NOFAIL and ditch free_pcpu_inst() along with the failure paths in crypto_rng_init(); failing to install the RNG override in FIPS mode would be catastrophic, so the setup isn't allowed to fail anyway. This brings the per-CPU DRBG implementation in line with the ciqlts9_6 tree's version of "crypto: rng - Implement fast per-CPU DRBG instances" [1]. [1] b0c560a Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
The fast per-CPU DRBG path computes its initial user destination address
straight from the iov_iter. For an ITER_IOVEC iter it reads iter_iov_addr()
and iter_iov_len() of the current segment, but when the iovec leads with
one or more zero-length segments, the current segment is one of those empty
entries. iter_iov_addr() then hands back the base of an empty segment,
which is whatever userspace put there: its base can be NULL or some other
unwritable address, since a zero-length segment is never actually touched.
Right after the setup, that address is prefaulted, and on a bogus base it
fails. A failed prefault on the very first address is treated as fatal, so
the whole read bails out to -EFAULT even though there are perfectly good
non-empty segments later in the iovec. This is reachable with something as
simple as readv() on /dev/urandom where the first iovec entry is {NULL, 0}.
Fix it by advancing the iterator by zero before reading the first address.
The iovec advance loop walks past every leading empty segment and stops at
the first non-empty one, and there's guaranteed to be such a segment
because iov_iter_count() is nonzero at this point. Empty segments that crop
up mid-stream are already skipped by the per-copy advance, so this only
needs to run once during setup.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
While GUP pinning makes it possible to pin the page _backing_ a user address, it *doesn't* pin the page table entry (PTE) for that mapping. This means the pinned physical page can be separated from the user address it was backing, and even back a _different_ user address within the same process. PTE zapping naturally happens during memory reclaim when memory pressure is elevated, and can even be done directly by userspace via madvise(MADV_DONTNEED). Since the optimized per-CPU DRBG loop assumes copy_to_user_nofault() will always succeed on a GUP-pinned page, it immediately bails out when the nofault copy actually *does* fail for the reasons described above. This results in either fewer than requested random bytes copied or, more seriously, a spurious EFAULT returned to userspace when no random bytes were copied. As it turns out, there's no way to pin a PTE. That means it's not possible to guarantee a 100% success rate for the copy_to_user_nofault() attempt. Fix this by handling copy_to_user_nofault() errors correctly with a fall back to a faultable copy attempt outside of the RNG lock. In order to guarantee forward progress for the caller, an on-stack bounce buffer is used to copy up to 256 bytes of the generated random bytes whenever this happens rather than discarding the whole thing. There's no need to use GUP pinning anymore since there's no use for having a page pinned without pinning a PTE to go along with that page, hence the page pinning is eliminated which saves a software page table walk that was performed for _at least_ every destination page. Reported-by: Kun Yi <kunyi@google.com> Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
This reverts commit ef467f3. This helper is no longer used by the FIPS-mode RNG, which was the motivation for reintroducing it. Remove it. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
local_unlock() is supposed to take a percpu pointer, which it then offsets for the current CPU. The problem is that the per-CPU DRBG code passes local_unlock() a pointer that has *already been offset for the current CPU*, so the percpu offset gets added twice. `pcri` is the percpu pointer and `cri` is the offset `pcri` pointer for the current CPU; passing `cri` to local_unlock() results in the current CPU's offset getting added again and thus the resulting pointer is garbage. This went unnoticed at runtime because local_unlock() only dereferences that pointer on PREEMPT_RT or CONFIG_DEBUG_LOCK_ALLOC=y kernels. The pointer is never actually used otherwise. This also went unnoticed at compile time because, for x86_64, __percpu only expands to something on GCC 14+; __percpu is otherwise an empty macro. So there's no pointer type mismatch detected at compile time on older GCC versions. On GCC 14+, the following compile error occurs: ../crypto/rng.c: In function 'lock_default_rng': ../include/linux/percpu-defs.h:221:45: error: initialization from pointer to non-enclosed address space Fix it by using __local_unlock() instead, which eliminates the duplicate per-CPU offset addition. While using local_unlock() with `pcri` also works, using `cri` with __local_unlock() is leaner because it doesn't need to redo the offset addition, saving an instruction on kernels that actually use the pointer. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
CONFIG_CRYPTO_FIPS_VERSION="ciq.6.12.20260826" Requested by lab. Signed-off-by: Jeremy Allison <jallison@ciq.com>
…E_128. CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=512 CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=256 Requested by lab. Signed-off-by: Jeremy Allison <jallison@ciq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR has been automatically created after successful completion of all CI stages.
Commit Message(s)
Test Results
✅ Build Stage
✅ Boot Verification
✅ Kernel Selftests
✅ LTP Results
🤖 This PR was automatically generated by GitHub Actions
Run ID: 33030966462