Skip to content

gh-135401: Test AWS-LC as a cryptography library in CI #135402

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 79 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ jobs:
free-threading: ${{ matrix.free-threading }}
os: ${{ matrix.os }}

build-ubuntu-ssltests:
build-ubuntu-ssltests-openssl:
name: 'Ubuntu SSL tests with OpenSSL'
runs-on: ${{ matrix.os }}
timeout-minutes: 60
Expand Down Expand Up @@ -322,6 +322,81 @@ jobs:
- name: SSL tests
run: ./python Lib/test/ssltests.py

build-ubuntu-ssltests-awslc:
name: 'Ubuntu SSL tests with AWS-LC'
runs-on: ${{ matrix.os }}
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04]
awslc_ver: [1.52.1]
env:
AWSLC_VER: ${{ matrix.awslc_ver}}
MULTISSL_DIR: ${{ github.workspace }}/multissl
OPENSSL_DIR: ${{ github.workspace }}/multissl/aws-lc/${{ matrix.awslc_ver }}
LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/aws-lc/${{ matrix.awslc_ver }}/lib
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Runner image version
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- name: Restore config.cache
uses: actions/cache@v4
with:
path: config.cache
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Configure SSL lib env vars
run: |
echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV"
echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/aws-lc/${AWSLC_VER}" >> "$GITHUB_ENV"
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/aws-lc/${AWSLC_VER}/lib" >> "$GITHUB_ENV"
- name: 'Restore AWS-LC build'
id: cache-aws-lc
uses: actions/cache@v4
with:
path: ./multissl/aws-lc/${{ matrix.awslc_ver }}
key: ${{ matrix.os }}-multissl-aws-lc-${{ matrix.awslc_ver }}
- name: Install AWS-LC
if: steps.cache-aws-lc.outputs.cache-hit != 'true'
run: |
python3 Tools/ssl/multissltests.py \
--steps=library \
--base-directory "$MULTISSL_DIR" \
--awslc ${{ matrix.awslc_ver }} \
--system Linux
- name: Add ccache to PATH
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
- name: Configure ccache action
uses: hendrikmuhs/ccache-action@v1.2
with:
save: false
- name: Configure CPython
run: |
./configure CFLAGS="-fdiagnostics-format=json" \
--config-cache \
--enable-slower-safety \
--with-pydebug \
--with-openssl="$OPENSSL_DIR" \
--with-builtin-hashlib-hashes=blake2 \
--with-ssl-default-suites=openssl
- name: Build CPython
run: make -j
- name: Display build info
run: make pythoninfo
- name: Verify python is linked to AWS-LC
run: ./python -c 'import ssl; print(ssl.OPENSSL_VERSION)' | grep AWS-LC
- name: SSL tests
run: ./python Lib/test/ssltests.py

