// 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>


// 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(void);
OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(void);

#if defined(BORINGSSL_FIPS)

// FIPS_service_indicator_update_state records that an approved service has been
// invoked.
void FIPS_service_indicator_update_state(void);

// 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);
void FIPS_service_indicator_unlock_state(void);

// 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(void) {}
inline void FIPS_service_indicator_lock_state(void) {}
inline void FIPS_service_indicator_unlock_state(void) {}

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

#endif  // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SERVICE_INDICATOR_INTERNAL_H
