From 85bf50aa2373d61ea7cb84c454c0ddb3595a916f Mon Sep 17 00:00:00 2001
From: Andrew Hopkins <andhop@amazon.com>
Date: Thu, 6 Jul 2023 15:41:46 -0700
Subject: [PATCH 1/2] BUILD: ssl: Build with new cryptographic library AWS-LC

This adds documentation on how to use AWS-LC when building HAProxy
and updates the GitHub runners to test with AWS-LC.

Update the type of the OCSP callback retrieved with
SSL_CTX_get_tlsext_status_cb with the actual type for
libcrypto versions greater than 1.0.2. This doesn't affect
OpenSSL which casts the callback to void* in SSL_CTX_ctrl.

Skip ssl_dh.vtc when built with AWS-LC.
---
 .github/matrix.py                |  1 +
 INSTALL                          | 32 +++++++++++++++++++++++---------
 Makefile                         | 16 ++++++++++++----
 include/haproxy/openssl-compat.h |  7 +++++++
 reg-tests/ssl/ssl_dh.vtc         |  3 ++-
 scripts/build-ssl.sh             | 21 +++++++++++++++++++++
 src/haproxy.c                    |  9 +++++++++
 src/ssl_sock.c                   |  4 ++++
 8 files changed, 79 insertions(+), 14 deletions(-)

diff --git a/.github/matrix.py b/.github/matrix.py
index dbf987e93..b88eb32d6 100755
--- a/.github/matrix.py
+++ b/.github/matrix.py
@@ -185,6 +185,7 @@ for CC in ["gcc", "clang"]:
         "OPENSSL_VERSION=1.1.1s",
         "QUICTLS=yes",
         # "BORINGSSL=yes",
+        'AWS_LC=yes',
     ]
 
     if "haproxy-" not in ref_name: # development branch
diff --git a/INSTALL b/INSTALL
index 8492a4f37..e257e6a73 100644
--- a/INSTALL
+++ b/INSTALL
@@ -244,14 +244,14 @@ https://github.com/openssl/openssl/issues/17627). If a migration to 3.x is
 mandated by support reasons, at least 3.1 recovers a small fraction of this
 important loss.
 
-Three OpenSSL derivatives called LibreSSL, BoringSSL and QUICTLS are reported
-to work as well. While there are some efforts from the community to ensure they
-work well, OpenSSL remains the primary target and this means that in case of
-conflicting choices, OpenSSL support will be favored over other options. Note
-that QUIC is not fully supported when haproxy is built with OpenSSL. In this
-case, QUICTLS is the preferred alternative.  As of writing this, the QuicTLS
-project follows OpenSSL very closely and provides update simultaneously, but
-being a volunteer-driven project, its long-term future does not look certain
+Four OpenSSL derivatives called LibreSSL, BoringSSL, QUICTLS, and AWS-LC are 
+reported to work as well. While there are some efforts from the community to 
+ensure they work well, OpenSSL remains the primary target and this means that in
+case of conflicting choices, OpenSSL support will be favored over other options. 
+Note that QUIC is not fully supported when haproxy is built with OpenSSL. In 
+this case, QUICTLS is the preferred alternative.  As of writing this, the 
+QuicTLS project follows OpenSSL very closely and provides update simultaneously, 
+but being a volunteer-driven project, its long-term future does not look certain
 enough to convince operating systems to package it, so it needs to be build
 locally. See the section about QUIC in this document.
 
@@ -281,7 +281,7 @@ SSL library files using SSL_LIB. Example :
     USE_OPENSSL=1 SSL_INC=/opt/ssl-1.1.1/include SSL_LIB=/opt/ssl-1.1.1/lib
 
 To use HAProxy with WolfSSL, WolfSSL must be built with haproxy support, at
-least WolfSSL 5.6.0 is needed, but a development version migh be needed for
+least WolfSSL 5.6.0 is needed, but a development version might be needed for
 some of the features:
 
   $ cd ~/build/wolfssl
@@ -300,6 +300,20 @@ command line, for example:
   $ make -j $(nproc) TARGET=generic USE_OPENSSL_WOLFSSL=1 USE_QUIC=1 \
     SSL_INC=/opt/wolfssl-5.6.0/include SSL_LIB=/opt/wolfssl-5.6.0/lib
 
