Refactor OpenSSL Implementation of SHA3 SHAKE to use new Squeeze API (#1694)

* Refactor OQS OpenSSL SHA3 SHAKE to use new EVP_DigestSqueeze() #1539

* Add OpenSSL 3.3.0 test and conditional fix

* Update ref to use human readable commit tag

Signed-off-by: Eddy Kim <Eddy.M.Kim@outlook.com>
Co-authored-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
This commit is contained in:
Eddy Kim 2024-04-07 10:27:15 -07:00 committed by GitHub
parent 701dea5d2a
commit cfc41f7560
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 72 additions and 4 deletions

View File

@ -222,3 +222,50 @@ jobs:
- name: Run tests
run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_kat_all.py ${{ matrix.PYTEST_ARGS }}
timeout-minutes: 60
linux_openssl330-dev:
needs: buildcheck
runs-on: ubuntu-latest
container:
image: openquantumsafe/ci-ubuntu-jammy:latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Retrieve OpenSSL330 from cache
id: cache-openssl330
uses: actions/cache@v3
with:
path: .localopenssl330
key: ${{ runner.os }}-openssl330
- name: Checkout the OpenSSL v3.3.0 commit
if: steps.cache-openssl330.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'openssl/openssl'
ref: 'openssl-3.3.0-beta1'
path: openssl
- name: Prepare the OpenSSL build directory
if: steps.cache-openssl330.outputs.cache-hit != 'true'
run: mkdir .localopenssl330
working-directory: openssl
- name: Build openssl3 if not cached
if: steps.cache-openssl330.outputs.cache-hit != 'true'
run: |
./config --prefix=`pwd`/../.localopenssl330 && make -j 4 && make install_sw install_ssldirs
working-directory: openssl
- name: Save OpenSSL
id: cache-openssl-save
if: steps.cache-openssl330.outputs.cache-hit != 'true'
uses: actions/cache/save@v3
with:
path: |
.localopenssl330
key: ${{ runner.os }}-openssl330
- name: Configure
run: mkdir build && cd build && cmake -GNinja -DOQS_STRICT_WARNINGS=ON -DOPENSSL_ROOT_DIR=../.localopenssl330 -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON .. && cmake -LA ..
- name: Build
run: ninja
working-directory: build
- name: Run tests
timeout-minutes: 60
run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py

View File

@ -144,6 +144,8 @@ static void SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input,
}
/* SHAKE-128 incremental
*
* Note: the comment below has been addressed in OpenSSL version 3.3.0
*
* XXX: The OpenSSL XOF API only allows for a single
* call to squeeze (EVP_DigestFinalXOF).
@ -185,6 +187,9 @@ static void SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state) {
static void SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state) {
intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)state->ctx;
#if OPENSSL_VERSION_NUMBER >= 0x30300000L
EVP_DigestSqueeze(s->mdctx, output, outlen);
#else
EVP_MD_CTX *clone;
clone = OSSL_FUNC(EVP_MD_CTX_new)();
@ -204,6 +209,7 @@ static void SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_s
}
OSSL_FUNC(EVP_MD_CTX_free)(clone);
s->n_out += outlen;
#endif
}
static void SHA3_shake128_inc_ctx_release(OQS_SHA3_shake128_inc_ctx *state) {
@ -232,10 +238,7 @@ static void SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input,
do_xof(output, outlen, input, inplen, oqs_shake256());
}
/* SHAKE-256 incremental
*
* XXX: See note above regarding SHAKE-128 incremental
*/
/* SHAKE-256 incremental */
typedef struct {
EVP_MD_CTX *mdctx;
@ -262,6 +265,9 @@ static void SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state) {
static void SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state) {
intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)state->ctx;
#if OPENSSL_VERSION_NUMBER >= 0x30300000L
EVP_DigestSqueeze(s->mdctx, output, outlen);
#else
EVP_MD_CTX *clone;
clone = OSSL_FUNC(EVP_MD_CTX_new)();
@ -281,6 +287,7 @@ static void SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_s
}
OSSL_FUNC(EVP_MD_CTX_free)(clone);
s->n_out += outlen;
#endif
}
static void SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) {

View File

@ -61,6 +61,12 @@ static void SHA3_shake128_x4_inc_finalize(OQS_SHA3_shake128_x4_inc_ctx *state) {
static void SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake128_x4_inc_ctx *state) {
intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)state->ctx;
#if OPENSSL_VERSION_NUMBER >= 0x30300000L
EVP_DigestSqueeze(s->mdctx0, out0, outlen);
EVP_DigestSqueeze(s->mdctx1, out1, outlen);
EVP_DigestSqueeze(s->mdctx2, out2, outlen);
EVP_DigestSqueeze(s->mdctx3, out3, outlen);
#else
EVP_MD_CTX *clone;
clone = OSSL_FUNC(EVP_MD_CTX_new)();
@ -96,6 +102,7 @@ static void SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *
}
OSSL_FUNC(EVP_MD_CTX_free)(clone);
s->n_out += outlen;
#endif
}
static void SHA3_shake128_x4_inc_ctx_clone(OQS_SHA3_shake128_x4_inc_ctx *dest, const OQS_SHA3_shake128_x4_inc_ctx *src) {
@ -179,6 +186,12 @@ static void SHA3_shake256_x4_inc_finalize(OQS_SHA3_shake256_x4_inc_ctx *state) {
static void SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake256_x4_inc_ctx *state) {
intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)state->ctx;
#if OPENSSL_VERSION_NUMBER >= 0x30300000L
EVP_DigestSqueeze(s->mdctx0, out0, outlen);
EVP_DigestSqueeze(s->mdctx1, out1, outlen);
EVP_DigestSqueeze(s->mdctx2, out2, outlen);
EVP_DigestSqueeze(s->mdctx3, out3, outlen);
#else
EVP_MD_CTX *clone;
clone = OSSL_FUNC(EVP_MD_CTX_new)();
@ -214,6 +227,7 @@ static void SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *
}
OSSL_FUNC(EVP_MD_CTX_free)(clone);
s->n_out += outlen;
#endif
}
static void SHA3_shake256_x4_inc_ctx_clone(OQS_SHA3_shake256_x4_inc_ctx *dest, const OQS_SHA3_shake256_x4_inc_ctx *src) {