| /** |
| * \file common.h |
| * \brief Utility functions for use in liboqs. |
| * |
| * SPDX-License-Identifier: MIT |
| */ |
| |
| |
| #ifndef OQS_COMMON_H |
| #define OQS_COMMON_H |
| |
| #include <limits.h> |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| #include <oqs/oqsconfig.h> |
| |
| #if defined(__cplusplus) |
| extern "C" { |
| #endif |
| |
| /** |
| * Macro for terminating the program if x is |
| * a null pointer. |
| */ |
| #define OQS_EXIT_IF_NULLPTR(x, loc) \ |
| do { \ |
| if ( (x) == (void*)0 ) { \ |
| fprintf(stderr, "Unexpected NULL returned from %s API. Exiting.\n", loc); \ |
| exit(EXIT_FAILURE); \ |
| } \ |
| } while (0) |
| |
| /** |
| * This macro is intended to replace those assert()s |
| * involving side-effecting statements in aes/aes_ossl.c. |
| * |
| * assert() becomes a no-op when -DNDEBUG is defined, |
| * which causes compilation failures when the statement |
| * being checked also results in side-effects. |
| * |
| * This is a temporary workaround until a better error |
| * handling strategy is developed. |
| */ |
| #define OQS_OPENSSL_GUARD(x) \ |
| do { \ |
| if( 1 != (x) ) { \ |
| fprintf(stderr, "Error return value from OpenSSL API: %d. Exiting.\n", x); \ |
| exit(EXIT_FAILURE); \ |
| } \ |
| } while (0) |
| |
| /** |
| * Certain functions (such as OQS_randombytes_openssl in |
| * src/rand/rand.c) take in a size_t parameter, but can |
| * only handle values up to INT_MAX for those parameters. |
| * This macro is a temporary workaround for such functions. |
| */ |
| #define SIZE_T_TO_INT_OR_EXIT(size_t_var_name, int_var_name) \ |
| int int_var_name = 0; \ |
| if (size_t_var_name <= INT_MAX) { \ |
| int_var_name = (int)size_t_var_name; \ |
| } else { \ |
| exit(EXIT_FAILURE); \ |
| } |
| |
| /** |
| * Defines which functions should be exposed outside the LibOQS library |
| * |
| * By default the visibility of all the symbols is defined to "hidden" |
| * Only the library API should be marked as default |
| * |
| * Example: OQS_API return_value function_name(void); |
| */ |
| #if defined(_WIN32) |
| #define OQS_API __declspec(dllexport) |
| #else |
| #define OQS_API __attribute__((visibility("default"))) |
| #endif |
| |
| #if defined(OQS_SYS_UEFI) |
| #undef OQS_API |
| #define OQS_API |
| #endif |
| |
| /** |
| * Represents return values from functions. |
| * |
| * Callers should compare with the symbol rather than the individual value. |
| * For example, |
| * |
| * ret = OQS_KEM_encaps(...); |
| * if (ret == OQS_SUCCESS) { ... } |
| * |
| * rather than |
| * |
| * if (!OQS_KEM_encaps(...) { ... } |
| * |
| */ |
| typedef enum { |
| /** Used to indicate that some undefined error occurred. */ |
| OQS_ERROR = -1, |
| /** Used to indicate successful return from function. */ |
| OQS_SUCCESS = 0, |
| /** Used to indicate failures in external libraries (e.g., OpenSSL). */ |
| OQS_EXTERNAL_LIB_ERROR_OPENSSL = 50, |
| } OQS_STATUS; |
| |
| /** |
| * CPU runtime detection flags |
| */ |
| typedef enum { |
| OQS_CPU_EXT_INIT, /* Must be first */ |
| /* Start extension list */ |
| OQS_CPU_EXT_ADX, |
| OQS_CPU_EXT_AES, |
| OQS_CPU_EXT_AVX, |
| OQS_CPU_EXT_AVX2, |
| OQS_CPU_EXT_AVX512, |
| OQS_CPU_EXT_BMI1, |
| OQS_CPU_EXT_BMI2, |
| OQS_CPU_EXT_PCLMULQDQ, |
| OQS_CPU_EXT_VPCLMULQDQ, |
| OQS_CPU_EXT_POPCNT, |
| OQS_CPU_EXT_SSE, |
| OQS_CPU_EXT_SSE2, |
| OQS_CPU_EXT_SSE3, |
| OQS_CPU_EXT_ARM_AES, |
| OQS_CPU_EXT_ARM_SHA2, |
| OQS_CPU_EXT_ARM_SHA3, |
| OQS_CPU_EXT_ARM_NEON, |
| /* End extension list */ |
| OQS_CPU_EXT_COUNT, /* Must be last */ |
| } OQS_CPU_EXT; |
| |
| /** |
| * Checks if the CPU supports a given extension |
| * |
| * \return 1 if the given CPU extension is available, 0 otherwise. |
| */ |
| OQS_API int OQS_CPU_has_extension(OQS_CPU_EXT ext); |
| |
| /** |
| * This currently sets the values in the OQS_CPU_EXTENSIONS |
| * and prefetches the OpenSSL objects if necessary. |
| */ |
| OQS_API void OQS_init(void); |
| |
| /** |
| * This function frees prefetched OpenSSL objects |
| */ |
| OQS_API void OQS_destroy(void); |
| |
| /** |
| * Return library version string. |
| */ |
| OQS_API const char *OQS_version(void); |
| |
| /** |
| * Constant time comparison of byte sequences `a` and `b` of length `len`. |
| * Returns 0 if the byte sequences are equal or if `len`=0. |
| * Returns 1 otherwise. |
| * |
| * @param[in] a A byte sequence of length at least `len`. |
| * @param[in] b A byte sequence of length at least `len`. |
| * @param[in] len The number of bytes to compare. |
| */ |
| OQS_API int OQS_MEM_secure_bcmp(const void *a, const void *b, size_t len); |
| |
| /** |
| * Zeros out `len` bytes of memory starting at `ptr`. |
| * |
| * Designed to be protected against optimizing compilers which try to remove |
| * "unnecessary" operations. Should be used for all buffers containing secret |
| * data. |
| * |
| * @param[in] ptr The start of the memory to zero out. |
| * @param[in] len The number of bytes to zero out. |
| */ |
| OQS_API void OQS_MEM_cleanse(void *ptr, size_t len); |
| |
| /** |
| * Zeros out `len` bytes of memory starting at `ptr`, then frees `ptr`. |
| * |
| * Can be called with `ptr = NULL`, in which case no operation is performed. |
| * |
| * Designed to be protected against optimizing compilers which try to remove |
| * "unnecessary" operations. Should be used for all buffers containing secret |
| * data. |
| * |
| * @param[in] ptr The start of the memory to zero out and free. |
| * @param[in] len The number of bytes to zero out. |
| */ |
| OQS_API void OQS_MEM_secure_free(void *ptr, size_t len); |
| |
| /** |
| * Frees `ptr`. |
| * |
| * Can be called with `ptr = NULL`, in which case no operation is performed. |
| * |
| * Should only be used on non-secret data. |
| * |
| * @param[in] ptr The start of the memory to free. |
| */ |
| OQS_API void OQS_MEM_insecure_free(void *ptr); |
| |
| /** |
| * Internal implementation of C11 aligned_alloc to work around compiler quirks. |
| * |
| * Allocates size bytes of uninitialized memory with a base pointer that is |
| * a multiple of alignment. Alignment must be a power of two and a multiple |
| * of sizeof(void *). Size must be a multiple of alignment. |
| */ |
| void *OQS_MEM_aligned_alloc(size_t alignment, size_t size); |
| |
| /** |
| * Free memory allocated with OQS_MEM_aligned_alloc. |
| */ |
| void OQS_MEM_aligned_free(void *ptr); |
| |
| #if defined(__cplusplus) |
| } // extern "C" |
| #endif |
| |
| #endif // OQS_COMMON_H |