|
| 1 | +# Approved images for integration tests |
| 2 | + |
| 3 | +There are two approved images that are used to run operator's |
| 4 | +integration tests: The "primary", held by the `APPROVED_IMAGE` |
| 5 | +environment variable in the [`Makefile`](/Makefile) and the "secondary", |
| 6 | +defined in the `COMBINE_PCRS_UPDATE_TEST_IMAGE_REF` constant in |
| 7 | +[`test_utils/src/constants.rs`](/tests/trusted_execution_cluster.rs). |
| 8 | + |
| 9 | +Integration tests assume those are the images that the VMs joining the |
| 10 | +test cluster are booting. Based on that assumption, a set of PCRs are |
| 11 | +defined as constants in |
| 12 | +[`test_utils/src/constants.rs`](/test_utils/src/constants.rs). |
| 13 | +Constant variable names try to be self-explanatory. |
| 14 | + |
| 15 | +In case any of the images need to be updated, the constant PCR values |
| 16 | +that integration tests rely on might very likely need to be updated too. |
| 17 | + |
| 18 | +## Updating approved images for integration tests |
| 19 | +Approved images used in integration tests are usually Fedora CoreOS |
| 20 | +images that are pinned in the trusted-execution-clusters quay.io. That |
| 21 | +is, basically pulled from a CoreOS mirror and pushed into this |
| 22 | +organization's. This is done so images are not garbage collected in the |
| 23 | +original mirror and the team is not kept busy dealing with test approved |
| 24 | +image updates so frequently. |
| 25 | + |
| 26 | +Between the pull and the push, some image modifications shall be applied |
| 27 | +to prepare the images to behave under the test cases. Mainly, to inject |
| 28 | +the clevis-pin and a custom ignition to them. There is a helpful |
| 29 | +[Containerfile][approved-image-containerfile] available in the investigations repository that does |
| 30 | +exactly that. |
| 31 | + |
| 32 | +[approved-image-containerfile]: https://github.com/trusted-execution-clusters/investigations/blob/3321d58394131b8c56430cf11a29dc0076c00f37/coreos/Containerfile |
| 33 | + |
| 34 | +## Updating reference PCR values for integration tests |
| 35 | + |
| 36 | +### When to update reference PCR value constants |
| 37 | +In the event of an approved image pointer update, integration tests will |
| 38 | +very likely break. Updating the reference PCR values should be enough to |
| 39 | +fix them back. |
| 40 | + |
| 41 | +In case the primary approved image was updated, `PRIMARY_*_HASH` consts |
| 42 | +will need an update, as well as the `MIX_*_KERNEL_PCR4_HASH` consts. |
| 43 | + |
| 44 | +For secondary approved image updates, `SECONDARY_*_HASH` and |
| 45 | +`MIX_*_KERNEL_PCR4_HASH` constants will need to be updated. |
| 46 | + |
| 47 | +In case both primary and secondary images are updated, all hashes will |
| 48 | +need to be updated. |
| 49 | + |
| 50 | +### How to compute reference PCR value constants |
| 51 | +The easiest way to compute the new PCR values is certainly to use the |
| 52 | +compute-pcrs library against the new image. However, that might not be |
| 53 | +the most desirable way to do it, as it would implicitly bypass some of |
| 54 | +the purpose of the integration tests. |
| 55 | + |
| 56 | +The better way to do it is to boot the new image in a disposable VM and |
| 57 | +check tpm event log. |
| 58 | + |
| 59 | +In this document section we are going to focus just in PCR4. |
| 60 | + |
| 61 | +First, a qcow2 image is needed. The bootable container image can be |
| 62 | +"turned" into a qcow2 image. Another way, when it comes to CoreOS is to |
| 63 | +find the image in the [CoreOS builds browser][coreos-build-browser] and |
| 64 | +obtain its already built qcow2 relative. |
| 65 | + |
| 66 | +To boot the VM, the investigations [`install_vm.sh`][installvm] script |
| 67 | +might come in handy. |
| 68 | + |
| 69 | +#### Boot stack event hashes |
| 70 | +Once booted, log into the VM and run: |
| 71 | +```bash |
| 72 | +$ sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements | \ |
| 73 | + yq '.events[] | |
| 74 | + select(.PCRIndex == 4 and |
| 75 | + .EventType == "EV_EFI_BOOT_SERVICES_APPLICATION") | |
| 76 | + .Digests[] | |
| 77 | + select(.AlgorithmId == "sha256") | |
| 78 | + .Digest' |
| 79 | +``` |
| 80 | +This should print 3 sha256 hash values. The ones relative to (in order |
| 81 | +of appearance) shim, grub and the vmlinuz hashes. |
| 82 | + |
| 83 | +If 3 values are not printed, it might be that secure boot was not |
| 84 | +enabled in the VM, and the hash values should be just shim and grub's. |
| 85 | +Make sure secure boot is enabled and try again. |
| 86 | + |
| 87 | +Take those values and update the values of |
| 88 | +`{PRIMARY|SECONDARY}_{SHIM,GRUB,KERNEL}_HASH` constants accordingly. |
| 89 | + |
| 90 | +#### PCR4 hashes |
| 91 | +Then again, run the following command in the VM: |
| 92 | +```bash |
| 93 | +$ sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements | \ |
| 94 | + yq '.pcrs.sha256.4' | \ |
| 95 | + sed 's/^0x//' |
| 96 | +``` |
| 97 | +This will print the resulting PCR4 hash of the new approved image. |
| 98 | +Update the `PRIMARY_PCR4_HASH` or `SECONDARY_PCR4_HASH` value. |
| 99 | + |
| 100 | +#### Combined PCR4 hashes |
| 101 | +The tricky part comes with the combination (or mix) PCR4 hashes. These |
| 102 | +model possible intermediate stages that the VM goes through during an |
| 103 | +update. That includes the VM booting a new kernel through the old |
| 104 | +bootloader, or booting the old kernel with a new bootloader in case of a |
| 105 | +rollback being needed. |
| 106 | + |
| 107 | +Set the shim and grub hashes of the primary image and the kernel hash of |
| 108 | +the secondary image and run the following bash script: |
| 109 | +```bash |
| 110 | +hashes=( |
| 111 | + "3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba" |
| 112 | + "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119" |
| 113 | + "${SHIM_HASH}" |
| 114 | + "${GRUB_HASH}" |
| 115 | + "${KERNEL_HASH}" |
| 116 | +) |
| 117 | +current_pcr="0000000000000000000000000000000000000000000000000000000000000000" |
| 118 | +for event_hash in "${hashes[@]}"; do |
| 119 | + current_pcr=$(echo -n "${current_pcr}${event_hash}" | xxd -r -p | sha256sum | awk '{print $1}') |
| 120 | +done |
| 121 | +echo $current_pcr |
| 122 | +``` |
| 123 | + |
| 124 | +The output is `MIX_PRIMARY_BOOT_SECONDARY_KERNEL_PCR4_HASH`. Then repeat |
| 125 | +again with shim and grub hashes from the secondary image and the kernel |
| 126 | +hash of the primary image to obtain |
| 127 | +`MIX_SECONDARY_BOOT_PRIMARY_KERNEL_PCR4_HASH`. |
| 128 | + |
| 129 | +[coreos-build-browser]: https://builds.coreos.fedoraproject.org/browser?stream=stable&arch=x86_64 |
| 130 | +[installvm]: https://github.com/trusted-execution-clusters/investigations/blob/f3bcaa95fff7c39092fae5cc63f9b31a2aacb221/scripts/install_vm.sh |
0 commit comments