Skip to content

Secure Boot for Virtual Machines

Marcelo Veiga Neves edited this page Jul 11, 2017 · 15 revisions

This page describes how to build a hypervisor that verifies signed virtual machines. For now, we have been tested it only on the Microchip PIC32MZ Starter Kit board, but it should work with other platforms as well.

Obtaining the prplHypervisor source code

git clone https://github.com/prplfoundation/prpl-hypervisor

The prpl-hypervisor directory should be created. Then, checkout the secure-boot-vm branch.

cd prpl-hypervisor
git checkout secure-boot-vm

Generating the pair of keys

Then, generate the pair of keys. In this version, we only support the ecdsa-p256 algorithm. For example:

cd prpl-hypervisor/scripts
./vmsectool.py keygen -t ecdsa-p256 
private_key: 7a2c97b9c73ad81d5e3d5b6bc6c953630398118c9ca742ad257c2a2f36fef13a
public_key: 6306b69303c3c5961b5395b6ad5f7d9ccc46b0083d9ddf30a9c74ec1e0c7a04c1c5a7084b1f2e37310c119e60f92725f8ec04126ec2ae89d40cd3e4c583ec5ab
File ./private_key.txt was sucessfully generated.
File ./public_key.txt was sucessfully generated.

Building a hypervsior with with signed VM images

cd prpl-hypervisor/platform/pic32mz_starter_kit
make
...
../../scripts/genhex.sh ping pong blink 
0+1 records in
1+0 records out
32768 bytes (33 kB) copied, 0,000121381 s, 270 MB/s
padding
32640

0+1 records in
1+0 records out
32640 bytes (33 kB) copied, 0,000103923 s, 314 MB/s
public_key: 50e67b9b0f4d77bf09b4dce976a7956b87a126dba21d059bbdb1e6ababdac36dfa0946f52609fe8cead853ae72aa7cf7e20142946bb8ddebc56dfa44b60d4ea3
file size: 32640
hash: ea4a04019b0bafd55054ae9ba54becb511993ebcb16c9e6d3a889c78ad3c1ed9
signature: 9a33e2fcba77f05cb5082e75fac1e3240c5bfdf7fbbb840c948841af695744743dce220e620eec7a61a0c4fb36f02f54c2f50f791048a79f62a5324950f0a135
Signature verification OK.

padding
32640

0+1 records in
1+0 records out
32640 bytes (33 kB) copied, 0,000119285 s, 274 MB/s
public_key: 50e67b9b0f4d77bf09b4dce976a7956b87a126dba21d059bbdb1e6ababdac36dfa0946f52609fe8cead853ae72aa7cf7e20142946bb8ddebc56dfa44b60d4ea3
file size: 32640
hash: 76a1cdd7e0fd1de681c39b33c858cd92ec607631404cbbb9a3bb1bc705695d50
signature: 1311c0e5022db2f7b2786afe956465e0cb1878899580bd5e5b2d0f7582db974ad3bafe284923f41400202e6936d5732fca7fbad345321e57d1b31bdb39541963
Signature verification OK.

padding
32640
32768
0+1 records in
1+0 records out
32640 bytes (33 kB) copied, 0,00010698 s, 305 MB/s
public_key: 50e67b9b0f4d77bf09b4dce976a7956b87a126dba21d059bbdb1e6ababdac36dfa0946f52609fe8cead853ae72aa7cf7e20142946bb8ddebc56dfa44b60d4ea3
file size: 32640
hash: aaf14cdce5deb1909d2bff233e1d162615d45ec5a227b98b09da84e684bf528e
signature: 6a38c38f1c38be91b5c1824d24ee16f6b0e73dea2ae9b491021ce63fb3b11bb3b64397affda939ca21027327c29eb1bbb56826c352ef458667a3bcb8f23e1626
Signature verification OK.

The resulting firmware image will be at firmware.hex. It will include all VM images. Write it to flash and reboot.

The hypervisor will will compute a hash and verify the corresponding signature for each VM:

===========================================================
prplHypervsior v0.11.102 (gcaf7511) [Jul 11 2017, 10:13:58]
Copyright (c) 2016, prpl Foundation
===========================================================
CPU Core:      M5150
Board:         Microchip Starter Kit
System Clock:  200MHz
Heap Size:     29Kbytes
Scheduler:     10ms
Guest Tick:    1ms
VMs:           3

Verifying virtual machines.
Number of VMs: 3
===========================================================
VM ID: 0
VM name: ping
VM start address: 0x9d008000
VM length:        0x7f80 (32640)
VM hash:          ea4a04019b0bafd55054ae9ba54becb511993ebcb16c9e6d3a889c78ad3c1ed9
VM signature:     9a33e2fcba77f05cb5082e75fac1e3240c5bfdf7fbbb840c948841af695744743dce220e620eec7a61a0c4fb36f02f54c2f50f791048a79f62a5324950f0a135
Verifying signature authenticity for VM 0 ... OK.

