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

Add Secure Boot Kernel configuration #298

Merged
merged 9 commits into from
Feb 2, 2023
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ KERNEL_VERSION ?= 5.10.140
KERNEL_SUBVERSION ?= 1
kernel_procure_method ?= build
CONFIGURED_ARCH ?= amd64
SECURE_UPGRADE_MODE ?=
SECURE_UPGRADE_DEV_SIGNING_CERT =?

LINUX_HEADER_COMMON = linux-headers-$(KVERSION_SHORT)-common_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_all.deb
LINUX_HEADER_AMD64 = linux-headers-$(KVERSION)_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb
Expand Down Expand Up @@ -123,7 +125,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :

# Optionally add/remove kernel options
if [ -f ../manage-config ]; then
../manage-config $(CONFIGURED_ARCH) $(CONFIGURED_PLATFORM)
../manage-config $(CONFIGURED_ARCH) $(CONFIGURED_PLATFORM) $(SECURE_UPGRADE_MODE) $(SECURE_UPGRADE_DEV_SIGNING_CERT)
davidpil2002 marked this conversation as resolved.
Show resolved Hide resolved
fi

# Building a custom kernel from Debian kernel source
Expand Down
184 changes: 114 additions & 70 deletions manage-config
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,21 @@
# Configuration file to change
ARCH=amd64
PLATFORM=
SECURE_UPGRADE_MODE="no_sign"
SECURE_UPGRADE_DEV_SIGNING_CERT=
if [ $# -ge 1 ]; then
ARCH=$1
fi
if [ $# -ge 2 ]; then
PLATFORM=$2
fi
if [ $# -ge 3 ]; then
SECURE_UPGRADE_MODE=$3
fi
if [ $# -ge 4 ]; then
SECURE_UPGRADE_DEV_SIGNING_CERT=$4
fi

case "$ARCH" in
amd64)
CONFIG_FILE_LOC=debian/build/build_amd64_none_amd64
Expand All @@ -58,88 +67,123 @@ function get_section_opts(){
echo "$opts"
}

ret=0
exclusion_file="../patch/kconfig-exclusions"
inclusion_file="../patch/kconfig-inclusions"
force_inclusion_file="../patch/kconfig-force-inclusions"
if [ -e ${exclusion_file} -o -e ${inclusion_file} -o -e ${force_inclusion_file} ]; then

# Process any exclusions in the kernel
if [ -f ${exclusion_file} ]; then
exclusion_opts=$(get_section_opts ${exclusion_file} "common" ${ARCH} ${PLATFORM})
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
scripts/config --file ${CONFIG_FILE} -d $opt
fi
done <<< ${exclusion_opts};
fi
function process_inclusion_exclusion_files(){
echo "process_inclusion_exclusion_files Start"
ret=0
echo "debug ret=$ret 1"
if [ -e ${exclusion_file} -o -e ${inclusion_file} -o -e ${force_inclusion_file} ]; then

# Process any inclusions in the kernel
if [ -f ${inclusion_file} ]; then
inclusion_opts=$(get_section_opts ${inclusion_file} "common" ${ARCH} ${PLATFORM})
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
n=${opt%=*}
v="${opt#*=}"
scripts/config --file ${CONFIG_FILE} -k --set-val "$n" "$v"
fi
done <<< ${inclusion_opts};
fi
# Process any exclusions in the kernel
if [ -f ${exclusion_file} ]; then
exclusion_opts=$(get_section_opts ${exclusion_file} "common" ${ARCH} ${PLATFORM})
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
scripts/config --file ${CONFIG_FILE} -d $opt
fi
done <<< ${exclusion_opts};
fi

# Update the .config file to be sure it's consistent
make -C ${CONFIG_FILE_LOC} olddefconfig
# Process any inclusions in the kernel
if [ -f ${inclusion_file} ]; then
inclusion_opts=$(get_section_opts ${inclusion_file} "common" ${ARCH} ${PLATFORM})
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
n=${opt%=*}
v="${opt#*=}"
scripts/config --file ${CONFIG_FILE} -k --set-val "$n" "$v"
fi
done <<< ${inclusion_opts};
fi

# Verify that the kernel options we want to remove are not in the updated configuration
if [ -f ${exclusion_file} ]; then
echo
echo "Checking removed kernel options..."
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
s=$(scripts/config --file ${CONFIG_FILE} -k --state $opt)
if [ ! "$s" = "undef" -a ! "$s" = "n" ]; then
ret=1
echo "Option $opt should not be set, but is set to [$s]"
# Update the .config file to be sure it's consistent
make -C ${CONFIG_FILE_LOC} olddefconfig

# Verify that the kernel options we want to remove are not in the updated configuration
if [ -f ${exclusion_file} ]; then
echo
echo "Checking removed kernel options..."
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
s=$(scripts/config --file ${CONFIG_FILE} -k --state $opt)
if [ ! "$s" = "undef" -a ! "$s" = "n" ]; then
ret=1
echo "Option $opt should not be set, but is set to [$s]"
fi
fi
done <<< ${exclusion_opts};
if [ $ret = 0 ]; then
echo "No error"
fi
done <<< ${exclusion_opts};
if [ $ret = 0 ]; then
echo "No error"
fi
fi

# Verify that the kernel options we want to add are now in the updated configuration
if [ -f ${inclusion_file} ]; then
echo
echo "Checking added kernel options..."
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
n=${opt%=*}
v="${opt#*=}"
v="${v/#\"/}"
v="${v/%\"/}"
s=$(scripts/config --file ${CONFIG_FILE} -k --state $n)
if [ ! "$s" = "$v" ]; then
ret=2
echo "Option $n should be set to [$v] instead of [$s]"
# Verify that the kernel options we want to add are now in the updated configuration
if [ -f ${inclusion_file} ]; then
echo
echo "Checking added kernel options..."
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
n=${opt%=*}
v="${opt#*=}"
v="${v/#\"/}"
v="${v/%\"/}"
s=$(scripts/config --file ${CONFIG_FILE} -k --state $n)
if [ ! "$s" = "$v" ]; then
ret=2
echo "Option $n should be set to [$v] instead of [$s]"
fi
fi
done <<< ${inclusion_opts};
if [ ! $ret = 2 ]; then
echo "No error"
fi
done <<< ${inclusion_opts};
if [ ! $ret = 2 ]; then
echo "No error"
fi
fi

# Process any force inclusions in the kernel
if [ -f ${force_inclusion_file} ]; then
force_inclusion_opts=$(get_section_opts ${force_inclusion_file} "common" ${ARCH} ${PLATFORM})
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
echo $opt >> ${CONFIG_FILE}
fi
done <<< ${force_inclusion_opts};
# Process any force inclusions in the kernel
if [ -f ${force_inclusion_file} ]; then
force_inclusion_opts=$(get_section_opts ${force_inclusion_file} "common" ${ARCH} ${PLATFORM})
while read -r opt; do
if [ ! -z "$opt" ] && [[ ! "$opt" =~ ^#.* ]]; then
echo $opt >> ${CONFIG_FILE}
fi
done <<< ${force_inclusion_opts};
fi

echo
fi

echo
echo "process_inclusion_exclusion_files Done"
return $ret
}

exclusion_file="../patch/kconfig-exclusions"
inclusion_file="../patch/kconfig-inclusions"
force_inclusion_file="../patch/kconfig-force-inclusions"
ret_process_inc_ex=0
ret_process_inc_ex=$(process_inclusion_exclusion_files > /dev/null; echo $?)

# Secure Boot support
if [ $ret_process_inc_ex -eq 0 ]; then
echo "Secure Boot params: SECURE_UPGRADE_MODE=${SECURE_UPGRADE_MODE}, SECURE_UPGRADE_DEV_SIGNING_CERT=${SECURE_UPGRADE_DEV_SIGNING_CERT}"
if [ ${SECURE_UPGRADE_MODE} == "dev" -o ${SECURE_UPGRADE_MODE} == "prod" ]; then
echo "set kconfig-secure-boot-exclusions & kconfig-secure-boot-inclusions"

if [ ! -f "${SECURE_UPGRADE_DEV_SIGNING_CERT}" ]; then
echo "ERROR: SECURE_UPGRADE_DEV_SIGNING_CERT=${SECURE_UPGRADE_DEV_SIGNING_CERT} file does not exist"
exit 1
fi

exclusion_file="../patch/kconfig-secure-boot-exclusions"
inclusion_file="../patch/kconfig-secure-boot-inclusions"
force_inclusion_file="../patch/kconfig-force-secure-boot-inclusions"

# save the new pub key in kernel
sed -i "s|^CONFIG_SYSTEM_TRUSTED_KEYS=.*|CONFIG_SYSTEM_TRUSTED_KEYS=\"$SECURE_UPGRADE_DEV_SIGNING_CERT\"|g" ${inclusion_file}
davidpil2002 marked this conversation as resolved.
Show resolved Hide resolved

ret_process_inc_ex=$(process_inclusion_exclusion_files > /dev/null; echo $?)
echo "Secure Boot kernel configuration done."
else
echo "no Secure Boot Kernel configuration required."
fi
fi

exit $ret
exit $ret_process_inc_ex
21 changes: 21 additions & 0 deletions patch/kconfig-secure-boot-exclusions
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[common]

[amd64]
CONFIG_MODULE_SIG_SHA256
# For mellanox
Copy link
Contributor

Choose a reason for hiding this comment

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

why these are excluded? can we have more explanation for the justifications?

Copy link
Contributor Author

@davidpil2002 davidpil2002 Jan 31, 2023

Choose a reason for hiding this comment

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

SHA256 is excluded because we are using SHA512. Its more secure.
there is more description in the HLD link attached in the description of this PR.
About the lockdown, we have a plan to support it in the future, for now for Mellanox its disabled.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm planning to move the SHA512 config to apply to all kernel builds in a future PR; this isn't necessarily secure-boot specific, and is nice to have in general.

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'm planning to move the SHA512 config to apply to all kernel builds in a future PR; this isn't necessarily secure-boot specific, and is nice to have in general.

Sound good, can we for now save the PR as is, and when you modify the general config you can remove it.

Because we are implicitly signing the kernel modules with sha512 in the sonic-buildimage:
https://github.com/sonic-net/sonic-buildimage/pull/12692/files#diff-de80d4961ffb88d808888c6d160af8717e70ec6c21675b0f5124b0d27db7a166
So, if the kernel configuration does not match, the image will not boot.

CONFIG_SECURITY_LOCKDOWN_LSM
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE
CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT

[arm64]
CONFIG_MODULE_SIG_SHA256
# For mellanox
CONFIG_SECURITY_LOCKDOWN_LSM
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE
CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT

[armhf]

[marvell-armhf]
19 changes: 19 additions & 0 deletions patch/kconfig-secure-boot-inclusions
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[common]

[amd64]
CONFIG_SYSTEM_TRUSTED_KEYS="debian/certs/debian-uefi-certs.pem"
CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_SIG_SHA512=y
CONFIG_KEXEC_SIG_FORCE=y
CONFIG_MODULE_SIG_FORCE=y

[arm64]
CONFIG_SYSTEM_TRUSTED_KEYS="debian/certs/debian-uefi-certs.pem"
CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_SIG_SHA512=y
CONFIG_KEXEC_SIG_FORCE=y
CONFIG_MODULE_SIG_FORCE=y

[armhf]

[marvell-armhf]