TPM enabled FIDO Device Onboard (FDO) guide.
- Prerequisites
- Device Set Up
- Services Set Up
- Execute FDO Protocols
- Execute Resale Protocol
- References
- License
- Raspberry Pi 4 Model B with TPM 2.0. Prepare the OS image according to [1]
- Install tpm2-tss, tpm2-tools, and tpm2-tss-engine according to [1]
- Install the following:
$ sudo apt install cmake maven openjdk-9-jre
Summary of [3].
Install dependencies:
$ git clone https://github.com/intel/safestringlib ~/safestringlib
$ cd ~/safestringlib
$ git checkout v1.0.0
$ mkdir obj
$ make
$ git clone https://github.com/intel/tinycbor ~/tinycbor
$ cd ~/tinycbor
$ git checkout v0.5.3
$ make
Environment set up:
$ export SAFESTRING_ROOT=~/safestringlib
$ export TINYCBOR_ROOT=~/tinycbor
$ export OPENSSL_ENGINES=/usr/lib/arm-linux-gnueabihf/engines-1.1/
$ sudo chmod a+rw /dev/tpmrm0
Build client SDK:
$ git clone https://github.com/secure-device-onboard/client-sdk-fidoiot ~/client-sdk-fidoiot
$ cd client-sdk-fidoiot
$ git checkout v1.1.0
# Apply patch
$ git clone https://github.com/wxleong/tpm2-fdo ~/tpm2-fdo
$ git am < ~/tpm2-fdo/patch/compile-error-fix.patch
$ git am < ~/tpm2-fdo/patch/tpm2-tss-engine-path-fix.patch
# Set manufacturer address
$ echo -n http://localhost:8039 > data/manufacturer_addr.bin
# Set the maximum ServiceInfo Size
$ echo -n 8192 > data/max_serviceinfo_sz.bin
# Set the device serial number
$ echo -n serial-01 > data/manufacturer_sn.bin
# Set the device model number
$ echo -n model-01 > data/manufacturer_mod.bin
# Use TPM
$ cmake -DDA=tpm20_ecdsa256 -DTPM2_TCTI_TYPE=tpmrm0 .
$ make -j$(nproc)
Provision TPM:
$ cd ~/client-sdk-fidoiot
$ tpm2_clear -c p
$ tpm2_createprimary -C e -g sha256 -G ecc256:aes128cfb -c data/tpm_primary_key.ctx
$ tpm2_evictcontrol -C o 0x81000001 -c data/tpm_primary_key.ctx
$ tpm2tss-genkey -a ecdsa -c nist_p256 data/tpm_ecdsa_priv_pub_blob.key -v -P 0x81000001
Generate CSR:
$ openssl req -new -engine tpm2tss -keyform engine -outform DER -out data/tpm_device_csr -key data/tpm_ecdsa_priv_pub_blob.key -subj "/CN=sdo-tpm-device" -verbose
Build manufacturer, rendezvous, owner, and reseller services:
$ git clone https://github.com/secure-device-onboard/pri-fidoiot ~/pri-fidoiot
$ cd ~/pri-fidoiot
$ git checkout v1.1.0
$ mvn clean install
$ ls ~/pri-fidoiot/component-samples/demo/
-
Start services:
Start manufacturer service (https://localhost:8038, http://localhost:8039):
$ cd ~/pri-fidoiot/component-samples/demo/manufacturer $ java -jar aio.jar
- Deleting
~/pri-fidoiot/component-samples/demo/manufacturer/app-data
will force the service to reinitialize the database.
Start rendezvous service (http://localhost:8040, https://localhost:8041):
$ cd ~/pri-fidoiot/component-samples/demo/rv $ java -jar aio.jar
- Deleting
~/pri-fidoiot/component-samples/demo/rv/app-data
will force the service to reinitialize the database.
Start owner service (http://localhost:8042, https://localhost:8043):
$ cd ~/pri-fidoiot/component-samples/demo/owner $ java -jar aio.jar
- Deleting
~/pri-fidoiot/component-samples/demo/owner/app-data
will force the service to reinitialize the database.
- Deleting
-
Device Initialize Protocol (DI):
Configure manufacturer service's RendezvousInfo:
$ curl -d \ "[[[5,\"localhost\"],[3,8041],[12,2],[2,\"localhost\"],[4,8041]]]" \ -H "Content-Type: text/plain" \ --digest -u apiUser:"" \ -X POST \ http://localhost:8039/api/v1/rvinfo
The RendezvousInfo is based on [7]:
[[[5, RVDns], [3, RVDevPort], [12, RVProtocol], [2, RVIPAddress], [4, RVOwnerPort]]]
- The RendezvousInfo type indicates the manner and order in which the Device and Owner find the Rendezvous Server. It is configured during manufacturing (e.g., at an ODM), so the manufacturing entity has the choice of which Rendezvous Server(s) to use and how to access it or them.
- The value for api_user is present in
~/pri-fidoiot/component-samples/demo/manufacturer/service.yml
file and value for api_password is present in~/pri-fidoiot/component-samples/demo/manufacturer/service.env
file.
Execute the DI protocol (client log, manufacturer log) and record down the GUID and serial number:
$ cd ~/client-sdk-fidoiot $ ./build/linux-client
- An Ownership Voucher will be created and store on manufacturer service
- A TPM backed HMAC key is created and stored on device
~/client-sdk-fidoiot/data/tpm_hmac_data_priv.key
. - Deleting
~/client-sdk-fidoiot/data/Normal.blob
file will force the device to re-run DI protocol.
-
Extension of the Ownership Voucher:
Get owner certificate:
$ curl \ --digest -u apiUser:"" \ http://localhost:8042/api/v1/certificate?alias=SECP256R1 \ > ~/owner.crt
- The value for api_user is present in
~/pri-fidoiot/component-samples/demo/owner/service.yml
file and value for api_password is present in~/pri-fidoiot/component-samples/demo/owner/service.env
file.
Extension of the Ownership Voucher, from manufacturer to a new owner:
$ curl --data-raw "`cat ~/owner.crt`" \ -H "Content-Type: text/plain" \ --digest -u apiUser:"" \ -X POST \ http://localhost:8039/api/v1/mfg/vouchers/${serial_number} \ > ~/extended-voucher.txt
- In this example, the serial_number is serial-01.
- The value for api_user is present in
-
Transfer Ownership Protocol 0 (TO0):
Upload the extended Ownership Voucher to owner:
$ curl --data-raw "`cat ~/extended-voucher.txt`" \ -H "Content-Type: text/plain" \ --digest -u apiUser:"" \ -X POST \ http://localhost:8042/api/v1/owner/vouchers
- Returns a list of registered Ownership Voucher:
$ curl \ --digest -u apiUser:"" \ http://localhost:8042/api/v1/owner/vouchers
Configure owner service's RVTO2Addr:
$ curl -d \ "[[\"localhost\",\"localhost\",8043,5]]" \ -H "Content-Type: text/plain" \ --digest -u apiUser:"" \ -X POST \ http://localhost:8042/api/v1/owner/redirect
The RVTO2Addr is based on [8]:
[[RVIP, RVDNS, RVPort, RVProtocol]]
- The RVTO2Addr indicates to the Device how to contact the Owner to run the TO2 protocol. The RVTO2Addr is transmitted by the Owner to the Rendezvous Server during the TO0 protocol, and conveyed to the Device during the TO1 protocol.
Execute the TO0 protocol (owner log, rendezvous log):
$ curl \ --digest -u apiUser:"" \ http://localhost:8042/api/v1/to0/${device_guid}
An example of device_guid: 30a9dbe4-206c-47e3-8c43-a18abba63697
- Returns a list of registered Ownership Voucher:
-
Optional step. ServiceInfo and Management Service - Agent Interactions:
Configure the owner service's ServiceInfo [9] package. The example given here will execute a custom script on the client platform:
# Upload a script to the owner service $ curl --data-binary \ '@/home/pi/tpm2-fdo/script/setup.sh' \ -H "Content-Type: text/plain" \ --digest -u apiUser:"" \ -X POST \ http://localhost:8042/api/v1/owner/resource?filename=setup-script # Configure the ServiceInfo $ curl --data-raw \ '[{"filedesc" : "setup.sh","resource" : "setup-script"}, {"exec" : ["/usr/bin/bash","setup.sh"] }]' \ -H "Content-Type: text/plain" \ --digest -u apiUser:"" \ -X POST \ http://localhost:8042/api/v1/owner/svi
This is based on [10]:
'[{"filedesc" : "setup.sh","resource" : "setup-script"}, {"exec" : ["/usr/bin/bash","setup.sh"] }]'
translates to download the resource "setup-script" and store it as "setup.sh" on the client platform, and subsequently run the "setup.sh" with a bash shell.
-
Transfer Ownership Protocol 1&2 (TO1 & TO2):
Execute the TO1 and TO2 protocol:
$ cd ~/client-sdk-fidoiot $ ./build/linux-client
Sample logs:
- Without custom ServiceInfo:
- With custom ServiceInfo:
To-do.
[1] https://github.com/wxleong/tpm2-rpi4
[2] https://github.com/secure-device-onboard/client-sdk-fidoiot/blob/master/docs/tpm.md
[3] https://github.com/secure-device-onboard/pri-fidoiot
[4] https://github.com/secure-device-onboard/pri-fidoiot/blob/master/component-samples/demo/manufacturer/README.md
[5] https://github.com/secure-device-onboard/pri-fidoiot/tree/master/component-samples/demo/rv/README.md
[6] https://github.com/secure-device-onboard/pri-fidoiot/tree/master/component-samples/demo/owner/README.md
[7] https://fidoalliance.org/specs/FDO/FIDO-Device-Onboard-RD-v1.0-20201202.html#RVInfo
[8] https://fidoalliance.org/specs/FDO/FIDO-Device-Onboard-RD-v1.0-20201202.html#rvto2addr
[9] https://fidoalliance.org/specs/FDO/FIDO-Device-Onboard-RD-v1.0-20201202.html#management-agent-service-interactions-using-serviceinfo
[10] https://fidoalliance.org/specs/FDO/FIDO-Device-Onboard-RD-v1.0-20201202.html#ServiceInfo
This project is licensed under the MIT License - see the LICENSE file for details.