Skip to content

Commit 53102a1

Browse files
Support for building with AWS Libcrypto (AWS-LC) (#929)
Hello, I'm an engineer at AWS working on AWS-LC, AWS's open-source fork of Google's BoringSSL. We would like to propose adding AWS-LC support to netty-tcnative, alongside its existing support for OpenSSL, BoringSSL, and LibreSSL. AWS-LC shares a similar API surface area to the existing BoringSSL integration within your library, while providing additional benefits for users. We are committed to backwards compatibility and maintain extensive CI testing infrastructure that continuously validates compatibility with many open-source projects. We plan to add netty-tcnative compatibility testing to this suite to ensure ongoing compatibility. Some of the highlights offered by this integration: 1. Performance optimizations specifically targeted for modern CPU architectures, including AWS Graviton processors, and Intel x86-64 with AVX-512 instructions 2. Formal verification of critical cryptographic primitives, with ongoing investment in expanding verification coverage. 3. FIPS 140-3 compliance support through a dedicated FIPS build mode. Given netty-tcnative's existing support for BoringSSL, integrating AWS-LC is relatively straightforward. This integration would provide netty users with a well-supported path to leverage AWS-LC's improvements in performance, security, and compliance without requiring them to maintain custom patches or modifications. The this integration supports all current netty-tcnative functionality that is supported for the BoringSSL integration. Currently this pull request targets users who build the netty-tcnative JARs themselves following the [How to build ](https://netty.io/wiki/forked-tomcat-native.html#how-to-build) instructions. This would allow users wanting to use AWS-LC to do so successfully. At this time I don't see an explicit need to offer static compilations of AWS-LC bundled in a jar file (similar to the BoringSSL integration). I noticed that the current LibreSSL static build is not published, so I wasn't sure if maintaining these static variants is a goal in the long-term, but would be open to discuss further if you'd like. Once this PR is merged in I can publish the corresponding PR to netty to make necessary adjustments there for the netty-tcnative with aws-lc integration to work as expected and have additional testing as necessary. --------- Co-authored-by: Norman Maurer <norman_maurer@apple.com>
1 parent b4543ac commit 53102a1

File tree

15 files changed

+308
-178
lines changed

15 files changed

+308
-178
lines changed

.github/workflows/ci-build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ jobs:
3737
- setup: centos7-aarch64
3838
docker-compose-build: "-f docker/docker-compose.centos-7.yaml build"
3939
docker-compose-run: "-f docker/docker-compose.centos-7.yaml run cross-compile-aarch64-build"
40+
- setup: al2023-x86_64-aws_lc
41+
docker-compose-build: "-f docker/docker-compose.al2023.yaml build"
42+
docker-compose-run: "-f docker/docker-compose.al2023.yaml run build"
4043

4144
name: ${{ matrix.setup }}
4245
steps:

.github/workflows/ci-pr.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ jobs:
3535
- setup: centos7-aarch64
3636
docker-compose-build: "-f docker/docker-compose.centos-7.yaml build"
3737
docker-compose-run: "-f docker/docker-compose.centos-7.yaml run cross-compile-aarch64-build"
38+
- setup: al2023-x86_64-aws_lc
39+
docker-compose-build: "-f docker/docker-compose.al2023.yaml build"
40+
docker-compose-run: "-f docker/docker-compose.al2023.yaml run build"
3841

3942
name: ${{ matrix.setup }}
4043
steps:

docker/Dockerfile.al2023

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
FROM --platform=linux/amd64 amazonlinux:2023
2+
3+
ARG java_version=8.0.452-amzn
4+
ARG aws_lc_version=v1.52.0
5+
ENV JAVA_VERSION $java_version
6+
ENV AWS_LC_VERSION $aws_lc_version
7+
8+
# install dependencies
9+
RUN dnf install -y \
10+
apr-devel \
11+
autoconf \
12+
automake \
13+
bzip2 \
14+
cmake \
15+
git \
16+
glibc-devel \
17+
golang \
18+
libtool \
19+
make \
20+
patch \
21+
perl \
22+
perl-parent \
23+
perl-devel \
24+
tar \
25+
unzip \
26+
wget \
27+
which \
28+
zip
29+
30+
# Downloading and installing SDKMAN!
31+
RUN curl -s "https://get.sdkman.io" | bash
32+
33+
# Installing Java removing some unnecessary SDKMAN files
34+
RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && \
35+
yes | sdk install java $JAVA_VERSION && \
36+
rm -rf $HOME/.sdkman/archives/* && \
37+
rm -rf $HOME/.sdkman/tmp/*"
38+
39+
RUN echo 'export JAVA_HOME="/root/.sdkman/candidates/java/current"' >> ~/.bashrc
40+
RUN echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
41+
42+
ENV PATH /root/.sdkman/candidates/java/current/bin:$PATH
43+
44+
RUN mkdir "$HOME/sources" && \
45+
git clone https://github.com/aws/aws-lc.git "$HOME/sources/aws-lc" && \
46+
cd "$HOME/sources/aws-lc" && \
47+
git checkout $AWS_LC_VERSION && \
48+
cmake -B build -S . -DCMAKE_INSTALL_PREFIX=/opt/aws-lc -DBUILD_SHARED_LIBS=1 -DBUILD_TESTING=0 && \
49+
cmake --build build -- -j && \
50+
cmake --install build
51+
52+
# Cleanup
53+
RUN dnf clean all && \
54+
rm -rf /var/cache/dnf && \
55+
rm -rf "$HOME/sources"

docker/docker-compose.al2023.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: "3"
2+
3+
services:
4+
5+
runtime-setup:
6+
image: netty-tcnative-al2023:x86_64
7+
build:
8+
context: ../
9+
dockerfile: docker/Dockerfile.al2023
10+
11+
common: &common
12+
image: netty-tcnative-al2023:x86_64
13+
depends_on: [runtime-setup]
14+
environment:
15+
MAVEN_OPTS:
16+
LD_LIBRARY_PATH: /opt/aws-lc/lib64
17+
LDFLAGS: -L/opt/aws-lc/lib64 -lssl -lcrypto
18+
CFLAGS: -I/opt/aws-lc/include -DHAVE_OPENSSL -lssl -lcrypto
19+
CXXFLAGS: -I/opt/aws-lc/include -DHAVE_OPENSSL -lssl -lcrypto
20+
volumes:
21+
- ~/.m2/repository:/root/.m2/repository
22+
- ..:/code
23+
working_dir: /code
24+
25+
build:
26+
<<: *common
27+
command: /bin/bash -cl "./mvnw -am -pl openssl-dynamic clean package"
28+
29+
shell:
30+
<<: *common
31+
volumes:
32+
- ~/.m2:/root/.m2
33+
- ~/.gitconfig:/root/.gitconfig
34+
- ~/.gitignore:/root/.gitignore
35+
- ..:/code
36+
entrypoint: /bin/bash -l

openssl-classes/src/main/java/io/netty/internal/tcnative/NativeStaticallyReferencedJniMethods.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ private NativeStaticallyReferencedJniMethods() {
153153
static native int x509vErrIpAddressMismatch();
154154
static native int x509vErrDaneNoMatch();
155155

156-
// BoringSSL specific.
156+
// BoringSSL and AWS-LC specific.
157157
static native int sslErrorWantCertificateVerify();
158158
static native int sslErrorWantPrivateKeyOperation();
159159
static native int sslSignRsaPkcsSha1();

openssl-classes/src/main/java/io/netty/internal/tcnative/SSL.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ private SSL() { }
176176
// https://boringssl.googlesource.com/boringssl/+/chromium-stable/include/openssl/ssl.h#519
177177
public static final int SSL_ERROR_WANT_PRIVATE_KEY_OPERATION = sslErrorWantPrivateKeyOperation();
178178

179-
// BoringSSL specific
179+
// BoringSSL and AWS-LC specific
180180
public static final int SSL_ERROR_WANT_CERTIFICATE_VERIFY = sslErrorWantCertificateVerify();
181181

182182
/**
@@ -961,7 +961,7 @@ public static AsyncTask getAsyncTask(long ssl) {
961961
public static native long getSession(long ssl);
962962

963963
/**
964-
* Allow to set the renegotiation mode that is used. This is only support by {@code BoringSSL}.
964+
* Allow to set the renegotiation mode that is used. This is only supported by {@code BoringSSL} and {@code AWS-LC}.
965965
*
966966
* See <a href="https://boringssl.googlesource.com/boringssl/+/refs/heads/master/include/openssl/ssl.h#4081">
967967
* SSL_set_renegotiate_mode</a>..

openssl-classes/src/main/java/io/netty/internal/tcnative/SSLContext.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ public static void setAlpnProtos(long ctx, String[] alpnProtos, int selectorFail
668668
* For servers, algorithm preference order is dictated by the order of algorithm registration.
669669
* Most preferred algorithm should be registered first.
670670
*
671-
* This method is currently only supported when {@code BoringSSL} is used.
671+
* This method is currently only supported when {@code BoringSSL} or {@code AWS-LC} is used.
672672
*
673673
* <a href="https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Certificate-compression">
674674
* SSL_CTX_add_cert_compression_alg</a>
@@ -696,7 +696,7 @@ public static int addCertificateCompressionAlgorithm(long ctx, int direction, fi
696696
* This allows to offload private key operations
697697
* if needed.
698698
*
699-
* This method is currently only supported when {@code BoringSSL} is used.
699+
* This method is currently only supported when {@code BoringSSL} and {@code AWS-LC} is used.
700700
*
701701
* @param ctx context to use
702702
* @param method method to use for the given context.
@@ -709,7 +709,7 @@ public static void setPrivateKeyMethod(long ctx, final SSLPrivateKeyMethod metho
709709
* Sets the {@link AsyncSSLPrivateKeyMethod} to use for the given {@link SSLContext}.
710710
* This allows to offload private key operations if needed.
711711
*
712-
* This method is currently only supported when {@code BoringSSL} is used.
712+
* This method is currently only supported when {@code BoringSSL} and {@code AWS-LC} is used.
713713
*
714714
* @param ctx context to use
715715
* @param method method to use for the given context.

openssl-dynamic/src/main/c/cert_compress.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#include "tcn.h"
1818
#include "ssl_private.h"
19-
#ifdef OPENSSL_IS_BORINGSSL
19+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
2020
#include "cert_compress.h"
2121

2222
static int compress(jobject compression_algorithm, jmethodID compress_method, SSL* ssl, CBB* out,
@@ -168,4 +168,4 @@ int zstd_decompress_java(SSL* ssl, CRYPTO_BUFFER** out, size_t uncompressed_len,
168168
ssl, out, uncompressed_len, in, in_len);
169169
}
170170

171-
#endif // OPENSSL_IS_BORINGSSL
171+
#endif // defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)

openssl-dynamic/src/main/c/cert_compress.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#ifndef NETTY_TCNATIVE_CERT_COMPRESS_H_
1818
#define NETTY_TCNATIVE_CERT_COMPRESS_H_
1919

20-
#ifdef OPENSSL_IS_BORINGSSL
20+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
2121

2222
int zlib_decompress_java(SSL* ssl, CRYPTO_BUFFER** out, size_t uncompressed_len, const uint8_t* in, size_t in_len);
2323
int zlib_compress_java(SSL* ssl, CBB* out, const uint8_t* in, size_t in_len);
@@ -28,6 +28,6 @@ int brotli_compress_java(SSL* ssl, CBB* out, const uint8_t* in, size_t in_len);
2828
int zstd_decompress_java(SSL* ssl, CRYPTO_BUFFER** out, size_t uncompressed_len, const uint8_t* in, size_t in_len);
2929
int zstd_compress_java(SSL* ssl, CBB* out, const uint8_t* in, size_t in_len);
3030

31-
#endif // OPENSSL_IS_BORINGSSL
31+
#endif // OPENSSL_IS_AWSLC
3232

33-
#endif /* NETTY_TCNATIVE_CERT_COMPRESS_H_ */
33+
#endif /* NETTY_TCNATIVE_CERT_COMPRESS_H_ */

openssl-dynamic/src/main/c/native_constants.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, x509vErrDaneNoMat
510510
#endif
511511
}
512512

