diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 90d520231a0..a03f1cc9915 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -424,3 +424,61 @@ jobs: run: echo 'RUN_SUDO="sudo -E"' >tests/t_server_null.rc - name: make check run: make -j3 check VERBOSE=1 + + aws-lc: + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04] + ssllib: [ awslc ] + build: [ normal, asan ] + include: + - build: asan + cflags: "-fsanitize=address -fno-sanitize-recover=all -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1" + ldflags: -fsanitize=address -fno-sanitize-recover=all + cc: clang + - build: normal + cflags: "-O2 -g" + ldflags: "" + cc: gcc + + name: "${{matrix.cc}} ${{matrix.build}} - ${{matrix.os}} - ${{matrix.ssllib}}" + runs-on: ${{matrix.os}} + env: + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CC: ${{matrix.cc}} + UBSAN_OPTIONS: print_stacktrace=1 + AWS_LC_INSTALL: ${{ github.workspace }}/aws-lc/aws-lc-install + + steps: + - name: Install dependencies + run: sudo apt update && sudo apt install -y cmake gcc ninja-build golang make liblzo2-dev libpam0g-dev liblz4-dev linux-libc-dev man2html clang libcmocka-dev python3-docutils python3-jinja2 python3-jsonschema libtool automake autoconf pkg-config libcap-ng-dev libnl-genl-3-dev + - name: "AWS-LC: checkout" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: aws-lc + repository: aws/aws-lc + ref: v1.42.0 + - name: "AWS-LC: build" + run: | + mkdir build + cd build + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${{ env.AWS_LC_INSTALL }}" -DBUILD_SHARED_LIBS=1 ../ + ninja install + working-directory: aws-lc + - name: Checkout OpenVPN + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: autoconf + run: autoreconf -fvi + - name: configure with AWS-LC + run: | + OPENSSL_CFLAGS="-I/${{ env.AWS_LC_INSTALL }}/include" \ + OPENSSL_LIBS="-L/${{ env.AWS_LC_INSTALL }}/lib -lssl -lcrypto" \ + ./configure --with-crypto-library=openssl + - name: make all + run: make -j3 + - name: configure checks + run: echo 'RUN_SUDO="sudo -E"' >tests/t_server_null.rc + - name: make check + run: LD_LIBRARY_PATH="${{ env.AWS_LC_INSTALL }}/lib" make -j3 check VERBOSE=1 diff --git a/README.aws-lc b/README.aws-lc new file mode 100644 index 00000000000..5f3d092f8e5 --- /dev/null +++ b/README.aws-lc @@ -0,0 +1,23 @@ +This version of OpenVPN supports AWS-LC (AWS Libcrypto), AWS's open-source cryptographic library. + +If you encounter bugs in OpenVPN while using AWS-LC: +1. Try compiling OpenVPN with OpenSSL to determine if the issue is specific to AWS-LC +2. For AWS-LC-specific issues, please report them at: https://github.com/aws/aws-lc + +To build and install OpenVPN with AWS-LC: + + OPENSSL_CFLAGS="-I/${AWS_LC_INSTALL_FOLDER}/include" \ + OPENSSL_LIBS="-L/${AWS_LC_INSTALL_FOLDER}/lib -lssl -lcrypto" \ + ./configure --with-crypto-library=openssl + make + make install + + export LD_LIBRARY_PATH="${AWS_LC_INSTALL_FOLDER}/lib" + +When running tests, LD_LIBRARY_PATH must be passed in again: + + LD_LIBRARY_PATH="${AWS_LC_INSTALL_FOLDER}/lib" make check + +************************************************************************* +Due to limitations in AWS-LC, the following features are missing +* Windows CryptoAPI support diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 914b1c4fb31..7947eb6ebba 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -1398,7 +1398,7 @@ ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, return ret; } -#elif !defined(LIBRESSL_VERSION_NUMBER) && !defined(ENABLE_CRYPTO_WOLFSSL) +#elif !defined(LIBRESSL_VERSION_NUMBER) && !defined(ENABLE_CRYPTO_WOLFSSL) && !defined(OPENSSL_IS_AWSLC) bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, int secret_len, uint8_t *output, int output_len) @@ -1444,6 +1444,13 @@ ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, EVP_PKEY_CTX_free(pctx); return ret; } +#elif defined(OPENSSL_IS_AWSLC) +bool +ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec, + int slen, uint8_t *out1, int olen) +{ + CRYPTO_tls1_prf(EVP_md5_sha1(), out1, olen, sec, slen, label, label_len, NULL, 0, NULL, 0); +} #else /* if defined(LIBRESSL_VERSION_NUMBER) */ /* LibreSSL and wolfSSL do not expose a TLS 1.0/1.1 PRF via the same APIs as * OpenSSL does. As result they will only be able to support diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 89f22d13f17..3e3b406a6c6 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -76,7 +76,7 @@ X509_OBJECT_free(X509_OBJECT *obj) #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT #endif -#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050400fL +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050400fL || defined(OPENSSL_IS_AWSLC) #define SSL_get_peer_tmp_key SSL_get_server_tmp_key #endif diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 89d0328e61f..891ea56df5f 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1669,7 +1669,11 @@ tls_ctx_use_external_ec_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey) /* Among init methods, we only need the finish method */ EC_KEY_METHOD_set_init(ec_method, NULL, openvpn_extkey_ec_finish, NULL, NULL, NULL, NULL); +#ifdef OPENSSL_IS_AWSLC + EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, NULL, ecdsa_sign_sig); +#else EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, ecdsa_sign_setup, ecdsa_sign_sig); +#endif ec = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(pkey)); if (!ec) @@ -1895,9 +1899,11 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, } sk_X509_INFO_pop_free(info_stack, X509_INFO_free); } - + + int cnum; if (tls_server) { + cnum = sk_X509_NAME_num(cert_names); SSL_CTX_set_client_CA_list(ctx->ctx, cert_names); } @@ -1910,7 +1916,6 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, if (tls_server) { - int cnum = sk_X509_NAME_num(cert_names); if (cnum != added) { crypto_msg(M_FATAL, "Cannot load CA certificate file %s (only %d " @@ -2558,7 +2563,7 @@ show_available_tls_ciphers_list(const char *cipher_list, crypto_msg(M_FATAL, "Cannot create SSL object"); } -#if OPENSSL_VERSION_NUMBER < 0x1010000fL +#if OPENSSL_VERSION_NUMBER < 0x1010000fL || defined(OPENSSL_IS_AWSLC) STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); #else STACK_OF(SSL_CIPHER) *sk = SSL_get1_supported_ciphers(ssl);