Skip to content
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

feat: Add support for AWS-LC build in ESDK #750

Merged
merged 13 commits into from
Sep 6, 2022
3 changes: 2 additions & 1 deletion codebuild/bin/codebuild-test.sh
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ set -euxo pipefail

PATH=$PWD/build-tools/bin:$PATH
ROOT=$PWD
NUM_CPU_THREADS=$(nproc)

# End to end tests require valid credentials (instance role, etc..)
# Disable for local runs.
@@ -67,7 +68,7 @@ run_test() {
-GNinja \
.. "$@" 2>&1|head -n 1000)
cmake --build $ROOT/build -- -v
(cd build; ctest --output-on-failure -j8)
(cd build; ctest --output-on-failure -j${NUM_CPU_THREADS})
(cd build; debug ./tests/test_local_cache_threading) || exit 1
"$ROOT/codebuild/bin/test-install.sh" "$PREFIX_PATH" "$PWD/build"
}
6 changes: 3 additions & 3 deletions codebuild/bin/install-aws-deps.sh
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ build_pkg() {
git clone --depth 1 --branch $GIT_REF --recurse-submodules "$GIT_URL" "$SRC_DIR"
fi

mkdir $BUILD_DIR
mkdir -p $BUILD_DIR
(cd $BUILD_DIR &&
export LD_LIBRARY_PATH=/deps/install &&
cmake $SRC_DIR "$@" -DCMAKE_INSTALL_PREFIX=$root/install -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja \
@@ -53,8 +53,8 @@ build_pkg() {
mkdir -p /deps

# These must refer to git tags
AWS_CRT_CPP_VERSION="v0.14.0"
AWS_SDK_CPP_VERSION="1.9.39"
AWS_CRT_CPP_VERSION="v0.17.28"
AWS_SDK_CPP_VERSION="1.9.263"

for libtype in shared static; do
root=/deps/$libtype
76 changes: 76 additions & 0 deletions codebuild/bin/install-shared-deps-awslc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/bash

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# This script is similar to |install-shared-deps.sh| except below differences:
# 1. OpenSSL is replaced with awslc.
# 2. LibCurl version is updated to 7.74.
# After this script, awslc(static and shared) and curl will be installed under /deps/install.

set -euxo pipefail

export AWSLC_SRC_DIR=/tmp/awslc
export INSTALL_DIR=/deps/install
export LD_LIBRARY_PATH=${INSTALL_DIR}
export NUM_CPU_THREADS=$(nproc)

function download_awslc() {
AWSLC_GIT_URL='https://github.com/awslabs/aws-lc.git'
AWSLC_GIT_REF='main'
Copy link
Contributor

Choose a reason for hiding this comment

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

We should pin a particular AWS-LC version as we do for the OpenSSL Dockerfiles. I tried changing this to the latest relevant tag I saw (AWS-LC-FIPS-1.0.2), but the Docker image failed to build because (I assume) that tag is a bit out of date. Can you tag the working commit on main and pin that tag here? Then I can build the image and set up a CI build that runs within it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry for the confusion, the AWS-LC-FIPS-1.0.2 branch points to a FIPS version release, which points to a branch of an older commit of the repo that's still in the process of getting FIPS validated.
I've set the docker image tag to v1.1.0, which points to a newer commit should work. Just so you know, we'll also be setting up an encryption-sdk CI in AWS-LC, so we can verify that all future versions of AWS-LC will build with ESDK :)

rm -rf ${AWSLC_SRC_DIR}
mkdir -p ${AWSLC_SRC_DIR}
git clone --depth 1 --branch ${AWSLC_GIT_REF} "${AWSLC_GIT_URL}" "${AWSLC_SRC_DIR}"
}

function build_awslc() {
BUILD_DIR=/tmp/build/awslc
rm -rf ${BUILD_DIR}
mkdir -p ${BUILD_DIR}
CMAKE_BUILD_COMMAND="cmake ${AWSLC_SRC_DIR} $@ \
-GNinja \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo"
if [[ !(-z "${CFLAGS+x}" || -z "${CFLAGS}") ]]; then
CMAKE_BUILD_COMMAND="${CMAKE_BUILD_COMMAND} -DCMAKE_C_FLAGS=${CFLAGS}"
fi
if [[ !(-z "${CXXFLAGS+x}" || -z "${CXXFLAGS}") ]]; then
CMAKE_BUILD_COMMAND="${CMAKE_BUILD_COMMAND} -DCMAKE_CXX_FLAGS=${CXXFLAGS}"
fi
alex-chew marked this conversation as resolved.
Show resolved Hide resolved
(cd ${BUILD_DIR} && ${CMAKE_BUILD_COMMAND})
cmake --build ${BUILD_DIR}
cmake --build ${BUILD_DIR} --target install
rm -rf ${BUILD_DIR}
}

function install_libcurl() {
mkdir /deps/curl
cd /deps/curl
wget https://curl.haxx.se/download/curl-7.74.0.tar.gz
tar xzf curl-*.tar.gz
cd curl-*/
# awslc is forked from boringssl.
# |OPENSSL_IS_AWSLC| macro is equivalent to |OPENSSL_IS_BORINGSSL|.
# Replacing OPENSSL_IS_BORINGSSL with OPENSSL_IS_AWSLC.
find ./ -type f -exec sed -i -e 's/OPENSSL_IS_BORINGSSL/OPENSSL_IS_AWSLC/g' {} \;
alex-chew marked this conversation as resolved.
Show resolved Hide resolved
./configure --with-ssl=/deps/install \
--prefix=/deps/install \
--disable-ldap \
--without-libidn \
--without-gnutls \
--without-nss \
--without-gssapi
make -j"${NUM_CPU_THREADS}"
make install
cd /
rm -rf /deps/curl
}

mkdir -p /deps

download_awslc

build_awslc '-DBUILD_SHARED_LIBS=ON'
build_awslc '-DBUILD_SHARED_LIBS=OFF'

install_libcurl
38 changes: 38 additions & 0 deletions codebuild/ubuntu-latest-x64-awslc.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

FROM ubuntu:latest

# Needed for setup-apt-cache.sh
ADD https://mirrors.kernel.org/ubuntu/pool/main/n/net-tools/net-tools_1.60+git20180626.aebd88e-1ubuntu1_amd64.deb /tmp
ADD https://mirrors.kernel.org/ubuntu/pool/universe/n/netcat/netcat-traditional_1.10-40_amd64.deb /tmp
RUN dpkg -i /tmp/net-tools_*.deb /tmp/netcat-*.deb

ADD bin/setup-apt-cache.sh /usr/local/bin/
ADD bin/setup-apt.sh /usr/local/bin/
RUN setup-apt-cache.sh
RUN setup-apt.sh

ENV PATH=/usr/local/bin:/usr/bin:/bin

ENV CC=/usr/bin/gcc
ENV CXX=/usr/bin/g++
ENV CFLAGS=
ENV CXXFLAGS=
ENV LDFLAGS=

# Same paths as the main docker file, ubuntu-latest-x64.Dockerfile.
ENV LDFLAGS="-Wl,-rpath -Wl,/deps/install/lib -Wl,-rpath -Wl,/deps/shared/install/lib -L/deps/install/lib -L/deps/shared/install/lib"

ADD bin/apt-install-pkgs /usr/local/bin/
ADD bin/install-shared-deps-awslc.sh /usr/local/bin/
RUN install-shared-deps-awslc.sh

ADD bin/install-aws-deps.sh /usr/local/bin
RUN install-aws-deps.sh

ADD bin/install-node.sh /usr/local/bin
RUN install-node.sh

# Remove apt proxy configuration before publishing the dockerfile
RUN rm -f /etc/apt/apt.conf.d/99proxy
24 changes: 20 additions & 4 deletions source/cipher_openssl.c
Original file line number Diff line number Diff line change
@@ -19,11 +19,16 @@
#include <openssl/crypto.h>
#include <openssl/opensslv.h>

#include <openssl/asn1.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>

#if defined(OPENSSL_IS_AWSLC)
# include <openssl/obj.h>
#endif

#include <aws/common/encoding.h>

#include <aws/cryptosdk/cipher.h>
@@ -70,6 +75,17 @@ static void ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) {

#endif

static void aws_cryptosdk_free(void *orig_ptr) {
#if defined(OPENSSL_IS_AWSLC)
// The memory within |i2o_ECPublicKey| is allocated with |OPENSSL_malloc|.
// Memory that has been allocated with |OPENSSL_malloc| in AWS-LC has to
// be freed with |OPENSSL_free|.
OPENSSL_free(orig_ptr);
#else
free(orig_ptr);
#endif
}

struct aws_cryptosdk_sig_ctx {
struct aws_allocator *alloc;
const struct aws_cryptosdk_alg_properties *props;
@@ -296,12 +312,12 @@ static int serialize_pubkey(struct aws_allocator *alloc, EC_KEY *keypair, struct
goto err;
}

free(buf);
aws_cryptosdk_free(buf);
return AWS_OP_SUCCESS;

err:
// buf (and tmp) hold a public key, so we don't need to zeroize them.
free(buf);
aws_cryptosdk_free(buf);

*pub_key = NULL;

@@ -413,11 +429,11 @@ int aws_cryptosdk_sig_get_privkey(
aws_secure_zero(tmparr, sizeof(tmparr));
if (privkey_buf) {
aws_secure_zero(privkey_buf, privkey_len);
free(privkey_buf);
aws_cryptosdk_free(privkey_buf);
}
if (pubkey_buf) {
aws_secure_zero(pubkey_buf, pubkey_len);
free(pubkey_buf);
aws_cryptosdk_free(pubkey_buf);
}

// There is no error path that results in a non-NULL priv_key, so we don't need to
15 changes: 13 additions & 2 deletions source/hkdf.c
Original file line number Diff line number Diff line change
@@ -29,7 +29,18 @@ static const EVP_MD *aws_cryptosdk_get_evp_md(enum aws_cryptosdk_sha_version whi
}
}

#if OPENSSL_VERSION_NUMBER < 0x10100000L
// AWS-LC does not support HKDF construction with the |EVP_PKEY*| methods in OpenSSL 1.1.1.
// We're backporting to ESDK's HKDF self implementation methods |aws_cryptosdk_hkdf_extract|
// and |aws_cryptosdk_hkdf_expand| when building with AWS-LC for now.
// The semantics of AWS-LC's HKDF API implementations (|HKDF_extract| & |HKDF_expand|)
// are nearly identical to ESDK's. We can look to add support if there are customer
// requirements to use AWS-LC's HKDF crypto implementation when building with ESDK.
alex-chew marked this conversation as resolved.
Show resolved Hide resolved
//
// Both APIs align with the RFC5869 requirements.
// HKDF_extract: https://tools.ietf.org/html/rfc5869#section-2.2
// HKDF_expand: https://tools.ietf.org/html/rfc5869#section-2.3
//
#if (OPENSSL_VERSION_NUMBER < 0x10100000L || defined(OPENSSL_IS_AWSLC))

static int aws_cryptosdk_hkdf_extract(
/* prk must be a buffer of EVP_MAX_MD_SIZE bytes */
@@ -151,7 +162,7 @@ int aws_cryptosdk_hkdf(
const struct aws_byte_buf *salt,
const struct aws_byte_buf *ikm,
const struct aws_byte_buf *info) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if (OPENSSL_VERSION_NUMBER < 0x10100000L || defined(OPENSSL_IS_AWSLC))
uint8_t prk[EVP_MAX_MD_SIZE];
unsigned int prk_len = 0;
if (aws_cryptosdk_hkdf_extract(prk, &prk_len, which_sha, salt, ikm)) goto err;