diff --git a/CONFIGURE.md b/CONFIGURE.md index 152907cedf..5712859cf0 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -8,7 +8,7 @@ The following options can be passed to CMake before the build file generation pr - [CMAKE_INSTALL_PREFIX](#CMAKE_INSTALL_PREFIX) - [OQS_ALGS_ENABLED](#OQS_ALGS_ENABLED) - [OQS_BUILD_ONLY_LIB](#OQS_BUILD_ONLY_LIB) -- [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG) +- [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG) - [OQS_MINIMAL_BUILD](#OQS_MINIMAL_BUILD) - [OQS_DIST_BUILD](#OQS_DIST_BUILD) - [OQS_USE_CPUFEATURE_INSTRUCTIONS](OQS_USE_CPUFEATURE_INSTRUCTIONS) @@ -42,21 +42,23 @@ Can be set to the following values: See the [CMake documentation](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html). -## OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG +## OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG -Note: `ALG` in `OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG` should be replaced with the specific algorithm name as demonstrated below. +Note: `ALG` in `OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG` should be replaced with the specific algorithm name as demonstrated below. This can be set to `ON` or `OFF`, and is `ON` by default. When `OFF`, `ALG` and its code are excluded from the build process. When `ON`, made available are additional options whereby individual variants of `ALG` can be excluded from the build process. For example: if `OQS_ENABLE_KEM_BIKE` is set to `ON`, the options `OQS_ENABLE_KEM_bike_l1`, `OQS_ENABLE_KEM_bike_l3`, and `OQS_ENABLE_KEM_bike_l5` are made available (and are set to be `ON` by default). +To enable `XMSS` stateful signature, set `OQS_ENABLE_SIG_STFL_XMSS` to `ON`, the options `OQS_ENABLE_SIG_STFL_xmss_sha256_h10` and its variants are also set to be `ON` by default. Similarly, `LMS` stateful signature family can also be enabled by setting `OQS_ENABLE_SIG_STFL_LMS` to `ON`. + For a full list of such options and their default values, consult [.CMake/alg_support.cmake](https://github.com/open-quantum-safe/liboqs/blob/master/.CMake/alg_support.cmake). **Default**: Unset. ## OQS_ALGS_ENABLED -Selects algorithm set enabled. Possible values are "STD" selecting all algorithms standardized by NIST; "NIST_R4" selecting all algorithms evaluated in round 4 of the NIST PQC competition; "All" (or any other value) selecting all algorithms integrated into liboqs. Parameter setting "STD" minimizes library size but may require re-running code generator scripts in projects integrating `liboqs`, e.g., [oqs-openssl111](https://github.com/open-quantum-safe/openssl). +A selected algorithm set is enabled. Possible values are "STD" selecting all algorithms standardized by NIST; "NIST_R4" selecting all algorithms evaluated in round 4 of the NIST PQC competition; "All" (or any other value) selecting all algorithms integrated into liboqs. Parameter setting "STD" minimizes library size but may require re-running code generator scripts in projects integrating `liboqs`, e.g., [oqs-openssl111](https://github.com/open-quantum-safe/openssl) or [oqs-openssh](https://github.com/open-quantum-safe/openssh). **Default**: `All`. @@ -68,9 +70,9 @@ Can be `ON` or `OFF`. When `ON`, only liboqs is built, and all the targets: `run ## OQS_MINIMAL_BUILD -If set, this defines a semicolon deliminated list of algorithms to be contained in a minimal build of `liboqs`: Only algorithms explicitly set here are included in a build: For example running `cmake -DOQS_MINIMAL_BUILD="KEM_kyber_768;SIG_dilithium_3" ..` will build a minimum-size `liboqs` library only containing support for Kyber768 and Dilithium3. +If set, this defines a semicolon-delimited list of algorithms to be contained in a minimal build of `liboqs`: Only algorithms explicitly set here are included in a build: For example running `cmake -DOQS_MINIMAL_BUILD="KEM_kyber_768;SIG_dilithium_3" ..` will build a minimum-size `liboqs` library only containing support for Kyber768 and Dilithium3. -The full list of identifiers that can set are listed [here for KEM algorithms](https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/kem.h#L34) and [here for Signature algorithms](https://github.com/open-quantum-safe/liboqs/blob/f3caccff9e6225e7c50ca27f5ee6e58b7bc74188/src/sig/sig.h#L34). Default setting is empty, thus including all [supported algorithms](https://github.com/open-quantum-safe/liboqs#supported-algorithms) in the build. +The full list of identifiers that can be set is listed [here](https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/kem.h#L34) for KEM algorithms](https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/kem.h#L34) and [here for Signature algorithms](https://github.com/open-quantum-safe/liboqs/blob/f3caccff9e6225e7c50ca27f5ee6e58b7bc74188/src/sig/sig.h#L34). The default setting is empty, thus including all [supported algorithms](https://github.com/open-quantum-safe/liboqs#supported-algorithms) in the build. **Default**: Unset. @@ -90,13 +92,13 @@ When built for use on a single machine, the library will only include the best a Note: `CPUFEATURE` in `OQS_USE_CPUFEATURE_INSTRUCTIONS` should be replaced with the specific CPU feature as noted below. -These can be set to `ON` or `OFF` and take an effect if liboqs is built for use on a single machine. By default, the CPU features are automatically determined and set to `ON` or `OFF` based on the CPU features available on the build system. The default values can be overridden by providing CMake build options. The available options on x86-64 are: `OQS_USE_ADX_INSTRUCTIONS`, `OQS_USE_AES_INSTRUCTIONS`, `OQS_USE_AVX_INSTRUCTIONS`, `OQS_USE_AVX2_INSTRUCTIONS`, `OQS_USE_AVX512_INSTRUCTIONS`, `OQS_USE_BMI1_INSTRUCTIONS`, `OQS_USE_BMI2_INSTRUCTIONS`, `OQS_USE_PCLMULQDQ_INSTRUCTIONS`, `OQS_USE_VPCLMULQDQ_INSTRUCTIONS`, `OQS_USE_POPCNT_INSTRUCTIONS`, `OQS_USE_SSE_INSTRUCTIONS`, `OQS_USE_SSE2_INSTRUCTIONS` and `OQS_USE_SSE3_INSTRUCTIONS`. The available options on ARM64v8 are `OQS_USE_ARM_AES_INSTRUCTIONS`, `OQS_USE_ARM_SHA2_INSTRUCTIONS`, `OQS_USE_ARM_SHA3_INSTRUCTIONS` and `OQS_USE_ARM_NEON_INSTRUCTIONS`. +These can be set to `ON` or `OFF` and take effect if liboqs is built for use on a single machine. By default, the CPU features are automatically determined and set to `ON` or `OFF` based on the CPU features available on the build system. The default values can be overridden by providing CMake build options. The available options on x86-64 are: `OQS_USE_ADX_INSTRUCTIONS`, `OQS_USE_AES_INSTRUCTIONS`, `OQS_USE_AVX_INSTRUCTIONS`, `OQS_USE_AVX2_INSTRUCTIONS`, `OQS_USE_AVX512_INSTRUCTIONS`, `OQS_USE_BMI1_INSTRUCTIONS`, `OQS_USE_BMI2_INSTRUCTIONS`, `OQS_USE_PCLMULQDQ_INSTRUCTIONS`, `OQS_USE_VPCLMULQDQ_INSTRUCTIONS`, `OQS_USE_POPCNT_INSTRUCTIONS`, `OQS_USE_SSE_INSTRUCTIONS`, `OQS_USE_SSE2_INSTRUCTIONS` and `OQS_USE_SSE3_INSTRUCTIONS`. The available options on ARM64v8 are `OQS_USE_ARM_AES_INSTRUCTIONS`, `OQS_USE_ARM_SHA2_INSTRUCTIONS`, `OQS_USE_ARM_SHA3_INSTRUCTIONS` and `OQS_USE_ARM_NEON_INSTRUCTIONS`. **Default**: Options valid on the build machine. ## OQS_USE_OPENSSL -In order to save size and limit the mount of different cryptographic code bases, it is possible to use OpenSSL as a crypto code provider by setting this configuration option. +To save size and limit the amount of different cryptographic code bases, it is possible to use OpenSSL as a crypto code provider by setting this configuration option. This can be set to `ON` or `OFF`. When `ON`, the additional options `OQS_USE_AES_OPENSSL`, `OQS_USE_SHA2_OPENSSL`, and `OQS_USE_SHA3_OPENSSL` are made available to control whether liboqs uses OpenSSL's AES, SHA-2, and SHA-3 implementations. @@ -105,7 +107,7 @@ By default, - `OQS_USE_SHA2_OPENSSL` is `ON` - `OQS_USE_SHA3_OPENSSL` is `OFF`. -These default choices have been made in order to optimize the default performance of all algorithms. Changing them implies performance penalties. +These default choices have been made to optimize the default performance of all algorithms. Changing them implies performance penalties. When `OQS_USE_OPENSSL` is `ON`, CMake also scans the filesystem to find the minimum version of OpenSSL required by liboqs (which happens to be 1.1.1). The [OPENSSL_ROOT_DIR](https://cmake.org/cmake/help/latest/module/FindOpenSSL.html) option can be set to aid CMake in its search. @@ -123,7 +125,7 @@ An optimization target. Only has an effect if the compiler is GCC or Clang and ` Can be `ON` or `OFF`. When `ON`, the benchmarking script will try to use the ARMv8 Performance Monitoring Unit (PMU). This will make cycle counts on ARMv8 platforms significantly more accurate. -In order to use this option, user mode access to the PMU must be enabled via a kernel module. If user mode access is not enabled via kernel module, benchmarking will throw an `Illegal Instruction` error. A kernel module that has been found to work on several platforms can be found [here for linux](https://github.com/mupq/pqax#enable-access-to-performance-counters). Follow the instructions there (i.e., clone the repository, `cd enable_ccr` and `make install`) to load the kernel module, after which benchmarking should work. Superuser permissions are required. Linux header files must also be installed on your platform, which may not be present by default. +In order to use this option, user mode access to the PMU must be enabled via a kernel module. If user mode access is not enabled via the kernel module, benchmarking will throw an `Illegal Instruction` error. A kernel module that has been found to work on several platforms can be found [here for Linux](https://github.com/mupq/pqax#enable-access-to-performance-counters). Follow the instructions there (i.e., clone the repository, `cd enable_ccr` and `make install`) to load the kernel module, after which benchmarking should work. Superuser permissions are required. Linux header files must also be installed on your platform, which may not be present by default. Note that this option is not known to work on Apple M1 chips. @@ -131,7 +133,7 @@ Note that this option is not known to work on Apple M1 chips. ## USE_SANITIZER -This has effect when the compiler is Clang and when [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE) is `Debug`. Then, it can be set to: +This has an effect when the compiler is Clang and when [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE) is `Debug`. Then, it can be set to: - `Address`: This enables Clang's `AddressSanitizer` - `Memory`: This enables Clang's `MemorySanitizer` @@ -146,13 +148,13 @@ This has effect when the compiler is Clang and when [CMAKE_BUILD_TYPE](#CMAKE_BU This is used in conjunction with `tests/test_constant_time.py` to use Valgrind to look for instances of secret-dependent control flow. liboqs must also be compiled with [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE) set to `Debug`. -See the documentation in [`tests/test_constant_time.py`](https://github.com/open-quantum-safe/liboqs/blob/main/tests/test_constant_time.py) for more information on usage. +See the documentation in [`tests/test_constant_time.py`](https://github.com/open-quantum-safe/liboqs/blob/main/tests/test_constant_time.py) for more usage information. **Default**: `OFF`. ## OQS_STRICT_WARNINGS -Can be `ON` or `OFF`. When `ON`, all compiler warnings are enabled and treated as errors. This setting is recommended to be enabled prior to submission of a Pull Request as CI runs with this setting active. When `OFF`, significantly fewer compiler warnings are enabled such as to avoid undue build errors triggered by (future) compiler warning features/unknown at development time of this library. +Can be `ON` or `OFF`. When `ON`, all compiler warnings are enabled and treated as errors. This setting is recommended to be enabled prior to submission of a Pull Request as CI runs with this setting active. When `OFF`, significantly fewer compiler warnings are enabled such as to avoid undue build errors triggered by (future) compiler warning features/unknown at the development time of this library. **Default**: `OFF`. diff --git a/src/common/common.c b/src/common/common.c index 9d6fc9f048..153144fb3a 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -275,6 +275,26 @@ OQS_API void OQS_MEM_cleanse(void *ptr, size_t len) { #endif } +void *OQS_MEM_checked_malloc(size_t len) { + void *ptr = malloc(len); + if (ptr == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + return ptr; +} + +void *OQS_MEM_checked_aligned_alloc(size_t alignment, size_t size) { + void *ptr = OQS_MEM_aligned_alloc(alignment, size); + if (ptr == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + return ptr; +} + OQS_API void OQS_MEM_secure_free(void *ptr, size_t len) { if (ptr != NULL) { OQS_MEM_cleanse(ptr, len); diff --git a/src/common/common.h b/src/common/common.h index 8ddeef6f8f..b092baa036 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -180,6 +180,59 @@ OQS_API int OQS_MEM_secure_bcmp(const void *a, const void *b, size_t len); */ OQS_API void OQS_MEM_cleanse(void *ptr, size_t len); +/** + * Allocates memory of a specified size and checks for successful allocation. + * + * This function attempts to allocate a block of memory of the specified size. + * If the allocation is successful, it returns a pointer to the beginning of the + * memory block. If the allocation fails, it prints an error message to stderr + * and terminates the program. + * + * @param[in] len The size of the memory block to allocate, in bytes. + * + * @return A pointer to the allocated memory block if the allocation is successful. + * + * @note This function is intended to be used when the allocation must succeed, + * and failure to allocate memory is considered a fatal error. As such, + * it does not return if the allocation fails, but instead terminates the + * program with an exit status indicating failure. + * + * @note The memory block returned by this function is not initialized. The caller + * is responsible for initializing the memory if required. + * + * @note The allocated memory should be freed using the standard `free` function + * when it is no longer needed. + */ +void *OQS_MEM_checked_malloc(size_t len); + +/** + * Allocates memory of a specified size and alignment and checks for successful allocation. + * + * This function attempts to allocate a block of memory with the specified size + * and alignment. If the allocation is successful, it returns a pointer to the + * memory block. If the allocation fails, it prints an error message to stderr + * and terminates the program. + * + * Alignment must be a power of two and a multiple of sizeof(void *). + * + * @param[in] alignment The alignment of the memory block to allocate. + * @param[in] size The size of the memory block to allocate, in bytes. + * + * @return A pointer to the allocated memory block if the allocation is successful. + * + * @note This function is intended to be used when the allocation must succeed, + * and failure to allocate memory is considered a fatal error. As such, + * it does not return if the allocation fails, but instead terminates the + * program with an exit status indicating failure. + * + * @note The memory block returned by this function is not initialized. The caller + * is responsible for initializing the memory if required. + * + * @note The allocated memory should be freed with `OQS_MEM_aligned_free` when it + * is no longer needed. + */ +void *OQS_MEM_checked_aligned_alloc(size_t alignment, size_t size); + /** * Zeros out `len` bytes of memory starting at `ptr`, then frees `ptr`. * @@ -211,6 +264,8 @@ OQS_API void OQS_MEM_insecure_free(void *ptr); * 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. + * @note The allocated memory should be freed with `OQS_MEM_aligned_free` when it + * is no longer needed. */ void *OQS_MEM_aligned_alloc(size_t alignment, size_t size); diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index dc8661485b..65ea6750c3 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -180,10 +180,7 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui new_in = in; } else { // Combine incremental data with final input - tmp_in = malloc(tmp_len); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(tmp_len); memcpy(tmp_in, state->data, state->data_len); if (in && inlen) { @@ -257,10 +254,7 @@ void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_ /* Process any existing incremental data first */ if (state->data_len) { - tmp_in = malloc(buf_len); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(buf_len); memcpy(tmp_in, state->data, state->data_len); memcpy(tmp_in + state->data_len, in, buf_len - state->data_len); @@ -280,17 +274,15 @@ void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_ } void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) { - uint64_t bytes = 0; - size_t in_index = 0; while (len) { size_t incr = 64 - state->data_len; if (incr > len) { incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { - state->data[state->data_len] = in[in_index]; - } + memcpy(state->data + state->data_len, in, incr); + state->data_len += incr; + in += incr; if (state->data_len < 64) { break; @@ -299,7 +291,7 @@ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) /* * Process a complete block now */ - bytes = load_bigendian_64(state->ctx + 32) + 64; + uint64_t bytes = load_bigendian_64(state->ctx + 32) + 64; crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); store_bigendian_64(state->ctx + 32, bytes); diff --git a/src/common/sha2/sha2_c.c b/src/common/sha2/sha2_c.c index b0f628136a..e5bd350889 100644 --- a/src/common/sha2/sha2_c.c +++ b/src/common/sha2/sha2_c.c @@ -502,10 +502,8 @@ static const uint8_t iv_512[64] = { }; void oqs_sha2_sha224_inc_init_c(sha224ctx *state) { - state->ctx = malloc(PQC_SHA256CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + for (size_t i = 0; i < 32; ++i) { state->ctx[i] = iv_224[i]; } @@ -518,10 +516,8 @@ void oqs_sha2_sha224_inc_init_c(sha224ctx *state) { void oqs_sha2_sha256_inc_init_c(sha256ctx *state) { state->data_len = 0; - state->ctx = malloc(PQC_SHA256CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + for (size_t i = 0; i < 32; ++i) { state->ctx[i] = iv_256[i]; } @@ -533,10 +529,8 @@ void oqs_sha2_sha256_inc_init_c(sha256ctx *state) { } void oqs_sha2_sha384_inc_init_c(sha384ctx *state) { - state->ctx = malloc(PQC_SHA512CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + for (size_t i = 0; i < 64; ++i) { state->ctx[i] = iv_384[i]; } @@ -548,10 +542,8 @@ void oqs_sha2_sha384_inc_init_c(sha384ctx *state) { } void oqs_sha2_sha512_inc_init_c(sha512ctx *state) { - state->ctx = malloc(PQC_SHA512CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + for (size_t i = 0; i < 64; ++i) { state->ctx[i] = iv_512[i]; } @@ -563,40 +555,32 @@ void oqs_sha2_sha512_inc_init_c(sha512ctx *state) { } void oqs_sha2_sha224_inc_ctx_clone_c(sha224ctx *stateout, const sha224ctx *statein) { - stateout->ctx = malloc(PQC_SHA256CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA256CTX_BYTES); } void oqs_sha2_sha256_inc_ctx_clone_c(sha256ctx *stateout, const sha256ctx *statein) { - stateout->ctx = malloc(PQC_SHA256CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA256CTX_BYTES); } void oqs_sha2_sha384_inc_ctx_clone_c(sha384ctx *stateout, const sha384ctx *statein) { - stateout->ctx = malloc(PQC_SHA512CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA512CTX_BYTES); } void oqs_sha2_sha512_inc_ctx_clone_c(sha512ctx *stateout, const sha512ctx *statein) { - stateout->ctx = malloc(PQC_SHA512CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA512CTX_BYTES); @@ -630,10 +614,7 @@ void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t in /* Process any existing incremental data first */ if (state->data_len) { - tmp_in = malloc(tmp_buflen); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(tmp_buflen); memcpy(tmp_in, state->data, state->data_len); memcpy(tmp_in + state->data_len, in, tmp_buflen - state->data_len); @@ -653,17 +634,15 @@ void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t in } void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len) { - uint64_t bytes = 0; - size_t in_index = 0; while (len) { size_t incr = 64 - state->data_len; if (incr > len) { incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { - state->data[state->data_len] = in[in_index]; - } + memcpy(state->data + state->data_len, in, incr); + state->data_len += incr; + in += incr; if (state->data_len < 64) { break; @@ -672,9 +651,8 @@ void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len) { /* * Process a complete block now */ - bytes = load_bigendian_64(state->ctx + 32); + uint64_t bytes = load_bigendian_64(state->ctx + 32) + 64; crypto_hashblocks_sha256_c(state->ctx, state->data, 64); - bytes += 64; store_bigendian_64(state->ctx + 32, bytes); /* @@ -713,10 +691,7 @@ void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_ if (new_inlen == inlen) { new_in = in; } else { //Combine incremental data with final input - tmp_in = malloc(tmp_len); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(tmp_len); memcpy(tmp_in, state->data, state->data_len); if (in && inlen) { @@ -868,4 +843,3 @@ void oqs_sha2_sha512_c(uint8_t *out, const uint8_t *in, size_t inlen) { oqs_sha2_sha512_inc_init_c(&state); oqs_sha2_sha512_inc_finalize_c(out, &state, in, inlen); } - diff --git a/src/common/sha3/ossl_sha3.c b/src/common/sha3/ossl_sha3.c index 8b8678a26f..57062e9567 100644 --- a/src/common/sha3/ossl_sha3.c +++ b/src/common/sha3/ossl_sha3.c @@ -194,11 +194,8 @@ void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shak if (s->n_out == 0) { EVP_DigestFinalXOF(clone, output, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); + EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); memcpy(output, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check @@ -271,11 +268,8 @@ void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shak if (s->n_out == 0) { EVP_DigestFinalXOF(clone, output, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); + EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); memcpy(output, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check diff --git a/src/common/sha3/ossl_sha3x4.c b/src/common/sha3/ossl_sha3x4.c index 1e4697201c..a8acc574eb 100644 --- a/src/common/sha3/ossl_sha3x4.c +++ b/src/common/sha3/ossl_sha3x4.c @@ -75,11 +75,8 @@ void OQS_SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out EVP_MD_CTX_copy_ex(clone, s->mdctx3); EVP_DigestFinalXOF(clone, out3, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); + EVP_MD_CTX_copy_ex(clone, s->mdctx0); EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); memcpy(out0, tmp + s->n_out, outlen); @@ -193,11 +190,8 @@ void OQS_SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out EVP_MD_CTX_copy_ex(clone, s->mdctx3); EVP_DigestFinalXOF(clone, out3, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); + EVP_MD_CTX_copy_ex(clone, s->mdctx0); EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); memcpy(out0, tmp + s->n_out, outlen); diff --git a/src/common/sha3/xkcp_sha3.c b/src/common/sha3/xkcp_sha3.c index e9192862ef..fa47005d27 100644 --- a/src/common/sha3/xkcp_sha3.c +++ b/src/common/sha3/xkcp_sha3.c @@ -199,10 +199,8 @@ void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { } void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); + keccak_inc_reset((uint64_t *)state->ctx); } @@ -238,10 +236,8 @@ void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) { } void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); + keccak_inc_reset((uint64_t *)state->ctx); } @@ -277,10 +273,8 @@ void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { } void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); + keccak_inc_reset((uint64_t *)state->ctx); } @@ -319,10 +313,8 @@ void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, siz /* SHAKE128 incremental */ void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); + keccak_inc_reset((uint64_t *)state->ctx); } @@ -364,10 +356,8 @@ void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, siz /* SHAKE256 incremental */ void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); + keccak_inc_reset((uint64_t *)state->ctx); } diff --git a/src/common/sha3/xkcp_sha3x4.c b/src/common/sha3/xkcp_sha3x4.c index fbd9a0e8c5..46b1455207 100644 --- a/src/common/sha3/xkcp_sha3x4.c +++ b/src/common/sha3/xkcp_sha3x4.c @@ -167,10 +167,8 @@ void OQS_SHA3_shake128_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t * /* SHAKE128 incremental */ void OQS_SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); + keccak_x4_inc_reset((uint64_t *)state->ctx); } @@ -212,10 +210,8 @@ void OQS_SHA3_shake256_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t * /* SHAKE256 incremental */ void OQS_SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); + keccak_x4_inc_reset((uint64_t *)state->ctx); }