* [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
@ 2026-10-18 1:28 Pablo Alessandro Santos Hugen
2026-10-19 17:11 ` Stephen Smalley
2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
0 siblings, 2 replies; 5+ messages in thread
From: Pablo Alessandro Santos Hugen @ 2026-10-18 1:28 UTC (permalink / raw)
To: selinux
Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
FIPS mode per SP800-56Arev3. As noted in the commit:
> This change will effectively render the
> keyctl(KEYCTL_DH_COMPUTE) syscall unusable in FIPS mode, but
> it has been brought up that this might even be a good thing
> ([1])."
>
> [1] https://lore.kernel.org/r/20211217055227.GA20698@gondor.apana.org.au
keyctl(KEYCTL_DH_COMPUTE) returns ENOENT in FIPS mode.
So, this patch treat ENOENT and ENOSYS as non-fatal in
keyctl.c (because the operation is unavailable, not denied by
policy). SELinux denials (EACCES) still exit 9. Skip
test_key_no_read_t in FIPS mode since KEYCTL_DH_COMPUTE is
the only operation requiring key { read }.
Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
---
tests/keys/keyctl.c | 15 ++++++++++-----
tests/keys/request_keys.c | 15 ++++++++++-----
tests/keys/test | 21 +++++++++++++++------
3 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/tests/keys/keyctl.c b/tests/keys/keyctl.c
index e13c655..261c00a 100644
--- a/tests/keys/keyctl.c
+++ b/tests/keys/keyctl.c
@@ -142,12 +142,17 @@ int main(int argc, char *argv[])
/* Requires key { create read write } */
compute = keyctl(KEYCTL_DH_COMPUTE, ¶ms, NULL, 0, 0);
if (compute < 0) {
- fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
- strerror(errno));
- exit(9);
- }
- if (verbose)
+ if (errno == ENOENT || errno == ENOSYS) {
+ if (verbose)
+ printf("KEYCTL_DH_COMPUTE not available, skipping\n");
+ } else {
+ fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+ strerror(errno));
+ exit(9);
+ }
+ } else if (verbose) {
printf("KEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+ }
/* Requires key { write link } */
link = keyctl(KEYCTL_LINK, base, KEY_SPEC_PROCESS_KEYRING);
diff --git a/tests/keys/request_keys.c b/tests/keys/request_keys.c
index 43b20d9..7cf7cd0 100644
--- a/tests/keys/request_keys.c
+++ b/tests/keys/request_keys.c
@@ -127,12 +127,17 @@ int main(int argc, char **argv)
/* Requires key { read write } */
compute = keyctl(KEYCTL_DH_COMPUTE, ¶ms, NULL, 0, 0);
if (compute < 0) {
- fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
- strerror(errno));
- exit(8);
- }
- if (verbose)
+ if (errno == ENOENT || errno == ENOSYS) {
+ if (verbose)
+ printf("\tKEYCTL_DH_COMPUTE not available, skipping\n");
+ } else {
+ fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+ strerror(errno));
+ exit(8);
+ }
+ } else if (verbose) {
printf("\tKEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+ }
exit(0);
}
diff --git a/tests/keys/test b/tests/keys/test
index 061bc62..9e50633 100755
--- a/tests/keys/test
+++ b/tests/keys/test
@@ -29,6 +29,9 @@ BEGIN {
$test_link_53 = 1;
}
+ # KEYCTL_DH_COMPUTE is disabled in FIPS mode
+ chomp( $fips = `cat /proc/sys/crypto/fips_enabled 2>/dev/null` );
+ $skip_dh = ( $fips eq "1" ) ? 1 : 0;
plan tests => $test_count;
}
@@ -51,8 +54,11 @@ ok( $result >> 8 eq 6 );
$result = system "runcon -t test_key_no_view_t $basedir/keyctl $v 2>&1";
ok( $result >> 8 eq 8 );
-$result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
-ok( $result >> 8 eq 9 );
+SKIP: {
+ skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
+ $result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
+ ok( $result >> 8 eq 9 );
+}
$result = system "runcon -t test_key_no_link_t $basedir/keyctl $v 2>&1";
if ($test_link_53) {
@@ -101,9 +107,12 @@ $result = system(
);
ok( $result >> 8 eq 6 );
-$result = system(
-"runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
-);
-ok( $result >> 8 eq 8 );
+SKIP: {
+ skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
+ $result = system(
+ "runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
+ );
+ ok( $result >> 8 eq 8 );
+}
exit;
--
2.56.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
2026-10-18 1:28 [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable Pablo Alessandro Santos Hugen
@ 2026-10-19 17:11 ` Stephen Smalley
2026-10-20 18:03 ` Pablo Hugen
2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
1 sibling, 1 reply; 5+ messages in thread
From: Stephen Smalley @ 2026-10-19 17:11 UTC (permalink / raw)
To: Pablo Alessandro Santos Hugen, Ondrej Mosnáček; +Cc: selinux
On Sat, Oct 17, 2026 at 9:29 PM Pablo Alessandro Santos Hugen
<phugen@redhat.com> wrote:
>
> Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
> FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
> FIPS mode per SP800-56Arev3. As noted in the commit:
>
> > This change will effectively render the
> > keyctl(KEYCTL_DH_COMPUTE) syscall unusable in FIPS mode, but
> > it has been brought up that this might even be a good thing
> > ([1])."
> >
> > [1] https://lore.kernel.org/r/20211217055227.GA20698@gondor.apana.org.au
>
> keyctl(KEYCTL_DH_COMPUTE) returns ENOENT in FIPS mode.
>
> So, this patch treat ENOENT and ENOSYS as non-fatal in
> keyctl.c (because the operation is unavailable, not denied by
> policy). SELinux denials (EACCES) still exit 9. Skip
> test_key_no_read_t in FIPS mode since KEYCTL_DH_COMPUTE is
> the only operation requiring key { read }.
>
> Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
> Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
> ---
> tests/keys/keyctl.c | 15 ++++++++++-----
> tests/keys/request_keys.c | 15 ++++++++++-----
> tests/keys/test | 21 +++++++++++++++------
> 3 files changed, 35 insertions(+), 16 deletions(-)
>
> diff --git a/tests/keys/keyctl.c b/tests/keys/keyctl.c
> index e13c655..261c00a 100644
> --- a/tests/keys/keyctl.c
> +++ b/tests/keys/keyctl.c
> @@ -142,12 +142,17 @@ int main(int argc, char *argv[])
> /* Requires key { create read write } */
> compute = keyctl(KEYCTL_DH_COMPUTE, ¶ms, NULL, 0, 0);
> if (compute < 0) {
> - fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
> - strerror(errno));
> - exit(9);
> - }
> - if (verbose)
> + if (errno == ENOENT || errno == ENOSYS) {
KEYCTL_DH_COMPUTE never returns ENOSYS; with !CONFIG_KEY_DH_OPERATIONS
the stub in security/keys/internal.h returns -EOPNOTSUPP, and the
sys_keyctl default case is also -EOPNOTSUPP. If you want to cover
kernels built with DH support, this should be EOPNOTSUPP instead (both
files).
> diff --git a/tests/keys/request_keys.c b/tests/keys/request_keys.c
> index 43b20d9..7cf7cd0 100644
> --- a/tests/keys/request_keys.c
> +++ b/tests/keys/request_keys.c
> @@ -127,12 +127,17 @@ int main(int argc, char **argv)
> /* Requires key { read write } */
> compute = keyctl(KEYCTL_DH_COMPUTE, ¶ms, NULL, 0, 0);
> if (compute < 0) {
> - fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
> - strerror(errno));
> - exit(8);
> - }
> - if (verbose)
> + if (errno == ENOENT || errno == ENOSYS) {
Same comment as above.
> diff --git a/tests/keys/test b/tests/keys/test
> index 061bc62..9e50633 100755
> --- a/tests/keys/test
> +++ b/tests/keys/test
> @@ -51,8 +54,11 @@ ok( $result >> 8 eq 6 );
> $result = system "runcon -t test_key_no_view_t $basedir/keyctl $v 2>&1";
> ok( $result >> 8 eq 8 );
>
> -$result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
> -ok( $result >> 8 eq 9 );
> +SKIP: {
> + skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
> + $result = system "runcon -t test_key_no_read_t $basedir/keyctl $v 2>&1";
> + ok( $result >> 8 eq 9 );
> +}
This SKIP block and the one below shouldn't be necessary. In
__keyctl_dh_compute() the three dh_data_from_key() calls each do
lookup_user_key(id, 0, KEY_NEED_READ) and run before
crypto_alloc_kpp("dh"). key_task_permission() for KEY_NEED_READ ends
with security_key_permission() as the final arbiter, so for
test_key_no_read_t the SELinux denial fires there, lookup_user_key()
returns -EACCES, and dh_data_from_key() squashes it to -ENOKEY. ENOKEY
isn't ENOENT or ENOSYS, so with just the C-side change the no_read_t
runs still exit 9 / 8 under FIPS exactly as they do today; the
FIPS-mode ENOENT is never reached when read is denied.
> -$result = system(
> -"runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
> -);
> -ok( $result >> 8 eq 8 );
> +SKIP: {
> + skip( "KEYCTL_DH_COMPUTE unavailable in FIPS mode", 1 ) if $skip_dh;
> + $result = system(
> + "runcon -t test_keyring_service_t $basedir/keyring_service $v test_request_keys_no_read_t $basedir/request_keys 2>&1"
> + );
> + ok( $result >> 8 eq 8 );
> +}
See above comment.
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
2026-10-18 1:28 [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable Pablo Alessandro Santos Hugen
2026-10-19 17:11 ` Stephen Smalley
@ 2026-10-20 18:06 ` Pablo Alessandro Santos Hugen
2026-10-21 12:57 ` Stephen Smalley
1 sibling, 1 reply; 5+ messages in thread
From: Pablo Alessandro Santos Hugen @ 2026-10-20 18:06 UTC (permalink / raw)
To: selinux; +Cc: stephen.smalley.work, omosnacek
Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
FIPS mode per SP800-56Arev3. keyctl(KEYCTL_DH_COMPUTE) returns
ENOENT in FIPS mode.
Treat ENOENT and EOPNOTSUPP as non-fatal in keyctl.c and
request_keys.c (the operation is unavailable, not denied by
policy). SELinux denials (EACCES) still exit 9/8.
Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
---
Changes in v2 (Stephen Smalley):
- Replace ENOSYS with EOPNOTSUPP — KEYCTL_DH_COMPUTE never
returns ENOSYS; the !CONFIG_KEY_DH_OPERATIONS stub returns
EOPNOTSUPP
- Drop SKIP blocks in Perl test — SELinux denial fires before
DH computation (EACCES -> ENOKEY), so no_read_t tests still
pass under FIPS
tests/keys/keyctl.c | 15 ++++++++++-----
tests/keys/request_keys.c | 15 ++++++++++-----
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/tests/keys/keyctl.c b/tests/keys/keyctl.c
index e13c655..5e98f11 100644
--- a/tests/keys/keyctl.c
+++ b/tests/keys/keyctl.c
@@ -142,12 +142,17 @@ int main(int argc, char *argv[])
/* Requires key { create read write } */
compute = keyctl(KEYCTL_DH_COMPUTE, ¶ms, NULL, 0, 0);
if (compute < 0) {
- fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
- strerror(errno));
- exit(9);
- }
- if (verbose)
+ if (errno == ENOENT || errno == EOPNOTSUPP) {
+ if (verbose)
+ printf("KEYCTL_DH_COMPUTE not available, skipping\n");
+ } else {
+ fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+ strerror(errno));
+ exit(9);
+ }
+ } else if (verbose) {
printf("KEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+ }
/* Requires key { write link } */
link = keyctl(KEYCTL_LINK, base, KEY_SPEC_PROCESS_KEYRING);
diff --git a/tests/keys/request_keys.c b/tests/keys/request_keys.c
index 43b20d9..291a522 100644
--- a/tests/keys/request_keys.c
+++ b/tests/keys/request_keys.c
@@ -127,12 +127,17 @@ int main(int argc, char **argv)
/* Requires key { read write } */
compute = keyctl(KEYCTL_DH_COMPUTE, ¶ms, NULL, 0, 0);
if (compute < 0) {
- fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
- strerror(errno));
- exit(8);
- }
- if (verbose)
+ if (errno == ENOENT || errno == EOPNOTSUPP) {
+ if (verbose)
+ printf("\tKEYCTL_DH_COMPUTE not available, skipping\n");
+ } else {
+ fprintf(stderr, "Failed KEYCTL_DH_COMPUTE: %s\n",
+ strerror(errno));
+ exit(8);
+ }
+ } else if (verbose) {
printf("\tKEYCTL_DH_COMPUTE key ID size: %d\n", compute);
+ }
exit(0);
}
--
2.56.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable
2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
@ 2026-10-21 12:57 ` Stephen Smalley
0 siblings, 0 replies; 5+ messages in thread
From: Stephen Smalley @ 2026-10-21 12:57 UTC (permalink / raw)
To: Pablo Alessandro Santos Hugen; +Cc: selinux, omosnacek
On Tue, Oct 20, 2026 at 2:07 PM Pablo Alessandro Santos Hugen
<phugen@redhat.com> wrote:
>
> Since 32f07cc40c9b ("crypto: dh - disallow plain "dh" usage in
> FIPS mode") landed in linux 5.18, plain "dh" is disallowed in
> FIPS mode per SP800-56Arev3. keyctl(KEYCTL_DH_COMPUTE) returns
> ENOENT in FIPS mode.
>
> Treat ENOENT and EOPNOTSUPP as non-fatal in keyctl.c and
> request_keys.c (the operation is unavailable, not denied by
> policy). SELinux denials (EACCES) still exit 9/8.
>
> Fixes: 2d7aad8a1f8c ("selinux-testsuite: Add keys tests")
> Signed-off-by: Pablo Alessandro Santos Hugen <phugen@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Note that this will skip this testing on FIPS-enabled hosts so it
won't be exercised if your testing infrastructure always enables FIPS;
that's ok with me but noting for the record.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-21 12:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-18 1:28 [PATCH] tests/keys: skip KEYCTL_DH_COMPUTE when unavailable Pablo Alessandro Santos Hugen
2026-10-19 17:11 ` Stephen Smalley
2026-10-20 18:03 ` Pablo Hugen
2026-10-20 18:06 ` [PATCH v2] " Pablo Alessandro Santos Hugen
2026-10-21 12:57 ` Stephen Smalley
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.