build-wasi:
name: 'WASI'
needs: build-context
Expand Down Expand Up @@ -620,7 +695,7 @@ jobs:
- build-windows-msi
- build-macos
- build-ubuntu
- build-ubuntu-ssltests
- build-ubuntu-ssltests-openssl
- build-wasi
- test-hypothesis
- build-asan
Expand All @@ -635,7 +710,7 @@ jobs:
with:
allowed-failures: >-
build-windows-msi,
build-ubuntu-ssltests,
build-ubuntu-ssltests-openssl
test-hypothesis,
cifuzz,
allowed-skips: >-
Expand All @@ -653,7 +728,7 @@ jobs:
check-generated-files,
build-macos,
build-ubuntu,
build-ubuntu-ssltests,
build-ubuntu-ssltests-openssl,
build-wasi,
test-hypothesis,
build-asan,
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/posix-deps-apt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ apt-get -yq install \
build-essential \
pkg-config \
ccache \
cmake \
gdb \
lcov \
libb2-dev \
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,10 @@ def test_clinic_signature(self):
with self.assertWarnsRegex(DeprecationWarning,
DEPRECATED_STRING_PARAMETER):
hashlib.new(digest_name, string=b'')
if self._hashlib:
# when using a combination of libcrypto and interned hash
# implementations, we need to make sure that _hashlib contains
# the constructor we're testing
if self._hashlib and digest_name in self._hashlib._constructors:
self._hashlib.new(digest_name, b'')
self._hashlib.new(digest_name, data=b'')
with self.assertWarnsRegex(DeprecationWarning,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add a new GitHub CI job to test the :py:mod:`ssl` module with AWS-LC__ as the backing cryptography and TLS library.

__ https://github.com/aws/aws-lc
69 changes: 59 additions & 10 deletions Tools/ssl/multissltests.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#!./python
"""Run Python tests against multiple installations of OpenSSL and LibreSSL
"""Run Python tests against multiple installations of crypto libraries
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Run Python tests against multiple installations of crypto libraries
"""Run Python tests against multiple installations of cryptographic libraries.
Currently tested are:
* OpenSSL
* LibreSSL
* AWS-LC

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that "crypto" is unfortunate shorthand. Not to get too deep in the semantic weeds, but I wonder if "cryptography" might be more appropriate than "cryptographic". The former noun-based nomenclature is more idiomatic when referring to libraries ("compression library", "serialization library", etc.) while the latter's adjective seems a bit off.

I don't have a strong preference, what do you think @AA-Turner?

by the way, thank you for the quick review :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libcrypto is the OpenSSL cryptographic library, and the other libs (BoringSSL, LibreSSL) are forks. So I'd prefer keeping crypto here or use libcrypto


The script

(1) downloads OpenSSL / LibreSSL tar bundle
(1) downloads the tar bundle
(2) extracts it to ./src
(3) compiles OpenSSL / LibreSSL
(4) installs OpenSSL / LibreSSL into ../multissl/$LIB/$VERSION/
(3) compiles the relevant library
(4) installs that library into ../multissl/$LIB/$VERSION/
(5) forces a recompilation of Python modules using the
header and library files from ../multissl/$LIB/$VERSION/
(6) runs Python's test suite
Expand Down Expand Up @@ -61,6 +61,10 @@
LIBRESSL_RECENT_VERSIONS = [
]

AWSLC_RECENT_VERSIONS = [
"1.52.1",
]

# store files in ../multissl
HERE = os.path.dirname(os.path.abspath(__file__))
PYTHONROOT = os.path.abspath(os.path.join(HERE, '..', '..'))
Expand All @@ -70,7 +74,7 @@
parser = argparse.ArgumentParser(
prog='multissl',
description=(
"Run CPython tests with multiple OpenSSL and LibreSSL "
"Run CPython tests with multiple crypto libraries"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Run CPython tests with multiple crypto libraries"
"Run CPython tests with multiple cryptographic libraries"

"versions."
)
)
Expand Down Expand Up @@ -102,6 +106,14 @@
"OpenSSL and LibreSSL versions are given."
).format(LIBRESSL_RECENT_VERSIONS, LIBRESSL_OLD_VERSIONS)
)
parser.add_argument(
'--awslc',
nargs='+',
default=(),
help=(
"AWS-LC versions, defaults to '{}'."
).format(AWSLC_RECENT_VERSIONS)
)
parser.add_argument(
'--tests',
nargs='*',
Expand All @@ -111,7 +123,7 @@
parser.add_argument(
'--base-directory',
default=MULTISSL_DIR,
help="Base directory for OpenSSL / LibreSSL sources and builds."
help="Base directory for crypto library sources and builds."
)
parser.add_argument(
'--no-network',
Expand All @@ -124,8 +136,8 @@
choices=['library', 'modules', 'tests'],
default='tests',
help=(
"Which steps to perform. 'library' downloads and compiles OpenSSL "
"or LibreSSL. 'module' also compiles Python modules. 'tests' builds "
"Which steps to perform. 'library' downloads and compiles a crypto"
"library. 'module' also compiles Python modules. 'tests' builds "
"all and runs the test suite."
)
)
Expand Down Expand Up @@ -453,6 +465,34 @@ class BuildLibreSSL(AbstractBuilder):
build_template = "libressl-{}"


class BuildAWSLC(AbstractBuilder):
library = "AWS-LC"
url_templates = (
"https://github.com/aws/aws-lc/archive/refs/tags/v{v}.tar.gz",
)
src_template = "aws-lc-{}.tar.gz"
build_template = "aws-lc-{}"

def _build_src(self, config_args=()):
cwd = self.build_dir
log.info("Running build in {}".format(cwd))
env = os.environ.copy()
env["LD_RUN_PATH"] = self.lib_dir # set rpath
if self.system:
env['SYSTEM'] = self.system
cmd = [
"cmake",
"-DCMAKE_BUILD_TYPE=RelWithDebInfo",
"-DCMAKE_PREFIX_PATH={}".format(self.install_dir),
"-DCMAKE_INSTALL_PREFIX={}".format(self.install_dir),
"-DBUILD_SHARED_LIBS=ON",
"-DBUILD_TESTING=OFF",
"-DFIPS=OFF",
]
self._subprocess_call(cmd, cwd=cwd, env=env)
self._subprocess_call(["make", f"-j{self.jobs}"], cwd=cwd, env=env)


def configure_make():
if not os.path.isfile('Makefile'):
log.info('Running ./configure')
Expand All @@ -467,9 +507,10 @@ def configure_make():

def main():
args = parser.parse_args()
if not args.openssl and not args.libressl:
if not args.openssl and not args.libressl and not args.awslc:
args.openssl = list(OPENSSL_RECENT_VERSIONS)
args.libressl = list(LIBRESSL_RECENT_VERSIONS)
args.awslc = list(AWSLC_RECENT_VERSIONS)
if not args.disable_ancient:
args.openssl.extend(OPENSSL_OLD_VERSIONS)
args.libressl.extend(LIBRESSL_OLD_VERSIONS)
Expand Down Expand Up @@ -513,6 +554,14 @@ def main():
build.install()
builds.append(build)

for version in args.awslc:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rewrite the three loops as:

for build_class, versions in [
    (BuildOpenSSL, args.openssl),
    (BuildLibreSSL, args.libressl),
    (BuildAWSLC, args.awslc),
]:
    for version in versions:
        build = build_class(version, args)
        build.install()
        builds.append(build)

build = BuildAWSLC(
version,
args
)
build.install()
builds.append(build)

if args.steps in {'modules', 'tests'}:
for build in builds:
try:
Expand All @@ -539,7 +588,7 @@ def main():
else:
print('Executed all SSL tests.')

print('OpenSSL / LibreSSL versions:')
print('OpenSSL / LibreSSL / AWS-LC versions:')
for build in builds:
print(" * {0.library} {0.version}".format(build))

Expand Down
1 change: 0 additions & 1 deletion configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -7545,7 +7545,6 @@ WITH_SAVE_ENV([
OBJ_nid2sn(NID_md5);
OBJ_nid2sn(NID_sha1);
OBJ_nid2sn(NID_sha3_512);
OBJ_nid2sn(NID_blake2b512);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update this check to actually check for sha2 as well? I doubt someone won't have SHA2 but has SHA3 but it will be consistent with our expectations. Also, for posterity, we don't use OpenSSL BLAKE-2 because it has limited support, so it doesn't make sense to enable it here (but we can use it in HMAC)

EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0);
])], [ac_cv_working_openssl_hashlib=yes], [ac_cv_working_openssl_hashlib=no])
])
Expand Down
Loading