From 4a175ba280196488e4ad15bdb6ccecc93902f4d0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 19 Jul 2023 15:26:04 +0200 Subject: [PATCH] Updates for Kerberos 5 1.21.1 - wolfssl_ec_point_mul: fix parameters being passed into ec_mul2add - Compile in compressed ecc key parsing for OPENSSLALL - Improve debugging around compat layer ecc operations - wolfSSL_BN_div: dv can be NULL - Add spake like computation test - Add CI krb5 testing - Add timeouts to CI --- .github/workflows/curl.yml | 1 - .github/workflows/krb5.yml | 84 +++++++++++++++++++++ .github/workflows/main.yml | 2 + .github/workflows/nginx.yml | 1 - configure.ac | 2 +- src/pk.c | 138 +++++++++++++++++++++++++++++++--- src/ssl.c | 26 ++++--- src/ssl_bn.c | 12 ++- tests/api.c | 145 ++++++++++++++++++++++++++++++++++++ wolfssl/openssl/ec.h | 3 + wolfssl/openssl/evp.h | 1 + wolfssl/openssl/opensslv.h | 4 +- 12 files changed, 392 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/krb5.yml diff --git a/.github/workflows/curl.yml b/.github/workflows/curl.yml index da2b149a18..77b1cee185 100644 --- a/.github/workflows/curl.yml +++ b/.github/workflows/curl.yml @@ -1,7 +1,6 @@ name: curl Test on: - push: workflow_call: jobs: diff --git a/.github/workflows/krb5.yml b/.github/workflows/krb5.yml new file mode 100644 index 0000000000..c7c7b417e8 --- /dev/null +++ b/.github/workflows/krb5.yml @@ -0,0 +1,84 @@ +name: Kerberos 5 Tests + +on: + workflow_call: + # TODO remove push when opening the PR + push: + +jobs: + build_wolfssl: + name: Build wolfSSL + # Just to keep it the same as the testing target + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 5 + steps: + - name: Build wolfSSL + uses: wolfSSL/actions-build-autotools-project@v1 + with: + path: wolfssl + configure: --enable-krb CFLAGS='-fsanitize=address' + install: true + + - name: Upload built lib + uses: actions/upload-artifact@v3 + with: + name: wolf-install-krb5 + path: build-dir + retention-days: 1 + + krb5_check: + strategy: + fail-fast: false + matrix: + # List of releases to test + ref: [ 1.21.1 ] + name: ${{ matrix.ref }} + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 8 + needs: build_wolfssl + steps: + - name: Download lib + uses: actions/download-artifact@v3 + with: + name: wolf-install-krb5 + path: build-dir + + - name: Checkout OSP + uses: actions/checkout@v3 + with: + # TODO revert repo to wolfssl on merge + repository: julek-wolfssl/osp + # TODO remove ref on merge + ref: krb5-1.21.1 + path: osp + + - name: Checkout krb5 + uses: actions/checkout@v3 + with: + repository: krb5/krb5 + ref: krb5-${{ matrix.ref }}-final + path: krb5 + + - name: Apply patch + working-directory: ./krb5 + run: | + patch -p1 < $GITHUB_WORKSPACE/osp/krb5/Patch-for-Kerberos-5-${{ matrix.ref }}.patch + + - name: Build krb5 + working-directory: ./krb5/src + run: | + autoreconf -ivf + # Using rpath because LD_LIBRARY_PATH is overwritten during testing + export WOLFSSL_CFLAGS="-I$GITHUB_WORKSPACE/build-dir/include -I$GITHUB_WORKSPACE/build-dir/include/wolfssl -Wl,-rpath=$GITHUB_WORKSPACE/build-dir/lib" + export WOLFSSL_LIBS="-lwolfssl -L$GITHUB_WORKSPACE/build-dir/lib -Wl,-rpath=$GITHUB_WORKSPACE/build-dir/lib" + ./configure --with-crypto-impl=wolfssl --with-tls-impl=wolfssl --disable-pkinit \ + CFLAGS='-fsanitize=address' LDFLAGS='-fsanitize=address' + CFLAGS='-fsanitize=address' LDFLAGS='-fsanitize=address' make -j + + - name: Run tests + working-directory: ./krb5/src + run: | + CFLAGS='-fsanitize=address' LDFLAGS='-fsanitize=address' make -j check + diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0818590776..dd550a9c87 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,6 +34,8 @@ jobs: uses: ./.github/workflows/hitch.yml curl: uses: ./.github/workflows/curl.yml + krb5: + uses: ./.github/workflows/krb5.yml # TODO: Currently this test fails. Enable it once it becomes passing. # haproxy: # uses: ./.github/workflows/haproxy.yml diff --git a/.github/workflows/nginx.yml b/.github/workflows/nginx.yml index 7ac5e92f80..c6f7b502da 100644 --- a/.github/workflows/nginx.yml +++ b/.github/workflows/nginx.yml @@ -1,7 +1,6 @@ name: nginx Tests on: - push: workflow_call: jobs: diff --git a/configure.ac b/configure.ac index 98013f58a5..a1d29d849e 100644 --- a/configure.ac +++ b/configure.ac @@ -3526,7 +3526,7 @@ AC_ARG_ENABLE([compkey], [ ENABLED_COMPKEY=no ] ) -if test "$ENABLED_WPAS" = "yes" +if test "$ENABLED_WPAS" = "yes" || test "$ENABLED_OPENSSLALL" = "yes" then ENABLED_COMPKEY=yes fi diff --git a/src/pk.c b/src/pk.c index 5e429939c4..8054e84659 100644 --- a/src/pk.c +++ b/src/pk.c @@ -9711,27 +9711,27 @@ void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *point) WOLFSSL_ENTER("wolfSSL_EC_POINT_dump"); - /* Only print when debugging on and logging callback set. */ - if (WOLFSSL_IS_DEBUG_ON() && (wolfSSL_GetLoggingCb() == NULL)) { + /* Only print when debugging on. */ + if (WOLFSSL_IS_DEBUG_ON()) { if (point == NULL) { /* No point passed in so just put out "NULL". */ - XFPRINTF(stderr, "%s = NULL\n", msg); + WOLFSSL_MSG_EX("%s = NULL\n", msg); } else { /* Put out message and status of internal/external data set. */ - XFPRINTF(stderr, "%s:\n\tinSet=%d, exSet=%d\n", msg, point->inSet, + WOLFSSL_MSG_EX("%s:\n\tinSet=%d, exSet=%d\n", msg, point->inSet, point->exSet); /* Get x-ordinate as a hex string and print. */ num = wolfSSL_BN_bn2hex(point->X); - XFPRINTF(stderr, "\tX = %s\n", num); + WOLFSSL_MSG_EX("\tX = %s\n", num); XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); /* Get x-ordinate as a hex string and print. */ num = wolfSSL_BN_bn2hex(point->Y); - XFPRINTF(stderr, "\tY = %s\n", num); + WOLFSSL_MSG_EX("\tY = %s\n", num); XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); /* Get z-ordinate as a hex string and print. */ num = wolfSSL_BN_bn2hex(point->Z); - XFPRINTF(stderr, "\tZ = %s\n", num); + WOLFSSL_MSG_EX("\tZ = %s\n", num); XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); } } @@ -9922,6 +9922,8 @@ int wolfSSL_ECPoint_d2i(const unsigned char *in, unsigned int len, const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *point) { int ret = 1; + WOLFSSL_BIGNUM* x = NULL; + WOLFSSL_BIGNUM* y = NULL; WOLFSSL_ENTER("wolfSSL_ECPoint_d2i"); @@ -9958,17 +9960,49 @@ int wolfSSL_ECPoint_d2i(const unsigned char *in, unsigned int len, #endif } + if (ret == 1) + point->inSet = 1; + /* Set new external point. */ - if ((ret == 1) && (ec_point_external_set(point) != 1)) { + if (ret == 1 && ec_point_external_set(point) != 1) { WOLFSSL_MSG("ec_point_external_set failed"); ret = 0; } + if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) { +#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) + x = wolfSSL_BN_new(); + y = wolfSSL_BN_new(); + if (x == NULL || y == NULL) + ret = 0; + + if (ret == 1 && wolfSSL_EC_POINT_get_affine_coordinates_GFp(group, + point, x, y, NULL) != 1) { + WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp failed"); + ret = 0; + } + + /* wolfSSL_EC_POINT_set_affine_coordinates_GFp check that the point is + * on the curve. */ + if (ret == 1 && wolfSSL_EC_POINT_set_affine_coordinates_GFp(group, + point, x, y, NULL) != 1) { + WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp failed"); + ret = 0; + } +#else + WOLFSSL_MSG("Importing non-affine point. This may cause issues in math " + "operations later on."); +#endif + } + if (ret == 1) { /* Dump new point. */ wolfSSL_EC_POINT_dump("d2i p", point); } + wolfSSL_BN_free(x); + wolfSSL_BN_free(y); + return ret; } @@ -10060,6 +10094,14 @@ size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, } } +#if defined(DEBUG_WOLFSSL) + if (!err) { + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_point2oct point", point); + WOLFSSL_MSG("\twolfSSL_EC_POINT_point2oct output:"); + WOLFSSL_BUFFER(buf, enc_len); + } +#endif + /* On error, return encoding length of 0. */ if (err) { enc_len = 0; @@ -10209,7 +10251,7 @@ int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, * @return 1 on success. * @return 0 on error. */ -static int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group, +int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *point) { int err = 0; @@ -10606,6 +10648,20 @@ int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP* group, WOLFSSL_EC_POINT* r, ret = 0; } +#ifdef DEBUG_WOLFSSL + if (ret == 1) { + int nid = wolfSSL_EC_GROUP_get_curve_name(group); + const char* curve = wolfSSL_OBJ_nid2ln(nid); + const char* nistName = wolfSSL_EC_curve_nid2nist(nid); + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p1", p1); + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p2", p2); + if (curve != NULL) + WOLFSSL_MSG_EX("curve name: %s", curve); + if (nistName != NULL) + WOLFSSL_MSG_EX("nist curve name: %s", nistName); + } +#endif + if (ret == 1) { /* Add points using wolfCrypt objects. */ ret = wolfssl_ec_point_add(group->curve_idx, (ecc_point*)r->internal, @@ -10618,6 +10674,12 @@ int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP* group, WOLFSSL_EC_POINT* r, ret = 0; } +#ifdef DEBUG_WOLFSSL + if (ret == 1) { + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add result", r); + } +#endif + return ret; } @@ -10779,7 +10841,7 @@ static int wolfssl_ec_point_mul(int curveIdx, ecc_point* r, mp_int* n, if ((ret == 1) && (n != NULL) && (q != NULL) && (m != NULL)) { /* r = base point * n + q * m */ - ec_mul2add(r, r, m, q, n, a, prime); + ret = ec_mul2add(r, r, n, q, m, a, prime); } /* Not all values present, see if we are only doing base point * n. */ else if ((ret == 1) && (n != NULL)) { @@ -10852,6 +10914,26 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, ret = 0; } +#ifdef DEBUG_WOLFSSL + if (ret == 1) { + int nid = wolfSSL_EC_GROUP_get_curve_name(group); + const char* curve = wolfSSL_OBJ_nid2ln(nid); + const char* nistName = wolfSSL_EC_curve_nid2nist(nid); + char* num; + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul input q", q); + num = wolfSSL_BN_bn2hex(n); + WOLFSSL_MSG_EX("\tn = %s", num); + XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); + num = wolfSSL_BN_bn2hex(m); + WOLFSSL_MSG_EX("\tm = %s", num); + XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); + if (curve != NULL) + WOLFSSL_MSG_EX("curve name: %s", curve); + if (nistName != NULL) + WOLFSSL_MSG_EX("nist curve name: %s", nistName); + } +#endif + if (ret == 1) { mp_int* ni = (n != NULL) ? (mp_int*)n->internal : NULL; ecc_point* qi = (q != NULL) ? (ecc_point*)q->internal : NULL; @@ -10872,6 +10954,12 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, ret = 0; } +#ifdef DEBUG_WOLFSSL + if (ret == 1) { + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul result", r); + } +#endif + return ret; } #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !HAVE_SELFTEST && @@ -10960,6 +11048,30 @@ int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, ret = 0; } +#ifdef DEBUG_WOLFSSL + if (ret == 1) { + int nid = wolfSSL_EC_GROUP_get_curve_name(group); + const char* curve = wolfSSL_OBJ_nid2ln(nid); + const char* nistName = wolfSSL_EC_curve_nid2nist(nid); + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert input", point); + if (curve != NULL) + WOLFSSL_MSG_EX("curve name: %s", curve); + if (nistName != NULL) + WOLFSSL_MSG_EX("nist curve name: %s", nistName); + + } +#endif + + if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) { +#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) + if (ec_point_convert_to_affine(group, point) != 0) + ret = 0; +#else + WOLFSSL_MSG("wolfSSL_EC_POINT_invert called on non-affine point"); + ret = 0; +#endif + } + if (ret == 1) { /* Perform inversion using wolfCrypt objects. */ ret = wolfssl_ec_point_invert(group->curve_idx, @@ -10972,6 +11084,12 @@ int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, ret = 0; } +#ifdef DEBUG_WOLFSSL + if (ret == 1) { + wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert result", point); + } +#endif + return ret; } diff --git a/src/ssl.c b/src/ssl.c index b89a5b888e..bf0890a679 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23747,12 +23747,14 @@ size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in, if (lastBlkLen == 0) lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ; - /* Encrypt data up to last block */ - (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPT); + if (len - lastBlkLen != 0) { + /* Encrypt data up to last block */ + (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPT); - /* Move to last block */ - in += len - lastBlkLen; - out += len - lastBlkLen; + /* Move to last block */ + in += len - lastBlkLen; + out += len - lastBlkLen; + } /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */ XMEMCPY(lastBlk, in, lastBlkLen); @@ -23783,13 +23785,15 @@ size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in, if (lastBlkLen == 0) lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ; - /* Decrypt up to last two blocks */ - (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv, - AES_DECRYPTION); + if (len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ != 0) { + /* Decrypt up to last two blocks */ + (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv, + AES_DECRYPTION); - /* Move to last two blocks */ - in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; - out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; + /* Move to last two blocks */ + in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; + out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; + } /* RFC2040: Decrypt Cn-1 to create Dn. * Use 0 buffer as IV to do straight decryption. diff --git a/src/ssl_bn.c b/src/ssl_bn.c index 9102a8e03e..8a054c807c 100644 --- a/src/ssl_bn.c +++ b/src/ssl_bn.c @@ -1689,23 +1689,31 @@ int wolfSSL_BN_div(WOLFSSL_BIGNUM* dv, WOLFSSL_BIGNUM* rem, const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* d, WOLFSSL_BN_CTX* ctx) { int ret = 1; + WOLFSSL_BIGNUM* res = dv; /* BN context not needed. */ (void)ctx; WOLFSSL_ENTER("wolfSSL_BN_div"); + if (BN_IS_NULL(res)) { + res = wolfSSL_BN_new(); + } + /* Validate parameters. */ - if (BN_IS_NULL(dv) || BN_IS_NULL(rem) || BN_IS_NULL(a) || BN_IS_NULL(d)) { + if (BN_IS_NULL(res) || BN_IS_NULL(rem) || BN_IS_NULL(a) || BN_IS_NULL(d)) { ret = 0; } /* Have wolfCrypt perform operation with internal representations. */ if ((ret == 1) && (mp_div((mp_int*)a->internal, (mp_int*)d->internal, - (mp_int*)dv->internal, (mp_int*)rem->internal) != MP_OKAY)) { + (mp_int*)res->internal, (mp_int*)rem->internal) != MP_OKAY)) { ret = 0; } + if (res != dv) + wolfSSL_BN_free(res); + WOLFSSL_LEAVE("wolfSSL_BN_div", ret); return ret; } diff --git a/tests/api.c b/tests/api.c index d11dc59dac..77dff94b4a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -56237,6 +56237,23 @@ static int test_wolfSSL_EC_POINT(void) ExpectIntEQ(EC_POINT_invert(group, NULL, ctx), 0); ExpectIntEQ(EC_POINT_invert(group, new_point, ctx), 1); +#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \ + !defined(WOLF_CRYPTO_CB_ONLY_ECC) + { + EC_POINT* orig_point = NULL; + ExpectNotNull(orig_point = EC_POINT_new(group)); + ExpectIntEQ(EC_POINT_add(group, orig_point, set_point, set_point, NULL), + 1); + /* new_point should be set_point inverted so adding it will revert + * the point back to set_point */ + ExpectIntEQ(EC_POINT_add(group, orig_point, orig_point, new_point, + NULL), 1); + ExpectIntEQ(EC_POINT_cmp(group, orig_point, set_point, NULL), 0); + EC_POINT_free(orig_point); + } +#endif + /* Test getting affine converts from projective. */ ExpectIntEQ(EC_POINT_copy(set_point, new_point), 1); /* Force non-affine coordinates */ @@ -56478,6 +56495,133 @@ static int test_wolfSSL_EC_POINT(void) return EXPECT_RESULT(); } +static int test_wolfSSL_SPAKE(void) +{ + EXPECT_DECLS; + +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(WOLFSSL_ATECC508A) \ + && !defined(WOLFSSL_ATECC608A) && !defined(HAVE_SELFTEST) && \ + !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) + BIGNUM* x = NULL; /* kdc priv */ + BIGNUM* y = NULL; /* client priv */ + BIGNUM* w = NULL; /* shared value */ + byte M_bytes[] = { + /* uncompressed */ + 0x04, + /* x */ + 0x88, 0x6e, 0x2f, 0x97, 0xac, 0xe4, 0x6e, 0x55, 0xba, 0x9d, 0xd7, 0x24, + 0x25, 0x79, 0xf2, 0x99, 0x3b, 0x64, 0xe1, 0x6e, 0xf3, 0xdc, 0xab, 0x95, + 0xaf, 0xd4, 0x97, 0x33, 0x3d, 0x8f, 0xa1, 0x2f, + /* y */ + 0x5f, 0xf3, 0x55, 0x16, 0x3e, 0x43, 0xce, 0x22, 0x4e, 0x0b, 0x0e, 0x65, + 0xff, 0x02, 0xac, 0x8e, 0x5c, 0x7b, 0xe0, 0x94, 0x19, 0xc7, 0x85, 0xe0, + 0xca, 0x54, 0x7d, 0x55, 0xa1, 0x2e, 0x2d, 0x20 + }; + EC_POINT* M = NULL; /* shared value */ + byte N_bytes[] = { + /* uncompressed */ + 0x04, + /* x */ + 0xd8, 0xbb, 0xd6, 0xc6, 0x39, 0xc6, 0x29, 0x37, 0xb0, 0x4d, 0x99, 0x7f, + 0x38, 0xc3, 0x77, 0x07, 0x19, 0xc6, 0x29, 0xd7, 0x01, 0x4d, 0x49, 0xa2, + 0x4b, 0x4f, 0x98, 0xba, 0xa1, 0x29, 0x2b, 0x49, + /* y */ + 0x07, 0xd6, 0x0a, 0xa6, 0xbf, 0xad, 0xe4, 0x50, 0x08, 0xa6, 0x36, 0x33, + 0x7f, 0x51, 0x68, 0xc6, 0x4d, 0x9b, 0xd3, 0x60, 0x34, 0x80, 0x8c, 0xd5, + 0x64, 0x49, 0x0b, 0x1e, 0x65, 0x6e, 0xdb, 0xe7 + }; + EC_POINT* N = NULL; /* shared value */ + EC_POINT* T = NULL; /* kdc pub */ + EC_POINT* tmp1 = NULL; /* kdc pub */ + EC_POINT* tmp2 = NULL; /* kdc pub */ + EC_POINT* S = NULL; /* client pub */ + EC_POINT* client_secret = NULL; + EC_POINT* kdc_secret = NULL; + EC_GROUP* group = NULL; + BN_CTX* bn_ctx = NULL; + + /* Values taken from a test run of Kerberos 5 */ + + ExpectNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + ExpectNotNull(bn_ctx = BN_CTX_new()); + + ExpectNotNull(M = EC_POINT_new(group)); + ExpectNotNull(N = EC_POINT_new(group)); + ExpectNotNull(T = EC_POINT_new(group)); + ExpectNotNull(tmp1 = EC_POINT_new(group)); + ExpectNotNull(tmp2 = EC_POINT_new(group)); + ExpectNotNull(S = EC_POINT_new(group)); + ExpectNotNull(client_secret = EC_POINT_new(group)); + ExpectNotNull(kdc_secret = EC_POINT_new(group)); + ExpectIntEQ(BN_hex2bn(&x, "DAC3027CD692B4BDF0EDFE9B7D0E4E7" + "E5D8768A725EAEEA6FC68EC239A17C0"), 1); + ExpectIntEQ(BN_hex2bn(&y, "6F6A1D394E26B1655A54B26DCE30D49" + "90CC47EBE08F809EF3FF7F6AEAABBB5"), 1); + ExpectIntEQ(BN_hex2bn(&w, "1D992AB8BA851B9BA05353453D81EE9" + "506AB395478F0AAB647752CF117B36250"), 1); + ExpectIntEQ(EC_POINT_oct2point(group, M, M_bytes, sizeof(M_bytes), bn_ctx), + 1); + ExpectIntEQ(EC_POINT_oct2point(group, N, N_bytes, sizeof(N_bytes), bn_ctx), + 1); + + /* Function pattern similar to ossl_keygen and ossl_result in krb5 */ + + /* kdc */ + /* T=x*P+w*M */ + /* All in one function call */ + ExpectIntEQ(EC_POINT_mul(group, T, x, M, w, bn_ctx), 1); + /* Spread into separate calls */ + ExpectIntEQ(EC_POINT_mul(group, tmp1, x, NULL, NULL, bn_ctx), 1); + ExpectIntEQ(EC_POINT_mul(group, tmp2, NULL, M, w, bn_ctx), 1); + ExpectIntEQ(EC_POINT_add(group, tmp1, tmp1, tmp2, bn_ctx), + 1); + ExpectIntEQ(EC_POINT_cmp(group, T, tmp1, bn_ctx), 0); + /* client */ + /* S=y*P+w*N */ + /* All in one function call */ + ExpectIntEQ(EC_POINT_mul(group, S, y, N, w, bn_ctx), 1); + /* Spread into separate calls */ + ExpectIntEQ(EC_POINT_mul(group, tmp1, y, NULL, NULL, bn_ctx), 1); + ExpectIntEQ(EC_POINT_mul(group, tmp2, NULL, N, w, bn_ctx), 1); + ExpectIntEQ(EC_POINT_add(group, tmp1, tmp1, tmp2, bn_ctx), + 1); + ExpectIntEQ(EC_POINT_cmp(group, S, tmp1, bn_ctx), 0); + /* K=y*(T-w*M) */ + ExpectIntEQ(EC_POINT_mul(group, client_secret, NULL, M, w, bn_ctx), 1); + ExpectIntEQ(EC_POINT_invert(group, client_secret, bn_ctx), 1); + ExpectIntEQ(EC_POINT_add(group, client_secret, T, client_secret, bn_ctx), + 1); + ExpectIntEQ(EC_POINT_mul(group, client_secret, NULL, client_secret, y, + bn_ctx), 1); + /* kdc */ + /* K=x*(S-w*N) */ + ExpectIntEQ(EC_POINT_mul(group, kdc_secret, NULL, N, w, bn_ctx), 1); + ExpectIntEQ(EC_POINT_invert(group, kdc_secret, bn_ctx), 1); + ExpectIntEQ(EC_POINT_add(group, kdc_secret, S, kdc_secret, bn_ctx), + 1); + ExpectIntEQ(EC_POINT_mul(group, kdc_secret, NULL, kdc_secret, x, bn_ctx), + 1); + + /* kdc_secret == client_secret */ + ExpectIntEQ(EC_POINT_cmp(group, client_secret, kdc_secret, bn_ctx), 0); + + BN_free(x); + BN_free(y); + BN_free(w); + EC_POINT_free(M); + EC_POINT_free(N); + EC_POINT_free(T); + EC_POINT_free(tmp1); + EC_POINT_free(tmp2); + EC_POINT_free(S); + EC_POINT_free(client_secret); + EC_POINT_free(kdc_secret); + EC_GROUP_free(group); + BN_CTX_free(bn_ctx); +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_EC_KEY_generate(void) { EXPECT_DECLS; @@ -63868,6 +64012,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_EC_GROUP), TEST_DECL(test_wolfSSL_PEM_read_bio_ECPKParameters), TEST_DECL(test_wolfSSL_EC_POINT), + TEST_DECL(test_wolfSSL_SPAKE), TEST_DECL(test_wolfSSL_EC_KEY_generate), TEST_DECL(test_EC_i2d), TEST_DECL(test_wolfSSL_EC_curve), diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 58ebdd3da2..23ef5e9a29 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -265,6 +265,9 @@ WOLFSSL_API int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth); WOLFSSL_API WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group); +WOLFSSL_LOCAL +int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *point); WOLFSSL_API int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, const WOLFSSL_EC_POINT *p, diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 4a40f260f2..c047d40957 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index 7584273cd7..c43e507baa 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -24,6 +24,8 @@ #ifndef WOLFSSL_OPENSSLV_H_ #define WOLFSSL_OPENSSLV_H_ +#include + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) /* api version compatibility */ @@ -37,7 +39,7 @@ defined(WOLFSSL_RSYSLOG) || defined(WOLFSSL_KRB) || defined(HAVE_STUNNEL) /* For Apache httpd, Use 1.1.0 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10100003L -#elif defined(WOLFSSL_QT) || defined(WOLFSSL_PYTHON) +#elif defined(WOLFSSL_QT) || defined(WOLFSSL_PYTHON) || defined(WOLFSSL_KRB) /* For Qt and Python 3.8.5 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10101000L #elif defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_FFMPEG)