Support SONiC OpenSSL FIPS 140-3 based on SymCrypt engine (#9573)

Why I did it
Support OpenSSL FIPS 140-3, see design doc: https://github.com/Azure/SONiC/blob/master/doc/fips/SONiC-OpenSSL-FIPS-140-3.md.

How I did it
Install the fips packages.
To build the fips packages, see https://github.com/Azure/sonic-fips
Azure pipelines: https://dev.azure.com/mssonic/build/_build?definitionId=412

How to verify it
Validate the SymCrypt engine:

admin@sonic:~$ dpkg-query -W | grep openssl
openssl 1.1.1k-1+deb11u1+fips
symcrypt-openssl        0.1

admin@sonic:~$ openssl engine -v | grep -i symcrypt
(symcrypt) SCOSSL (SymCrypt engine for OpenSSL)
admin@sonic:~$
This commit is contained in:
xumia 2022-05-06 07:21:30 +08:00 committed by GitHub
parent 681c24878b
commit 8ec8900d31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 152 additions and 24 deletions

View File

@ -138,13 +138,25 @@ endif
endif
SLAVE_IMAGE = $(SLAVE_BASE_IMAGE)-$(USER_LC)
# Support FIPS feature, armhf not supported yet
ifeq ($(PLATFORM_ARCH),armhf)
ENABLE_FIPS_FEATURE := n
ENABLE_FIPS := n
endif
ifeq ($(ENABLE_FIPS_FEATURE), n)
ifeq ($(ENABLE_FIPS), y)
$(error Cannot set fips config ENABLE_FIPS=y when ENABLE_FIPS_FEATURE=n)
endif
endif
# Generate the version control build info
$(shell SONIC_VERSION_CONTROL_COMPONENTS=$(SONIC_VERSION_CONTROL_COMPONENTS) \
TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \
scripts/generate_buildinfo_config.sh)
# Generate the slave Dockerfile, and prepare build info for it
$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) DOCKER_EXTRA_OPTS=$(DOCKER_EXTRA_OPTS) DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile)
$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) ENABLE_FIPS_FEATURE=$(ENABLE_FIPS_FEATURE) DOCKER_EXTRA_OPTS=$(DOCKER_EXTRA_OPTS) DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile)
$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) j2 $(SLAVE_DIR)/Dockerfile.user.j2 > $(SLAVE_DIR)/Dockerfile.user)
$(shell BUILD_SLAVE=y DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) scripts/prepare_docker_buildinfo.sh $(SLAVE_BASE_IMAGE) $(SLAVE_DIR)/Dockerfile $(CONFIGURED_ARCH) "" $(BLDENV))
@ -355,6 +367,8 @@ SONIC_BUILD_INSTRUCTION := make \
ENABLE_AUTO_TECH_SUPPORT=$(ENABLE_AUTO_TECH_SUPPORT) \
BUILD_MULTIASIC_KVM=$(BUILD_MULTIASIC_KVM) \
ENABLE_ASAN=$(ENABLE_ASAN) \
ENABLE_FIPS_FEATURE=$(ENABLE_FIPS_FEATURE) \
ENABLE_FIPS=$(ENABLE_FIPS) \
$(SONIC_OVERRIDE_BUILD_VARS)
.PHONY: sonic-slave-build sonic-slave-bash init reset

View File

@ -43,7 +43,9 @@ variables:
- ${{ else }}:
- template: .azure-pipelines/template-variables.yml@buildimage
- name: CACHE_MODE
value: rcache
value: rcache
- name: ENABLE_FIPS
value: y
stages:
- stage: BuildVS

View File

@ -62,7 +62,8 @@ RUN apt-get update && \
# for processing/handling json files in bash environment
jq \
# for sairedis zmq rpc channel
libzmq5
libzmq5 \
libwrap0
# Upgrade pip via PyPI and uninstall the Debian version
RUN pip3 install --upgrade pip