+To use HAProxy with AWS-LC you must have version v1.13.0 of AWS-LC built and 
+installed locally. 
+ $ cd ~/build/aws-lc
+ $ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/aws-lc
+ $ make -j $(nproc)
+ $ make install
+
+Building HAProxy with AWS-LC requires you to enable AWS-LC support, and specify
+the path it was installed to when running make for HAPRoxy.
+
+ $ cd ~/build/haproxy
+ $ make -j $(nproc) TARGET=generic USE_OPENSSL_AWSLC=1 \
+   SSL_INC=/opt/aws-lc/include SSL_LIB=/opt/aws-lc/lib
+
 In order to link OpenSSL statically against HAProxy, first download OpenSSL
 from https://www.openssl.org/ then build it with the "no-shared" keyword and
 install it to a local directory, so your system is not affected :
diff --git a/Makefile b/Makefile
index 329c64ba2..e6fb822d5 100644
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@
 #   USE_GETADDRINFO      : use getaddrinfo() to resolve IPv6 host names.
 #   USE_OPENSSL          : enable use of OpenSSL. Recommended, but see below.
 #   USE_OPENSSL_WOLFSSL  : enable use of wolfSSL with the OpenSSL API
+#   USE_OPENSSL_AWSLC    : enable use of AWS-LC
 #   USE_ENGINE           : enable use of OpenSSL Engine.
 #   USE_LUA              : enable Lua support.
 #   USE_ACCEPT4          : enable use of accept4() on linux. Automatic.
@@ -305,10 +306,10 @@ use_opts = USE_EPOLL USE_KQUEUE USE_NETFILTER USE_POLL                        \
            USE_THREAD USE_PTHREAD_EMULATION USE_BACKTRACE                     \
            USE_TPROXY USE_LINUX_TPROXY                                        \
            USE_LINUX_SPLICE USE_LIBCRYPT USE_CRYPT_H USE_ENGINE               \
-           USE_GETADDRINFO USE_OPENSSL USE_OPENSSL_WOLFSSL USE_SSL USE_LUA    \
-           USE_ACCEPT4 USE_CLOSEFROM USE_ZLIB USE_SLZ USE_CPU_AFFINITY        \
-           USE_TFO USE_NS USE_DL USE_RT USE_LIBATOMIC USE_MATH                \
-           USE_DEVICEATLAS USE_51DEGREES                                      \
+           USE_GETADDRINFO USE_OPENSSL USE_OPENSSL_WOLFSSL USE_OPENSSL_AWSLC  \
+           USE_SSL USE_LUA USE_ACCEPT4 USE_CLOSEFROM USE_ZLIB USE_SLZ         \
+           USE_CPU_AFFINITY USE_TFO USE_NS USE_DL USE_RT USE_LIBATOMIC        \
+           USE_MATH USE_DEVICEATLAS USE_51DEGREES                             \
            USE_WURFL USE_SYSTEMD USE_OBSOLETE_LINKER USE_PRCTL USE_PROCCTL    \
            USE_THREAD_DUMP USE_EVPORTS USE_OT USE_QUIC USE_PROMEX             \
            USE_MEMORY_PROFILING USE_SHM_OPEN                                  \
@@ -580,6 +581,13 @@ ifneq ($(USE_OPENSSL_WOLFSSL),)
   USE_OPENSSL     := $(if $(USE_OPENSSL),$(USE_OPENSSL),implicit)
 endif
 
+# This is for the AWS-LC variant of the OpenSSL API. Setting it implies
+# OPENSSL so it's not necessary to set the latter.
+ifneq ($(USE_OPENSSL_AWSLC),)
+  # always automatically set USE_OPENSSL
+  USE_OPENSSL     := $(if $(USE_OPENSSL),$(USE_OPENSSL),implicit)
+endif
+
 # This is for any variant of the OpenSSL API. By default it uses OpenSSL.
 ifneq ($(USE_OPENSSL),)
   # only preset these for the regular openssl
