1// Copyright 2017 The BoringSSL Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include <openssl/crypto.h> 16 17#include "../../internal.h" 18#include "../delocate.h" 19 20 21int FIPS_mode(void) { 22#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) 23 return 1; 24#else 25 return 0; 26#endif 27} 28 29int FIPS_mode_set(int on) { return on == FIPS_mode(); } 30 31const char *FIPS_module_name(void) { return "BoringCrypto"; } 32 33int CRYPTO_has_asm(void) { 34#if defined(OPENSSL_NO_ASM) 35 return 0; 36#else 37 return 1; 38#endif 39} 40 41uint32_t FIPS_version(void) { 42 return 0; 43} 44 45int FIPS_query_algorithm_status(const char *algorithm) { 46#if defined(BORINGSSL_FIPS) 47 static const char kApprovedAlgorithms[][13] = { 48 "AES-CBC", 49 "AES-CCM", 50 "AES-CTR", 51 "AES-ECB", 52 "AES-GCM", 53 "AES-KW", 54 "AES-KWP", 55 "ctrDRBG", 56 "ECC-SSC", 57 "ECDSA-sign", 58 "ECDSA-verify", 59 "FFC-SSC", 60 "HMAC", 61 "RSA-sign", 62 "RSA-verify", 63 "SHA-1", 64 "SHA2-224", 65 "SHA2-256", 66 "SHA2-384", 67 "SHA2-512", 68 "SHA2-512/256", 69 }; 70 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kApprovedAlgorithms); i++) { 71 if (strcmp(algorithm, kApprovedAlgorithms[i]) == 0) { 72 return 1; 73 } 74 } 75#endif // BORINGSSL_FIPS 76 77 return 0; 78} 79 80#if defined(BORINGSSL_FIPS_COUNTERS) 81 82size_t FIPS_read_counter(enum fips_counter_t counter) { 83 size_t index = (size_t)counter; 84 if (index > fips_counter_max) { 85 abort(); 86 } 87 88 const size_t *array = reinterpret_cast<const size_t *>( 89 CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS)); 90 if (!array) { 91 return 0; 92 } 93 94 return array[index]; 95} 96 97void boringssl_fips_inc_counter(enum fips_counter_t counter) { 98 size_t index = (size_t)counter; 99 if (index > fips_counter_max) { 100 abort(); 101 } 102 103 size_t *array = reinterpret_cast<size_t *>( 104 CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS)); 105 if (!array) { 106 const size_t num_bytes = sizeof(size_t) * (fips_counter_max + 1); 107 array = reinterpret_cast<size_t *>(OPENSSL_zalloc(num_bytes)); 108 if (!array) { 109 return; 110 } 111 112 if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS, array, 113 OPENSSL_free)) { 114 // |OPENSSL_free| has already been called by |CRYPTO_set_thread_local|. 115 return; 116 } 117 } 118 119 array[index]++; 120} 121 122#else 123 124size_t FIPS_read_counter(enum fips_counter_t counter) { return 0; } 125 126// boringssl_fips_inc_counter is a no-op, inline function in internal.h in this 127// case. That should let the compiler optimise away the callsites. 128 129#endif 130