View File

@ -330,12 +330,7 @@ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/restart_service
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install smartmontools=7.2-1
# Install custom-built openssh sshd
sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/openssh-server_*.deb
# Remove sshd host keys, and will regenerate on first sshd start. This needs to be
# done again here because our custom version of sshd is being installed, which
# will regenerate the sshd host keys.
sudo rm -f $FILESYSTEM_ROOT/etc/ssh/ssh_host_*_key*
sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/openssh-server_${OPENSSH_VERSION}_*.deb
{% if sonic_asic_platform == 'broadcom' %}
# Install custom-built flashrom
@ -625,6 +620,11 @@ sudo dpkg --root=$FILESYSTEM_ROOT -P {{ debname }}
{% endfor %}
{% endif %}
# Remove sshd host keys, and will regenerate on first sshd start. This needs to be
# done again here because our custom version of sshd is being installed, which
# will regenerate the sshd host keys.
sudo rm -f $FILESYSTEM_ROOT/etc/ssh/ssh_host_*_key*
sudo rm -f $FILESYSTEM_ROOT/usr/sbin/policy-rc.d
# Copy fstrim service and timer file, enable fstrim timer

View File

@ -666,6 +666,11 @@ else # install_env = "onie"
fi
fi
# Add extra linux command line
extra_cmdline_linux=%%EXTRA_CMDLINE_LINUX%%
echo "EXTRA_CMDLINE_LINUX=$extra_cmdline_linux"
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX $extra_cmdline_linux"
cat <<EOF >> $grub_cfg
menuentry '$demo_grub_entry' {
search --no-floppy --label --set=root $demo_volume_label

View File

@ -79,6 +79,11 @@ cp -r $installer_dir/$arch/* $tmp_installdir || clean_up 1
cp onie-image.conf $tmp_installdir
cp onie-image-*.conf $tmp_installdir
# Set sonic fips config for the installer script
if [ "$ENABLE_FIPS" = "y" ]; then
EXTRA_CMDLINE_LINUX="$EXTRA_CMDLINE_LINUX sonic_fips=1"
fi
# Escape special chars in the user provide kernel cmdline string for use in
# sed. Special chars are: \ / &
EXTRA_CMDLINE_LINUX=`echo $EXTRA_CMDLINE_LINUX | sed -e 's/[\/&]/\\\&/g'`

View File

@ -224,3 +224,8 @@ ENABLE_ASAN ?= n
# reset default container registry from dockerhub to other
DEFAULT_CONTAINER_REGISTRY ?=
# ENABLE_FIPS_FEATURE - support FIPS feature, only for amd64 or arm64, armhf not supported yet
# ENABLE_FIPS - support FIPS flag, if enabled, no additional config requred for the image to support FIPS
ENABLE_FIPS_FEATURE ?= y
ENABLE_FIPS ?= n

View File

@ -11,6 +11,11 @@ VIM = vim
OPENSSH = openssh-client
SSHPASS = sshpass
STRACE = strace
ifeq ($(ENABLE_FIPS_FEATURE), y)
$(DOCKER_BASE_BULLSEYE)_DEPENDS += $(FIPS_OPENSSL_LIBSSL) $(FIPS_OPENSSL_LIBSSL_DEV) $(FIPS_OPENSSL) $(SYMCRYPT_OPENSSL) $(FIPS_KRB5)
endif
$(DOCKER_BASE_BULLSEYE)_DBG_IMAGE_PACKAGES += $(GDB) $(GDBSERVER) $(VIM) $(OPENSSH) $(SSHPASS) $(STRACE)
SONIC_DOCKER_IMAGES += $(DOCKER_BASE_BULLSEYE)

10
rules/sonic-fips.dep Normal file
View File

@ -0,0 +1,10 @@
SPATH := $($(SYMCRYPT_OPENSSL)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-fips.mk rules/sonic-fips.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files))
$(SYMCRYPT_OPENSSL)_CACHE_MODE := GIT_CONTENT_SHA
$(SYMCRYPT_OPENSSL)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(SYMCRYPT_OPENSSL)_DEP_FILES := $(DEP_FILES)
$(SYMCRYPT_OPENSSL)_SMDEP_FILES := $(SMDEP_FILES)
$(SYMCRYPT_OPENSSL)_SMDEP_PATHS := $(SPATH)

53
rules/sonic-fips.mk Normal file
View File

@ -0,0 +1,53 @@
# fips packages
FIPS_VERSION = 0.1
FIPS_OPENSSL_VERSION = 1.1.1k-1+deb11u1+fips
FIPS_OPENSSH_VERSION = 8.4p1-5+fips
FIPS_PYTHON_MAIN_VERSION = 3.9
FIPS_PYTHON_VERSION = 3.9.2-1+fips
FIPS_GOLANG_MAIN_VERSION = 1.15
FIPS_GOLANG_VERSION = 1.15.15-1~deb11u4+fips
FIPS_KRB5_VERSION = 1.18.3-6+deb11u1+fips
FIPS_URL_PREFIX = https://sonicstorage.blob.core.windows.net/public/fips/$(BLDENV)/$(FIPS_VERSION)/$(CONFIGURED_ARCH)
SYMCRYPT_OPENSSL_NAME = symcrypt-openssl
SYMCRYPT_OPENSSL = $(SYMCRYPT_OPENSSL_NAME)_$(FIPS_VERSION)_$(CONFIGURED_ARCH).deb
$(SYMCRYPT_OPENSSL)_SRC_PATH = $(SRC_PATH)/sonic-fips
FIPS_OPENSSL = openssl_$(FIPS_OPENSSL_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSL_LIBSSL = libssl1.1_$(FIPS_OPENSSL_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSL_LIBSSL_DEV = libssl-dev_$(FIPS_OPENSSL_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSL_LIBSSL_DOC = libssl-doc_$(FIPS_OPENSSL_VERSION)_all.deb
FIPS_OPENSSL_ALL = $(FIPS_OPENSSL) $(FIPS_OPENSSL_LIBSSL) $(FIPS_OPENSSL_LIBSSL_DEV) $(FIPS_OPENSSL_LIBSSL_DOC)
FIPS_OPENSSH = ssh_$(FIPS_OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSH_CLIENT = openssh-client_$(FIPS_OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSH_SFTP_SERVER = openssh-sftp-server_$(FIPS_OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSH_SERVER = openssh-server_$(FIPS_OPENSSH_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_OPENSSH_ALL = $(FIPS_SSH) $(FIPS_OPENSSH_CLIENT) $(FIPS_OPENSSH_SFTP_SERVER) $(FIPS_OPENSSH_SERVER)
FIPS_PYTHON = python$(FIPS_PYTHON_MAIN_VERSION)_$(FIPS_PYTHON_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_PYTHON_MINIMAL = python$(FIPS_PYTHON_MAIN_VERSION)-minimal_$(FIPS_PYTHON_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_LIBPYTHON = libpython$(FIPS_PYTHON_MAIN_VERSION)_$(FIPS_PYTHON_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_LIBPYTHON_MINIMAL = libpython$(FIPS_PYTHON_MAIN_VERSION)-minimal_$(FIPS_PYTHON_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_LIBPYTHON_STDLIB = libpython$(FIPS_PYTHON_MAIN_VERSION)-stdlib_$(FIPS_PYTHON_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_PYTHON_ALL = $(FIPS_PYTHON) $(FIPS_PYTHON_MINIMAL) $(FIPS_LIBPYTHON) $(FIPS_LIBPYTHON_MINIMAL) $(FIPS_LIBPYTHON_STDLIB)
FIPS_GOLANG = golang-$(FIPS_GOLANG_MAIN_VERSION)_$(FIPS_GOLANG_VERSION)_all.deb
FIPS_GOLANG_GO = golang-$(FIPS_GOLANG_MAIN_VERSION)-go_$(FIPS_GOLANG_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_GOLANG_SRC = golang-$(FIPS_GOLANG_MAIN_VERSION)-src_$(FIPS_GOLANG_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_GOLANG_DOC = golang-$(FIPS_GOLANG_MAIN_VERSION)-doc_$(FIPS_GOLANG_VERSION)_all.deb
FIPS_GOLANG_ALL = $(FIPS_GOLANG) $(FIPS_GOLANG_GO) $(FIPS_GOLANG_SRC) $(FIPS_GOLANG_DOC)
FIPS_KRB5 = libk5crypto3_$(FIPS_KRB5_VERSION)_$(CONFIGURED_ARCH).deb
FIPS_KRB5_ALL = $(FIPS_KRB5)
FIPS_DERIVED_TARGET = $(FIPS_OPENSSL_ALL) $(FIPS_OPENSSH_ALL) $(FIPS_GOLANG_ALL) $(FIPS_PYTHON_ALL) $(FIPS_KRB5_ALL)
FIPS_PACKAGE_ALL = $(SYMCRYPT_OPENSSL) $(FIPS_DERIVED_TARGET)
$(foreach package,$(FIPS_DERIVED_TARGET),$(eval $(call add_extra_package,$(SYMCRYPT_OPENSSL),$(package))))
ifeq ($(ENABLE_FIPS_FEATURE), y)
FIPS_BASEIMAGE_INSTALLERS = $(FIPS_OPENSSL_LIBSSL) $(FIPS_OPENSSL_LIBSSL_DEV) $(FIPS_OPENSSL) $(SYMCRYPT_OPENSSL) $(FIPS_OPENSSH) $(FIPS_OPENSSH_CLIENT) $(FIPS_OPENSSH_SFTP_SERVER) $(FIPS_OPENSSH_SERVER) $(FIPS_KRB5)
SONIC_MAKE_DEBS += $(SYMCRYPT_OPENSSL)
endif

View File

@ -80,6 +80,7 @@ export IMAGE_DISTRO
export IMAGE_DISTRO_DEBS_PATH
export MULTIARCH_QEMU_ENVIRON
export DOCKER_BASE_ARCH
export BLDENV
###############################################################################
## Utility rules
@ -93,7 +94,6 @@ ifneq ($(CONFIGURED_PLATFORM),generic)
endif
configure :
@mkdir -p $(DEBS_PATH)
@mkdir -p $(JESSIE_DEBS_PATH)
@mkdir -p $(STRETCH_DEBS_PATH)
@mkdir -p $(BUSTER_DEBS_PATH)
@ -271,6 +271,8 @@ endif
export SONIC_ROUTING_STACK
export FRR_USER_UID
export FRR_USER_GID
export ENABLE_FIPS_FEATURE
export ENABLE_FIPS
###############################################################################
## Build Options
@ -332,6 +334,7 @@ $(info "INCLUDE_P4RT" : "$(INCLUDE_P4RT)")
$(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)")
$(info "INCLUDE_MACSEC" : "$(INCLUDE_MACSEC)")
$(info "INCLUDE_MUX" : "$(INCLUDE_MUX)")
$(info "ENABLE_FIPS_FEATURE" : "$(ENABLE_FIPS_FEATURE)")
$(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)")
$(info "ENABLE_AUTO_TECH_SUPPORT" : "$(ENABLE_AUTO_TECH_SUPPORT)")
$(info "PDDF_SUPPORT" : "$(PDDF_SUPPORT)")
@ -1054,6 +1057,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \
$(addsuffix -install,$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(DEBOOTSTRAP))) \
$(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \
$(if $(findstring y,$(ENABLE_FIPS_FEATURE)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SYMCRYPT_OPENSSL))) \
$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_UTILITIES_PY3)) \
$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY2)) \
$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PY_COMMON_PY3)) \
@ -1106,7 +1110,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
export include_kubernetes="$(INCLUDE_KUBERNETES)"
export kube_docker_proxy="$(KUBE_DOCKER_PROXY)"
export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)"
export installer_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($*_INSTALLS))"
export installer_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($*_INSTALLS) $(FIPS_BASEIMAGE_INSTALLERS))"
export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(IMAGE_DISTRO_DEBS_PATH)/$(deb))))"
export lazy_build_installer_debs="$(foreach deb, $($*_LAZY_BUILD_INSTALLS), $(addprefix $($(deb)_MACHINE)|,$(deb)))"
export installer_images="$(foreach docker, $($*_DOCKERS),\

View File

@ -397,20 +397,14 @@ RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold"
RUN apt-get -y build-dep linux
# For gobgp and telemetry build
RUN export VERSION=1.14.2 \
{%- if CONFIGURED_ARCH == "armhf" %}
&& wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \
&& tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \
{%- elif CONFIGURED_ARCH == "arm64" %}
&& wget https://storage.googleapis.com/golang/go$VERSION.linux-arm64.tar.gz \
&& tar -C /usr/local -xzf go$VERSION.linux-arm64.tar.gz \
{%- else %}
&& wget https://storage.googleapis.com/golang/go$VERSION.linux-amd64.tar.gz \
&& tar -C /usr/local -xzf go$VERSION.linux-amd64.tar.gz \
RUN apt-get install -y golang-1.15 && ln -s /usr/lib/go-1.15 /usr/local/go
{%- if ENABLE_FIPS_FEATURE == "y" %}
RUN wget -O golang-go.deb 'https://sonicstorage.blob.core.windows.net/public/fips/bullseye/0.1/{{ CONFIGURED_ARCH }}/golang-1.15-go_1.15.15-1~deb11u4%2Bfips_{{ CONFIGURED_ARCH }}.deb' \
&& wget -O golang-src.deb 'https://sonicstorage.blob.core.windows.net/public/fips/bullseye/0.1/{{ CONFIGURED_ARCH }}/golang-1.15-src_1.15.15-1~deb11u4%2Bfips_{{ CONFIGURED_ARCH }}.deb' \
&& dpkg -i golang-go.deb golang-src.deb \
&& ln -sf /usr/lib/go-1.15 /usr/local/go \
&& rm golang-go.deb golang-src.deb
{%- endif %}
&& echo 'export GOROOT=/usr/local/go' >> /etc/bash.bashrc \
&& echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \
&& rm go$VERSION.linux-*.tar.gz
RUN pip3 install --upgrade pip
RUN apt-get purge -y python3-pip python3-yaml

1
src/sonic-fips/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
sonic-fips

29
src/sonic-fips/Makefile Normal file
View File

@ -0,0 +1,29 @@
.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS += -e
SONIC_FIPS_BUILD_FROM_SOURCE =? n
include ../../rules/sonic-fips.mk
MAIN_TARGET = $(SYMCRYPT_OPENSSL)
$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
if [ "$(SONIC_FIPS_BUILD_FROM_SOURCE)" == "y" ]; then
git clone -b "$(FIPS_VERSION)" https://github.com/Azure/sonic-fips
push sonic-fips
git submodule update --init
push src/SymCrypt; git submodule update --init -- jitterentropy-library; pop
make all
pop
cp sonic-fips/target/*.deb $(DEST)/
exit 0
fi
for target in $(FIPS_PACKAGE_ALL); do
filename=$$(basename $$target)
url=$(FIPS_URL_PREFIX)/$$filename
mkdir -p "$$(dirname $(DEST)/$$target)"
wget -O "$(DEST)/$$target" "$$url"
done
$(addprefix $(DEST)/, $(FIPS_DERIVED_TARGET)): $(DEST)/% : $(DEST)/$(MAIN_TARGET)