diff --git a/crypto/fipsmodule/cpucap/cpu_intel.c b/crypto/fipsmodule/cpucap/cpu_intel.c index e236e3e6999..5e469ad2c49 100644 --- a/crypto/fipsmodule/cpucap/cpu_intel.c +++ b/crypto/fipsmodule/cpucap/cpu_intel.c @@ -133,6 +133,8 @@ static void handle_cpu_env(uint32_t *out, const char *in) { const int or = in[0] == '|'; const int skip_first_byte = invert || or; const int hex = in[skip_first_byte] == '0' && in[skip_first_byte+1] == 'x'; + uint32_t intelcap0 = out[0]; + uint32_t intelcap1 = out[1]; int sscanf_result; uint64_t v; @@ -146,15 +148,31 @@ static void handle_cpu_env(uint32_t *out, const char *in) { return; } + uint32_t reqcap0 = (uint32_t)(v & UINT32_MAX); + uint32_t reqcap1 = (uint32_t)(v >> 32); + + // Detect if the user is trying to use the environment variable to set + // a capability that is _not_ available on the CPU. + // The case of invert cannot enable an unexisting capability; + // it can only disable an existing one. + if (!invert && (intelcap0 || intelcap1)) { + if((~intelcap0 & reqcap0) || (~intelcap1 & reqcap1)) { + fprintf(stderr, + "Fatal Error: HW capability found: 0x%02X 0x%02X, but HW capability requested: 0x%02X 0x%02X.\n", + intelcap0, intelcap1, reqcap0, reqcap1); + abort(); + } + } + if (invert) { - out[0] &= ~v; - out[1] &= ~(v >> 32); + out[0] &= ~reqcap0; + out[1] &= ~reqcap1; } else if (or) { - out[0] |= v; - out[1] |= (v >> 32); + out[0] |= reqcap0; + out[1] |= reqcap1; } else { - out[0] = v; - out[1] = v >> 32; + out[0] = reqcap0; + out[1] = reqcap1; } } diff --git a/crypto/fipsmodule/cpucap/cpu_ppc64le.c b/crypto/fipsmodule/cpucap/cpu_ppc64le.c index e9e9891fe39..237964915ae 100644 --- a/crypto/fipsmodule/cpucap/cpu_ppc64le.c +++ b/crypto/fipsmodule/cpucap/cpu_ppc64le.c @@ -31,25 +31,37 @@ static void handle_cpu_env(unsigned long *out, const char *in) { const int or = in[0] == '|'; const int skip_first_byte = (invert || or) ? 1 : 0; const int hex = in[skip_first_byte] == '0' && in[skip_first_byte+1] == 'x'; + unsigned long ppccap = *out; int sscanf_result; - uint64_t v; + uint64_t reqcap; if (hex) { - sscanf_result = sscanf(in + skip_first_byte + 2, "%" PRIx64, &v); + sscanf_result = sscanf(in + skip_first_byte + 2, "%" PRIx64, &reqcap); } else { - sscanf_result = sscanf(in + skip_first_byte, "%" PRIu64, &v); + sscanf_result = sscanf(in + skip_first_byte, "%" PRIu64, &reqcap); } if (!sscanf_result) { return; } + // Detect if the user is trying to use the environment variable to set + // a capability that is _not_ available on the CPU. + // The case of invert cannot enable an unexisting capability; + // it can only disable an existing one. + if (!invert && ppccap && (~ppccap & reqcap)) { + fprintf(stderr, + "Fatal Error: HW capability found: 0x%02X, but HW capability requested: 0x%02X.\n", + ppccap, reqcap); + abort(); + } + if (invert) { - *out &= ~v; + *out &= ~reqcap; } else if (or) { - *out |= v; + *out |= reqcap; } else { - *out = v; + *out = reqcap; } }