513-
// BoringSSL specific
513+
// BoringSSL and AWS-LC specific
514514
TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslErrorWantCertificateVerify)(TCN_STDARGS) {
515515
return SSL_ERROR_WANT_CERTIFICATE_VERIFY;
516516
}
@@ -572,23 +572,23 @@ TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslSignRsaPkcs1Md
572572
}
573573

574574
TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslRenegotiateNever)(TCN_STDARGS) {
575-
#ifdef OPENSSL_IS_BORINGSSL
575+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
576576
return (jint) ssl_renegotiate_never;
577577
#else
578578
return 0;
579579
#endif
580580
}
581581

582582
TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslRenegotiateOnce)(TCN_STDARGS) {
583-
#ifdef OPENSSL_IS_BORINGSSL
583+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
584584
return (jint) ssl_renegotiate_once;
585585
#else
586586
return 0;
587587
#endif
588588
}
589589

590590
TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslRenegotiateFreely)(TCN_STDARGS) {
591-
#ifdef OPENSSL_IS_BORINGSSL
591+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
592592
return (jint) ssl_renegotiate_freely;
593593
#else
594594
return 0;
@@ -597,15 +597,15 @@ TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslRenegotiateFre
597597

598598

599599
TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslRenegotiateIgnore)(TCN_STDARGS) {
600-
#ifdef OPENSSL_IS_BORINGSSL
600+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
601601
return (jint) ssl_renegotiate_ignore;
602602
#else
603603
return 0;
604604
#endif
605605
}
606606