diff --git a/include/haproxy/openssl-compat.h b/include/haproxy/openssl-compat.h
index 248ae284e..066db0cac 100644
--- a/include/haproxy/openssl-compat.h
+++ b/include/haproxy/openssl-compat.h
@@ -7,6 +7,13 @@
 #include <wolfssl/options.h>
 #endif
 
+#ifdef USE_OPENSSL_AWSLC
+#include <openssl/base.h>
+#if !defined(OPENSSL_IS_AWSLC)
+#error "USE_OPENSSL_AWSLC is set but OPENSSL_IS_AWSLC is not defined, wrong header files detected"
+#endif
+#endif
+
 #include <openssl/bn.h>
 #include <openssl/crypto.h>
 #include <openssl/ssl.h>
diff --git a/reg-tests/ssl/ssl_dh.vtc b/reg-tests/ssl/ssl_dh.vtc
index 9553f371d..36e72b8ff 100644
--- a/reg-tests/ssl/ssl_dh.vtc
+++ b/reg-tests/ssl/ssl_dh.vtc
@@ -18,7 +18,8 @@
 # stop using deprecated APIs.
 
 varnishtest "Test the DH related SSL options"
-feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'"
+# AWS-LC does not support any FFDH ciphersuites
+feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && !ssllib_name_startswith(AWS-LC)'"
 feature cmd "command -v openssl && command -v grep && command -v socat"
 feature ignore_unknown_macro
 
diff --git a/scripts/build-ssl.sh b/scripts/build-ssl.sh
index a1935dd1e..70b9f418f 100755
--- a/scripts/build-ssl.sh
+++ b/scripts/build-ssl.sh
@@ -86,6 +86,17 @@ download_boringssl () {
     fi
 }
 
+download_aws_lc () {
+    if [ ! -d "download-cache/aws-lc" ]; then
+        git clone --depth=1 https://github.com/aws/aws-lc.git download-cache/aws-lc
+    else
+       (
+        cd download-cache/aws-lc
+        git pull
+       )
+    fi
+}
+
 download_quictls () {
     if [ ! -d "download-cache/quictls" ]; then
         git clone --depth=1 https://github.com/quictls/openssl download-cache/quictls
@@ -132,6 +143,16 @@ if [ ! -z ${BORINGSSL+x} ]; then
 	)
 fi
 
+if [ ! -z ${AWS_LC+x} ]; then
+	download_aws_lc
+  cd download-cache/aws-lc
+  if [ -d build ]; then rm -rf build; fi
+	mkdir build
+	cd build
+	cmake  -GNinja -DCMAKE_BUILD_TYPE=release -DBUILD_SHARED_LIBS=1 -DDISABLE_GO=1 -DDISABLE_PERL=1 -DBUILD_TESTING=0 -DCMAKE_INSTALL_PREFIX=${HOME}/opt ..
+	ninja install
+fi
+
 if [ ! -z ${QUICTLS+x} ]; then
         (
         download_quictls
diff --git a/src/haproxy.c b/src/haproxy.c
index ac6c50340..80a7f498d 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1954,6 +1954,15 @@ static void init(int argc, char **argv)
         wolfSSL_Init();
         wolfSSL_Debugging_ON();
 #endif
+
+#ifdef USE_OPENSSL_AWSLC
+        const char *version_str = OpenSSL_version(OPENSSL_VERSION);
+        if (strncmp(version_str, "AWS-LC", 6) != 0) {
+            ha_alert("HAPRoxy built with AWS-LC but running with %s.\n", version_str);
+		    exit(1);
+        }
+#endif
+
 #if (HA_OPENSSL_VERSION_NUMBER < 0x1010000fL)
 	/* Initialize the error strings of OpenSSL
 	 * It only needs to be done explicitly with older versions of the SSL
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 6453265a3..c1c20d050 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1112,7 +1112,11 @@ static int ssl_sock_load_ocsp(const char *path, SSL_CTX *ctx, struct ckch_data *
 	char *warn = NULL;
 	unsigned char *p;
 #ifndef USE_OPENSSL_WOLFSSL
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L)
+    int (*callback) (SSL *, void *);
+#else
 	void (*callback) (void);
+#endif
 #else
 	tlsextStatusCb callback;
 #endif
-- 
2.37.1 (Apple Git-137.1)

