diff --git a/build_library/build_image_util.sh b/build_library/build_image_util.sh index 6f827cc4e6..5c2cfb44d6 100755 --- a/build_library/build_image_util.sh +++ b/build_library/build_image_util.sh @@ -285,6 +285,9 @@ finish_image() { local install_grub=0 local disk_img="${BUILD_DIR}/${image_name}" + local pcr_policy="${image_name%.bin}_pcr_policy.zip" + local pcr_dir="${BUILD_DIR}/pcrs" + mkdir -p "${pcr_dir}" # Copy kernel to support dm-verity boots sudo mkdir -p "${root_fs_dir}/boot/coreos" @@ -361,6 +364,7 @@ finish_image() { "${root_fs_dir}/boot/coreos/vmlinuz-a" fi + ${BUILD_LIBRARY_DIR}/generate_kernel_hash.sh "${root_fs_dir}/boot/coreos/vmlinuz-a" ${COREOS_VERSION} >${pcr_dir}/kernel.config rm -rf "${BUILD_DIR}"/configroot cleanup_mounts "${root_fs_dir}" trap - EXIT @@ -381,5 +385,9 @@ finish_image() { --target="${target}" --disk_image="${disk_img}" --noverity fi done + ${BUILD_LIBRARY_DIR}/generate_grub_hashes.py ${disk_img} /usr/lib/grub/ ${pcr_dir} ${COREOS_VERSION} fi + pushd ${BUILD_DIR} + zip -r -9 $pcr_policy pcrs + popd } diff --git a/build_library/dev_image_util.sh b/build_library/dev_image_util.sh index 38a28edfb4..e15f56dbe1 100755 --- a/build_library/dev_image_util.sh +++ b/build_library/dev_image_util.sh @@ -91,6 +91,7 @@ create_dev_image() { local image_contents="${image_name%.bin}_contents.txt" local image_packages="${image_name%.bin}_packages.txt" local image_licenses="${image_name%.bin}_licenses.txt" + local image_pcr_policy="${image_name%.bin}_pcr_policy.zip" start_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${update_group}" @@ -125,5 +126,6 @@ EOF upload_image -d "${BUILD_DIR}/${image_name}.bz2.DIGESTS" \ "${BUILD_DIR}/${image_contents}" \ "${BUILD_DIR}/${image_packages}" \ - "${BUILD_DIR}/${image_name}" + "${BUILD_DIR}/${image_name}" \ + "${BUILD_DIR}/${image_pcr_policy}" } diff --git a/build_library/generate_grub_hashes.py b/build_library/generate_grub_hashes.py new file mode 100755 index 0000000000..8bc82a3dfe --- /dev/null +++ b/build_library/generate_grub_hashes.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +import hashlib +import json +import os +import string +import subprocess +import sys + +filename = sys.argv[1] +grubdir = sys.argv[2] +outputdir = sys.argv[3] +version = sys.argv[4] +bootoffset = string.atoi(subprocess.check_output(['cgpt', 'show', '-i', '2', '-b', filename])) * 512 +with open(filename, "rb") as f: + boot = f.read(440) + f.seek(bootoffset) + diskboot = f.read(512) + corelen = bytearray(diskboot)[508] | bytearray(diskboot)[509] << 8 + f.seek(bootoffset+512) + core = f.read(corelen * 512) + hashes = {"4": {"binaryvalues": [{"values": [{"value": hashlib.sha1(boot).hexdigest(), "description": "CoreOS Grub boot.img %s" % version}]}]}, + "8": {"binaryvalues" : [{"values": [{"value": hashlib.sha1(diskboot).hexdigest(), "description": "CoreOS Grub diskboot.img %s" % version}]}]}, + "9": {"binaryvalues": [{"values": [{"value": hashlib.sha1(core).hexdigest(), "description": "CoreOS Grub core.img %s" % version}]}]}} + with open(os.path.join(outputdir, "grub_loader.config"), "w") as f: + f.write(json.dumps(hashes, sort_keys=True)) + + +hashvalues = [] +for folder, subs, files in os.walk(grubdir): + for filename in files: + if filename.endswith(".mod"): + with open(os.path.join(folder, filename), "rb") as f: + mod = f.read() + value = hashlib.sha1(mod).hexdigest() + description = "CoreOS Grub %s %s" % (filename, version) + hashvalues.append({"value": value, "description": description}) + +with open(os.path.join(outputdir, "grub_modules.config"), "w") as f: + f.write(json.dumps({"9": {"binaryvalues": [{"prefix": "grub_module", "values": hashvalues}]}})) + +with open(os.path.join(outputdir, "kernel_cmdline.config"), "w") as f: + f.write(json.dumps({"8": {"asciivalues": [{"prefix": "grub_kernel_cmdline", "values": [{"value": "rootflags=rw mount.usrflags=ro BOOT_IMAGE=/coreos/vmlinuz-[ab] mount.usr=PARTUUID=\S{36} rootflags=rw mount.usrflags=ro consoleblank=0 root=LABEL=ROOT (console=\S+)? (coreos.autologin=\S+)? verity.usrhash=\\S{64}", "description": "CoreOS kernel command line %s" % version}]}]}})) + +commands = [{"value": '\[.*\]', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'gptprio.next -d usr -u usr_uuid', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'insmod all_video', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'linux /coreos/vmlinuz-[ab] rootflags=rw mount.usrflags=ro consoleblank=0 root=LABEL=ROOT (console=\S+)? (coreos.autologin=\S+)?', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'menuentry CoreOS \S+ --id=coreos\S* {', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'search --no-floppy --set first_boot --disk-uuid 00000000-0000-0000-0000-000000000001', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'search --no-floppy --set oem --part-label OEM --hint hd0,gpt1', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'set .+', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'setparams CoreOS default', "description": "CoreOS Grub configuration %s" % version}, + {"value": 'source (hd0,gpt6)/grub.cfg', "description": "CoreOS Grub configuration %s" % version}] + +with open(os.path.join(outputdir, "grub_commands.config"), "w") as f: + f.write(json.dumps({"8": {"asciivalues": [{"prefix": "grub_cmd", "values": commands}]}})) diff --git a/build_library/generate_kernel_hash.sh b/build_library/generate_kernel_hash.sh new file mode 100755 index 0000000000..e9a258180b --- /dev/null +++ b/build_library/generate_kernel_hash.sh @@ -0,0 +1,13 @@ +#!/usr/bin/python + +import hashlib +import json +import os +import sys + +path=sys.argv[1] +version=sys.argv[2] + +with open(path, "rb") as f: + kernel = f.read() + print json.dumps({"9": {"binaryvalues": [{"prefix": "grub_linux", "values": [{"value": hashlib.sha1(kernel).hexdigest(), "description": "coreos-%s" % version}]}]}}) diff --git a/build_library/prod_image_util.sh b/build_library/prod_image_util.sh index 6bf1755c8d..17bccd2b84 100755 --- a/build_library/prod_image_util.sh +++ b/build_library/prod_image_util.sh @@ -66,6 +66,7 @@ create_prod_image() { local image_contents="${image_name%.bin}_contents.txt" local image_packages="${image_name%.bin}_packages.txt" local image_licenses="${image_name%.bin}_licenses.txt" + local image_pcr_policy="${image_name%.bin}_pcr_policy.zip" start_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${update_group}" @@ -111,5 +112,6 @@ EOF upload_image -d "${BUILD_DIR}/${image_name}.bz2.DIGESTS" \ "${BUILD_DIR}/${image_contents}" \ "${BUILD_DIR}/${image_packages}" \ - "${BUILD_DIR}/${image_name}" + "${BUILD_DIR}/${image_name}" \ + "${BUILD_DIR}/${image_pcr_policy}" }