Skip to content

Commit

Permalink
feat: Add support for AWS-LC build in ESDK (#750)
Browse files Browse the repository at this point in the history
* add support for AWS-LC build in ESDK

* align with clang format linters

* clang format linters need another whitespace

* different memory freeing behaviour

* clarify some ambiguities

* remove local testing change

* update aws-lc version tag

* fix OPENSSL_ROOT_DIR

* rerun CI

* test adding delay in timing

Co-authored-by: Alex Chew <[email protected]>
Co-authored-by: Andrew Jewell <[email protected]>
Co-authored-by: Alex Chew <[email protected]>
  • Loading branch information
4 people authored Sep 6, 2022
1 parent 072bce0 commit c40940e
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,10 @@ static int run_test_decryption(
}

static void kms_delay(test_type test_type_idx) {
static int tenth_second_in_millis = 100;
static int fifteen_millis = 15000;
if ((test_type_idx == AWS_CRYPTOSDK_KMS) || (test_type_idx == AWS_CRYPTOSDK_KMS_MRK_AWARE) ||
(test_type_idx == AWS_CRYPTOSDK_KMS_MRK_AWARE_DISCOVERY)) {
usleep(tenth_second_in_millis);
usleep(fifteen_millis);
}
}

Expand Down
5 changes: 3 additions & 2 deletions codebuild/bin/codebuild-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -60,14 +61,14 @@ run_test() {
-DCMAKE_C_FLAGS="$CFLAGS" \
-DCMAKE_CXX_FLAGS="$CXXFLAGS" \
-DCMAKE_SHARED_LINKER_FLAGS="$LDFLAGS" \
-DOPENSSL_ROOT_DIR=/deps/openssl \
-DOPENSSL_ROOT_DIR=/deps/install \
-DVALGRIND_OPTIONS="--gen-suppressions=all;--suppressions=$ROOT/valgrind.suppressions" \
-DCMAKE_PREFIX_PATH="$PREFIX_PATH" \
-DBUILD_SHARED_LIBS="$BUILD_SHARED_LIBS" \
-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"
}
Expand Down
6 changes: 3 additions & 3 deletions codebuild/bin/install-aws-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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
Expand Down
78 changes: 78 additions & 0 deletions codebuild/bin/install-shared-deps-awslc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/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_TAG='v1.1.0'
rm -rf ${AWSLC_SRC_DIR}
mkdir -p ${AWSLC_SRC_DIR}
git clone --depth 1 --branch ${AWSLC_TAG} "${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 [[ -n "${CFLAGS-}" ]]; then
CMAKE_BUILD_COMMAND="${CMAKE_BUILD_COMMAND} -DCMAKE_C_FLAGS=${CFLAGS}"
fi
if [[ -n "${CXXFLAGS-}" ]]; then
CMAKE_BUILD_COMMAND="${CMAKE_BUILD_COMMAND} -DCMAKE_CXX_FLAGS=${CXXFLAGS}"
fi
(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.
#
# TODO: Remove the extra command below when curl has official support for AWS-LC.
find ./ -type f -exec sed -i -e 's/OPENSSL_IS_BORINGSSL/OPENSSL_IS_AWSLC/g' {} \;
./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
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
18 changes: 16 additions & 2 deletions source/hkdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,21 @@ 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. The only slight difference is that AWS-LC's |HKDF_expand|
// sets the initial |HMAC_Init_ex| paramaters before the key expansion loop, while
// |aws_cryptosdk_hkdf_expand| initializes HMAC with the same parameters continuously.
// We can look to add support if there are customer requirements to use AWS-LC's HKDF crypto
// implementation when building with ESDK.
//
// 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 */
Expand Down Expand Up @@ -151,7 +165,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;
Expand Down

0 comments on commit c40940e

Please sign in to comment.