1/* Copyright 2017 The BoringSSL Authors 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 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 20250107; 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