mirror of https://github.com/wolfSSL/wolfBoot.git
Support for sealing/unseal a secret based on an externally signed PCR policy.
* Added new `WOLFBOOT_TPM_SEAL` and `WOLFBOOT_TPM_SEAL_NV_BASE` config options. * Added new `tools/tpm/policy_create` tool for assisting with creation of a policy digest. The sign keytool `--policy=file` signs the policy. * Added new `WOLFBOOT_TPM_VERIFY` option to enable offloading of the asymmetric verification to the TPM. By default wolfCrypt will be used. * Added example seal/unseal to update_flash for ARCH_SIM. * Renamed `WOLFBOOT_TPM_KEYSTORE_NV_INDEX` to `WOLFBOOT_TPM_KEYSTORE_NV_BASE` to support multiple public keys. * Refactored most TPM code into tpm.c. * Refactored the keystore ROT to use new `wolfBoot_check_rot` API. * Refactored the sign keytool to have a sign_digest function to allow signing firmware and policy for sealing/unsealing. * Fix for make distclean && make using the wrong key tools.pull/366/head
parent
f55a27c62f
commit
490286be7d
|
@ -53,9 +53,10 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
make -C tools/keytools && make -C tools/bin-assemble
|
make -C tools/keytools && make -C tools/bin-assemble
|
||||||
|
|
||||||
- name: Build wolfboot
|
# needed for tpm tools
|
||||||
|
- name: Build keystore.c
|
||||||
run: |
|
run: |
|
||||||
make ${{inputs.make-args}} WOLFBOOT_TPM_KEYSTORE_AUTH="${{inputs.authstr}}"
|
make keys ${{inputs.make-args}}
|
||||||
|
|
||||||
- name: Build TPM tools
|
- name: Build TPM tools
|
||||||
run: |
|
run: |
|
||||||
|
@ -65,6 +66,16 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
./tools/tpm/rot -write ${{inputs.rot-args}} -auth="${{inputs.authstr}}"
|
./tools/tpm/rot -write ${{inputs.rot-args}} -auth="${{inputs.authstr}}"
|
||||||
|
|
||||||
|
- name: Create a PCR Policy
|
||||||
|
run: |
|
||||||
|
echo aaa > aaa.bin
|
||||||
|
./tools/tpm/pcr_extend 0 aaa.bin
|
||||||
|
./tools/tpm/policy_create -pcr=0 -out=policy.bin
|
||||||
|
|
||||||
|
- name: Build wolfboot
|
||||||
|
run: |
|
||||||
|
make ${{inputs.make-args}} WOLFBOOT_TPM_KEYSTORE_AUTH="${{inputs.authstr}}"
|
||||||
|
|
||||||
- name: Run wolfBoot
|
- name: Run wolfBoot
|
||||||
run: |
|
run: |
|
||||||
./wolfboot.elf get_version
|
./wolfboot.elf get_version
|
||||||
|
|
|
@ -36,6 +36,7 @@ jobs:
|
||||||
config-file: ./config/examples/sim-tpm.config
|
config-file: ./config/examples/sim-tpm.config
|
||||||
make-args: SIGN=RSA2048 HASH=SHA256
|
make-args: SIGN=RSA2048 HASH=SHA256
|
||||||
|
|
||||||
|
|
||||||
sim_tpm_measured_ecc256:
|
sim_tpm_measured_ecc256:
|
||||||
uses: ./.github/workflows/test-build-sim-tpm.yml
|
uses: ./.github/workflows/test-build-sim-tpm.yml
|
||||||
with:
|
with:
|
||||||
|
@ -82,3 +83,29 @@ jobs:
|
||||||
config-file: ./config/examples/sim-tpm-keystore.config
|
config-file: ./config/examples/sim-tpm-keystore.config
|
||||||
make-args: SIGN=RSA2048 HASH=SHA256
|
make-args: SIGN=RSA2048 HASH=SHA256
|
||||||
authstr: TestAuth
|
authstr: TestAuth
|
||||||
|
|
||||||
|
|
||||||
|
sim_tpm_seal_ecc256:
|
||||||
|
uses: ./.github/workflows/test-build-sim-tpm.yml
|
||||||
|
with:
|
||||||
|
arch: host
|
||||||
|
config-file: ./config/examples/sim-tpm-seal.config
|
||||||
|
make-args: SIGN=ECC256 HASH=SHA256 POLICY_FILE=policy.bin
|
||||||
|
authstr: TestAuth
|
||||||
|
|
||||||
|
sim_tpm_seal_ecc384:
|
||||||
|
uses: ./.github/workflows/test-build-sim-tpm.yml
|
||||||
|
with:
|
||||||
|
arch: host
|
||||||
|
config-file: ./config/examples/sim-tpm-seal.config
|
||||||
|
make-args: SIGN=ECC384 HASH=SHA384 POLICY_FILE=policy.bin
|
||||||
|
rot-args: -sha384
|
||||||
|
authstr: TestAuth
|
||||||
|
|
||||||
|
sim_tpm_seal_rsa2048:
|
||||||
|
uses: ./.github/workflows/test-build-sim-tpm.yml
|
||||||
|
with:
|
||||||
|
arch: host
|
||||||
|
config-file: ./config/examples/sim-tpm-seal.config
|
||||||
|
make-args: SIGN=RSA2048 HASH=SHA256 POLICY_FILE=policy.bin
|
||||||
|
authstr: TestAuth
|
||||||
|
|
|
@ -101,6 +101,10 @@ tools/unit-tests/unit-parser
|
||||||
tools/bin-assemble/bin-assemble
|
tools/bin-assemble/bin-assemble
|
||||||
tools/elf-parser/elf-parser
|
tools/elf-parser/elf-parser
|
||||||
tools/tpm/rot
|
tools/tpm/rot
|
||||||
|
tools/tpm/pcr_read
|
||||||
|
tools/tpm/pcr_reset
|
||||||
|
tools/tpm/pcr_extend
|
||||||
|
tools/tpm/policy_create
|
||||||
config/*.ld
|
config/*.ld
|
||||||
|
|
||||||
# Generated confiuguration file
|
# Generated confiuguration file
|
||||||
|
|
|
@ -37,7 +37,8 @@ Note: If not using Position Independent Code (PIC) the linker script `ldscript.l
|
||||||
## Signing Example
|
## Signing Example
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
python3 ./tools/keytools/sign.py --rsa4096 --sha3 ../helloworld/Debug/helloworld.elf ./rsa4096.der 1
|
make keytools
|
||||||
|
./tools/keytools/sign --rsa4096 --sha3 ../helloworld/Debug/helloworld.elf ./rsa4096.der 1
|
||||||
```
|
```
|
||||||
|
|
||||||
## Bootgen
|
## Bootgen
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -154,10 +154,8 @@ include tools/test-enc.mk
|
||||||
include tools/test-delta.mk
|
include tools/test-delta.mk
|
||||||
include tools/test-renode.mk
|
include tools/test-renode.mk
|
||||||
|
|
||||||
PYTHON?=python3
|
|
||||||
keytools_check: keytools FORCE
|
keytools_check: keytools FORCE
|
||||||
|
|
||||||
|
|
||||||
$(PRIVATE_KEY):
|
$(PRIVATE_KEY):
|
||||||
$(Q)$(MAKE) keytools_check
|
$(Q)$(MAKE) keytools_check
|
||||||
$(Q)(test $(SIGN) = NONE) || ("$(KEYGEN_TOOL)" $(KEYGEN_OPTIONS) -g $(PRIVATE_KEY)) || true
|
$(Q)(test $(SIGN) = NONE) || ("$(KEYGEN_TOOL)" $(KEYGEN_OPTIONS) -g $(PRIVATE_KEY)) || true
|
||||||
|
|
|
@ -19,7 +19,7 @@ WOLFBOOT_FIXED_PARTITIONS=1
|
||||||
|
|
||||||
# Use NV for TPM based Root of Trust
|
# Use NV for TPM based Root of Trust
|
||||||
WOLFBOOT_TPM_KEYSTORE?=1
|
WOLFBOOT_TPM_KEYSTORE?=1
|
||||||
WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=0x01400200
|
WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01400200
|
||||||
#WOLFBOOT_TPM_KEYSTORE_AUTH?=TestAuth
|
#WOLFBOOT_TPM_KEYSTORE_AUTH?=TestAuth
|
||||||
|
|
||||||
# TPM Logging
|
# TPM Logging
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
ARCH=sim
|
||||||
|
TARGET=sim
|
||||||
|
SIGN?=ECC256
|
||||||
|
HASH?=SHA256
|
||||||
|
SPI_FLASH=0
|
||||||
|
DEBUG=0
|
||||||
|
WOLFTPM=1
|
||||||
|
|
||||||
|
# sizes should be multiple of system page size
|
||||||
|
WOLFBOOT_PARTITION_SIZE=0x40000
|
||||||
|
WOLFBOOT_SECTOR_SIZE=0x1000
|
||||||
|
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
|
||||||
|
# if on external flash, it should be multiple of system page size
|
||||||
|
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000
|
||||||
|
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x180000
|
||||||
|
|
||||||
|
# required for keytools
|
||||||
|
WOLFBOOT_FIXED_PARTITIONS=1
|
||||||
|
|
||||||
|
# Use NV for TPM based Root of Trust
|
||||||
|
WOLFBOOT_TPM_KEYSTORE?=1
|
||||||
|
WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01400200
|
||||||
|
#WOLFBOOT_TPM_KEYSTORE_AUTH?=TestAuth
|
||||||
|
|
||||||
|
# Measured boot at test PCR index 16
|
||||||
|
MEASURED_BOOT?=1
|
||||||
|
MEASURED_PCR_A?=16
|
||||||
|
|
||||||
|
# Sealing a secret into TPM based on external PCR policy signed by the sign tool
|
||||||
|
WOLFBOOT_TPM_SEAL?=1
|
||||||
|
WOLFBOOT_TPM_SEAL_NV_BASE=0x01400300
|
||||||
|
|
||||||
|
# TPM Logging
|
||||||
|
#CFLAGS_EXTRA+=-DDEBUG_WOLFTPM
|
||||||
|
#CFLAGS_EXTRA+=-DWOLFTPM_DEBUG_VERBOSE
|
|
@ -5,6 +5,8 @@ HASH?=SHA256
|
||||||
SPI_FLASH=0
|
SPI_FLASH=0
|
||||||
DEBUG=0
|
DEBUG=0
|
||||||
WOLFTPM=1
|
WOLFTPM=1
|
||||||
|
# enable offloading of asymmetric verify to TPM
|
||||||
|
WOLFBOOT_TPM_VERIFY?=1
|
||||||
|
|
||||||
# sizes should be multiple of system page size
|
# sizes should be multiple of system page size
|
||||||
WOLFBOOT_PARTITION_SIZE=0x40000
|
WOLFBOOT_PARTITION_SIZE=0x40000
|
||||||
|
|
|
@ -13,7 +13,7 @@ WOLFTPM=0
|
||||||
|
|
||||||
# TPM Keystore options
|
# TPM Keystore options
|
||||||
#WOLFBOOT_TPM_KEYSTORE?=1
|
#WOLFBOOT_TPM_KEYSTORE?=1
|
||||||
#WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=0x01800200
|
#WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200
|
||||||
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
||||||
|
|
||||||
# 4gb - 8mb
|
# 4gb - 8mb
|
||||||
|
|
|
@ -13,7 +13,7 @@ WOLFTPM=0
|
||||||
|
|
||||||
# TPM Keystore options
|
# TPM Keystore options
|
||||||
#WOLFBOOT_TPM_KEYSTORE?=1
|
#WOLFBOOT_TPM_KEYSTORE?=1
|
||||||
#WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=0x01800200
|
#WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200
|
||||||
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
||||||
|
|
||||||
# 4gb - 8mb
|
# 4gb - 8mb
|
||||||
|
|
|
@ -13,7 +13,7 @@ WOLFTPM=1
|
||||||
|
|
||||||
# TPM Keystore options
|
# TPM Keystore options
|
||||||
#WOLFBOOT_TPM_KEYSTORE?=1
|
#WOLFBOOT_TPM_KEYSTORE?=1
|
||||||
#WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=0x01800200
|
#WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200
|
||||||
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
||||||
|
|
||||||
# 4gb - 8mb
|
# 4gb - 8mb
|
||||||
|
|
|
@ -13,7 +13,7 @@ WOLFTPM=1
|
||||||
|
|
||||||
# TPM Keystore options
|
# TPM Keystore options
|
||||||
WOLFBOOT_TPM_KEYSTORE?=1
|
WOLFBOOT_TPM_KEYSTORE?=1
|
||||||
WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=0x01800200
|
WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200
|
||||||
WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201
|
||||||
|
|
||||||
# 4gb - 8mb
|
# 4gb - 8mb
|
||||||
|
|
|
@ -157,7 +157,6 @@ be used for the key, 16 for the initialization of the IV.
|
||||||
SHAREDKEY.BIN is expected to be exactly 48 bytes in size, of which 32 will
|
SHAREDKEY.BIN is expected to be exactly 48 bytes in size, of which 32 will
|
||||||
be used for the key, 16 for the initialization of the IV.
|
be used for the key, 16 for the initialization of the IV.
|
||||||
|
|
||||||
|
|
||||||
#### Delta updates (incremental updates from a known version)
|
#### Delta updates (incremental updates from a known version)
|
||||||
|
|
||||||
An incremental update is created using the sign tool when the following option
|
An incremental update is created using the sign tool when the following option
|
||||||
|
@ -167,6 +166,16 @@ is provided:
|
||||||
`BASE_SIGNED_IMG.BIN` and the new image signed starting from `IMAGE.BIN`. The
|
`BASE_SIGNED_IMG.BIN` and the new image signed starting from `IMAGE.BIN`. The
|
||||||
result is stored in a file ending in `_signed_diff.bin`.
|
result is stored in a file ending in `_signed_diff.bin`.
|
||||||
|
|
||||||
|
#### Policy signing (for sealing/unsealing with a TPM)
|
||||||
|
|
||||||
|
Provides a PCR mask and digest to be signed and included in the header. The signing key is used to sign the digest.
|
||||||
|
|
||||||
|
* `--policy policy.bin`: This argument is multi-purpose.
|
||||||
|
By default the file should contain a 4-byte PCR mask and SHA2-256 PCR digest to be signed.
|
||||||
|
If using `--manual-sign` then the file should contain the 4-byte PCR mask and signature.
|
||||||
|
The PCR mask and signature will be included in the `HDR_POLICY_SIGNATURE` header tag.
|
||||||
|
Note: This may require increasing the `IMAGE_HEADER_SIZE` as two signatures will be stored in the header.
|
||||||
|
|
||||||
#### Three-steps signing using external provisioning tools
|
#### Three-steps signing using external provisioning tools
|
||||||
|
|
||||||
If the private key is not accessible, while it's possible to sign payloads using
|
If the private key is not accessible, while it's possible to sign payloads using
|
||||||
|
|
143
docs/TPM.md
143
docs/TPM.md
|
@ -6,11 +6,14 @@ In wolfBoot we support TPM based root of trust, sealing/unsealing, cryptographic
|
||||||
|
|
||||||
| Config Option | Preprocessor Macro | Description |
|
| Config Option | Preprocessor Macro | Description |
|
||||||
| ------------- | ------------------ | ----------------------------------- |
|
| ------------- | ------------------ | ----------------------------------- |
|
||||||
| `WOLFTPM=1` | `WOLFBOOT_TPM` | Enables wolfTPM support and cryptographic offloading for RSA2048 and ECC256/384 |
|
| `WOLFTPM=1` | `WOLFBOOT_TPM` | Enables wolfTPM support |
|
||||||
|
| `WOLFBOOT_TPM_VERIFY=1` | `WOLFBOOT_TPM_VERIFY` | Enables cryptographic offloading for RSA2048 and ECC256/384 to the TPM. |
|
||||||
| `WOLFBOOT_TPM_KEYSTORE=1` | `WOLFBOOT_TPM_KEYSTORE` | Enables TPM based root of trust. NV Index must store a hash of the trusted public key. |
|
| `WOLFBOOT_TPM_KEYSTORE=1` | `WOLFBOOT_TPM_KEYSTORE` | Enables TPM based root of trust. NV Index must store a hash of the trusted public key. |
|
||||||
| `WOLFBOOT_TPM_KEYSTORE_NV_INDEX=0x` | `WOLFBOOT_TPM_KEYSTORE_NV_INDEX=0x` | NV index in platform range 0x1400000 - 0x17FFFFF |
|
| `WOLFBOOT_TPM_KEYSTORE_NV_BASE=0x` | `WOLFBOOT_TPM_KEYSTORE_NV_BASE=0x` | NV index in platform range 0x1400000 - 0x17FFFFF. |
|
||||||
| `MEASURED_BOOT=1` | `WOLFBOOT_MEASURED_BOOT` | Enable measured boot. Extend PCR with wolfBoot hash. |
|
| `MEASURED_BOOT=1` | `WOLFBOOT_MEASURED_BOOT` | Enable measured boot. Extend PCR with wolfBoot hash. |
|
||||||
| `MEASURED_PCR_A=16` | `WOLFBOOT_MEASURED_PCR_A=16` | The PCR index to use. See [docs/measured_boot.md](/docs/measured_boot.md) |
|
| `MEASURED_PCR_A=16` | `WOLFBOOT_MEASURED_PCR_A=16` | The PCR index to use. See [docs/measured_boot.md](/docs/measured_boot.md). |
|
||||||
|
| `WOLFBOOT_TPM_SEAL=1` | `WOLFBOOT_TPM_SEAL` | Enables support for sealing/unsealing based on PCR policy signed externally. |
|
||||||
|
| `WOLFBOOT_TPM_SEAL_NV_BASE=0x01400300` | `WOLFBOOT_TPM_SEAL_NV_BASE` | To override the default sealed blob storage location in the platform hierarchy. |
|
||||||
|
|
||||||
## Root of Trust (ROT)
|
## Root of Trust (ROT)
|
||||||
|
|
||||||
|
@ -20,12 +23,140 @@ The design uses a platform NV handle that has been locked. The NV stores a hash
|
||||||
|
|
||||||
## Cryptographic offloading
|
## Cryptographic offloading
|
||||||
|
|
||||||
The RSA2048 and ECC256/384 bit verification can be offloaded to a TPM for code size reduction or performance improvement.
|
The RSA2048 and ECC256/384 bit verification can be offloaded to a TPM for code size reduction or performance improvement. Enabled using `WOLFBOOT_TPM_VERIFY`
|
||||||
|
|
||||||
## Measured Boot
|
## Measured Boot
|
||||||
|
|
||||||
The wolfBoot image is hashed and extended to the indicated PCR. This can be used later in the application to prove the boot process was not tampered with.
|
The wolfBoot image is hashed and extended to the indicated PCR. This can be used later in the application to prove the boot process was not tampered with. Enabled with `WOLFBOOT_MEASURED_BOOT` and exposes API `wolfBoot_tpm2_extend`.
|
||||||
|
|
||||||
## Sealing and Unsealing a secret
|
## Sealing and Unsealing a secret
|
||||||
|
|
||||||
API's for this will be available soon.
|
See the wolfTPM Sealing/Unsealing example [here](https://github.com/wolfSSL/wolfTPM/tree/secret_seal/examples/boot#secure-boot-encryption-key-storage)
|
||||||
|
|
||||||
|
Known PCR values must be signed to seal/unseal a secret. The signature for the authorization policy resides in the signed header using the `--policy` argument.
|
||||||
|
If a signed policy is not in the header then a value cannot be sealed. Instead the PCR(s) and a digest to sign will be printed for use with the sign tool.
|
||||||
|
|
||||||
|
This exposes two new wolfBoot API's for sealing and unsealing data with blob stored to NV index:
|
||||||
|
```c
|
||||||
|
int wolfBoot_seal(struct wolfBoot_image* img, int index, const uint8_t* secret, int secret_sz);
|
||||||
|
int wolfBoot_unseal(struct wolfBoot_image* img, int index, uint8_t* secret, int* secret_sz);
|
||||||
|
```
|
||||||
|
|
||||||
|
By default this index will be based on an NV Index at `(0x01400300 + index)`.
|
||||||
|
The default NV base can be overridden with `WOLFBOOT_TPM_SEAL_NV_BASE`.
|
||||||
|
|
||||||
|
|
||||||
|
### Testing seal/unseal with simulator
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp config/examples/sim-tpm-seal.config .config
|
||||||
|
make keytools
|
||||||
|
make tpmtools
|
||||||
|
echo aaa > aaa.bin
|
||||||
|
./tools/tpm/pcr_extend 0 aaa.bin
|
||||||
|
./tools/tpm/policy_create -pcr=0
|
||||||
|
# if ROT enabled
|
||||||
|
./tools/tpm/rot -write
|
||||||
|
make clean && make POLICY_FILE=policy.bin
|
||||||
|
./wolfboot.elf get_version
|
||||||
|
Simulator assigned ./internal_flash.dd to base 0x103797000
|
||||||
|
Mfg IBM (0), Vendor SW TPM, Fw 8217.4131 (0x163636), FIPS 140-2 1, CC-EAL4 0
|
||||||
|
Unlocking disk...
|
||||||
|
Boot partition: 0x103817000
|
||||||
|
Image size 54400
|
||||||
|
Sealing 32 bytes
|
||||||
|
11c6ac0ec972ae567c541750c6ecccd426f131dad3eeca5e6540d901d9f0c336
|
||||||
|
Unsealed 32 bytes
|
||||||
|
11c6ac0ec972ae567c541750c6ecccd426f131dad3eeca5e6540d901d9f0c336
|
||||||
|
Boot partition: 0x103817000
|
||||||
|
Image size 54400
|
||||||
|
TPM Root of Trust valid (id 0)
|
||||||
|
Simulator assigned ./internal_flash.dd to base 0x103962000
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing seal/unseal on actual hardware
|
||||||
|
|
||||||
|
1) Get the actual PCR digest for policy.
|
||||||
|
2) Sign policy and include in firmware image header.
|
||||||
|
|
||||||
|
|
||||||
|
#### Getting PCR values
|
||||||
|
|
||||||
|
If no signed policy exists, then the seal function will generate and display the active PCR's, PCR digest and policy digest (to sign)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
% make tpmtools
|
||||||
|
% ./tools/tpm/rot -write
|
||||||
|
% ./tools/tpm/pcr_reset 16
|
||||||
|
% ./wolfboot.elf get_version
|
||||||
|
Simulator assigned ./internal_flash.dd to base 0x101a64000
|
||||||
|
Mfg IBM (0), Vendor SW TPM, Fw 8217.4131 (0x163636), FIPS 140-2 1, CC-EAL4 0
|
||||||
|
Boot partition: 0x101ae4000
|
||||||
|
Image size 57192
|
||||||
|
Policy header not found!
|
||||||
|
Generating policy based on active PCR's!
|
||||||
|
Getting active PCR's (0-16)
|
||||||
|
PCR 16 (counter 20)
|
||||||
|
8f7ac1d5a5eac58a2305ca459f27c35705a9212c0fb2a9088b1df761f3d5f842
|
||||||
|
Found 1 active PCR's (mask 0x00010000)
|
||||||
|
PCR Digest (32 bytes):
|
||||||
|
f84085631f85333ad0338b06c82f16888b7923abaccffb881d5416e389be256c
|
||||||
|
PCR Mask (0x00010000) and PCR Policy Digest (36 bytes):
|
||||||
|
0000010034ba061436aba2e9a167a1ee46af4a9578a8c6b9f71fdece21607a0cb40468ec
|
||||||
|
Use this policy with the sign tool (--policy arg) or POLICY_FILE config
|
||||||
|
Image policy signature missing!
|
||||||
|
Boot partition: 0x101ae4000
|
||||||
|
Image size 57192
|
||||||
|
TPM Root of Trust valid (id 0)
|
||||||
|
Simulator assigned ./internal_flash.dd to base 0x101c2f000
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
The `0000010034ba061436aba2e9a167a1ee46af4a9578a8c6b9f71fdece21607a0cb40468ec` above can be directly used by the keytool. The
|
||||||
|
|
||||||
|
`echo "0000010034ba061436aba2e9a167a1ee46af4a9578a8c6b9f71fdece21607a0cb40468ec" | xxd -r -p > policy.bin`
|
||||||
|
|
||||||
|
OR use the `tools/tpm/policy_create` tool to generate a digest to be signed. The used PCR(s) must be set using "-pcr=#". The PCR digest can be supplied using "-pcrdigest=" or if not supplied will be read from the TPM directly.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
% ./tools/tpm/policy_create -pcr=16 -pcrdigest=f84085631f85333ad0338b06c82f16888b7923abaccffb881d5416e389be256c -out=policy.bin
|
||||||
|
# OR
|
||||||
|
% ./tools/tpm/policy_create -pcrmask=0x00010000 -pcrdigest=f84085631f85333ad0338b06c82f16888b7923abaccffb881d5416e389be256c -out=policy.bin
|
||||||
|
Policy Create Tool
|
||||||
|
PCR Index(s) (SHA256): 16 (mask 0x00010000)
|
||||||
|
PCR Digest (32 bytes):
|
||||||
|
f84085631f85333ad0338b06c82f16888b7923abaccffb881d5416e389be256c
|
||||||
|
PCR Mask (0x00010000) and PCR Policy Digest (36 bytes):
|
||||||
|
0000010034ba061436aba2e9a167a1ee46af4a9578a8c6b9f71fdece21607a0cb40468ec
|
||||||
|
Wrote 36 bytes to policy.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Signing Policy
|
||||||
|
|
||||||
|
Building firmware with the policy digest to sign:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
% make POLICY_FILE=policy.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
OR manually using:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
% ./tools/keytools/sign --ecc256 --policy policy.bin test-app/image.elf wolfboot_signing_private_key.der 1
|
||||||
|
wolfBoot KeyTools (Compiled C version)
|
||||||
|
wolfBoot version 1100000
|
||||||
|
Update type: Firmware
|
||||||
|
Input image: test-app/image.elf
|
||||||
|
Selected cipher: ECC256
|
||||||
|
Selected hash : SHA256
|
||||||
|
Public key: wolfboot_signing_private_key.der
|
||||||
|
Output image: test-app/image_v1_signed.bin
|
||||||
|
Target partition id : 1
|
||||||
|
image header size calculated at runtime (256 bytes)
|
||||||
|
Calculating SHA256 digest...
|
||||||
|
Signing the digest...
|
||||||
|
Opening policy file policy.bin
|
||||||
|
Signing the policy digest...
|
||||||
|
Output image(s) successfully created.
|
||||||
|
```
|
||||||
|
|
|
@ -569,7 +569,11 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
|
||||||
/* Defined in libwolfboot */
|
/* Defined in libwolfboot */
|
||||||
uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
|
uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
|
||||||
|
|
||||||
|
/* get header type for image */
|
||||||
|
uint16_t wolfBoot_get_header(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr);
|
||||||
|
|
||||||
|
/* Find the key slot ID based on the SHA hash of the key. */
|
||||||
|
int keyslot_id_by_sha(const uint8_t *hint);
|
||||||
|
|
||||||
#ifdef EXT_FLASH
|
#ifdef EXT_FLASH
|
||||||
# ifdef PART_BOOT_EXT
|
# ifdef PART_BOOT_EXT
|
||||||
|
|
|
@ -71,11 +71,6 @@ extern "C" {
|
||||||
# error "No public key available for given signing algorithm."
|
# error "No public key available for given signing algorithm."
|
||||||
#endif /* Algorithm selection */
|
#endif /* Algorithm selection */
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM
|
|
||||||
int wolfBoot_tpm2_init(void);
|
|
||||||
void wolfBoot_tpm2_deinit(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wolfBoot_start(void);
|
void wolfBoot_start(void);
|
||||||
|
|
||||||
#if defined(ARCH_ARM) && defined(WOLFBOOT_ARMORED)
|
#if defined(ARCH_ARM) && defined(WOLFBOOT_ARMORED)
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* tpm.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfBoot.
|
||||||
|
*
|
||||||
|
* wolfBoot is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfBoot is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WOLFBOOT_TPM_H_
|
||||||
|
#define _WOLFBOOT_TPM_H_
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_TPM
|
||||||
|
|
||||||
|
#include "wolftpm/tpm2.h"
|
||||||
|
#include "wolftpm/tpm2_wrap.h"
|
||||||
|
|
||||||
|
extern WOLFTPM2_DEV wolftpm_dev;
|
||||||
|
#if defined(WOLFBOOT_TPM_KEYSTORE) || defined(WOLFBOOT_TPM_SEAL)
|
||||||
|
extern WOLFTPM2_SESSION wolftpm_session;
|
||||||
|
extern WOLFTPM2_KEY wolftpm_srk;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WOLFBOOT_TPM_KEYSTORE_NV_BASE
|
||||||
|
#define WOLFBOOT_TPM_KEYSTORE_NV_BASE 0x01400200
|
||||||
|
#endif
|
||||||
|
#ifndef WOLFBOOT_TPM_SEAL_NV_BASE
|
||||||
|
#define WOLFBOOT_TPM_SEAL_NV_BASE 0x01400300
|
||||||
|
#endif
|
||||||
|
#ifndef WOLFBOOT_TPM_PCR_ALG
|
||||||
|
/* Prefer SHA2-256 for PCR's, and all TPM 2.0 devices support it */
|
||||||
|
#define WOLFBOOT_TPM_PCR_ALG TPM_ALG_SHA256
|
||||||
|
#define WOLFBOOT_TPM_PCR_DIG_SZ 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WOLFBOOT_MAX_SEAL_SZ MAX_SYM_DATA
|
||||||
|
|
||||||
|
|
||||||
|
int wolfBoot_tpm2_init(void);
|
||||||
|
void wolfBoot_tpm2_deinit(void);
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_TPM_KEYSTORE
|
||||||
|
int wolfBoot_check_rot(int key_slot, uint8_t* pubkey_hint);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_TPM_SEAL
|
||||||
|
int wolfBoot_get_random(uint8_t* buf, int sz);
|
||||||
|
int wolfBoot_get_pcr_active(uint8_t pcrAlg, uint32_t* pcrMask, uint8_t pcrMax);
|
||||||
|
int wolfBoot_build_policy(uint8_t pcrAlg, uint32_t pcrMask, uint8_t* policy, uint32_t* policySz, uint8_t* policyRef, uint32_t policyRefSz);
|
||||||
|
int wolfBoot_get_policy(struct wolfBoot_image* img, uint8_t** policy, uint16_t* policySz);
|
||||||
|
int wolfBoot_seal(struct wolfBoot_image* img, int index, const uint8_t* secret, int secret_sz);
|
||||||
|
int wolfBoot_seal_blob(struct wolfBoot_image* img, WOLFTPM2_KEYBLOB* seal_blob, const uint8_t* secret, int secret_sz);
|
||||||
|
int wolfBoot_unseal(struct wolfBoot_image* img, int index, uint8_t* secret, int* secret_sz);
|
||||||
|
int wolfBoot_unseal_blob(struct wolfBoot_image* img, WOLFTPM2_KEYBLOB* seal_blob, uint8_t* secret, int* secret_sz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_MEASURED_BOOT
|
||||||
|
int wolfBoot_tpm2_extend(uint8_t pcrIndex, uint8_t* hash, int line);
|
||||||
|
|
||||||
|
/* helper for measuring boot at line */
|
||||||
|
#define measure_boot(hash) \
|
||||||
|
wolfBoot_tpm2_extend(WOLFBOOT_MEASURED_PCR_A, (hash), __LINE__)
|
||||||
|
#endif /* WOLFBOOT_MEASURED_BOOT */
|
||||||
|
|
||||||
|
/* debugging */
|
||||||
|
void wolfBoot_print_hexstr(const unsigned char* bin, unsigned long sz,
|
||||||
|
unsigned long maxLine);
|
||||||
|
void wolfBoot_print_bin(const byte* buffer, word32 length);
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* stubs */
|
||||||
|
#define measure_boot(hash)
|
||||||
|
|
||||||
|
#endif /* WOLFBOOT_TPM */
|
||||||
|
|
||||||
|
#endif /* !_WOLFBOOT_TPM_H_ */
|
|
@ -44,6 +44,10 @@ extern int tolower(int c);
|
||||||
# define WC_NO_HARDEN
|
# define WC_NO_HARDEN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFBOOT_TPM_KEYSTORE) || defined(WOLFBOOT_TPM_SEAL)
|
||||||
|
# define WOLFBOOT_TPM_PARMENC /* used in this file to gate features */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ED25519 and SHA512 */
|
/* ED25519 and SHA512 */
|
||||||
#ifdef WOLFBOOT_SIGN_ED25519
|
#ifdef WOLFBOOT_SIGN_ED25519
|
||||||
# define HAVE_ED25519
|
# define HAVE_ED25519
|
||||||
|
@ -110,7 +114,7 @@ extern int tolower(int c);
|
||||||
# define WOLFSSL_SP_384
|
# define WOLFSSL_SP_384
|
||||||
# define WOLFSSL_SP_NO_256
|
# define WOLFSSL_SP_NO_256
|
||||||
# endif
|
# endif
|
||||||
# if !defined(WOLFBOOT_TPM_KEYSTORE)
|
# if !defined(WOLFBOOT_TPM_PARMENC)
|
||||||
# define NO_ECC256
|
# define NO_ECC256
|
||||||
# endif
|
# endif
|
||||||
#elif defined(WOLFBOOT_SIGN_ECC521)
|
#elif defined(WOLFBOOT_SIGN_ECC521)
|
||||||
|
@ -120,7 +124,7 @@ extern int tolower(int c);
|
||||||
# define WOLFSSL_SP_521
|
# define WOLFSSL_SP_521
|
||||||
# define WOLFSSL_SP_NO_256
|
# define WOLFSSL_SP_NO_256
|
||||||
# endif
|
# endif
|
||||||
# if !defined(WOLFBOOT_TPM_KEYSTORE)
|
# if !defined(WOLFBOOT_TPM_PARMENC)
|
||||||
# define NO_ECC256
|
# define NO_ECC256
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,7 +139,7 @@ extern int tolower(int c);
|
||||||
# define WOLFSSL_RSA_VERIFY_INLINE
|
# define WOLFSSL_RSA_VERIFY_INLINE
|
||||||
# define WOLFSSL_RSA_VERIFY_ONLY
|
# define WOLFSSL_RSA_VERIFY_ONLY
|
||||||
# endif
|
# endif
|
||||||
# ifndef WOLFBOOT_TPM_KEYSTORE
|
# if !defined(WOLFBOOT_TPM_PARMENC)
|
||||||
# define WC_NO_RSA_OAEP
|
# define WC_NO_RSA_OAEP
|
||||||
# endif
|
# endif
|
||||||
# define FP_MAX_BITS (2048 * 2)
|
# define FP_MAX_BITS (2048 * 2)
|
||||||
|
@ -190,14 +194,14 @@ extern int tolower(int c);
|
||||||
|
|
||||||
#ifdef WOLFBOOT_HASH_SHA3_384
|
#ifdef WOLFBOOT_HASH_SHA3_384
|
||||||
# define WOLFSSL_SHA3
|
# define WOLFSSL_SHA3
|
||||||
# if defined(NO_RSA) && !defined(WOLFBOOT_TPM_KEYSTORE)
|
# if defined(NO_RSA) && !defined(WOLFBOOT_TPM_PARMENC)
|
||||||
# define NO_SHA256
|
# define NO_SHA256
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFBOOT_HASH_SHA384
|
#ifdef WOLFBOOT_HASH_SHA384
|
||||||
# define WOLFSSL_SHA384
|
# define WOLFSSL_SHA384
|
||||||
# if defined(NO_RSA) && !defined(WOLFBOOT_TPM_KEYSTORE)
|
# if defined(NO_RSA) && !defined(WOLFBOOT_TPM_PARMENC)
|
||||||
# define NO_SHA256
|
# define NO_SHA256
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -232,8 +236,16 @@ extern int tolower(int c);
|
||||||
#ifdef WOLFBOOT_TPM
|
#ifdef WOLFBOOT_TPM
|
||||||
/* Do not use heap */
|
/* Do not use heap */
|
||||||
#define WOLFTPM2_NO_HEAP
|
#define WOLFTPM2_NO_HEAP
|
||||||
|
/* small stack options */
|
||||||
|
#ifdef WOLFTPM_SMALL_STACK
|
||||||
|
#define MAX_COMMAND_SIZE 1024
|
||||||
|
#define MAX_RESPONSE_SIZE 1350
|
||||||
|
#define WOLFTPM2_MAX_BUFFER 1500
|
||||||
|
#define MAX_SESSION_NUM 2
|
||||||
|
#define MAX_DIGEST_BUFFER 973
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM_KEYSTORE
|
#ifdef WOLFBOOT_TPM_PARMENC
|
||||||
/* Enable AES CFB (parameter encryption) and HMAC (for KDF) */
|
/* Enable AES CFB (parameter encryption) and HMAC (for KDF) */
|
||||||
#define WOLFSSL_AES_CFB
|
#define WOLFSSL_AES_CFB
|
||||||
|
|
||||||
|
@ -241,7 +253,7 @@ extern int tolower(int c);
|
||||||
#define WOLFSSL_PUBLIC_MP
|
#define WOLFSSL_PUBLIC_MP
|
||||||
|
|
||||||
/* Configure RNG seed */
|
/* Configure RNG seed */
|
||||||
#define CUSTOM_RAND_GENERATE_SEED(buf, sz) 0 /* stub, not used */
|
#define CUSTOM_RAND_GENERATE_SEED(buf, sz) ({(void)buf; (void)sz; 0;}) /* stub, not used */
|
||||||
#define WC_RNG_SEED_CB
|
#define WC_RNG_SEED_CB
|
||||||
#define HAVE_HASHDRBG
|
#define HAVE_HASHDRBG
|
||||||
#endif
|
#endif
|
||||||
|
@ -269,10 +281,10 @@ extern int tolower(int c);
|
||||||
|
|
||||||
/* Disables - For minimum wolfCrypt build */
|
/* Disables - For minimum wolfCrypt build */
|
||||||
#if !defined(ENCRYPT_WITH_AES128) && !defined(ENCRYPT_WITH_AES256) && \
|
#if !defined(ENCRYPT_WITH_AES128) && !defined(ENCRYPT_WITH_AES256) && \
|
||||||
!defined(WOLFBOOT_TPM_KEYSTORE)
|
!defined(WOLFBOOT_TPM_PARMENC)
|
||||||
#define NO_AES
|
#define NO_AES
|
||||||
#endif
|
#endif
|
||||||
#if !defined(WOLFBOOT_TPM_KEYSTORE)
|
#if !defined(WOLFBOOT_TPM_PARMENC)
|
||||||
#define NO_HMAC
|
#define NO_HMAC
|
||||||
#define WC_NO_RNG
|
#define WC_NO_RNG
|
||||||
#define WC_NO_HASHDRBG
|
#define WC_NO_HASHDRBG
|
||||||
|
|
|
@ -209,6 +209,7 @@ extern "C" {
|
||||||
|
|
||||||
#endif /* defined WOLFBOOT */
|
#endif /* defined WOLFBOOT */
|
||||||
|
|
||||||
|
|
||||||
#define PART_BOOT 0
|
#define PART_BOOT 0
|
||||||
#define PART_UPDATE 1
|
#define PART_UPDATE 1
|
||||||
#define PART_SWAP 2
|
#define PART_SWAP 2
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5b7e50a19c79ef51530df6f32912c60490336fb4
|
Subproject commit 50bfac48a970a61afa1463ec6514bf9b404830cb
|
|
@ -1 +1 @@
|
||||||
Subproject commit 05b692d01cb2fa172d8a86e04a1dbbdb5eb88703
|
Subproject commit cd02d5140fccd2478dcd4845d1b7cef6be881dde
|
38
options.mk
38
options.mk
|
@ -1,3 +1,8 @@
|
||||||
|
ifeq ($(WOLFBOOT_TPM_VERIFY),1)
|
||||||
|
WOLFTPM:=1
|
||||||
|
CFLAGS+=-D"WOLFBOOT_TPM_VERIFY"
|
||||||
|
endif
|
||||||
|
|
||||||
## Measured boot requires TPM to be present
|
## Measured boot requires TPM to be present
|
||||||
ifeq ($(MEASURED_BOOT),1)
|
ifeq ($(MEASURED_BOOT),1)
|
||||||
WOLFTPM:=1
|
WOLFTPM:=1
|
||||||
|
@ -7,15 +12,28 @@ endif
|
||||||
|
|
||||||
## TPM keystore
|
## TPM keystore
|
||||||
ifeq ($(WOLFBOOT_TPM_KEYSTORE),1)
|
ifeq ($(WOLFBOOT_TPM_KEYSTORE),1)
|
||||||
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/random.o
|
|
||||||
ifneq ($(WOLFBOOT_TPM_KEYSTORE_NV_INDEX),)
|
|
||||||
WOLFTPM:=1
|
WOLFTPM:=1
|
||||||
CFLAGS+=-DWOLFBOOT_TPM_KEYSTORE
|
CFLAGS+=-D"WOLFBOOT_TPM_KEYSTORE"
|
||||||
CFLAGS+=-DWOLFBOOT_TPM_KEYSTORE_NV_INDEX=$(WOLFBOOT_TPM_KEYSTORE_NV_INDEX)
|
ifneq ($(WOLFBOOT_TPM_KEYSTORE_AUTH),)
|
||||||
CFLAGS+=-DWOLFBOOT_TPM_KEYSTORE_AUTH='"$(WOLFBOOT_TPM_KEYSTORE_AUTH)"'
|
CFLAGS+=-DWOLFBOOT_TPM_KEYSTORE_AUTH='"$(WOLFBOOT_TPM_KEYSTORE_AUTH)"'
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(WOLFBOOT_TPM_KEYSTORE_NV_BASE),)
|
||||||
|
CFLAGS+=-D"WOLFBOOT_TPM_KEYSTORE_NV_BASE=$(WOLFBOOT_TPM_KEYSTORE_NV_BASE)"
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
## Sealing a secret into the TPM
|
||||||
|
ifeq ($(WOLFBOOT_TPM_SEAL),1)
|
||||||
|
WOLFTPM:=1
|
||||||
|
CFLAGS+=-D"WOLFBOOT_TPM_SEAL"
|
||||||
|
ifneq ($(WOLFBOOT_TPM_SEAL_NV_BASE),)
|
||||||
|
CFLAGS+=-D"WOLFBOOT_TPM_SEAL_NV_BASE=$(WOLFBOOT_TPM_SEAL_NV_BASE)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(POLICY_FILE),)
|
||||||
|
SIGN_OPTIONS+=--policy $(POLICY_FILE)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
## DSA Settings
|
## DSA Settings
|
||||||
ifeq ($(SIGN),NONE)
|
ifeq ($(SIGN),NONE)
|
||||||
|
@ -503,15 +521,16 @@ ifeq ($(WOLFBOOT_HUGE_STACK),1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(WOLFTPM),1)
|
ifeq ($(WOLFTPM),1)
|
||||||
OBJS += lib/wolfTPM/src/tpm2.o \
|
OBJS+=\
|
||||||
|
./src/tpm.o \
|
||||||
|
lib/wolfTPM/src/tpm2.o \
|
||||||
lib/wolfTPM/src/tpm2_packet.o \
|
lib/wolfTPM/src/tpm2_packet.o \
|
||||||
lib/wolfTPM/src/tpm2_tis.o \
|
lib/wolfTPM/src/tpm2_tis.o \
|
||||||
lib/wolfTPM/src/tpm2_wrap.o \
|
lib/wolfTPM/src/tpm2_wrap.o \
|
||||||
lib/wolfTPM/src/tpm2_param_enc.o
|
lib/wolfTPM/src/tpm2_param_enc.o
|
||||||
CFLAGS+=-D"WOLFBOOT_TPM" -D"SIZEOF_LONG=4" -Ilib/wolfTPM \
|
CFLAGS+=-Ilib/wolfTPM
|
||||||
-D"MAX_COMMAND_SIZE=1024" -D"MAX_RESPONSE_SIZE=1024" -D"WOLFTPM2_MAX_BUFFER=1500" \
|
CFLAGS+=-D"WOLFBOOT_TPM"
|
||||||
-D"MAX_SESSION_NUM=2" -D"MAX_DIGEST_BUFFER=973" \
|
CFLAGS+=-D"WOLFTPM_SMALL_STACK"
|
||||||
-D"WOLFTPM_SMALL_STACK"
|
|
||||||
CFLAGS+=-D"WOLFTPM_AUTODETECT"
|
CFLAGS+=-D"WOLFTPM_AUTODETECT"
|
||||||
ifneq ($(SPI_FLASH),1)
|
ifneq ($(SPI_FLASH),1)
|
||||||
# don't use spi if we're using simulator
|
# don't use spi if we're using simulator
|
||||||
|
@ -534,6 +553,7 @@ ifeq ($(WOLFTPM),1)
|
||||||
endif
|
endif
|
||||||
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/aes.o
|
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/aes.o
|
||||||
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/hmac.o
|
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/hmac.o
|
||||||
|
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/random.o
|
||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
CFLAGS+=-DWOLFBOOT_DEBUG_TPM=1
|
CFLAGS+=-DWOLFBOOT_DEBUG_TPM=1
|
||||||
endif
|
endif
|
||||||
|
|
503
src/image.c
503
src/image.c
|
@ -25,45 +25,24 @@
|
||||||
*/
|
*/
|
||||||
#ifndef IMAGE_H_
|
#ifndef IMAGE_H_
|
||||||
#define IMAGE_H_
|
#define IMAGE_H_
|
||||||
|
|
||||||
|
#include <wolfssl/wolfcrypt/settings.h> /* for wolfCrypt hash/sign routines */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "spi_drv.h"
|
#include "spi_drv.h"
|
||||||
#include <stddef.h>
|
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
#include <wolfssl/wolfcrypt/settings.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM
|
#ifdef WOLFBOOT_TPM
|
||||||
#include <stdlib.h>
|
#include "tpm.h"
|
||||||
#include "wolftpm/tpm2.h"
|
|
||||||
#include "wolftpm/tpm2_wrap.h"
|
|
||||||
#include "wolftpm/tpm2_tis.h" /* for TIS header size and wait state */
|
|
||||||
static WOLFTPM2_DEV wolftpm_dev;
|
|
||||||
#ifdef WOLFBOOT_TPM_KEYSTORE
|
|
||||||
static WOLFTPM2_SESSION wolftpm_session;
|
|
||||||
static WOLFTPM2_KEY wolftpm_srk;
|
|
||||||
#endif
|
|
||||||
#endif /* WOLFBOOT_TPM */
|
|
||||||
|
|
||||||
#if defined(WOLFBOOT_TPM_KEYSTORE) && !defined(WOLFBOOT_TPM)
|
|
||||||
#error For TPM keystore please make sure WOLFBOOT_TPM is also defined
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
static uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE];
|
static uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE];
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
/**
|
|
||||||
* @brief Find the key slot ID based on the SHA hash of the key.
|
|
||||||
*
|
|
||||||
* @param hint The SHA hash to find the key slot ID for.
|
|
||||||
* @return The key slot ID corresponding to the provided SHA hash.
|
|
||||||
*/
|
|
||||||
static int keyslot_id_by_sha(const uint8_t *hint);
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_SIGN_ED25519
|
#ifdef WOLFBOOT_SIGN_ED25519
|
||||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||||
|
@ -144,7 +123,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
||||||
int pubkey_sz = keystore_get_size(key_slot);
|
int pubkey_sz = keystore_get_size(key_slot);
|
||||||
int point_sz = pubkey_sz/2;
|
int point_sz = pubkey_sz/2;
|
||||||
#ifdef WOLFBOOT_TPM
|
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)
|
||||||
WOLFTPM2_KEY tpmKey;
|
WOLFTPM2_KEY tpmKey;
|
||||||
#else
|
#else
|
||||||
ecc_key ecc;
|
ecc_key ecc;
|
||||||
|
@ -155,7 +134,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM
|
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)
|
||||||
/* Use TPM for ECC verify */
|
/* Use TPM for ECC verify */
|
||||||
/* Load public key into TPM */
|
/* Load public key into TPM */
|
||||||
memset(&tpmKey, 0, sizeof(tpmKey));
|
memset(&tpmKey, 0, sizeof(tpmKey));
|
||||||
|
@ -203,10 +182,10 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
}
|
}
|
||||||
wc_ecc_free(&ecc);
|
wc_ecc_free(&ecc);
|
||||||
}
|
}
|
||||||
#endif /* WOLFBOOT_TPM */
|
#endif /* WOLFBOOT_TPM && WOLFBOOT_TPM_VERIFY*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WOLFBOOT_SIGN_ECC256 */
|
#endif /* WOLFBOOT_SIGN_ECC256 || WOLFBOOT_SIGN_ECC384 || WOLFBOOT_SIGN_ECC521 */
|
||||||
|
|
||||||
|
|
||||||
#if defined(WOLFBOOT_SIGN_RSA2048) || \
|
#if defined(WOLFBOOT_SIGN_RSA2048) || \
|
||||||
|
@ -268,7 +247,7 @@ static int RsaDecodeSignature(uint8_t** pInput, int inputSz)
|
||||||
}
|
}
|
||||||
#endif /* !NO_RSA_SIG_ENCODING */
|
#endif /* !NO_RSA_SIG_ENCODING */
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM
|
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)
|
||||||
/* RSA PKCSV15 un-padding with RSA_BLOCK_TYPE_1 (public) */
|
/* RSA PKCSV15 un-padding with RSA_BLOCK_TYPE_1 (public) */
|
||||||
/* UnPad plaintext, set start to *output, return length of plaintext or error */
|
/* UnPad plaintext, set start to *output, return length of plaintext or error */
|
||||||
static int RsaUnPad(const byte *pkcsBlock, int pkcsBlockLen, byte **output)
|
static int RsaUnPad(const byte *pkcsBlock, int pkcsBlockLen, byte **output)
|
||||||
|
@ -291,7 +270,7 @@ static int RsaUnPad(const byte *pkcsBlock, int pkcsBlockLen, byte **output)
|
||||||
ret = pkcsBlockLen - i;
|
ret = pkcsBlockLen - i;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* WOLFBOOT_TPM */
|
#endif /* WOLFBOOT_TPM && WOLFBOOT_TPM_VERIFY*/
|
||||||
|
|
||||||
static void wolfBoot_verify_signature(uint8_t key_slot,
|
static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
struct wolfBoot_image *img, uint8_t *sig)
|
struct wolfBoot_image *img, uint8_t *sig)
|
||||||
|
@ -303,7 +282,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
||||||
int pubkey_sz = keystore_get_size(key_slot);
|
int pubkey_sz = keystore_get_size(key_slot);
|
||||||
word32 inOutIdx = 0;
|
word32 inOutIdx = 0;
|
||||||
#ifdef WOLFBOOT_TPM
|
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)
|
||||||
WOLFTPM2_KEY tpmKey;
|
WOLFTPM2_KEY tpmKey;
|
||||||
const byte *n = NULL, *e = NULL;
|
const byte *n = NULL, *e = NULL;
|
||||||
word32 nSz = 0, eSz = 0;
|
word32 nSz = 0, eSz = 0;
|
||||||
|
@ -315,7 +294,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM
|
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY)
|
||||||
/* Extract DER RSA key struct */
|
/* Extract DER RSA key struct */
|
||||||
memset(&tpmKey, 0, sizeof(tpmKey));
|
memset(&tpmKey, 0, sizeof(tpmKey));
|
||||||
ret = wc_RsaPublicKeyDecode_ex(pubkey, &inOutIdx, pubkey_sz,
|
ret = wc_RsaPublicKeyDecode_ex(pubkey, &inOutIdx, pubkey_sz,
|
||||||
|
@ -378,7 +357,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
|
||||||
}
|
}
|
||||||
#endif /* SCE || TSIP */
|
#endif /* SCE || TSIP */
|
||||||
wc_FreeRsaKey(&rsa);
|
wc_FreeRsaKey(&rsa);
|
||||||
#endif /* WOLFBOOT_TPM */
|
#endif /* WOLFBOOT_TPM && WOLFBOOT_TPM_VERIFY*/
|
||||||
|
|
||||||
#ifndef NO_RSA_SIG_ENCODING
|
#ifndef NO_RSA_SIG_ENCODING
|
||||||
if (ret > WOLFBOOT_SHA_DIGEST_SIZE) {
|
if (ret > WOLFBOOT_SHA_DIGEST_SIZE) {
|
||||||
|
@ -480,7 +459,8 @@ static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type,
|
||||||
* @param ptr A pointer to store the position of the header.
|
* @param ptr A pointer to store the position of the header.
|
||||||
* @return The size of the data if found, otherwise 0.
|
* @return The size of the data if found, otherwise 0.
|
||||||
*/
|
*/
|
||||||
static uint16_t get_header(struct wolfBoot_image *img, uint16_t type,
|
#define get_header wolfBoot_get_header /* internal reference to function */
|
||||||
|
uint16_t wolfBoot_get_header(struct wolfBoot_image *img, uint16_t type,
|
||||||
uint8_t **ptr)
|
uint8_t **ptr)
|
||||||
{
|
{
|
||||||
if (PART_IS_EXT(img))
|
if (PART_IS_EXT(img))
|
||||||
|
@ -560,36 +540,6 @@ static uint8_t *get_img_hdr(struct wolfBoot_image *img)
|
||||||
#if defined(WOLFBOOT_HASH_SHA256)
|
#if defined(WOLFBOOT_HASH_SHA256)
|
||||||
#include <wolfssl/wolfcrypt/sha256.h>
|
#include <wolfssl/wolfcrypt/sha256.h>
|
||||||
|
|
||||||
#ifdef WOLFBOOT_MEASURED_BOOT
|
|
||||||
static int self_sha256(uint8_t *hash)
|
|
||||||
{
|
|
||||||
uintptr_t p = (uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
|
||||||
uint32_t sz = (uint32_t)WOLFBOOT_PARTITION_SIZE;
|
|
||||||
uint32_t blksz, position = 0;
|
|
||||||
wc_Sha256 sha256_ctx;
|
|
||||||
|
|
||||||
wc_InitSha256(&sha256_ctx);
|
|
||||||
do {
|
|
||||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
|
||||||
if (position + blksz > sz)
|
|
||||||
blksz = sz - position;
|
|
||||||
#if defined(EXT_FLASH) && defined(NO_XIP)
|
|
||||||
rc = ext_flash_read(p, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE);
|
|
||||||
if (rc != WOLFBOOT_SHA_BLOCK_SIZE)
|
|
||||||
return -1;
|
|
||||||
wc_Sha256Update(&sha256_ctx, ext_hash_block, blksz);
|
|
||||||
#else
|
|
||||||
wc_Sha256Update(&sha256_ctx, (uint8_t*)p, blksz);
|
|
||||||
#endif
|
|
||||||
position += blksz;
|
|
||||||
p += blksz;
|
|
||||||
} while (position < sz);
|
|
||||||
wc_Sha256Final(&sha256_ctx, hash);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* WOLFBOOT_MEASURED_BOOT */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate the SHA256 hash of the image.
|
* @brief Calculate the SHA256 hash of the image.
|
||||||
*
|
*
|
||||||
|
@ -672,36 +622,6 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash)
|
||||||
#if defined(WOLFBOOT_HASH_SHA384)
|
#if defined(WOLFBOOT_HASH_SHA384)
|
||||||
#include <wolfssl/wolfcrypt/sha512.h>
|
#include <wolfssl/wolfcrypt/sha512.h>
|
||||||
|
|
||||||
#ifdef WOLFBOOT_MEASURED_BOOT
|
|
||||||
static int self_sha384(uint8_t *hash)
|
|
||||||
{
|
|
||||||
uintptr_t p = (uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
|
||||||
uint32_t sz = (uint32_t)WOLFBOOT_PARTITION_SIZE;
|
|
||||||
uint32_t blksz, position = 0;
|
|
||||||
wc_Sha384 sha384_ctx;
|
|
||||||
|
|
||||||
wc_InitSha384(&sha384_ctx);
|
|
||||||
do {
|
|
||||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
|
||||||
if (position + blksz > sz)
|
|
||||||
blksz = sz - position;
|
|
||||||
#if defined(EXT_FLASH) && defined(NO_XIP)
|
|
||||||
rc = ext_flash_read(p, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE);
|
|
||||||
if (rc != WOLFBOOT_SHA_BLOCK_SIZE)
|
|
||||||
return -1;
|
|
||||||
wc_Sha384Update(&sha384_ctx, ext_hash_block, blksz);
|
|
||||||
#else
|
|
||||||
wc_Sha384Update(&sha384_ctx, (uint8_t*)p, blksz);
|
|
||||||
#endif
|
|
||||||
position += blksz;
|
|
||||||
p += blksz;
|
|
||||||
} while (position < sz);
|
|
||||||
wc_Sha384Final(&sha384_ctx, hash);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* WOLFBOOT_MEASURED_BOOT */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate SHA-384 hash of the image.
|
* @brief Calculate SHA-384 hash of the image.
|
||||||
*
|
*
|
||||||
|
@ -876,340 +796,6 @@ static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
|
||||||
#endif /* WOLFBOOT_NO_SIGN */
|
#endif /* WOLFBOOT_NO_SIGN */
|
||||||
#endif /* SHA3-384 */
|
#endif /* SHA3-384 */
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM
|
|
||||||
#if defined(DEBUG_WOLFTPM) || defined(WOLFTPM_DEBUG_IO) || \
|
|
||||||
defined(WOLFBOOT_DEBUG_TPM)
|
|
||||||
#define LINE_LEN 16
|
|
||||||
static void wolfBoot_PrintBin(const byte* buffer, word32 length)
|
|
||||||
{
|
|
||||||
word32 i, sz;
|
|
||||||
|
|
||||||
if (!buffer) {
|
|
||||||
wolfBoot_printf("\tNULL\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (length > 0) {
|
|
||||||
sz = length;
|
|
||||||
if (sz > LINE_LEN)
|
|
||||||
sz = LINE_LEN;
|
|
||||||
|
|
||||||
wolfBoot_printf("\t");
|
|
||||||
for (i = 0; i < LINE_LEN; i++) {
|
|
||||||
if (i < length)
|
|
||||||
wolfBoot_printf("%02x ", buffer[i]);
|
|
||||||
else
|
|
||||||
wolfBoot_printf(" ");
|
|
||||||
}
|
|
||||||
wolfBoot_printf("| ");
|
|
||||||
for (i = 0; i < sz; i++) {
|
|
||||||
if (buffer[i] > 31 && buffer[i] < 127)
|
|
||||||
wolfBoot_printf("%c", buffer[i]);
|
|
||||||
else
|
|
||||||
wolfBoot_printf(".");
|
|
||||||
}
|
|
||||||
wolfBoot_printf("\r\n");
|
|
||||||
|
|
||||||
buffer += sz;
|
|
||||||
length -= sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WOLFTPM_DEBUG_IO || WOLFBOOT_DEBUG_TPM */
|
|
||||||
|
|
||||||
#if !defined(ARCH_SIM) && !defined(WOLFTPM_MMIO)
|
|
||||||
#ifdef WOLFTPM_ADV_IO
|
|
||||||
static int TPM2_IoCb(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf,
|
|
||||||
word16 size, void* userCtx)
|
|
||||||
#else
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TPM2 I/O callback function for communication with TPM2 device.
|
|
||||||
*
|
|
||||||
* This function is used as the I/O callback function for communication
|
|
||||||
* with the TPM2 device. It is called during TPM operations to send and
|
|
||||||
* receive data from the TPM2 device.
|
|
||||||
*
|
|
||||||
* @param ctx The pointer to the TPM2 context.
|
|
||||||
* @param txBuf The buffer containing data to be sent to the TPM2 device.
|
|
||||||
* @param rxBuf The buffer to store the received data from the TPM2 device.
|
|
||||||
* @param xferSz The size of the data to be transferred.
|
|
||||||
* @param userCtx The user context (not used in this implementation).
|
|
||||||
* @return The return code from the TPM2 device operation.
|
|
||||||
*/
|
|
||||||
static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
|
||||||
word16 xferSz, void* userCtx)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
#ifdef WOLFTPM_CHECK_WAIT_STATE
|
|
||||||
int timeout = TPM_SPI_WAIT_RETRY;
|
|
||||||
#endif
|
|
||||||
#ifdef WOLFTPM_ADV_IO
|
|
||||||
byte txBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
|
||||||
byte rxBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
|
|
||||||
int xferSz = TPM_TIS_HEADER_SZ + size;
|
|
||||||
|
|
||||||
#ifdef WOLFTPM_DEBUG_IO
|
|
||||||
wolfBoot_printf("TPM2_IoCb (Adv): Read %d, Addr %x, Size %d\n",
|
|
||||||
isRead ? 1 : 0, addr, size);
|
|
||||||
if (!isRead) {
|
|
||||||
wolfBoot_PrintBin(buf, size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Build TPM header */
|
|
||||||
txBuf[1] = (addr>>16) & 0xFF;
|
|
||||||
txBuf[2] = (addr>>8) & 0xFF;
|
|
||||||
txBuf[3] = (addr) & 0xFF;
|
|
||||||
if (isRead) {
|
|
||||||
txBuf[0] = TPM_TIS_READ | ((size & 0xFF) - 1);
|
|
||||||
memset(&txBuf[TPM_TIS_HEADER_SZ], 0, size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
txBuf[0] = TPM_TIS_WRITE | ((size & 0xFF) - 1);
|
|
||||||
memcpy(&txBuf[TPM_TIS_HEADER_SZ], buf, size);
|
|
||||||
}
|
|
||||||
memset(rxBuf, 0, sizeof(rxBuf));
|
|
||||||
#endif /* WOLFTPM_ADV_IO */
|
|
||||||
|
|
||||||
#ifdef WOLFTPM_CHECK_WAIT_STATE /* Handle TIS wait states */
|
|
||||||
/* Send header - leave CS asserted */
|
|
||||||
ret = spi_xfer(SPI_CS_TPM, txBuf, rxBuf, TPM_TIS_HEADER_SZ,
|
|
||||||
0x1 /* 1=SPI_XFER_FLAG_CONTINUE */
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Handle wait states */
|
|
||||||
while (ret == 0 &&
|
|
||||||
--timeout > 0 &&
|
|
||||||
(rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0)
|
|
||||||
{
|
|
||||||
/* clock additional byte until 0x01 LSB is set (keep CS asserted) */
|
|
||||||
ret = spi_xfer(SPI_CS_TPM,
|
|
||||||
&txBuf[TPM_TIS_HEADER_SZ-1],
|
|
||||||
&rxBuf[TPM_TIS_HEADER_SZ-1], 1,
|
|
||||||
0x1 /* 1=SPI_XFER_FLAG_CONTINUE */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* Check for timeout */
|
|
||||||
if (ret == 0 && timeout <= 0) {
|
|
||||||
ret = TPM_RC_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Transfer remainder of payload (command / response) */
|
|
||||||
if (ret == 0) {
|
|
||||||
ret = spi_xfer(SPI_CS_TPM,
|
|
||||||
&txBuf[TPM_TIS_HEADER_SZ],
|
|
||||||
&rxBuf[TPM_TIS_HEADER_SZ],
|
|
||||||
xferSz-TPM_TIS_HEADER_SZ,
|
|
||||||
0 /* de-assert CS*/ );
|
|
||||||
}
|
|
||||||
/* On error make sure SPI is de-asserted */
|
|
||||||
else {
|
|
||||||
spi_xfer(SPI_CS_TPM, NULL, NULL, 0, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else /* Send Entire Message - no wait states */
|
|
||||||
ret = spi_xfer(SPI_CS_TPM, txBuf, rxBuf, xferSz, 0);
|
|
||||||
|
|
||||||
#ifdef WOLFTPM_DEBUG_IO
|
|
||||||
wolfBoot_printf("TPM2_IoCb: Ret %d, Sz %d\n", ret, xferSz);
|
|
||||||
wolfBoot_PrintBin(txBuf, xferSz);
|
|
||||||
wolfBoot_PrintBin(rxBuf, xferSz);
|
|
||||||
#endif
|
|
||||||
#endif /* !WOLFTPM_CHECK_WAIT_STATE */
|
|
||||||
|
|
||||||
#ifdef WOLFTPM_ADV_IO
|
|
||||||
if (isRead) {
|
|
||||||
memcpy(buf, &rxBuf[TPM_TIS_HEADER_SZ], size);
|
|
||||||
#ifdef WOLFTPM_DEBUG_IO
|
|
||||||
wolfBoot_PrintBin(buf, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif /* !ARCH_SIM && !WOLFTPM_MMIO */
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_MEASURED_BOOT
|
|
||||||
#define measure_boot(hash) wolfBoot_tpm2_extend((hash), __LINE__)
|
|
||||||
/**
|
|
||||||
* @brief Extends a PCR in the TPM with a hash.
|
|
||||||
*
|
|
||||||
* Extends a specified PCR's value in the TPM with a given hash. Uses
|
|
||||||
* TPM2_PCR_Extend. Optionally, if DEBUG_WOLFTPM or WOLFBOOT_DEBUG_TPM defined,
|
|
||||||
* prints debug info.
|
|
||||||
*
|
|
||||||
* @param[in] hash Pointer to the hash value to extend into the PCR.
|
|
||||||
* @param[in] line Line number where the function is called (for debugging).
|
|
||||||
* @return 0 on success, an error code on failure.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static int wolfBoot_tpm2_extend(uint8_t* hash, int line)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
PCR_Extend_In pcrExtend;
|
|
||||||
#ifdef WOLFBOOT_DEBUG_TPM
|
|
||||||
PCR_Read_In pcrReadCmd;
|
|
||||||
PCR_Read_Out pcrReadResp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pcrExtend.pcrHandle = WOLFBOOT_MEASURED_PCR_A;
|
|
||||||
pcrExtend.digests.count = 1;
|
|
||||||
pcrExtend.digests.digests[0].hashAlg = TPM_ALG_SHA256;
|
|
||||||
XMEMCPY(pcrExtend.digests.digests[0].digest.H,
|
|
||||||
hash, TPM_SHA256_DIGEST_SIZE);
|
|
||||||
|
|
||||||
rc = TPM2_PCR_Extend(&pcrExtend);
|
|
||||||
#ifdef DEBUG_WOLFTPM
|
|
||||||
wolfBoot_printf("Measured boot: Res %d, Index %d, Line %d\n",
|
|
||||||
rc, pcrExtend.pcrHandle, line);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_DEBUG_TPM
|
|
||||||
if (rc == 0) {
|
|
||||||
memset(&pcrReadCmd, 0, sizeof(pcrReadCmd));
|
|
||||||
memset(&pcrReadResp, 0, sizeof(pcrReadResp));
|
|
||||||
TPM2_SetupPCRSel(&pcrReadCmd.pcrSelectionIn, TPM_ALG_SHA256,
|
|
||||||
pcrExtend.pcrHandle);
|
|
||||||
rc = TPM2_PCR_Read(&pcrReadCmd, &pcrReadResp);
|
|
||||||
|
|
||||||
wolfBoot_printf("PCR %d: Res %d, Digest Sz %d, Update Counter %d\n",
|
|
||||||
pcrExtend.pcrHandle, rc,
|
|
||||||
(int)pcrReadResp.pcrValues.digests[0].size,
|
|
||||||
(int)pcrReadResp.pcrUpdateCounter);
|
|
||||||
wolfBoot_PrintBin(pcrReadResp.pcrValues.digests[0].buffer,
|
|
||||||
pcrReadResp.pcrValues.digests[0].size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
(void)line;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif /* WOLFBOOT_MEASURED_BOOT */
|
|
||||||
|
|
||||||
#if defined(WOLFBOOT_TPM_KEYSTORE) && defined(WC_RNG_SEED_CB)
|
|
||||||
static int wolfRNG_GetSeedCB(OS_Seed* os, byte* seed, word32 sz)
|
|
||||||
{
|
|
||||||
(void)os;
|
|
||||||
return wolfTPM2_GetRandom(&wolftpm_dev, seed, sz);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the TPM2 device and retrieve its capabilities.
|
|
||||||
*
|
|
||||||
* This function initializes the TPM2 device and retrieves its capabilities.
|
|
||||||
*
|
|
||||||
* @return 0 on success, an error code on failure.
|
|
||||||
*/
|
|
||||||
int wolfBoot_tpm2_init(void)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
word32 idx;
|
|
||||||
WOLFTPM2_CAPS caps;
|
|
||||||
#ifdef WOLFBOOT_TPM_KEYSTORE
|
|
||||||
TPM_ALG_ID alg;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(ARCH_SIM) && !defined(WOLFTPM_MMIO)
|
|
||||||
spi_init(0,0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Init the TPM2 device */
|
|
||||||
/* simulator should use the network connection, not spi */
|
|
||||||
#if defined(ARCH_SIM) || defined(WOLFTPM_MMIO)
|
|
||||||
rc = wolfTPM2_Init(&wolftpm_dev, NULL, NULL);
|
|
||||||
#else
|
|
||||||
rc = wolfTPM2_Init(&wolftpm_dev, TPM2_IoCb, NULL);
|
|
||||||
#endif
|
|
||||||
if (rc == 0) {
|
|
||||||
/* Get device capabilities + options */
|
|
||||||
rc = wolfTPM2_GetCapabilities(&wolftpm_dev, &caps);
|
|
||||||
}
|
|
||||||
if (rc == 0) {
|
|
||||||
wolfBoot_printf("Mfg %s (%d), Vendor %s, Fw %u.%u (0x%x), "
|
|
||||||
"FIPS 140-2 %d, CC-EAL4 %d\n",
|
|
||||||
caps.mfgStr, caps.mfg, caps.vendorStr, caps.fwVerMajor,
|
|
||||||
caps.fwVerMinor, caps.fwVerVendor, caps.fips140_2, caps.cc_eal4);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
wolfBoot_printf("TPM Init failed! %d\n", rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM_KEYSTORE
|
|
||||||
memset(&wolftpm_session, 0, sizeof(wolftpm_session));
|
|
||||||
|
|
||||||
#ifdef WC_RNG_SEED_CB
|
|
||||||
/* setup callback for RNG seed to use TPM */
|
|
||||||
wc_SetSeed_Cb(wolfRNG_GetSeedCB);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Create a primary storage key - no auth (used for parameter encryption) */
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
alg = TPM_ALG_ECC;
|
|
||||||
#elif !defined(NO_RSA)
|
|
||||||
alg = TPM_ALG_RSA;
|
|
||||||
#else
|
|
||||||
alg = TPM_ALG_NULL;
|
|
||||||
#endif
|
|
||||||
rc = wolfTPM2_CreateSRK(&wolftpm_dev, &wolftpm_srk, alg, NULL, 0);
|
|
||||||
if (rc == 0) {
|
|
||||||
/* Setup a TPM session that can be used for parameter encryption */
|
|
||||||
rc = wolfTPM2_StartSession(&wolftpm_dev, &wolftpm_session, &wolftpm_srk,
|
|
||||||
NULL, TPM_SE_HMAC, TPM_ALG_CFB);
|
|
||||||
}
|
|
||||||
if (rc != 0) {
|
|
||||||
wolfBoot_printf("TPM Create SRK or Start Session error %d (%s)!\n",
|
|
||||||
rc, wolfTPM2_GetRCString(rc));
|
|
||||||
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
|
|
||||||
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_srk.handle);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_MEASURED_BOOT
|
|
||||||
/* hash wolfBoot and extend PCR */
|
|
||||||
rc = self_hash(digest);
|
|
||||||
if (rc == 0) {
|
|
||||||
rc = measure_boot(digest);
|
|
||||||
}
|
|
||||||
if (rc != 0) {
|
|
||||||
wolfBoot_printf("Error %d performing wolfBoot measurement!\n", rc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize the TPM2 device.
|
|
||||||
*
|
|
||||||
* This function deinitializes the TPM2 device and cleans up any resources.
|
|
||||||
*
|
|
||||||
* @return None.
|
|
||||||
*/
|
|
||||||
void wolfBoot_tpm2_deinit(void)
|
|
||||||
{
|
|
||||||
#ifdef WOLFBOOT_TPM_KEYSTORE
|
|
||||||
#if !defined(ARCH_SIM) && !defined(WOLFBOOT_TPM_NO_CHG_PLAT_AUTH)
|
|
||||||
/* Change platform auth to random value, to prevent application from being
|
|
||||||
* able to use platform hierarchy. This is defined in section 10 of the
|
|
||||||
* TCG PC Client Platform specification.
|
|
||||||
*/
|
|
||||||
int rc = wolfTPM2_ChangePlatformAuth(&wolftpm_dev, &wolftpm_session);
|
|
||||||
if (rc != 0) {
|
|
||||||
wolfBoot_printf("Error %d setting platform auth\n", rc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
|
|
||||||
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_srk.handle);
|
|
||||||
#endif /* WOLFBOOT_TPM_KEYSTORE */
|
|
||||||
|
|
||||||
wolfTPM2_Cleanup(&wolftpm_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WOLFBOOT_TPM */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert a 32-bit integer from little-endian to native byte order.
|
* @brief Convert a 32-bit integer from little-endian to native byte order.
|
||||||
*
|
*
|
||||||
|
@ -1482,8 +1068,15 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
|
||||||
if (key_slot < 0) {
|
if (key_slot < 0) {
|
||||||
return -1; /* Key was not found */
|
return -1; /* Key was not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_TPM_KEYSTORE
|
||||||
|
if (wolfBoot_check_rot(key_slot, pubkey_hint) != 0) {
|
||||||
|
return -1; /* TPM root of trust failed! */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return -1; /* Invalid hash size for public key hint */
|
return -1; /* Invalid hash size for public key hint */
|
||||||
}
|
}
|
||||||
image_type_size = get_header(img, HDR_IMG_TYPE, &image_type_buf);
|
image_type_size = get_header(img, HDR_IMG_TYPE, &image_type_buf);
|
||||||
|
@ -1501,8 +1094,9 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
|
||||||
image_part = image_type & HDR_IMG_TYPE_PART_MASK;
|
image_part = image_type & HDR_IMG_TYPE_PART_MASK;
|
||||||
|
|
||||||
/* Check if the key permission mask matches the current partition id */
|
/* Check if the key permission mask matches the current partition id */
|
||||||
if (((1U << image_part) & key_mask) != (1U << image_part))
|
if (((1U << image_part) & key_mask) != (1U << image_part)) {
|
||||||
return -1; /* Key not allowed to verify this partition id */
|
return -1; /* Key not allowed to verify this partition id */
|
||||||
|
}
|
||||||
|
|
||||||
CONFIRM_MASK_VALID(image_part, key_mask);
|
CONFIRM_MASK_VALID(image_part, key_mask);
|
||||||
|
|
||||||
|
@ -1552,51 +1146,22 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
|
||||||
* @param hint The SHA hash of the public key to search for.
|
* @param hint The SHA hash of the public key to search for.
|
||||||
* @return The key slot ID if found, -1 if the key was not found.
|
* @return The key slot ID if found, -1 if the key was not found.
|
||||||
*/
|
*/
|
||||||
static int keyslot_id_by_sha(const uint8_t *hint)
|
int keyslot_id_by_sha(const uint8_t *hint)
|
||||||
{
|
{
|
||||||
|
int id;
|
||||||
#ifdef STAGE1_AUTH
|
#ifdef STAGE1_AUTH
|
||||||
/* Override global */
|
/* Override global */
|
||||||
uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE];
|
uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_KEYSTORE)
|
|
||||||
/* use public key hash (hint) */
|
|
||||||
int rc;
|
|
||||||
WOLFTPM2_NV nv;
|
|
||||||
word32 digestSz = (word32)TPM2_GetHashDigestSize(WOLFBOOT_TPM_HASH_ALG);
|
|
||||||
XMEMSET(&nv, 0, sizeof(nv));
|
|
||||||
nv.handle.hndl = WOLFBOOT_TPM_KEYSTORE_NV_INDEX;
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_TPM_KEYSTORE_AUTH
|
|
||||||
nv.handle.auth.size = (UINT16)strlen(WOLFBOOT_TPM_KEYSTORE_AUTH);
|
|
||||||
memcpy(nv.handle.auth.buffer, WOLFBOOT_TPM_KEYSTORE_AUTH, nv.handle.auth.size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rc = wolfTPM2_NVReadAuth(&wolftpm_dev, &nv, WOLFBOOT_TPM_KEYSTORE_NV_INDEX,
|
|
||||||
digest, &digestSz, 0);
|
|
||||||
if (rc == 0 && memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0) {
|
|
||||||
#ifdef DEBUG_WOLFTPM
|
|
||||||
wolfBoot_printf("TPM Root of Trust valid\n");
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef DEBUG_WOLFTPM
|
|
||||||
wolfBoot_printf("TPM Root of Trust failed! %d (%s)\n",
|
|
||||||
rc, wolfTPM2_GetRCString(rc));
|
|
||||||
wolfBoot_printf("Expected Hash %d\n", WOLFBOOT_SHA_DIGEST_SIZE);
|
|
||||||
wolfBoot_PrintBin(hint, WOLFBOOT_SHA_DIGEST_SIZE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int id = 0;
|
|
||||||
for (id = 0; id < keystore_num_pubkeys(); id++) {
|
for (id = 0; id < keystore_num_pubkeys(); id++) {
|
||||||
key_hash(id, digest);
|
key_hash(id, digest);
|
||||||
if (memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0)
|
if (memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* !WOLFBOOT_NO_SIGN && !WOLFBOOT_RENESAS_SCEPROTECT */
|
||||||
|
|
||||||
#endif /* IMAGE_H_ */
|
#endif /* IMAGE_H_ */
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
#include "uart_flash.h"
|
#include "uart_flash.h"
|
||||||
#include "wolfboot/wolfboot.h"
|
#include "wolfboot/wolfboot.h"
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_TPM
|
||||||
|
#include "tpm.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RAM_CODE
|
#ifdef RAM_CODE
|
||||||
/**
|
/**
|
||||||
* @brief Start address of the text section in RAM code.
|
* @brief Start address of the text section in RAM code.
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "wolfboot/wolfboot.h"
|
#include "wolfboot/wolfboot.h"
|
||||||
#include "delta.h"
|
#include "delta.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
#include "tpm.h"
|
||||||
|
|
||||||
#ifdef RAM_CODE
|
#ifdef RAM_CODE
|
||||||
extern unsigned int _start_text;
|
extern unsigned int _start_text;
|
||||||
|
@ -568,11 +568,89 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(ARCH_SIM) && defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_SEAL)
|
||||||
|
int wolfBoot_unlock_disk(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct wolfBoot_image img;
|
||||||
|
WOLFTPM2_KEYBLOB seal_blob;
|
||||||
|
uint8_t secret[WOLFBOOT_MAX_SEAL_SZ];
|
||||||
|
int secretSz;
|
||||||
|
uint8_t* policy = NULL;
|
||||||
|
uint16_t policySz = 0;
|
||||||
|
|
||||||
|
memset(&seal_blob, 0, sizeof(seal_blob));
|
||||||
|
memset(secret, 0, sizeof(secret));
|
||||||
|
|
||||||
|
wolfBoot_printf("Unlocking disk...\n");
|
||||||
|
|
||||||
|
/* check policy */
|
||||||
|
ret = wolfBoot_open_image(&img, PART_BOOT);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wolfBoot_get_policy(&img, &policy, &policySz);
|
||||||
|
if (ret == -TPM_RC_POLICY_FAIL) {
|
||||||
|
/* the image is not signed with a policy */
|
||||||
|
wolfBoot_printf("Image policy signature missing!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
/* for testing seal and unseal */
|
||||||
|
/* create secret to seal */
|
||||||
|
secretSz = 32;
|
||||||
|
ret = wolfBoot_get_random(secret, secretSz);
|
||||||
|
if (ret == 0) {
|
||||||
|
wolfBoot_printf("Sealing %d bytes\n", secretSz);
|
||||||
|
wolfBoot_print_hexstr(secret, secretSz, 0);
|
||||||
|
|
||||||
|
/* seal new secret */
|
||||||
|
ret = wolfBoot_seal_blob(&img, &seal_blob, secret, secretSz);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
uint8_t secretCheck[WOLFBOOT_MAX_SEAL_SZ];
|
||||||
|
int secretCheckSz = 0;
|
||||||
|
|
||||||
|
/* unseal again to make sure it works */
|
||||||
|
memset(secretCheck, 0, sizeof(secretCheck));
|
||||||
|
ret = wolfBoot_unseal_blob(&img, &seal_blob, secretCheck, &secretCheckSz);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (secretSz != secretCheckSz || memcmp(secret, secretCheck, secretSz) != 0) {
|
||||||
|
wolfBoot_printf("secret check mismatch!\n");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wolfBoot_printf("Unsealed %d bytes\n", secretCheckSz);
|
||||||
|
wolfBoot_print_hexstr(secretCheck, secretCheckSz, 0);
|
||||||
|
TPM2_ForceZero(secretCheck, sizeof(secretCheck));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
/* TODO: Unlock disk */
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wolfBoot_printf("unlock disk failed! %d (%s)\n",
|
||||||
|
ret, wolfTPM2_GetRCString(ret));
|
||||||
|
}
|
||||||
|
TPM2_ForceZero(secret, sizeof(secretSz));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void RAMFUNCTION wolfBoot_start(void)
|
void RAMFUNCTION wolfBoot_start(void)
|
||||||
{
|
{
|
||||||
uint8_t st;
|
uint8_t st;
|
||||||
struct wolfBoot_image boot;
|
struct wolfBoot_image boot;
|
||||||
|
|
||||||
|
#if defined(ARCH_SIM) && defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_SEAL)
|
||||||
|
wolfBoot_unlock_disk();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RAM_CODE
|
#ifdef RAM_CODE
|
||||||
wolfBoot_check_self_update();
|
wolfBoot_check_self_update();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,23 +44,21 @@ void hal_init(void);
|
||||||
|
|
||||||
int do_cmd(const char *cmd)
|
int do_cmd(const char *cmd)
|
||||||
{
|
{
|
||||||
if (strcmp(cmd, "powerfail") == 0)
|
if (strcmp(cmd, "powerfail") == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if (strcmp(cmd, "get_version") == 0) {
|
if (strcmp(cmd, "get_version") == 0) {
|
||||||
printf("%d\n", wolfBoot_current_firmware_version());
|
printf("%d\n", wolfBoot_current_firmware_version());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmd, "success") == 0) {
|
if (strcmp(cmd, "success") == 0) {
|
||||||
wolfBoot_success();
|
wolfBoot_success();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmd, "update_trigger") == 0) {
|
if (strcmp(cmd, "update_trigger") == 0) {
|
||||||
wolfBoot_update_trigger();
|
wolfBoot_update_trigger();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmd, "reset") == 0) {
|
if (strcmp(cmd, "reset") == 0) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,10 @@ ifeq ($(ARCH),)
|
||||||
PKA?=1
|
PKA?=1
|
||||||
PSOC6_CRYPTO?=1
|
PSOC6_CRYPTO?=1
|
||||||
WOLFTPM?=0
|
WOLFTPM?=0
|
||||||
|
WOLFBOOT_TPM_VERIFY?=0
|
||||||
|
MEASURED_BOOT?=0
|
||||||
|
WOLFBOOT_TPM_SEAL?=0
|
||||||
|
WOLFBOOT_TPM_KEYSTORE?=0
|
||||||
TZEN?=0
|
TZEN?=0
|
||||||
WOLFBOOT_PARTITION_SIZE?=0x20000
|
WOLFBOOT_PARTITION_SIZE?=0x20000
|
||||||
WOLFBOOT_SECTOR_SIZE?=0x20000
|
WOLFBOOT_SECTOR_SIZE?=0x20000
|
||||||
|
@ -73,7 +77,8 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
|
||||||
MCUXPRESSO_CMSIS FREEDOM_E_SDK STM32CUBE CYPRESS_PDL CYPRESS_CORE_LIB CYPRESS_TARGET_LIB DEBUG VTOR \
|
MCUXPRESSO_CMSIS FREEDOM_E_SDK STM32CUBE CYPRESS_PDL CYPRESS_CORE_LIB CYPRESS_TARGET_LIB DEBUG VTOR \
|
||||||
CORTEX_M0 CORTEX_M7 CORTEX_M33 NO_ASM EXT_FLASH SPI_FLASH NO_XIP UART_FLASH ALLOW_DOWNGRADE NVM_FLASH_WRITEONCE \
|
CORTEX_M0 CORTEX_M7 CORTEX_M33 NO_ASM EXT_FLASH SPI_FLASH NO_XIP UART_FLASH ALLOW_DOWNGRADE NVM_FLASH_WRITEONCE \
|
||||||
DISABLE_BACKUP WOLFBOOT_VERSION V NO_MPU ENCRYPT FLAGS_HOME FLAGS_INVERT \
|
DISABLE_BACKUP WOLFBOOT_VERSION V NO_MPU ENCRYPT FLAGS_HOME FLAGS_INVERT \
|
||||||
SPMATH SPMATHALL RAM_CODE DUALBANK_SWAP IMAGE_HEADER_SIZE PKA TZEN PSOC6_CRYPTO WOLFTPM \
|
SPMATH SPMATHALL RAM_CODE DUALBANK_SWAP IMAGE_HEADER_SIZE PKA TZEN PSOC6_CRYPTO \
|
||||||
|
WOLFTPM WOLFBOOT_TPM_VERIFY MEASURED_BOOT WOLFBOOT_TPM_SEAL WOLFBOOT_TPM_KEYSTORE \
|
||||||
WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \
|
WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \
|
||||||
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
|
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
|
||||||
WOLFBOOT_PARTITION_SWAP_ADDRESS WOLFBOOT_LOAD_ADDRESS \
|
WOLFBOOT_PARTITION_SWAP_ADDRESS WOLFBOOT_LOAD_ADDRESS \
|
||||||
|
@ -83,4 +88,3 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
|
||||||
ENCRYPT_WITH_CHACHA ENCRYPT_WITH_AES128 ENCRYPT_WITH_AES256 ARMORED \
|
ENCRYPT_WITH_CHACHA ENCRYPT_WITH_AES128 ENCRYPT_WITH_AES256 ARMORED \
|
||||||
LMS_LEVELS LMS_HEIGHT LMS_WINTERNITZ \
|
LMS_LEVELS LMS_HEIGHT LMS_WINTERNITZ \
|
||||||
ELF
|
ELF
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,13 @@ ifeq ($(SIGN),LMS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# option variables
|
# option variables
|
||||||
DEBUG_FLAGS = -g -DDEBUG -DDEBUG_SIGNTOOL -DDEBUG_WOLFSSL -DDEBUG_WOLFSSL_VERBOSE -fsanitize=address
|
DEBUG_FLAGS = -g -DDEBUG -DDEBUG_SIGNTOOL -DDEBUG_WOLFSSL -DDEBUG_WOLFSSL_VERBOSE
|
||||||
|
SANITIZE_FLAGS = -fsanitize=address
|
||||||
OPTIMIZE = -O2
|
OPTIMIZE = -O2
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
#CFLAGS+=$(DEBUG_FLAGS)
|
#CFLAGS+=$(DEBUG_FLAGS)
|
||||||
|
#CFLAGS+=$(SANITIZE_FLAGS)
|
||||||
CFLAGS+=$(OPTIMIZE)
|
CFLAGS+=$(OPTIMIZE)
|
||||||
|
|
||||||
ifeq ($(IMAGE_HEADER_SIZE),)
|
ifeq ($(IMAGE_HEADER_SIZE),)
|
||||||
|
|
|
@ -101,7 +101,7 @@ static inline int fp_truncate(FILE *f, size_t len)
|
||||||
#include <wolfssl/wolfcrypt/random.h>
|
#include <wolfssl/wolfcrypt/random.h>
|
||||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||||
|
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
#include <wolfssl/wolfcrypt/lms.h>
|
#include <wolfssl/wolfcrypt/lms.h>
|
||||||
#ifdef HAVE_LIBLMS
|
#ifdef HAVE_LIBLMS
|
||||||
#include <wolfssl/wolfcrypt/ext_lms.h>
|
#include <wolfssl/wolfcrypt/ext_lms.h>
|
||||||
|
@ -199,7 +199,7 @@ static void header_append_tag(uint8_t* header, uint32_t* idx, uint16_t tag,
|
||||||
*idx += len;
|
*idx += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
#include "../lms/lms_common.h"
|
#include "../lms/lms_common.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ static union {
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
RsaKey rsa;
|
RsaKey rsa;
|
||||||
#endif
|
#endif
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
LmsKey lms;
|
LmsKey lms;
|
||||||
#endif
|
#endif
|
||||||
} key;
|
} key;
|
||||||
|
@ -238,7 +238,7 @@ struct cmd_options {
|
||||||
const char *key_file;
|
const char *key_file;
|
||||||
const char *fw_version;
|
const char *fw_version;
|
||||||
const char *signature_file;
|
const char *signature_file;
|
||||||
const char* policy_signature_file;
|
const char *policy_file;
|
||||||
const char *encrypt_key_file;
|
const char *encrypt_key_file;
|
||||||
const char *delta_base_file;
|
const char *delta_base_file;
|
||||||
char output_image_file[PATH_MAX];
|
char output_image_file[PATH_MAX];
|
||||||
|
@ -247,6 +247,7 @@ struct cmd_options {
|
||||||
uint32_t pubkey_sz;
|
uint32_t pubkey_sz;
|
||||||
uint32_t header_sz;
|
uint32_t header_sz;
|
||||||
uint32_t signature_sz;
|
uint32_t signature_sz;
|
||||||
|
uint32_t policy_sz;
|
||||||
uint8_t partition_id;
|
uint8_t partition_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -691,7 +692,7 @@ static uint8_t *load_key(uint8_t **key_buffer, uint32_t *key_buffer_sz,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
FALL_THROUGH;
|
FALL_THROUGH;
|
||||||
case SIGN_LMS:
|
case SIGN_LMS:
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -728,7 +729,7 @@ static uint8_t *load_key(uint8_t **key_buffer, uint32_t *key_buffer_sz,
|
||||||
*key_buffer_sz );
|
*key_buffer_sz );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(WOLFSSL_HAVE_LMS) */
|
#endif /* WOLFSSL_HAVE_LMS */
|
||||||
break;
|
break;
|
||||||
} /* end switch (CMD.sign) */
|
} /* end switch (CMD.sign) */
|
||||||
|
|
||||||
|
@ -759,6 +760,115 @@ failure:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sign the digest */
|
||||||
|
static int sign_digest(int sign, int hash_algo,
|
||||||
|
uint8_t* signature, uint32_t* signature_sz,
|
||||||
|
uint8_t* digest, uint32_t digest_sz)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
WC_RNG rng;
|
||||||
|
|
||||||
|
if ((ret = wc_InitRng(&rng)) != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ED25519
|
||||||
|
if (sign == SIGN_ED25519) {
|
||||||
|
ret = wc_ed25519_sign_msg(digest, digest_sz, signature,
|
||||||
|
signature_sz, &key.ed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ED448
|
||||||
|
if (sign == SIGN_ED448) {
|
||||||
|
ret = wc_ed448_sign_msg(digest, digest_sz, signature,
|
||||||
|
signature_sz, &key.ed4, NULL, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (sign == SIGN_ECC256 ||
|
||||||
|
sign == SIGN_ECC384 ||
|
||||||
|
sign == SIGN_ECC521)
|
||||||
|
{
|
||||||
|
mp_int r, s;
|
||||||
|
int sigSz;
|
||||||
|
if (sign == SIGN_ECC256) sigSz = 32;
|
||||||
|
if (sign == SIGN_ECC384) sigSz = 48;
|
||||||
|
if (sign == SIGN_ECC521) sigSz = 66;
|
||||||
|
|
||||||
|
mp_init(&r); mp_init(&s);
|
||||||
|
ret = wc_ecc_sign_hash_ex(digest, digest_sz, &rng, &key.ecc,
|
||||||
|
&r, &s);
|
||||||
|
mp_to_unsigned_bin(&r, &signature[0]);
|
||||||
|
mp_to_unsigned_bin(&s, &signature[sigSz]);
|
||||||
|
mp_clear(&r); mp_clear(&s);
|
||||||
|
*signature_sz = sigSz*2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifndef NO_RSA
|
||||||
|
if (sign == SIGN_RSA2048 ||
|
||||||
|
sign == SIGN_RSA3072 ||
|
||||||
|
sign == SIGN_RSA4096)
|
||||||
|
{
|
||||||
|
#ifndef WC_MAX_ENCODED_DIG_ASN_SZ
|
||||||
|
#define WC_MAX_ENCODED_DIG_ASN_SZ 9 /* enum(bit or octet) + length(4) */
|
||||||
|
#endif
|
||||||
|
uint8_t buf[WC_MAX_DIGEST_SIZE + WC_MAX_ENCODED_DIG_ASN_SZ];
|
||||||
|
uint32_t enchash_sz = digest_sz;
|
||||||
|
uint8_t* enchash = digest;
|
||||||
|
if (CMD.sign_wenc) {
|
||||||
|
/* add ASN.1 signature encoding */
|
||||||
|
int hashOID = 0;
|
||||||
|
if (hash_algo == HASH_SHA256)
|
||||||
|
hashOID = SHA256h;
|
||||||
|
else if (hash_algo == HASH_SHA384)
|
||||||
|
hashOID = SHA384h;
|
||||||
|
else if (hash_algo == HASH_SHA3)
|
||||||
|
hashOID = SHA3_384h;
|
||||||
|
enchash_sz = wc_EncodeSignature(buf, digest, digest_sz, hashOID);
|
||||||
|
enchash = buf;
|
||||||
|
}
|
||||||
|
ret = wc_RsaSSL_Sign(enchash, enchash_sz, signature, *signature_sz,
|
||||||
|
&key.rsa, &rng);
|
||||||
|
if (ret > 0) {
|
||||||
|
*signature_sz = ret;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
|
if (sign == SIGN_LMS) {
|
||||||
|
/* Set the callbacks, so LMS can update the private key while signing */
|
||||||
|
ret = wc_LmsKey_SetWriteCb(&key.lms, lms_write_key);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_LmsKey_SetReadCb(&key.lms, lms_read_key);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_LmsKey_SetContext(&key.lms, (void*)CMD.key_file);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_LmsKey_Reload(&key.lms);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_LmsKey_Sign(&key.lms, signature, signature_sz, digest,
|
||||||
|
digest_sz);
|
||||||
|
}
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "error signing with LMS: %d\n", ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* WOLFSSL_HAVE_LMS */
|
||||||
|
{
|
||||||
|
ret = NOT_COMPILED_IN;
|
||||||
|
}
|
||||||
|
wc_FreeRng(&rng);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
const char *image_file, const char *outfile,
|
const char *image_file, const char *outfile,
|
||||||
uint32_t delta_base_version, uint32_t patch_len, uint32_t patch_inv_off,
|
uint32_t delta_base_version, uint32_t patch_len, uint32_t patch_inv_off,
|
||||||
|
@ -771,7 +881,7 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
struct stat attrib;
|
struct stat attrib;
|
||||||
uint16_t image_type;
|
uint16_t image_type;
|
||||||
uint8_t* signature = NULL;
|
uint8_t* signature = NULL;
|
||||||
uint8_t* policy_signature = NULL;
|
uint8_t* policy = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
uint8_t buf[1024];
|
uint8_t buf[1024];
|
||||||
uint32_t read_sz, pos;
|
uint32_t read_sz, pos;
|
||||||
|
@ -999,7 +1109,6 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
/* Add image hash to header */
|
/* Add image hash to header */
|
||||||
header_append_tag(header, &header_idx, CMD.hash_algo, digest_sz, digest);
|
header_append_tag(header, &header_idx, CMD.hash_algo, digest_sz, digest);
|
||||||
if (CMD.sign != NO_SIGN) {
|
if (CMD.sign != NO_SIGN) {
|
||||||
WC_RNG rng;
|
|
||||||
/* Add Pubkey Hash to header */
|
/* Add Pubkey Hash to header */
|
||||||
header_append_tag(header, &header_idx, HDR_PUBKEY, digest_sz, buf);
|
header_append_tag(header, &header_idx, HDR_PUBKEY, digest_sz, buf);
|
||||||
|
|
||||||
|
@ -1015,137 +1124,27 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
printf("Digest image %s successfully created.\n", outfile);
|
printf("Digest image %s successfully created.\n", outfile);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
/* save max sig size */
|
||||||
|
CMD.policy_sz = CMD.signature_sz;
|
||||||
|
|
||||||
/* Sign the digest */
|
/* Signing Image */
|
||||||
ret = NOT_COMPILED_IN; /* default error */
|
|
||||||
signature = malloc(CMD.signature_sz);
|
signature = malloc(CMD.signature_sz);
|
||||||
if (signature == NULL) {
|
if (signature == NULL) {
|
||||||
printf("Signature malloc error!\n");
|
printf("Signature malloc error!\n");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
memset(signature, 0, CMD.signature_sz);
|
memset(signature, 0, CMD.signature_sz);
|
||||||
if (CMD.manual_sign && CMD.policy_sign) {
|
|
||||||
policy_signature = malloc(CMD.signature_sz);
|
|
||||||
if (policy_signature == NULL) {
|
|
||||||
printf("Policy Signature malloc error!\n");
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
memset(policy_signature, 0, CMD.signature_sz);
|
|
||||||
}
|
|
||||||
if (!CMD.manual_sign) {
|
if (!CMD.manual_sign) {
|
||||||
printf("Signing the digest...\n");
|
printf("Signing the digest...\n");
|
||||||
#ifdef DEBUG_SIGTOOL
|
#ifdef DEBUG_SIGNTOOL
|
||||||
printf("Digest %d\n", digest_sz);
|
printf("Digest %d\n", digest_sz);
|
||||||
WOLFSSL_BUFFER(digest, digest_sz);
|
WOLFSSL_BUFFER(digest, digest_sz);
|
||||||
#endif
|
#endif
|
||||||
wc_InitRng(&rng);
|
|
||||||
if (CMD.sign == SIGN_ED25519) {
|
|
||||||
#ifdef HAVE_ED25519
|
|
||||||
ret = wc_ed25519_sign_msg(digest, digest_sz, signature,
|
|
||||||
&CMD.signature_sz, &key.ed);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (CMD.sign == SIGN_ED448) {
|
|
||||||
#ifdef HAVE_ED448
|
|
||||||
ret = wc_ed448_sign_msg(digest, digest_sz, signature,
|
|
||||||
&CMD.signature_sz, &key.ed4, NULL, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
else if (CMD.sign == SIGN_ECC256) {
|
|
||||||
mp_int r, s;
|
|
||||||
mp_init(&r); mp_init(&s);
|
|
||||||
ret = wc_ecc_sign_hash_ex(digest, digest_sz, &rng, &key.ecc,
|
|
||||||
&r, &s);
|
|
||||||
mp_to_unsigned_bin(&r, &signature[0]);
|
|
||||||
mp_to_unsigned_bin(&s, &signature[32]);
|
|
||||||
mp_clear(&r); mp_clear(&s);
|
|
||||||
}
|
|
||||||
else if (CMD.sign == SIGN_ECC384) {
|
|
||||||
mp_int r, s;
|
|
||||||
mp_init(&r); mp_init(&s);
|
|
||||||
ret = wc_ecc_sign_hash_ex(digest, digest_sz, &rng, &key.ecc,
|
|
||||||
&r, &s);
|
|
||||||
mp_to_unsigned_bin(&r, &signature[0]);
|
|
||||||
mp_to_unsigned_bin(&s, &signature[48]);
|
|
||||||
mp_clear(&r); mp_clear(&s);
|
|
||||||
}
|
|
||||||
else if (CMD.sign == SIGN_ECC521) {
|
|
||||||
mp_int r, s;
|
|
||||||
mp_init(&r); mp_init(&s);
|
|
||||||
ret = wc_ecc_sign_hash_ex(digest, digest_sz, &rng, &key.ecc,
|
|
||||||
&r, &s);
|
|
||||||
mp_to_unsigned_bin(&r, &signature[0]);
|
|
||||||
mp_to_unsigned_bin(&s, &signature[66]);
|
|
||||||
mp_clear(&r); mp_clear(&s);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (CMD.sign == SIGN_RSA2048 ||
|
|
||||||
CMD.sign == SIGN_RSA3072 ||
|
|
||||||
CMD.sign == SIGN_RSA4096) {
|
|
||||||
|
|
||||||
#ifndef NO_RSA
|
|
||||||
uint32_t enchash_sz = digest_sz;
|
|
||||||
uint8_t* enchash = digest;
|
|
||||||
if (CMD.sign_wenc) {
|
|
||||||
/* add ASN.1 signature encoding */
|
|
||||||
int hashOID = 0;
|
|
||||||
if (CMD.hash_algo == HASH_SHA256)
|
|
||||||
hashOID = SHA256h;
|
|
||||||
else if (CMD.hash_algo == HASH_SHA3)
|
|
||||||
hashOID = SHA3_384h;
|
|
||||||
enchash_sz = wc_EncodeSignature(buf, digest, digest_sz,
|
|
||||||
hashOID);
|
|
||||||
enchash = buf;
|
|
||||||
}
|
|
||||||
ret = wc_RsaSSL_Sign(enchash, enchash_sz, signature,
|
|
||||||
CMD.signature_sz,
|
|
||||||
&key.rsa, &rng);
|
|
||||||
if (ret > 0) {
|
|
||||||
CMD.signature_sz = ret;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (CMD.sign == SIGN_LMS) {
|
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
|
||||||
/* Set the callbacks, so LMS can update the private key
|
|
||||||
* while signing. */
|
|
||||||
ret = wc_LmsKey_SetWriteCb(&key.lms, lms_write_key);
|
|
||||||
if (ret != 0) {
|
|
||||||
fprintf(stderr, "error: wc_LmsKey_SetWriteCb returned %d\n", ret);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = wc_LmsKey_SetReadCb(&key.lms, lms_read_key);
|
|
||||||
if (ret != 0) {
|
|
||||||
fprintf(stderr, "error: wc_LmsKey_SetReadCb returned %d\n", ret);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = wc_LmsKey_SetContext(&key.lms, (void *) CMD.key_file);
|
|
||||||
if (ret != 0) {
|
|
||||||
fprintf(stderr, "error: wc_LmsKey_SetContext returned %d\n", ret);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = wc_LmsKey_Reload(&key.lms);
|
|
||||||
if (ret != 0) {
|
|
||||||
fprintf(stderr, "error: wc_LmsKey_Reload returned %d\n", ret);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = wc_LmsKey_Sign(&key.lms, signature, &CMD.signature_sz, digest,
|
|
||||||
digest_sz);
|
|
||||||
if (ret != 0) {
|
|
||||||
fprintf(stderr, "error: wc_LmsKey_Sign returned %d\n", ret);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
#endif /* defined(WOLFSSL_HAVE_LMS) */
|
|
||||||
}
|
|
||||||
|
|
||||||
wc_FreeRng(&rng);
|
|
||||||
|
|
||||||
|
/* Sign the digest */
|
||||||
|
ret = sign_digest(CMD.sign, CMD.hash_algo,
|
||||||
|
signature, &CMD.signature_sz, digest, digest_sz);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("Signing error %d\n", ret);
|
printf("Signing error %d\n", ret);
|
||||||
goto failure;
|
goto failure;
|
||||||
|
@ -1161,36 +1160,83 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
}
|
}
|
||||||
io_sz = (int)fread(signature, 1, CMD.signature_sz, f);
|
io_sz = (int)fread(signature, 1, CMD.signature_sz, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (io_sz != (int)CMD.signature_sz) {
|
if (io_sz <= 0) {
|
||||||
printf("Error reading file %s\n", CMD.signature_file);
|
printf("Error reading file %s\n", CMD.signature_file);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
CMD.signature_sz = io_sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signing Policy */
|
||||||
if (CMD.policy_sign) {
|
if (CMD.policy_sign) {
|
||||||
printf("Opening signature file %s\n",
|
/* Policy is always SHA2-256 */
|
||||||
CMD.policy_signature_file);
|
digest_sz = HDR_SHA256_LEN;
|
||||||
|
|
||||||
f = fopen(CMD.policy_signature_file, "rb");
|
policy = malloc(CMD.policy_sz + sizeof(uint32_t));
|
||||||
|
if (policy == NULL) {
|
||||||
|
printf("Policy Signature malloc error!\n");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
memset(policy, 0, CMD.policy_sz);
|
||||||
|
|
||||||
|
/* open policy file */
|
||||||
|
printf("Opening policy file %s\n", CMD.policy_file);
|
||||||
|
f = fopen(CMD.policy_file, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
printf("Open signature file %s failed\n",
|
printf("Open policy digest file %s failed\n", CMD.policy_file);
|
||||||
CMD.policy_signature_file);
|
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
io_sz = (int)fread(policy_signature, 1, CMD.signature_sz, f);
|
/* policy file starts with 4 byte PCR mask */
|
||||||
|
io_sz = (int)fread(policy, 1, sizeof(uint32_t), f);
|
||||||
|
if (io_sz != sizeof(uint32_t)) {
|
||||||
|
printf("Error reading file %s\n", CMD.policy_file);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (io_sz != (int)CMD.signature_sz) {
|
goto failure;
|
||||||
printf("Error reading file %s\n",
|
}
|
||||||
CMD.policy_signature_file);
|
|
||||||
|
if (!CMD.manual_sign) {
|
||||||
|
/* in normal sign mode PCR digest (32 bytes) */
|
||||||
|
io_sz = (int)fread(digest, 1, digest_sz, f);
|
||||||
|
fclose(f);
|
||||||
|
if (io_sz != (int)digest_sz) {
|
||||||
|
printf("Error reading file %s\n", CMD.policy_file);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Signing the policy digest...\n");
|
||||||
|
#ifdef DEBUG_SIGNTOOL
|
||||||
|
printf("Policy Digest %d\n", digest_sz);
|
||||||
|
WOLFSSL_BUFFER(digest, digest_sz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Policy is always SHA2-256 */
|
||||||
|
ret = sign_digest(CMD.sign, HASH_SHA256,
|
||||||
|
policy + sizeof(uint32_t), &CMD.policy_sz,
|
||||||
|
digest, digest_sz);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("Signing policy error %d\n", ret);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* in manual mode PCR signature */
|
||||||
|
io_sz = (int)fread(policy, 1, CMD.policy_sz, f);
|
||||||
|
fclose(f);
|
||||||
|
if (io_sz <= 0) {
|
||||||
|
printf("Error reading file %s\n", CMD.policy_file);
|
||||||
|
goto failure;
|
||||||
}
|
}
|
||||||
|
CMD.policy_sz = io_sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_SIGNTOOL
|
#ifdef DEBUG_SIGNTOOL
|
||||||
printf("Signature %d\n", CMD.signature_sz);
|
printf("Signature %d\n", CMD.signature_sz);
|
||||||
WOLFSSL_BUFFER(signature, CMD.signature_sz);
|
WOLFSSL_BUFFER(signature, CMD.signature_sz);
|
||||||
if (CMD.manual_sign && CMD.policy_sign) {
|
if (CMD.policy_sign) {
|
||||||
printf("Policy Signature %d\n", CMD.signature_sz);
|
printf("PCR Mask 0x%08x\n", *((uint32_t*)policy));
|
||||||
WOLFSSL_BUFFER(policy_signature, CMD.signature_sz);
|
printf("Policy Signature %d\n", CMD.policy_sz);
|
||||||
|
WOLFSSL_BUFFER(policy + sizeof(uint32_t), CMD.policy_sz);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1198,9 +1244,10 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
header_append_tag(header, &header_idx, HDR_SIGNATURE, CMD.signature_sz,
|
header_append_tag(header, &header_idx, HDR_SIGNATURE, CMD.signature_sz,
|
||||||
signature);
|
signature);
|
||||||
|
|
||||||
if (CMD.manual_sign && CMD.policy_sign) {
|
if (CMD.policy_sign) {
|
||||||
|
/* Add policy signature to header */
|
||||||
header_append_tag(header, &header_idx, HDR_POLICY_SIGNATURE,
|
header_append_tag(header, &header_idx, HDR_POLICY_SIGNATURE,
|
||||||
CMD.signature_sz, policy_signature);
|
CMD.policy_sz + sizeof(uint32_t), policy);
|
||||||
}
|
}
|
||||||
} /* end if(sign != NO_SIGN) */
|
} /* end if(sign != NO_SIGN) */
|
||||||
|
|
||||||
|
@ -1322,6 +1369,8 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||||
fclose(f2);
|
fclose(f2);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
failure:
|
failure:
|
||||||
|
if (policy)
|
||||||
|
free(policy);
|
||||||
if (header)
|
if (header)
|
||||||
free(header);
|
free(header);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1697,7 +1746,7 @@ int main(int argc, char** argv)
|
||||||
CMD.sign = SIGN_RSA4096;
|
CMD.sign = SIGN_RSA4096;
|
||||||
sign_str = "RSA4096";
|
sign_str = "RSA4096";
|
||||||
}
|
}
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
else if (strcmp(argv[i], "--lms") == 0) {
|
else if (strcmp(argv[i], "--lms") == 0) {
|
||||||
CMD.sign = SIGN_LMS;
|
CMD.sign = SIGN_LMS;
|
||||||
sign_str = "LMS";
|
sign_str = "LMS";
|
||||||
|
@ -1753,8 +1802,9 @@ int main(int argc, char** argv)
|
||||||
CMD.delta = 1;
|
CMD.delta = 1;
|
||||||
CMD.delta_base_file = argv[++i];
|
CMD.delta_base_file = argv[++i];
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[i], "--policy-signed") == 0) {
|
else if (strcmp(argv[i], "--policy") == 0) {
|
||||||
CMD.policy_sign = 1;
|
CMD.policy_sign = 1;
|
||||||
|
CMD.policy_file = argv[++i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
i--;
|
i--;
|
||||||
|
@ -1768,10 +1818,6 @@ int main(int argc, char** argv)
|
||||||
CMD.fw_version = argv[i+3];
|
CMD.fw_version = argv[i+3];
|
||||||
if (CMD.manual_sign) {
|
if (CMD.manual_sign) {
|
||||||
CMD.signature_file = argv[i+4];
|
CMD.signature_file = argv[i+4];
|
||||||
|
|
||||||
if (CMD.policy_sign) {
|
|
||||||
CMD.policy_signature_file = argv[i+5];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CMD.image_file = argv[i+1];
|
CMD.image_file = argv[i+1];
|
||||||
|
@ -1877,7 +1923,7 @@ int main(int argc, char** argv)
|
||||||
CMD.header_sz = 1024;
|
CMD.header_sz = 1024;
|
||||||
CMD.signature_sz = 512;
|
CMD.signature_sz = 512;
|
||||||
}
|
}
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
else if (CMD.sign == SIGN_LMS) {
|
else if (CMD.sign == SIGN_LMS) {
|
||||||
int lms_ret = 0;
|
int lms_ret = 0;
|
||||||
word32 sig_sz = 0;
|
word32 sig_sz = 0;
|
||||||
|
@ -1912,7 +1958,7 @@ int main(int argc, char** argv)
|
||||||
CMD.header_sz = 2 * sig_sz;
|
CMD.header_sz = 2 * sig_sz;
|
||||||
CMD.signature_sz = sig_sz;
|
CMD.signature_sz = sig_sz;
|
||||||
}
|
}
|
||||||
#endif /* defined(WOLFSSL_HAVE_LMS) */
|
#endif /* WOLFSSL_HAVE_LMS */
|
||||||
|
|
||||||
if (((CMD.sign != NO_SIGN) && (CMD.signature_sz == 0)) ||
|
if (((CMD.sign != NO_SIGN) && (CMD.signature_sz == 0)) ||
|
||||||
CMD.header_sz == 0) {
|
CMD.header_sz == 0) {
|
||||||
|
@ -1959,7 +2005,7 @@ int main(int argc, char** argv)
|
||||||
wc_FreeRsaKey(&key.rsa);
|
wc_FreeRsaKey(&key.rsa);
|
||||||
#endif
|
#endif
|
||||||
} else if (CMD.sign == SIGN_LMS) {
|
} else if (CMD.sign == SIGN_LMS) {
|
||||||
#if defined(WOLFSSL_HAVE_LMS)
|
#ifdef WOLFSSL_HAVE_LMS
|
||||||
wc_LmsKey_Free(&key.lms);
|
wc_LmsKey_Free(&key.lms);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,6 @@
|
||||||
#define NO_PWDBASED
|
#define NO_PWDBASED
|
||||||
#define NO_WRITEV
|
#define NO_WRITEV
|
||||||
#define NO_FILESYSTEM
|
#define NO_FILESYSTEM
|
||||||
#define NO_MAIN_DRIVER
|
|
||||||
#define NO_OLD_RNGNAME
|
#define NO_OLD_RNGNAME
|
||||||
#define NO_WOLFSSL_DIR
|
#define NO_WOLFSSL_DIR
|
||||||
#define WOLFSSL_NO_SOCK
|
#define WOLFSSL_NO_SOCK
|
||||||
|
|
|
@ -20,23 +20,23 @@ RENODE_BINASSEMBLE=tools/bin-assemble/bin-assemble
|
||||||
LMS_OPTS=LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 WOLFBOOT_SMALL_STACK=0 \
|
LMS_OPTS=LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 WOLFBOOT_SMALL_STACK=0 \
|
||||||
IMAGE_SIGNATURE_SIZE=2644 IMAGE_HEADER_SIZE=5288
|
IMAGE_SIGNATURE_SIZE=2644 IMAGE_HEADER_SIZE=5288
|
||||||
|
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen)","")
|
# python version only supported using
|
||||||
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen
|
# KEYGEN_TOOL="python3 $(WOLFBOOT_ROOT)/tools/keytools/keygen.py"
|
||||||
else
|
ifeq ("$(KEYGEN_TOOL)","")
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","")
|
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","")
|
||||||
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe
|
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe
|
||||||
else
|
else
|
||||||
KEYGEN_TOOL=python3 $(WOLFBOOT_ROOT)/tools/keytools/keygen.py
|
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign)","")
|
# python version only supported using
|
||||||
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign
|
# SIGN_TOOL="python3 $(WOLFBOOT_ROOT)/tools/keytools/sign.py"
|
||||||
else
|
ifeq ("$(SIGN_TOOL)","")
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","")
|
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","")
|
||||||
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe
|
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe
|
||||||
else
|
else
|
||||||
SIGN_TOOL=python3 $(WOLFBOOT_ROOT)/tools/keytools/sign.py
|
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,23 @@ SPI_OPTIONS=SPI_FLASH=1 WOLFBOOT_PARTITION_SIZE=0x80000 WOLFBOOT_PARTITION_UPDAT
|
||||||
SIGN_ARGS=
|
SIGN_ARGS=
|
||||||
SIGN_ENC_ARGS=
|
SIGN_ENC_ARGS=
|
||||||
|
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen)","")
|
# python version only supported using
|
||||||
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen
|
# KEYGEN_TOOL="python3 $(WOLFBOOT_ROOT)/tools/keytools/keygen.py"
|
||||||
else
|
ifeq ("$(KEYGEN_TOOL)","")
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","")
|
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","")
|
||||||
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe
|
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe
|
||||||
else
|
else
|
||||||
KEYGEN_TOOL=python3 $(WOLFBOOT_ROOT)/tools/keytools/keygen.py
|
KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign)","")
|
# python version only supported using
|
||||||
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign
|
# SIGN_TOOL="python3 $(WOLFBOOT_ROOT)/tools/keytools/sign.py"
|
||||||
else
|
ifeq ("$(SIGN_TOOL)","")
|
||||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","")
|
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","")
|
||||||
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe
|
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe
|
||||||
else
|
else
|
||||||
SIGN_TOOL=python3 $(WOLFBOOT_ROOT)/tools/keytools/sign.py
|
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ $(BINASSEMBLE):
|
||||||
test-size: FORCE
|
test-size: FORCE
|
||||||
$(Q)make clean
|
$(Q)make clean
|
||||||
$(Q)make wolfboot.bin
|
$(Q)make wolfboot.bin
|
||||||
$(Q)FP=`$(SIZE) -A wolfboot.elf | awk -e ' /Total/ {print $$2;}'`; echo SIZE: $$FP LIMIT: $$LIMIT; test $$FP -le $$LIMIT
|
$(Q)FP=`$(SIZE) -A wolfboot.elf | awk ' /Total/ {print $$2;}'`; echo SIZE: $$FP LIMIT: $$LIMIT; test $$FP -le $$LIMIT
|
||||||
|
|
||||||
# Testbed actions
|
# Testbed actions
|
||||||
#
|
#
|
||||||
|
@ -941,29 +941,29 @@ test-all: clean
|
||||||
|
|
||||||
|
|
||||||
test-size-all:
|
test-size-all:
|
||||||
make test-size SIGN=NONE LIMIT=4722
|
make test-size SIGN=NONE LIMIT=4730
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ED25519 LIMIT=11398
|
make test-size SIGN=ED25519 LIMIT=11398
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC256 LIMIT=22266
|
make test-size SIGN=ECC256 LIMIT=22270
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13702
|
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13706
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA2048 LIMIT=11182
|
make test-size SIGN=RSA2048 LIMIT=11186
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11162
|
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11166
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA4096 LIMIT=11546
|
make test-size SIGN=RSA4096 LIMIT=11550
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=11462
|
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=11466
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC384 LIMIT=17562
|
make test-size SIGN=ECC384 LIMIT=17566
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15172
|
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15172
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ED448 LIMIT=13414
|
make test-size SIGN=ED448 LIMIT=13414
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA3072 LIMIT=11382
|
make test-size SIGN=RSA3072 LIMIT=11386
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11254
|
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11258
|
||||||
make keysclean
|
make keysclean
|
||||||
|
|
|
@ -13,16 +13,19 @@ WOLFBOOTDIR = ../..
|
||||||
WOLFDIR = $(WOLFBOOTDIR)/lib/wolfssl/
|
WOLFDIR = $(WOLFBOOTDIR)/lib/wolfssl/
|
||||||
WOLFTPMDIR = $(WOLFBOOTDIR)/lib/wolfTPM/
|
WOLFTPMDIR = $(WOLFBOOTDIR)/lib/wolfTPM/
|
||||||
CFLAGS = -Wall -Wextra -Werror
|
CFLAGS = -Wall -Wextra -Werror
|
||||||
CFLAGS += -I. -DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS -I$(WOLFDIR) -I$(WOLFTPMDIR) -I$(WOLFBOOTDIR)/include
|
CFLAGS += -DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS -DWOLFBOOT_TPM
|
||||||
|
CFLAGS += -I. -I$(WOLFDIR) -I$(WOLFTPMDIR) -I$(WOLFBOOTDIR)/include
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
OBJDIR = ./
|
OBJDIR = ./
|
||||||
|
|
||||||
# option variables
|
# option variables
|
||||||
DEBUG_FLAGS = -g -DDEBUG -DDEBUG_SIGNTOOL -DDEBUG_WOLFSSL -DDEBUG_WOLFSSL_VERBOSE -fsanitize=address
|
DEBUG_FLAGS = -g -DDEBUG -DDEBUG_WOLFTPM -DDEBUG_WOLFSSL -DWOLFTPM_DEBUG_VERBOSE
|
||||||
|
SANITIZE_FLAGS = -fsanitize=address
|
||||||
OPTIMIZE = -O2
|
OPTIMIZE = -O2
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
#CFLAGS+=$(DEBUG_FLAGS)
|
#CFLAGS+=$(DEBUG_FLAGS)
|
||||||
|
#CFLAGS+=$(SANITIZE_FLAGS)
|
||||||
CFLAGS+=$(OPTIMIZE)
|
CFLAGS+=$(OPTIMIZE)
|
||||||
|
|
||||||
ifeq ($(TARGET),sim)
|
ifeq ($(TARGET),sim)
|
||||||
|
@ -68,11 +71,12 @@ vpath %.c $(WOLFDIR)/wolfcrypt/src/
|
||||||
vpath %.c $(WOLFBOOTDIR)/src/
|
vpath %.c $(WOLFBOOTDIR)/src/
|
||||||
vpath %.c $(WOLFTPMDIR)/src/
|
vpath %.c $(WOLFTPMDIR)/src/
|
||||||
vpath %.c $(WOLFTPMDIR)/hal/
|
vpath %.c $(WOLFTPMDIR)/hal/
|
||||||
|
vpath %.c $(WOLFTPMDIR)/examples/pcr
|
||||||
vpath %.c ./
|
vpath %.c ./
|
||||||
|
|
||||||
.PHONY: clean all
|
.PHONY: clean all
|
||||||
|
|
||||||
all: rot
|
all: rot policy_create pcr_extend pcr_read pcr_reset
|
||||||
|
|
||||||
debug: CFLAGS+=$(DEBUG_FLAGS)
|
debug: CFLAGS+=$(DEBUG_FLAGS)
|
||||||
debug: all
|
debug: all
|
||||||
|
@ -94,5 +98,21 @@ rot: $(OBJS_VIRT) rot.o
|
||||||
@echo "Building Root of Trust (ROT) tool"
|
@echo "Building Root of Trust (ROT) tool"
|
||||||
$(Q)$(LD) -o $@ $@.o $(OBJS_VIRT) $(LDFLAGS)
|
$(Q)$(LD) -o $@ $@.o $(OBJS_VIRT) $(LDFLAGS)
|
||||||
|
|
||||||
|
policy_create: $(OBJS_VIRT) policy_create.o
|
||||||
|
@echo "Building Policy Creation Tool"
|
||||||
|
$(Q)$(LD) -o $@ $@.o $(OBJS_VIRT) $(LDFLAGS)
|
||||||
|
|
||||||
|
pcr_extend: $(OBJS_VIRT) $(WOLFTPMDIR)/examples/pcr/extend.o
|
||||||
|
@echo "Building PCR Extend Tool"
|
||||||
|
$(Q)$(LD) -o $@ $(WOLFTPMDIR)/examples/pcr/extend.o $(OBJS_VIRT) $(LDFLAGS)
|
||||||
|
|
||||||
|
pcr_read: $(OBJS_VIRT) $(WOLFTPMDIR)/examples/pcr/read_pcr.o
|
||||||
|
@echo "Building PCR Read Tool"
|
||||||
|
$(Q)$(LD) -o $@ $(WOLFTPMDIR)/examples/pcr/read_pcr.o $(OBJS_VIRT) $(LDFLAGS)
|
||||||
|
|
||||||
|
pcr_reset: $(OBJS_VIRT) $(WOLFTPMDIR)/examples/pcr/reset.o
|
||||||
|
@echo "Building PCR Reset Tool"
|
||||||
|
$(Q)$(LD) -o $@ $(WOLFTPMDIR)/examples/pcr/reset.o $(OBJS_VIRT) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f rot *.o
|
rm -f rot policy_create pcr_extend pcr_read pcr_reset *.o
|
||||||
|
|
|
@ -4,7 +4,7 @@ Tools to help with TPM setup.
|
||||||
|
|
||||||
For wolfBoot TPM features see (docs/TPM.md)[/docs/TPM.md].
|
For wolfBoot TPM features see (docs/TPM.md)[/docs/TPM.md].
|
||||||
|
|
||||||
# Secure Boot Root of Trust (ROT)
|
## Secure Boot Root of Trust (ROT)
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -13,3 +13,18 @@ Examples:
|
||||||
* `./tools/tpm/rot -write -lock`: Write and lock the NV
|
* `./tools/tpm/rot -write -lock`: Write and lock the NV
|
||||||
* `./tools/tpm/rot -write -sha384`: Write NV using SHA2-384
|
* `./tools/tpm/rot -write -sha384`: Write NV using SHA2-384
|
||||||
* `./tools/tpm/rot -write -auth=test`: Use password for NV access
|
* `./tools/tpm/rot -write -auth=test`: Use password for NV access
|
||||||
|
|
||||||
|
## Sealing / Unsealing
|
||||||
|
|
||||||
|
A PCR policy is signed with the `tools/keytool/sign` tool using the --policy argument.
|
||||||
|
The policy file comes from the `tools/tpm/policy_create` tool and contains a 4-byte PCR mask and PCR digest.
|
||||||
|
The authorization for the sealing/unsealing comes from the signed policy and its public key (stored in `keystore.c`).
|
||||||
|
Typically PCR's 0-15 are used for boot measurements and sealing/unsealing, since they can only be reset on a reboot. The PCR 16 is used for testing.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* `./tools/tpm/pcr_reset 16`: Reset PCR 16
|
||||||
|
* `./tools/tpm/pcr_extend 16 aaa.bin`: Extend PCR 16 with the SHA2-256 hash of "aaa"
|
||||||
|
* `./tools/tpm/policy_create -pcr=16 -pcrdigest=eca4e8eda468b8667244ae972b8240d3244ea72341b2bf2383e79c66643bbecc -out=policy.bin`: Create a policy.bin file with 4-byte PCR mask and 32-byte PCR digest.
|
||||||
|
* `./tools/keytools/sign --ecc256 --policy policy.bin test-app/image.elf wolfboot_signing_private_key.der 1`: Sign the PCR policy and include in the `HDR_POLICY_SIGNATURE` image header.
|
||||||
|
* `make POLICY_FILE=policy.bin`: This will perform a build and include the policy file argument to the sign tool. This can also go into the .config file.
|
||||||
|
|
|
@ -0,0 +1,273 @@
|
||||||
|
/* policy_create.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2023 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfBoot.
|
||||||
|
*
|
||||||
|
* wolfTPM is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfTPM is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Tool for creating a policy digest file that is then signed by the key tool
|
||||||
|
* and included in the image header using HDR_POLICY_SIGNATURE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
|
#include <wolfssl/wolfcrypt/ecc.h>
|
||||||
|
#include <wolfssl/wolfcrypt/hash.h>
|
||||||
|
#include <wolftpm/tpm2_wrap.h>
|
||||||
|
#include <hal/tpm_io.h>
|
||||||
|
#include "keystore.h"
|
||||||
|
#include "tpm.h"
|
||||||
|
|
||||||
|
#define DEFAULT_PCR 16
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
printf("Expected usage:\n");
|
||||||
|
printf("./examples/pcr/policy_create [-pcr=/-pcrmask] [-pcrdigest=] [-out=]\n");
|
||||||
|
printf("* -pcr=index: SHA2-256 PCR index < 24 (multiple can be supplied) (default %d)\n", DEFAULT_PCR);
|
||||||
|
printf("* -pcrmask=0x00000000: PCR mask (or -pcr= args)\n");
|
||||||
|
printf("* -pcrdigest=hexstr: PCR Digest (default=Read actual PCR's)\n");
|
||||||
|
printf("* -out=file: Policy Digest to sign (default policy.bin)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int writeBin(const char* filename, const uint8_t*buf, word32 bufSz)
|
||||||
|
{
|
||||||
|
int rc = TPM_RC_FAILURE;
|
||||||
|
|
||||||
|
if (filename == NULL || buf == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
XFILE fp = NULL;
|
||||||
|
size_t fileSz = 0;
|
||||||
|
|
||||||
|
fp = XFOPEN(filename, "wt");
|
||||||
|
if (fp != XBADFILE) {
|
||||||
|
fileSz = XFWRITE(buf, 1, bufSz, fp);
|
||||||
|
/* sanity check */
|
||||||
|
if (fileSz == (word32)bufSz) {
|
||||||
|
rc = TPM_RC_SUCCESS;
|
||||||
|
}
|
||||||
|
printf("Wrote %d bytes to %s\n", (int)fileSz, filename);
|
||||||
|
XFCLOSE(fp);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static signed char hexCharToByte(signed char ch)
|
||||||
|
{
|
||||||
|
signed char ret = (signed char)ch;
|
||||||
|
if (ret >= '0' && ret <= '9')
|
||||||
|
ret -= '0';
|
||||||
|
else if (ret >= 'A' && ret <= 'F')
|
||||||
|
ret -= 'A' - 10;
|
||||||
|
else if (ret >= 'a' && ret <= 'f')
|
||||||
|
ret -= 'a' - 10;
|
||||||
|
else
|
||||||
|
ret = -1; /* error case - return code must be signed */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
static int hexToByte(const char *hex, unsigned char *output, unsigned long sz)
|
||||||
|
{
|
||||||
|
int outSz = 0;
|
||||||
|
word32 i;
|
||||||
|
for (i = 0; i < sz; i+=2) {
|
||||||
|
signed char ch1, ch2;
|
||||||
|
ch1 = hexCharToByte(hex[i]);
|
||||||
|
ch2 = hexCharToByte(hex[i+1]);
|
||||||
|
if ((ch1 < 0) || (ch2 < 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
output[outSz++] = (unsigned char)((ch1 << 4) + ch2);
|
||||||
|
}
|
||||||
|
return outSz;
|
||||||
|
}
|
||||||
|
static void printHexString(const unsigned char* bin, unsigned long sz,
|
||||||
|
unsigned long maxLine)
|
||||||
|
{
|
||||||
|
unsigned long i;
|
||||||
|
printf("\t");
|
||||||
|
if (maxLine == 0) maxLine = sz;
|
||||||
|
for (i = 0; i < sz; i++) {
|
||||||
|
printf("%02x", bin[i]);
|
||||||
|
if (((i+1) % maxLine) == 0 && i+1 != sz)
|
||||||
|
printf("\n\t");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tpm_mask_sel_pcr(uint32_t pcrMask, uint8_t* pcrArray,
|
||||||
|
uint32_t* pcrArraySz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
*pcrArraySz = 0;
|
||||||
|
for (i=0; i<IMPLEMENTATION_PCR; i++) {
|
||||||
|
if (pcrMask & (1 << i)) {
|
||||||
|
pcrArray[(*pcrArraySz)++] = i;
|
||||||
|
/* make sure we have room */
|
||||||
|
if (*pcrArraySz >= PCR_SELECT_MAX*2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int TPM2_PCR_Policy_Create(TPM_ALG_ID pcrAlg,
|
||||||
|
uint8_t* pcrArray, word32 pcrArraySz,
|
||||||
|
const char* outFile,
|
||||||
|
uint8_t* pcrDigest, word32 pcrDigestSz,
|
||||||
|
uint8_t* policyRef, word32 policyRefSz)
|
||||||
|
{
|
||||||
|
int rc = -1, i;
|
||||||
|
word32 pcrMask = 0;
|
||||||
|
byte policy[sizeof(pcrMask) + WC_MAX_DIGEST_SIZE]; /* pcrmask + digest */
|
||||||
|
word32 policySz = 0;
|
||||||
|
byte* digest = &policy[sizeof(pcrMask)];
|
||||||
|
word32 digestSz;
|
||||||
|
|
||||||
|
printf("Policy Create Tool\n");
|
||||||
|
|
||||||
|
/* calculate pcrMask */
|
||||||
|
printf("PCR Index(s) (%s): ", TPM2_GetAlgName(pcrAlg));
|
||||||
|
for (i = 0; i < (int)pcrArraySz; i++) {
|
||||||
|
printf("%d ", pcrArray[i]);
|
||||||
|
pcrMask |= (1 << pcrArray[i]);
|
||||||
|
}
|
||||||
|
printf(" (mask 0x%08x)\n", pcrMask);
|
||||||
|
XMEMSET(policy, 0, sizeof(policy));
|
||||||
|
XMEMCPY(policy, &pcrMask, sizeof(pcrMask));
|
||||||
|
policySz += (word32)sizeof(pcrMask);
|
||||||
|
|
||||||
|
/* PCR Hash - Use provided hash or read PCR's and get hash */
|
||||||
|
if (pcrDigestSz == 0) {
|
||||||
|
WOLFTPM2_DEV dev;
|
||||||
|
XMEMSET(&dev, 0, sizeof(WOLFTPM2_DEV));
|
||||||
|
rc = wolfTPM2_Init(&dev, TPM2_IoCb, NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
rc = wolfTPM2_PCRGetDigest(&dev, pcrAlg, pcrArray, pcrArraySz,
|
||||||
|
pcrDigest, &pcrDigestSz);
|
||||||
|
wolfTPM2_Cleanup(&dev);
|
||||||
|
}
|
||||||
|
if (rc != TPM_RC_SUCCESS) {
|
||||||
|
printf("Error getting PCR's! 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("PCR Digest (%d bytes):\n", pcrDigestSz);
|
||||||
|
printHexString(pcrDigest, pcrDigestSz, 0);
|
||||||
|
|
||||||
|
/* Build PCR Policy to Sign */
|
||||||
|
digestSz = TPM2_GetHashDigestSize(pcrAlg);
|
||||||
|
/* Note: digest is used an input here to allow chaining policies,
|
||||||
|
* but for this use-case should be zero'd */
|
||||||
|
rc = wolfTPM2_PolicyPCRMake(pcrAlg, pcrArray, pcrArraySz,
|
||||||
|
pcrDigest, pcrDigestSz, digest, &digestSz);
|
||||||
|
if (rc == 0) {
|
||||||
|
/* Add policyRef (if blank just re-hash) */
|
||||||
|
rc = wolfTPM2_PolicyRefMake(pcrAlg, digest, &digestSz,
|
||||||
|
policyRef, policyRefSz);
|
||||||
|
}
|
||||||
|
if (rc == 0) {
|
||||||
|
policySz += digestSz;
|
||||||
|
|
||||||
|
printf("PCR Mask (0x%08x) and PCR Policy Digest (%d bytes):\n",
|
||||||
|
pcrMask, digestSz);
|
||||||
|
printHexString(digest, digestSz, 0);
|
||||||
|
|
||||||
|
/* Write pcrMask (4) and digest */
|
||||||
|
writeBin(outFile, policy, policySz);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (rc != 0) {
|
||||||
|
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
TPM_ALG_ID pcrAlg = WOLFBOOT_TPM_PCR_ALG;
|
||||||
|
byte pcrArray[PCR_SELECT_MAX*2];
|
||||||
|
word32 pcrArraySz = 0;
|
||||||
|
const char* outFile = "policy.bin";
|
||||||
|
byte pcrDigest[WC_MAX_DIGEST_SIZE];
|
||||||
|
word32 pcrDigestSz = 0;
|
||||||
|
uint8_t* policyRef = NULL; /* optional nonce */
|
||||||
|
word32 policyRefSz = 0;
|
||||||
|
word32 pcrMask = 0;
|
||||||
|
|
||||||
|
if (argc >= 2) {
|
||||||
|
if (XSTRCMP(argv[1], "-?") == 0 ||
|
||||||
|
XSTRCMP(argv[1], "-h") == 0 ||
|
||||||
|
XSTRCMP(argv[1], "--help") == 0) {
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (argc > 1) {
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-pcr=", XSTRLEN("-pcr=")) == 0) {
|
||||||
|
const char* pcrStr = argv[argc-1] + XSTRLEN("-pcr=");
|
||||||
|
byte pcrIndex = (byte)XATOI(pcrStr);
|
||||||
|
if (pcrIndex > PCR_LAST) {
|
||||||
|
printf("PCR index is out of range (0-23)\n");
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pcrArray[pcrArraySz++] = pcrIndex;
|
||||||
|
}
|
||||||
|
else if (XSTRNCMP(argv[argc-1], "-pcrmask=", XSTRLEN("-pcrmask=")) == 0) {
|
||||||
|
const char* pcrMaskStr = argv[argc-1] + XSTRLEN("-pcrmask=");
|
||||||
|
pcrMask = (word32)XSTRTOL(pcrMaskStr, NULL, 0);
|
||||||
|
}
|
||||||
|
else if (XSTRNCMP(argv[argc-1], "-pcrdigest=", XSTRLEN("-pcrdigest=")) == 0) {
|
||||||
|
const char* hashHexStr = argv[argc-1] + XSTRLEN("-pcrdigest=");
|
||||||
|
int hashHexStrLen = (int)XSTRLEN(hashHexStr);
|
||||||
|
if (hashHexStrLen > (int)sizeof(pcrDigest)*2+1)
|
||||||
|
pcrDigestSz = -1;
|
||||||
|
else
|
||||||
|
pcrDigestSz = hexToByte(hashHexStr, pcrDigest, hashHexStrLen);
|
||||||
|
if (pcrDigestSz <= 0) {
|
||||||
|
fprintf(stderr, "Invalid PCR hash length\n");
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (XSTRNCMP(argv[argc-1], "-out=",
|
||||||
|
XSTRLEN("-out=")) == 0) {
|
||||||
|
outFile = argv[argc-1] + XSTRLEN("-out=");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine PCR's based on mask or default (if none set) */
|
||||||
|
if (pcrArraySz == 0) {
|
||||||
|
if (pcrMask == 0) {
|
||||||
|
pcrArray[pcrArraySz++] = DEFAULT_PCR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tpm_mask_sel_pcr(pcrMask, pcrArray, &pcrArraySz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TPM2_PCR_Policy_Create(pcrAlg,
|
||||||
|
pcrArray, pcrArraySz, outFile,
|
||||||
|
pcrDigest, pcrDigestSz, policyRef, policyRefSz);
|
||||||
|
}
|
|
@ -24,7 +24,8 @@
|
||||||
#include <wolfssl/wolfcrypt/hash.h>
|
#include <wolfssl/wolfcrypt/hash.h>
|
||||||
#include <wolftpm/tpm2_wrap.h>
|
#include <wolftpm/tpm2_wrap.h>
|
||||||
#include <hal/tpm_io.h>
|
#include <hal/tpm_io.h>
|
||||||
#include <keystore.h>
|
#include "keystore.h"
|
||||||
|
#include "tpm.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -32,13 +33,11 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define TPM2_DEMO_NV_SECURE_ROT_INDEX 0x01400200
|
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
printf("Expected usage:\n");
|
printf("Expected usage:\n");
|
||||||
printf("./tools/tpm/rot [-nvindex] [-write] [-auth] [-sha384] [-lock]\n");
|
printf("./tools/tpm/rot [-nvbase] [-write] [-auth] [-sha384] [-lock]\n");
|
||||||
printf("* -nvindex=[handle] (default 0x%x)\n", TPM2_DEMO_NV_SECURE_ROT_INDEX);
|
printf("* -nvbase=[handle] (default 0x%x)\n", WOLFBOOT_TPM_KEYSTORE_NV_BASE);
|
||||||
printf("* -write: Using keystore.c API's hashes each public key and stores into NV\n");
|
printf("* -write: Using keystore.c API's hashes each public key and stores into NV\n");
|
||||||
printf("* -auth=password: Optional password for NV\n");
|
printf("* -auth=password: Optional password for NV\n");
|
||||||
printf("* -sha384: Use SHA2-384 (default is SHA2-256)\n");
|
printf("* -sha384: Use SHA2-384 (default is SHA2-256)\n");
|
||||||
|
@ -48,7 +47,7 @@ static void usage(void)
|
||||||
printf("\t./tools/tpm/rot -write\n");
|
printf("\t./tools/tpm/rot -write\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPM2_Boot_SecureROT_Example(TPMI_RH_NV_AUTH authHandle, word32 nvIndex,
|
static int TPM2_Boot_SecureROT_Example(TPMI_RH_NV_AUTH authHandle, word32 nvBaseIdx,
|
||||||
enum wc_HashType hashType, int doWrite, int doLock,
|
enum wc_HashType hashType, int doWrite, int doLock,
|
||||||
const char *authBuf, int authBufSz)
|
const char *authBuf, int authBufSz)
|
||||||
{
|
{
|
||||||
|
@ -93,17 +92,17 @@ int TPM2_Boot_SecureROT_Example(TPMI_RH_NV_AUTH authHandle, word32 nvIndex,
|
||||||
if (rc != 0) goto exit;
|
if (rc != 0) goto exit;
|
||||||
|
|
||||||
printf("NV Auth (%d)\n", authBufSz);
|
printf("NV Auth (%d)\n", authBufSz);
|
||||||
TPM2_PrintBin((const byte*)authBuf, authBufSz);
|
TPM2_PrintBin((const uint8_t*)authBuf, authBufSz);
|
||||||
|
|
||||||
for (id = 0; id < keystore_num_pubkeys(); id++) {
|
for (id = 0; id < keystore_num_pubkeys(); id++) {
|
||||||
TPM_HANDLE handle = nvIndex + id;
|
TPM_HANDLE handle = nvBaseIdx + id;
|
||||||
uint32_t keyType = keystore_get_key_type(id);
|
uint32_t keyType = keystore_get_key_type(id);
|
||||||
int bufSz = keystore_get_size(id);
|
int bufSz = keystore_get_size(id);
|
||||||
byte *buf = keystore_get_buffer(id);
|
uint8_t*buf = keystore_get_buffer(id);
|
||||||
|
|
||||||
(void)keyType; /* not used */
|
(void)keyType; /* not used */
|
||||||
|
|
||||||
printf("Computing keystore has for index %d\n", id);
|
printf("Computing keystore hash for index %d\n", id);
|
||||||
|
|
||||||
/* hash public key */
|
/* hash public key */
|
||||||
digestSz = wc_HashGetDigestSize(hashType);
|
digestSz = wc_HashGetDigestSize(hashType);
|
||||||
|
@ -124,7 +123,7 @@ int TPM2_Boot_SecureROT_Example(TPMI_RH_NV_AUTH authHandle, word32 nvIndex,
|
||||||
|
|
||||||
/* Create NV - NV struct populated */
|
/* Create NV - NV struct populated */
|
||||||
rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, handle,
|
rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, handle,
|
||||||
nvAttributes, digestSz, (const byte*)authBuf, authBufSz);
|
nvAttributes, digestSz, (const uint8_t*)authBuf, authBufSz);
|
||||||
if (rc == TPM_RC_NV_DEFINED) {
|
if (rc == TPM_RC_NV_DEFINED) {
|
||||||
printf("Warning: NV Index 0x%x already exists!\n", handle);
|
printf("Warning: NV Index 0x%x already exists!\n", handle);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
@ -192,7 +191,7 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* use platform handle to prevent TPM2_Clear from removing */
|
/* use platform handle to prevent TPM2_Clear from removing */
|
||||||
TPMI_RH_NV_AUTH authHandle = TPM_RH_PLATFORM;
|
TPMI_RH_NV_AUTH authHandle = TPM_RH_PLATFORM;
|
||||||
word32 nvIndex = TPM2_DEMO_NV_SECURE_ROT_INDEX;
|
word32 nvBaseIdx = WOLFBOOT_TPM_KEYSTORE_NV_BASE;
|
||||||
int doWrite = 0, doLock = 0;
|
int doWrite = 0, doLock = 0;
|
||||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
|
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
|
||||||
const char* authBuf = NULL;
|
const char* authBuf = NULL;
|
||||||
|
@ -207,17 +206,17 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (argc > 1) {
|
while (argc > 1) {
|
||||||
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
|
if (XSTRNCMP(argv[argc-1], "-nvbase=", XSTRLEN("-nvbase=")) == 0) {
|
||||||
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
|
const char* nvBaseIdxStr = argv[argc-1] + XSTRLEN("-nvbase=");
|
||||||
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
|
nvBaseIdx = (word32)XSTRTOL(nvBaseIdxStr, NULL, 0);
|
||||||
if (!(authHandle == TPM_RH_PLATFORM && (
|
if (!(authHandle == TPM_RH_PLATFORM && (
|
||||||
nvIndex > TPM_20_PLATFORM_MFG_NV_SPACE &&
|
nvBaseIdx > TPM_20_PLATFORM_MFG_NV_SPACE &&
|
||||||
nvIndex < TPM_20_OWNER_NV_SPACE)) &&
|
nvBaseIdx < TPM_20_OWNER_NV_SPACE)) &&
|
||||||
!(authHandle == TPM_RH_OWNER && (
|
!(authHandle == TPM_RH_OWNER && (
|
||||||
nvIndex > TPM_20_OWNER_NV_SPACE &&
|
nvBaseIdx > TPM_20_OWNER_NV_SPACE &&
|
||||||
nvIndex < TPM_20_TCG_NV_SPACE)))
|
nvBaseIdx < TPM_20_TCG_NV_SPACE)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid NV Index %s\n", nvIndexStr);
|
fprintf(stderr, "Invalid NV Index %s\n", nvBaseIdxStr);
|
||||||
fprintf(stderr, "\tPlatform Range: 0x%x -> 0x%x\n",
|
fprintf(stderr, "\tPlatform Range: 0x%x -> 0x%x\n",
|
||||||
TPM_20_PLATFORM_MFG_NV_SPACE, TPM_20_OWNER_NV_SPACE);
|
TPM_20_PLATFORM_MFG_NV_SPACE, TPM_20_OWNER_NV_SPACE);
|
||||||
fprintf(stderr, "\tOwner Range: 0x%x -> 0x%x\n",
|
fprintf(stderr, "\tOwner Range: 0x%x -> 0x%x\n",
|
||||||
|
@ -247,7 +246,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
return TPM2_Boot_SecureROT_Example(
|
return TPM2_Boot_SecureROT_Example(
|
||||||
authHandle,
|
authHandle,
|
||||||
nvIndex,
|
nvBaseIdx,
|
||||||
hashType,
|
hashType,
|
||||||
doWrite,
|
doWrite,
|
||||||
doLock,
|
doLock,
|
||||||
|
|
|
@ -83,7 +83,6 @@
|
||||||
#define NO_DES3
|
#define NO_DES3
|
||||||
#define NO_PWDBASED
|
#define NO_PWDBASED
|
||||||
#define NO_WRITEV
|
#define NO_WRITEV
|
||||||
#define NO_MAIN_DRIVER
|
|
||||||
#define NO_OLD_RNGNAME
|
#define NO_OLD_RNGNAME
|
||||||
#define NO_WOLFSSL_DIR
|
#define NO_WOLFSSL_DIR
|
||||||
#define WOLFSSL_NO_SOCK
|
#define WOLFSSL_NO_SOCK
|
||||||
|
|
Loading…
Reference in New Issue