summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@chromium.org>2014-06-12 23:45:27 -0400
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-06-16 10:02:43 +0000
commitaa888463b860c2852f3fcb17baf8de395fcca294 (patch)
tree329c599101e97cffb3c59f2d30ec8064be252b68
parentd81a3269b862e30c2726ab5a70436060436c93da (diff)
downloadvboot-aa888463b860c2852f3fcb17baf8de395fcca294.tar.gz
image_signing: support loem keysets with firmware shellballs
With an loem keyset in a recovery shellball, we don't want to write the rootkeys & vblocks to the firmware image directly. Instead, we'll put them into a keyset subdir that the firmware updater will process later. bios.bin keyset/ rootkey.LOEMID vblock_A.LOEMID vblock_B.LOEMID We still write the recovery key to the firmware image though as that is shared between all the keysets. BUG=chromium:381862 TEST=Ran against a recovery image with devkeys & loemkeys and checked shellball TEST=`cbuildbot daisy-release` works BRANCH=none Change-Id: I6fc99c71e6c7dee25f7f9a466a97314ff750fda9 Reviewed-on: https://chromium-review.googlesource.com/203682 Reviewed-by: Gaurav Shah <gauravsh@chromium.org> Commit-Queue: Mike Frysinger <vapier@chromium.org> Tested-by: Mike Frysinger <vapier@chromium.org>
-rwxr-xr-xscripts/image_signing/resign_firmwarefd.sh31
-rwxr-xr-xscripts/image_signing/sign_firmware.sh99
-rwxr-xr-xscripts/image_signing/sign_official_build.sh24
-rw-r--r--tests/loemkeys/README1
l---------tests/loemkeys/firmware.loem1.keyblock1
l---------tests/loemkeys/firmware.loem2.keyblock1
l---------tests/loemkeys/firmware.loem3.keyblock1
l---------tests/loemkeys/firmware.loem4.keyblock1
l---------tests/loemkeys/firmware_data_key.loem1.vbprivk1
l---------tests/loemkeys/firmware_data_key.loem1.vbpubk1
l---------tests/loemkeys/firmware_data_key.loem2.vbprivk1
l---------tests/loemkeys/firmware_data_key.loem2.vbpubk1
l---------tests/loemkeys/firmware_data_key.loem3.vbprivk1
l---------tests/loemkeys/firmware_data_key.loem3.vbpubk1
l---------tests/loemkeys/firmware_data_key.loem4.vbprivk1
l---------tests/loemkeys/firmware_data_key.loem4.vbpubk1
l---------tests/loemkeys/installer_kernel.keyblock1
l---------tests/loemkeys/installer_kernel_data_key.vbprivk1
l---------tests/loemkeys/installer_kernel_data_key.vbpubk1
l---------tests/loemkeys/kernel.keyblock1
l---------tests/loemkeys/kernel_data_key.vbprivk1
l---------tests/loemkeys/kernel_data_key.vbpubk1
l---------tests/loemkeys/kernel_subkey.vbprivk1
l---------tests/loemkeys/kernel_subkey.vbpubk1
l---------tests/loemkeys/key.versions1
-rw-r--r--tests/loemkeys/loem.ini3
l---------tests/loemkeys/recovery_kernel.keyblock1
l---------tests/loemkeys/recovery_kernel_data_key.vbprivk1
l---------tests/loemkeys/recovery_kernel_data_key.vbpubk1
l---------tests/loemkeys/recovery_key.vbprivk1
l---------tests/loemkeys/recovery_key.vbpubk1
l---------tests/loemkeys/root_key.loem1.vbprivk1
l---------tests/loemkeys/root_key.loem1.vbpubk1
l---------tests/loemkeys/root_key.loem2.vbprivk1
l---------tests/loemkeys/root_key.loem2.vbpubk1
l---------tests/loemkeys/root_key.loem3.vbprivk1
l---------tests/loemkeys/root_key.loem3.vbpubk1
l---------tests/loemkeys/root_key.loem4.vbprivk1
l---------tests/loemkeys/root_key.loem4.vbpubk1
39 files changed, 155 insertions, 37 deletions
diff --git a/scripts/image_signing/resign_firmwarefd.sh b/scripts/image_signing/resign_firmwarefd.sh
index 578d2826..1f9bd219 100755
--- a/scripts/image_signing/resign_firmwarefd.sh
+++ b/scripts/image_signing/resign_firmwarefd.sh
@@ -48,9 +48,10 @@
set -e
# Check arguments
-if [ $# -lt 7 ] || [ $# -gt 9 ]; then
- echo "Usage: $PROG src_fd dst_fd firmware_datakey firmware_keyblock"\
- "dev_firmware_datakey dev_firmware_keyblock kernel_subkey [version [flag]]"
+if [ $# -lt 7 ] || [ $# -gt 11 ]; then
+ echo "Usage: $PROG src_fd dst_fd firmware_datakey firmware_keyblock" \
+ "dev_firmware_datakey dev_firmware_keyblock kernel_subkey [version]" \
+ "[flag] [loem_output_dir] [loemid]" \
exit 1
fi
@@ -72,6 +73,8 @@ VERSION=$8
# 0 for RW-NORMAL firmware, and 1 for RO-NORMAL firmware (search "two_stop
# firmware" for more information).
PREAMBLE_FLAG=$9
+LOEM_OUTPUT_DIR=${10}
+LOEMID=${11}
# Disables using developer keyblocks
disable_dev_keyblock() {
@@ -201,10 +204,14 @@ vbutil_firmware \
--fv "${temp_fwimage_a}" \
--kernelkey "${KERNEL_SUBKEY}"
-# Create a copy of the input image and put in the new vblock for firmware A
-cp "${SRC_FD}" "${DST_FD}"
-dd if="${temp_out_vb}" of="${DST_FD}" seek="${fwA_vblock_offset}" bs=1 \
- count="${fwA_vblock_size}" conv=notrunc 2>/dev/null
+if [ -z "${LOEMID}" ]; then
+ # Create a copy of the input image and put in the new vblock for firmware A
+ cp "${SRC_FD}" "${DST_FD}"
+ dd if="${temp_out_vb}" of="${DST_FD}" seek="${fwA_vblock_offset}" bs=1 \
+ count="${fwA_vblock_size}" conv=notrunc 2>/dev/null
+else
+ cp "${temp_out_vb}" "${LOEM_OUTPUT_DIR}/vblock_A.${LOEMID}"
+fi
echo "Re-calculating Firmware B vblock"
vbutil_firmware \
@@ -216,8 +223,12 @@ vbutil_firmware \
--fv "${temp_fwimage_b}" \
--kernelkey "${KERNEL_SUBKEY}"
-# Destination image has already been created.
-dd if="${temp_out_vb}" of="${DST_FD}" seek="${fwB_vblock_offset}" bs=1 \
- count="${fwB_vblock_size}" conv=notrunc 2>/dev/null
+if [[ -z ${LOEMID} ]]; then
+ # Destination image has already been created.
+ dd if="${temp_out_vb}" of="${DST_FD}" seek="${fwB_vblock_offset}" bs=1 \
+ count="${fwB_vblock_size}" conv=notrunc 2>/dev/null
+else
+ cp "${temp_out_vb}" "${LOEM_OUTPUT_DIR}/vblock_A.${LOEMID}"
+fi
echo "New signed image was output to ${DST_FD}"
diff --git a/scripts/image_signing/sign_firmware.sh b/scripts/image_signing/sign_firmware.sh
index 9a0c7830..fa200837 100755
--- a/scripts/image_signing/sign_firmware.sh
+++ b/scripts/image_signing/sign_firmware.sh
@@ -8,12 +8,16 @@
# Determine script directory.
SCRIPT_DIR=$(dirname "$0")
+# Load common constants and variables.
+. "${SCRIPT_DIR}/common_minimal.sh"
+
# Abort on error.
set -e
usage() {
cat<<EOF
-Usage: $0 <input_firmware> <key_dir> <output_firmware> [firmware_version]
+Usage: $0 <input_firmware> <key_dir> <output_firmware> [firmware_version] \
+[loem_output_dir]
Signs <input_firmware> with keys in <key_dir>, setting firmware version
to <firmware_version>. Outputs signed firmware to <output_firmware>.
@@ -22,37 +26,88 @@ EOF
exit 1
}
-main() {
- if [[ $# -lt 3 || $# -gt 4 ]]; then
- usage
- fi
-
- local in_firmware=$1
- local key_dir=$2
- local out_firmware=$3
- local firmware_version=${4:-1}
-
- local temp_fw=$(mktemp)
- trap "rm -f '${temp_fw}'" EXIT
+# Sign a single firmware image.
+# ARGS: [loem_key] [loemid]
+sign_one() {
+ local loem_key="$1"
+ local loemid="$2"
# Resign the firmware with new keys.
"${SCRIPT_DIR}/resign_firmwarefd.sh" \
"${in_firmware}" \
"${temp_fw}" \
- "${key_dir}/firmware_data_key.vbprivk" \
- "${key_dir}/firmware.keyblock" \
- "${key_dir}/dev_firmware_data_key.vbprivk" \
- "${key_dir}/dev_firmware.keyblock" \
+ "${key_dir}/firmware_data_key${loem_key}.vbprivk" \
+ "${key_dir}/firmware${loem_key}.keyblock" \
+ "${key_dir}/dev_firmware_data_key${loem_key}.vbprivk" \
+ "${key_dir}/dev_firmware${loem_key}.keyblock" \
"${key_dir}/kernel_subkey.vbpubk" \
- "${firmware_version}"
+ "${firmware_version}" \
+ "" \
+ "${loem_output_dir}" \
+ "${loemid}"
# Replace the root and recovery key in the Google Binary Block of the
# firmware. Note: This needs to happen after calling resign_firmwarefd.sh
# since it needs to be able to verify the firmware using the root key to
# determine the preamble flags.
- gbb_utility -s \
- --rootkey="${key_dir}/root_key.vbpubk" \
- --recoverykey="${key_dir}/recovery_key.vbpubk" \
- "${temp_fw}" "${out_firmware}"
+ local rootkey="${key_dir}/root_key${loem_key}.vbpubk"
+ local gbb_args=( -s --recoverykey="${key_dir}/recovery_key.vbpubk" )
+ if [[ -z ${loemid} ]]; then
+ gbb_args+=( --rootkey="${rootkey}" "${temp_fw}" )
+ else
+ gbb_args+=( "${in_firmware}" )
+ cp "${rootkey}" "${loem_output_dir}/rootkey.${loemid}"
+ fi
+ gbb_utility "${gbb_args[@]}" "${out_firmware}"
+}
+
+# Process all the keysets in the loem.ini file.
+sign_loems() {
+ local line loem_section=false loem_index loemid
+
+ while read line; do
+ # Find the [loem] section.
+ if ! ${loem_section}; then
+ if grep -q "^ *\[loem\] *$" <<<"${line}"; then
+ loem_section=true
+ fi
+ continue
+ # Abort when we hit the next section.
+ elif [[ ${line} == *"["* ]]; then
+ break
+ fi
+
+ # Strip comments/whitespace.
+ line=$(sed -e 's:#.*::' -e 's:^ *::' -e 's: *$::' <<<"${line}")
+ loem_index=$(cut -d= -f1 <<<"${line}" | sed 's: *$::')
+ loemid=$(cut -d= -f2 <<<"${line}" | sed 's:^ *::')
+
+ echo "### Processing LOEM ${loem_index} ${loemid}"
+ sign_one ".loem${loem_index}" "${loemid}"
+ echo
+ done <"${key_dir}/loem.ini"
+}
+
+main() {
+ if [[ $# -lt 3 || $# -gt 5 ]]; then
+ usage
+ fi
+
+ local in_firmware=$1
+ local key_dir=$2
+ local out_firmware=$3
+ local firmware_version=${4:-1}
+ local loem_output_dir=${5:-}
+
+ local temp_fw=$(make_temp_file)
+
+ if [[ -e ${key_dir}/loem.ini ]]; then
+ if [[ -z ${loem_output_dir} ]]; then
+ err_die "need loem_output_dir w/loem keysets"
+ fi
+ sign_loems
+ else
+ sign_one
+ fi
}
main "$@"
diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh
index d7bc4d02..78305ae9 100755
--- a/scripts/image_signing/sign_official_build.sh
+++ b/scripts/image_signing/sign_official_build.sh
@@ -365,17 +365,18 @@ repack_firmware_bundle() {
}
# Sign a firmware in-place with the given keys.
-# Args: FIRMWARE_IMAGE KEY_DIR FIRMWARE_VERSION
+# Args: FIRMWARE_IMAGE KEY_DIR FIRMWARE_VERSION [LOEM_OUTPUT_DIR]
sign_firmware() {
local image=$1
local key_dir=$2
local firmware_version=$3
+ local loem_output_dir=${4:-}
local temp_firmware=$(make_temp_file)
# Resign the firmware with new keys, also replacing the root and recovery
# public keys in the GBB.
- ${SCRIPT_DIR}/sign_firmware.sh ${image} ${key_dir} ${temp_firmware} \
- ${firmware_version}
+ "${SCRIPT_DIR}/sign_firmware.sh" "${image}" "${key_dir}" "${temp_firmware}" \
+ "${firmware_version}" "${loem_output_dir}"
# Note: Although sign_firmware.sh may correctly handle specifying the same
# output file as the input file, we do not want to rely on it correctly
# handing that. Hence, the use of a temporary file.
@@ -434,9 +435,18 @@ resign_firmware_payload() {
return; }
echo "Found a valid firmware update shellball."
- local image_file
+ local image_file sign_args=() loem_sfx loem_output_dir
for image_file in "${shellball_dir}"/bios*.bin; do
- sign_firmware "${image_file}" ${KEY_DIR} ${FIRMWARE_VERSION}
+ if [[ -e "${KEY_DIR}/loem.ini" ]]; then
+ # Extract the extended details from "bios.bin" and use that in the
+ # subdir for the keyset.
+ loem_sfx=$(sed -r 's:.*/bios([^/]*)[.]bin$:\1:' <<<"${image_file}")
+ loem_output_dir="${shellball_dir}/keyset${loem_sfx}"
+ sign_args=( "${loem_output_dir}" )
+ mkdir -p "${loem_output_dir}"
+ fi
+ sign_firmware "${image_file}" "${KEY_DIR}" "${FIRMWARE_VERSION}" \
+ "${sign_args[@]}"
done
local signer_notes="${shellball_dir}/VERSION.signer"
@@ -732,6 +742,10 @@ elif [ "${TYPE}" == "factory" ] || [ "${TYPE}" == "install" ]; then
2
sign_for_factory_install ${OUTPUT_IMAGE}
elif [ "${TYPE}" == "firmware" ]; then
+ if [[ -e "${KEY_DIR}/loem.ini" ]]; then
+ echo "LOEM signing not implemented yet for firmware images"
+ exit 1
+ fi
cp ${INPUT_IMAGE} ${OUTPUT_IMAGE}
sign_firmware ${OUTPUT_IMAGE} ${KEY_DIR} ${FIRMWARE_VERSION}
elif [ "${TYPE}" == "update_payload" ]; then
diff --git a/tests/loemkeys/README b/tests/loemkeys/README
new file mode 100644
index 00000000..58b3bc8a
--- /dev/null
+++ b/tests/loemkeys/README
@@ -0,0 +1 @@
+These are devkeys, but with filename tweaks for testing loem keysets.
diff --git a/tests/loemkeys/firmware.loem1.keyblock b/tests/loemkeys/firmware.loem1.keyblock
new file mode 120000
index 00000000..0d6087df
--- /dev/null
+++ b/tests/loemkeys/firmware.loem1.keyblock
@@ -0,0 +1 @@
+../devkeys/firmware.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/firmware.loem2.keyblock b/tests/loemkeys/firmware.loem2.keyblock
new file mode 120000
index 00000000..0d6087df
--- /dev/null
+++ b/tests/loemkeys/firmware.loem2.keyblock
@@ -0,0 +1 @@
+../devkeys/firmware.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/firmware.loem3.keyblock b/tests/loemkeys/firmware.loem3.keyblock
new file mode 120000
index 00000000..0d6087df
--- /dev/null
+++ b/tests/loemkeys/firmware.loem3.keyblock
@@ -0,0 +1 @@
+../devkeys/firmware.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/firmware.loem4.keyblock b/tests/loemkeys/firmware.loem4.keyblock
new file mode 120000
index 00000000..0d6087df
--- /dev/null
+++ b/tests/loemkeys/firmware.loem4.keyblock
@@ -0,0 +1 @@
+../devkeys/firmware.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem1.vbprivk b/tests/loemkeys/firmware_data_key.loem1.vbprivk
new file mode 120000
index 00000000..d361c316
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem1.vbprivk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem1.vbpubk b/tests/loemkeys/firmware_data_key.loem1.vbpubk
new file mode 120000
index 00000000..013e040f
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem1.vbpubk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem2.vbprivk b/tests/loemkeys/firmware_data_key.loem2.vbprivk
new file mode 120000
index 00000000..d361c316
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem2.vbprivk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem2.vbpubk b/tests/loemkeys/firmware_data_key.loem2.vbpubk
new file mode 120000
index 00000000..013e040f
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem2.vbpubk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem3.vbprivk b/tests/loemkeys/firmware_data_key.loem3.vbprivk
new file mode 120000
index 00000000..d361c316
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem3.vbprivk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem3.vbpubk b/tests/loemkeys/firmware_data_key.loem3.vbpubk
new file mode 120000
index 00000000..013e040f
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem3.vbpubk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem4.vbprivk b/tests/loemkeys/firmware_data_key.loem4.vbprivk
new file mode 120000
index 00000000..d361c316
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem4.vbprivk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/firmware_data_key.loem4.vbpubk b/tests/loemkeys/firmware_data_key.loem4.vbpubk
new file mode 120000
index 00000000..013e040f
--- /dev/null
+++ b/tests/loemkeys/firmware_data_key.loem4.vbpubk
@@ -0,0 +1 @@
+../devkeys/firmware_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/installer_kernel.keyblock b/tests/loemkeys/installer_kernel.keyblock
new file mode 120000
index 00000000..32e5e92d
--- /dev/null
+++ b/tests/loemkeys/installer_kernel.keyblock
@@ -0,0 +1 @@
+../devkeys/installer_kernel.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/installer_kernel_data_key.vbprivk b/tests/loemkeys/installer_kernel_data_key.vbprivk
new file mode 120000
index 00000000..3581b5e5
--- /dev/null
+++ b/tests/loemkeys/installer_kernel_data_key.vbprivk
@@ -0,0 +1 @@
+../devkeys/installer_kernel_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/installer_kernel_data_key.vbpubk b/tests/loemkeys/installer_kernel_data_key.vbpubk
new file mode 120000
index 00000000..2b684128
--- /dev/null
+++ b/tests/loemkeys/installer_kernel_data_key.vbpubk
@@ -0,0 +1 @@
+../devkeys/installer_kernel_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/kernel.keyblock b/tests/loemkeys/kernel.keyblock
new file mode 120000
index 00000000..27352c7b
--- /dev/null
+++ b/tests/loemkeys/kernel.keyblock
@@ -0,0 +1 @@
+../devkeys/kernel.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/kernel_data_key.vbprivk b/tests/loemkeys/kernel_data_key.vbprivk
new file mode 120000
index 00000000..39a35a7e
--- /dev/null
+++ b/tests/loemkeys/kernel_data_key.vbprivk
@@ -0,0 +1 @@
+../devkeys/kernel_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/kernel_data_key.vbpubk b/tests/loemkeys/kernel_data_key.vbpubk
new file mode 120000
index 00000000..19865269
--- /dev/null
+++ b/tests/loemkeys/kernel_data_key.vbpubk
@@ -0,0 +1 @@
+../devkeys/kernel_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/kernel_subkey.vbprivk b/tests/loemkeys/kernel_subkey.vbprivk
new file mode 120000
index 00000000..5fa82c81
--- /dev/null
+++ b/tests/loemkeys/kernel_subkey.vbprivk
@@ -0,0 +1 @@
+../devkeys/kernel_subkey.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/kernel_subkey.vbpubk b/tests/loemkeys/kernel_subkey.vbpubk
new file mode 120000
index 00000000..b0cf2f14
--- /dev/null
+++ b/tests/loemkeys/kernel_subkey.vbpubk
@@ -0,0 +1 @@
+../devkeys/kernel_subkey.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/key.versions b/tests/loemkeys/key.versions
new file mode 120000
index 00000000..db9cdbd1
--- /dev/null
+++ b/tests/loemkeys/key.versions
@@ -0,0 +1 @@
+../devkeys/key.versions \ No newline at end of file
diff --git a/tests/loemkeys/loem.ini b/tests/loemkeys/loem.ini
new file mode 100644
index 00000000..8501f0c1
--- /dev/null
+++ b/tests/loemkeys/loem.ini
@@ -0,0 +1,3 @@
+[loem]
+1 = ACME
+2 = SHINRA
diff --git a/tests/loemkeys/recovery_kernel.keyblock b/tests/loemkeys/recovery_kernel.keyblock
new file mode 120000
index 00000000..ad3fd6e6
--- /dev/null
+++ b/tests/loemkeys/recovery_kernel.keyblock
@@ -0,0 +1 @@
+../devkeys/recovery_kernel.keyblock \ No newline at end of file
diff --git a/tests/loemkeys/recovery_kernel_data_key.vbprivk b/tests/loemkeys/recovery_kernel_data_key.vbprivk
new file mode 120000
index 00000000..b47a51bf
--- /dev/null
+++ b/tests/loemkeys/recovery_kernel_data_key.vbprivk
@@ -0,0 +1 @@
+../devkeys/recovery_kernel_data_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/recovery_kernel_data_key.vbpubk b/tests/loemkeys/recovery_kernel_data_key.vbpubk
new file mode 120000
index 00000000..395583b6
--- /dev/null
+++ b/tests/loemkeys/recovery_kernel_data_key.vbpubk
@@ -0,0 +1 @@
+../devkeys/recovery_kernel_data_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/recovery_key.vbprivk b/tests/loemkeys/recovery_key.vbprivk
new file mode 120000
index 00000000..9a7733b9
--- /dev/null
+++ b/tests/loemkeys/recovery_key.vbprivk
@@ -0,0 +1 @@
+../devkeys/recovery_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/recovery_key.vbpubk b/tests/loemkeys/recovery_key.vbpubk
new file mode 120000
index 00000000..1ea4a982
--- /dev/null
+++ b/tests/loemkeys/recovery_key.vbpubk
@@ -0,0 +1 @@
+../devkeys/recovery_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem1.vbprivk b/tests/loemkeys/root_key.loem1.vbprivk
new file mode 120000
index 00000000..d032898a
--- /dev/null
+++ b/tests/loemkeys/root_key.loem1.vbprivk
@@ -0,0 +1 @@
+../devkeys/root_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem1.vbpubk b/tests/loemkeys/root_key.loem1.vbpubk
new file mode 120000
index 00000000..7a61f84c
--- /dev/null
+++ b/tests/loemkeys/root_key.loem1.vbpubk
@@ -0,0 +1 @@
+../devkeys/root_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem2.vbprivk b/tests/loemkeys/root_key.loem2.vbprivk
new file mode 120000
index 00000000..d032898a
--- /dev/null
+++ b/tests/loemkeys/root_key.loem2.vbprivk
@@ -0,0 +1 @@
+../devkeys/root_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem2.vbpubk b/tests/loemkeys/root_key.loem2.vbpubk
new file mode 120000
index 00000000..7a61f84c
--- /dev/null
+++ b/tests/loemkeys/root_key.loem2.vbpubk
@@ -0,0 +1 @@
+../devkeys/root_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem3.vbprivk b/tests/loemkeys/root_key.loem3.vbprivk
new file mode 120000
index 00000000..d032898a
--- /dev/null
+++ b/tests/loemkeys/root_key.loem3.vbprivk
@@ -0,0 +1 @@
+../devkeys/root_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem3.vbpubk b/tests/loemkeys/root_key.loem3.vbpubk
new file mode 120000
index 00000000..7a61f84c
--- /dev/null
+++ b/tests/loemkeys/root_key.loem3.vbpubk
@@ -0,0 +1 @@
+../devkeys/root_key.vbpubk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem4.vbprivk b/tests/loemkeys/root_key.loem4.vbprivk
new file mode 120000
index 00000000..d032898a
--- /dev/null
+++ b/tests/loemkeys/root_key.loem4.vbprivk
@@ -0,0 +1 @@
+../devkeys/root_key.vbprivk \ No newline at end of file
diff --git a/tests/loemkeys/root_key.loem4.vbpubk b/tests/loemkeys/root_key.loem4.vbpubk
new file mode 120000
index 00000000..7a61f84c
--- /dev/null
+++ b/tests/loemkeys/root_key.loem4.vbpubk
@@ -0,0 +1 @@
+../devkeys/root_key.vbpubk \ No newline at end of file