-
Notifications
You must be signed in to change notification settings - Fork 230
USHIFT-6925 USHIFT-6851: Introduce Post-Quantum Curves to Ingress defaults and FIPs detection #6622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
60cf2ba
d65e623
0852771
9e1e64a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,9 @@ const ( | |
| haproxyMaxTimeoutMilliseconds = 2147483647 * time.Millisecond | ||
| ) | ||
|
|
||
| // isFIPSEnabled reports whether the cluster has FIPS enabled. | ||
| var isFIPSEnabled = detectFIPS() | ||
|
|
||
| var ( | ||
| tlsVersion13Ciphers = sets.NewString( | ||
| "TLS_AES_128_GCM_SHA256", | ||
|
|
@@ -35,8 +38,41 @@ var ( | |
| "TLS_AES_128_CCM_SHA256", | ||
| "TLS_AES_128_CCM_8_SHA256", | ||
| ) | ||
|
|
||
| fipsApprovedTLS13Ciphers = sets.NewString( | ||
| "TLS_AES_128_GCM_SHA256", | ||
| "TLS_AES_256_GCM_SHA384", | ||
| ) | ||
| ) | ||
|
|
||
| // detectFIPS reports whether the cluster is operating in FIPS | ||
| // mode by checking the FIPS_ENABLED environment variable if set or | ||
| // the /proc/sys/crypto/fips_enabled file otherwise. | ||
| func detectFIPS() bool { | ||
| if v, ok := os.LookupEnv("FIPS_ENABLED"); ok { | ||
| if result, err := strconv.ParseBool(v); err != nil { | ||
| klog.Warningf("Failed to parse FIPS_ENABLED environment variable: %v; falling back to procfs", err) | ||
| } else { | ||
| klog.Infof("Found FIPS_ENABLED environment variable: value=%s, result=%v", v, result) | ||
| return result | ||
| } | ||
| } | ||
|
|
||
| result := false | ||
| data, err := os.ReadFile("/proc/sys/crypto/fips_enabled") | ||
| if err != nil { | ||
| klog.Warningf("Failed to read /proc/sys/crypto/fips_enabled: %v; assuming FIPS is not enabled", err) | ||
| return result | ||
| } | ||
| if len(data) == 0 { | ||
| klog.Warningf("Got empty /proc/sys/crypto/fips_enabled; assuming FIPS is not enabled") | ||
| return result | ||
| } | ||
| result = data[0] == '1' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make this a bit more robust/clear with strings.TrimSpace(string(data)) == "1" |
||
| klog.Infof("Read /proc/sys/crypto/fips_enabled: data=%s, result=%v", string(data), result) | ||
| return result | ||
| } | ||
|
|
||
| func startServiceCAController(ctx context.Context, cfg *config.Config, kubeconfigPath string) error { | ||
| var ( | ||
| //TODO: fix the rolebinding and sa | ||
|
|
@@ -472,12 +508,34 @@ func generateIngressParams(cfg *config.Config) (assets.RenderParams, error) { | |
| } | ||
| } | ||
|
|
||
| // On FIPS-enabled clusters, remove non-FIPS-compliant TLS 1.3 cipher | ||
| // suites (e.g. TLS_CHACHA20_POLY1305_SHA256). HAProxy would fail TLS | ||
| // handshakes when a client offers a non-FIPS cipher first if that cipher | ||
| // is listed in ssl-default-bind-ciphersuites but excluded by the OS FIPS policy. | ||
| if isFIPSEnabled { | ||
| fipsCiphers := tls13Ciphers[:0] | ||
| for _, c := range tls13Ciphers { | ||
| if fipsApprovedTLS13Ciphers.Has(c) { | ||
| fipsCiphers = append(fipsCiphers, c) | ||
| } | ||
| } | ||
| tls13Ciphers = fipsCiphers | ||
| } | ||
|
|
||
| RouterCiphers := strings.Join(otherCiphers, ":") | ||
| RouterCiphersSuites := "" | ||
| if len(tls13Ciphers) != 0 { | ||
| RouterCiphersSuites = strings.Join(tls13Ciphers, ":") | ||
| } | ||
|
|
||
| // Default TLS supportedGroups (curves) include X25519MLKEM768 for | ||
| // post-quantum readiness. In FIPS mode, ML-KEM and X25519 are not | ||
| // supported by OpenSSL FIPS 140-3. | ||
| tlsCurves := "X25519MLKEM768:X25519:P-256:P-384:P-521" | ||
| if isFIPSEnabled { | ||
| tlsCurves = "P-256:P-384:P-521" | ||
| } | ||
|
|
||
| var RouterSSLMinVersion string | ||
| switch tlsProfileSpec.MinTLSVersion { | ||
| // TLS 1.0 is not supported, convert to TLS 1.1. | ||
|
|
@@ -569,6 +627,7 @@ func generateIngressParams(cfg *config.Config) (assets.RenderParams, error) { | |
| "RouterCiphers": RouterCiphers, | ||
| "RouterCiphersSuites": RouterCiphersSuites, | ||
| "RouterSSLMinVersion": RouterSSLMinVersion, | ||
| "RouterTLSCurves": tlsCurves, | ||
| "RouterAllowWildcardRoutes": RouterAllowWildcardRoutes, | ||
| "ClientCAMapName": clientCAMapName, | ||
| "ClientAuthPolicy": clientAuthPolicy, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,10 @@ TLS Scanner Host Scan Completes And Produces Artifacts | |
| ... Cleanup TLS Scanner Job | ||
| ... Ensure Cluster Reader Role Deleted | ||
|
|
||
| Ingress Router TLS Curves supports ML-KEM Post Quantum Curves | ||
| [Documentation] Verify TLS curve negotiation with openssl from inside the router pod. | ||
| Verify ML-KEM Post Quantum Curve Negotiation | ||
|
Comment on lines
+52
to
+54
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add explicit FIPS gating before asserting ML-KEM negotiation. The keyword unconditionally expects Also applies to: 130-144 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| *** Keywords *** | ||
| Check Required Scanner Variables | ||
|
|
@@ -123,3 +127,19 @@ Cleanup TLS Scanner Job | |
| IF '${TLS_SCANNER_DIR}' != '' | ||
| Run Keyword And Ignore Error Remove Directory ${TLS_SCANNER_DIR} recursive=True | ||
| END | ||
|
|
||
| Verify ML-KEM Post Quantum Curve Negotiation | ||
| [Documentation] Verify X25519MLKEM768 post-quantum hybrid key exchange | ||
| ... negotiates successfully via oc exec into the router pod, which | ||
| ... has OpenSSL 3.5+ (the host OpenSSL may be too old for ML-KEM). | ||
| ... Skipped on FIPS clusters where ML-KEM is not configured. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does it get skipped? Should we check the value for the ENV var in the deployment and skip it based on that? I see in the controller this situation is handled like that. |
||
| ${router_ip}= Oc Get JsonPath svc openshift-ingress router-default | ||
| ... .spec.clusterIP | ||
| ${pod_name}= Oc Get JsonPath pod openshift-ingress ${EMPTY} | ||
| ... .items[0].metadata.name | ||
| ${output}= Oc Exec ${pod_name} | ||
| ... echo Q | openssl s_client -connect ${router_ip}:443 -groups X25519MLKEM768 2>&1 || true | ||
| ... ns=openshift-ingress | ||
| Should Contain ${output} Negotiated TLS1.3 group: X25519MLKEM768 | ||
| ... msg=ML-KEM post-quantum curve X25519MLKEM768 negotiation failed | ||
| Log Post-quantum ML-KEM negotiation verified: OK | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have this injectable in the function below (
generateConfigParams) so that we can unit test it?