===========================================================
VM ID: 1
VM name: pong
VM start address: 0x9d010000
VM length:        0x7f80 (32640)
VM hash:          76a1cdd7e0fd1de681c39b33c858cd92ec607631404cbbb9a3bb1bc705695d50
VM signature:     1311c0e5022db2f7b2786afe956465e0cb1878899580bd5e5b2d0f7582db974ad3bafe284923f41400202e6936d5732fca7fbad345321e57d1b31bdb39541963
Verifying signature authenticity for VM 1 ... OK.

===========================================================
VM ID: 2
VM name: blink
VM start address: 0x9d018000
VM length:        0x7f80 (32640)
VM hash:          aaf14cdce5deb1909d2bff233e1d162615d45ec5a227b98b09da84e684bf528e
VM signature:     6a38c38f1c38be91b5c1824d24ee16f6b0e73dea2ae9b491021ce63fb3b11bb3b64397affda939ca21027327c29eb1bbb56826c352ef458667a3bcb8f23e1626
Verifying signature authenticity for VM 2 ... OK.


Initializing Virtual Machines.
Configuring ping VM starting at 0x80008000 RAM address.
Configuring pong VM starting at 0x80010000 RAM address.
Configuring blink VM starting at 0x80018000 RAM address.
PIC32mz in Vectored Interrupt Mode.
Inter-VM communication hypercalls registered.
Interrupt redirect driver registered.
Initializing USB device in Host mode.
USB interrupt vector at 0x220
Software reset interrupt (SW1) registered at offset 0x240.
Device mapping hypercalls registered.
Ethernet PHY at 0
Ethernet interface en0: interrupt 153, MAC address d8:80:39:75:a6:1a
Ethernet device is a SMSC LAN8740A
CP0 Timer interrupt registered at 0x260.
Starting hypervisor execution.

Blink red LED! Total of 0 timer ticks.
Blink red LED! Total of 335 timer ticks.
Blink red LED! Total of 670 timer ticks.
...

The hypervisor will only start VMs if all of them have been successfully verified. Otherwise, the hypervisor will abort execution and a red LED (LED1) will be turned on, as showed in image bellow.

Boot verification failed

Example of output for a validation error:

===========================================================
prplHypervsior v0.11.102 (gcaf7511) [Jul 11 2017, 10:13:58]
Copyright (c) 2016, prpl Foundation
===========================================================
CPU Core:      M5150
Board:         Microchip Starter Kit
System Clock:  200MHz
Heap Size:     29Kbytes
Scheduler:     10ms
Guest Tick:    1ms
VMs:           3

Verifying virtual machines.
Number of VMs: 3
===========================================================
VM ID: 0
VM name: ping
VM start address: 0x9d008000
VM length:        0x7f80 (32640)
VM hash:          ea4a04019b0bafd55054ae9ba54becb511993ebcb16c9e6d3a889c78ad3c1ed9
VM signature:     8cc58d8d71d13a24f2c2ac7632fa4a9954c8eb3dff96d995b8d1d2cc26ab49f9d1fd93a12e081091f54910d527b5cdd65c88a4455b8a53ec523934ab35ed495b
Verifying signature authenticity for VM 0 ... OK.

===========================================================
VM ID: 1
VM name: pong
VM start address: 0x9d010000
VM length:        0x7f80 (32640)
VM hash:          fd4b19da3929aa822e183f214b2380fd02e1d4bbbd5435f318b02da47763d992
VM signature:     97252e411f2e4d54dc753d8e9a0adb894db3c798f037e379c3e9378c84d6992f96a9bf94290c2f42df36289fea34fbf8da7bf5f00c8f74498ddc5007b099844f
Verifying signature authenticity for VM 1 ... failed.

CRITICAL: Virtual machines validation error.
Reset button (sw1) pressed. Performing software reset.

Signing virtual machine images individually

In the example about, the makefile automatically sign all VMs using the same private key. However, it is possible to sign each VM individually using different keys. This is specially useful when combining VM from different developer/vendors. For example:

cd prpl-hypervisor/scripts
./vmsectool.py sign -t ecdsa-p256 -k ./private_key.txt /tmp/blink.bin
public_key: 6306b69303c3c5961b5395b6ad5f7d9ccc46b0083d9ddf30a9c74ec1e0c7a04c1c5a7084b1f2e37310c119e60f92725f8ec04126ec2ae89d40cd3e4c583ec5ab
file size: 32768
hash: 18047514d4ad0c0393ca201be1ea1084e2a3aaf5f3a5da024812cb2a6ab6981a
signature: 2bdf93dae336ce6c193ef7c37f35f535e79780806475e51faf6ce501c228a9d821d38d1baa19fc4ad30f9ddd6bf54ef4568779fb272bc611763737abd31321c6
Signature verification OK.