607607
TCN_IMPLEMENT_CALL(jint, NativeStaticallyReferencedJniMethods, sslRenegotiateExplicit)(TCN_STDARGS) {
608-
#ifdef OPENSSL_IS_BORINGSSL
608+
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
609609
return (jint) ssl_renegotiate_explicit;
610610
#else
611611
return 0;
@@ -744,7 +744,7 @@ static const JNINativeMethod method_table[] = {
744744
{ TCN_METHOD_TABLE_ENTRY(x509vErrEmailMismatch, ()I, NativeStaticallyReferencedJniMethods) },
745745
{ TCN_METHOD_TABLE_ENTRY(x509vErrIpAddressMismatch, ()I, NativeStaticallyReferencedJniMethods) },
746746
{ TCN_METHOD_TABLE_ENTRY(x509vErrDaneNoMatch, ()I, NativeStaticallyReferencedJniMethods) },
747-
// BoringSSL specific
747+
// BoringSSL and AWS-LC specific
748748
{ TCN_METHOD_TABLE_ENTRY(sslErrorWantCertificateVerify, ()I, NativeStaticallyReferencedJniMethods) },
749749
{ TCN_METHOD_TABLE_ENTRY(sslErrorWantPrivateKeyOperation, ()I, NativeStaticallyReferencedJniMethods) },
750750
{ TCN_METHOD_TABLE_ENTRY(sslSignRsaPkcsSha1, ()I, NativeStaticallyReferencedJniMethods) },

0 commit comments

Comments
 (0)