| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SERVICE_INDICATOR_INTERNAL_H | |
| #define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SERVICE_INDICATOR_INTERNAL_H | |
| #include <openssl/base.h> | |
| BSSL_NAMESPACE_BEGIN | |
| // FIPS_service_indicator_before_call and `FIPS_service_indicator_after_call` | |
| // both currently return the same local thread counter which is slowly | |
| // incremented whenever approved services are called. The | |
| // `CALL_SERVICE_AND_CHECK_APPROVED` macro is strongly recommended over calling | |
| // these functions directly. | |
| // | |
| // `FIPS_service_indicator_before_call` is intended to be called immediately | |
| // before an approved service, while `FIPS_service_indicator_after_call` should | |
| // be called immediately after. If the values returned from these two functions | |
| // are not equal, this means that the service called in between is deemed to be | |
| // approved. If the values are still the same, this means the counter has not | |
| // been incremented, and the service called is not approved for FIPS. | |
| // | |
| // In non-FIPS builds, `FIPS_service_indicator_before_call` always returns zero | |
| // and `FIPS_service_indicator_after_call` always returns one. Thus calls always | |
| // appear to be approved. This is intended to simplify testing. | |
| OPENSSL_EXPORT uint64_t FIPS_service_indicator_before_call(); | |
| OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(); | |
| #if defined(BORINGSSL_FIPS) | |
| // FIPS_service_indicator_update_state records that an approved service has been | |
| // invoked. | |
| void FIPS_service_indicator_update_state(); | |
| // FIPS_service_indicator_lock_state and `FIPS_service_indicator_unlock_state` | |
| // stop `FIPS_service_indicator_update_state` from actually updating the service | |
| // indicator. This is used when a primitive calls a potentially approved | |
| // primitive to avoid false positives. For example, just because a key | |
| // generation calls `BCM_rand_bytes` (and thus the approved DRBG) doesn't mean | |
| // that the key generation operation itself is approved. | |
| // | |
| // This lock nests: i.e. locking twice is fine so long as each lock is paired | |
| // with an unlock. If the (64-bit) counter overflows, the process aborts. | |
| void FIPS_service_indicator_lock_state(); | |
| void FIPS_service_indicator_unlock_state(); | |
| // The following functions may call `FIPS_service_indicator_update_state` if | |
| // their parameter specifies an approved operation. | |
| void AEAD_GCM_verify_service_indicator(const EVP_AEAD_CTX *ctx); | |
| void AEAD_CCM_verify_service_indicator(const EVP_AEAD_CTX *ctx); | |
| void EC_KEY_keygen_verify_service_indicator(const EC_KEY *eckey); | |
| void ECDH_verify_service_indicator(const EC_KEY *ec_key); | |
| void EVP_Cipher_verify_service_indicator(const EVP_CIPHER_CTX *ctx); | |
| void EVP_DigestSign_verify_service_indicator(const EVP_MD_CTX *ctx); | |
| void EVP_DigestVerify_verify_service_indicator(const EVP_MD_CTX *ctx); | |
| void HMAC_verify_service_indicator(const EVP_MD *evp_md); | |
| void TLSKDF_verify_service_indicator(const EVP_MD *dgst); | |
| #else | |
| // Service indicator functions are no-ops in non-FIPS builds. | |
| inline void FIPS_service_indicator_update_state() {} | |
| inline void FIPS_service_indicator_lock_state() {} | |
| inline void FIPS_service_indicator_unlock_state() {} | |
| inline void AEAD_GCM_verify_service_indicator( | |
| [[maybe_unused]] const EVP_AEAD_CTX *ctx) {} | |
| inline void AEAD_CCM_verify_service_indicator( | |
| [[maybe_unused]] const EVP_AEAD_CTX *ctx) {} | |
| inline void EC_KEY_keygen_verify_service_indicator( | |
| [[maybe_unused]] const EC_KEY *eckey) {} | |
| inline void ECDH_verify_service_indicator( | |
| [[maybe_unused]] const EC_KEY *ec_key) {} | |
| inline void EVP_Cipher_verify_service_indicator( | |
| [[maybe_unused]] const EVP_CIPHER_CTX *ctx) {} | |
| inline void EVP_DigestSign_verify_service_indicator( | |
| [[maybe_unused]] const EVP_MD_CTX *ctx) {} | |
| inline void EVP_DigestVerify_verify_service_indicator( | |
| [[maybe_unused]] const EVP_MD_CTX *ctx) {} | |
| inline void HMAC_verify_service_indicator( | |
| [[maybe_unused]] const EVP_MD *evp_md) {} | |
| inline void TLSKDF_verify_service_indicator( | |
| [[maybe_unused]] const EVP_MD *dgst) {} | |
| #endif // BORINGSSL_FIPS | |
| BSSL_NAMESPACE_END | |
| #endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SERVICE_INDICATOR_INTERNAL_H |