tpm2sh 0.15.0 is much more stabilized than previous iterations, and
enhances key management with a proper support for compiling command
lists from policy expressions embedded to the TPM 2.0 ASN.1 key
files:

~ main ≡
❯ tpm2sh create tpm:81000001 --data deadbeef --policy  '(pcr(sha256:16) or 
pcr(sha256:7)) and secret(tpm:81000001)' keyedhash:sha256 | tpm2sh load
vtpm:80000000

~ main ≡
❯ tpm2sh cache
HANDLE    TYPE       DETAILS
80000000  transient  keyedhash:sha256

~ main ≡
❯ tpm2sh unseal vtpm:80000000
deadbeef


RustCrypto crates have been erased and all software crypto is based
on openssl crate and libssl in order to have a patchable crypto:

❯ ldd target/release/tpm2sh
        linux-vdso.so.1 (0x00007f4eddc64000)
        libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007f4edd757000)
        libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 
(0x00007f4edd2d0000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 
(0x00007f4eddc0a000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4edd1f0000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4edd00e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4eddc66000)

Total size of dependency graph is 129, which is not whole a lot in the
usual Rust metrics and tpm2sh is fine-tuned to compile nicely with rustc
1.7x toolchains. This allows to compile it fluently to e.g., BuildRoot
and Yocto images. E.g., to keep some control and narrow down
dependencies I wrote my own custom PKCS#1, PCKS#8, SEC1 and X.509
parsers using rasn [1].

Converting external keys to TPM keys is super trivial:

~ main ≡
❯ tpm2sh create-primary ecc-nist-p256:sha256
vtpm:80000000

~ main ≡
❯ tpm2sh cache
HANDLE    TYPE       DETAILS
80000000  transient  ecc-nist-p256:sha256

~ main ≡
❯ tpm2sh convert vtpm:80000000 -I private.pem | tpm2sh load
vtpm:80000001

~ main ≡
❯ tpm2sh cache
HANDLE    TYPE       DETAILS
80000000  transient  ecc-nist-p256:sha256
80000001  transient  rsa-2048:sha256

`tpm2-tpmkey` crate reads and writes otherwise the format following the
standard, except it adds an optional `parentPubkey` attribute, which
enable parent auto-discovery from persistent handles and vtpm cache
for the tpm2sh load subcommand.

The custom (and stripped off) X.509 parser allows to trivially download
EC certificates:

~ main ≡
❯ tpm2sh memory
HANDLE    TYPE         DETAILS
01c00002  certificate  rsa-2048:sha256
01c0000a  certificate  ecc-nist-p256:sha256
81000001  persistent   rsa-2048:sha256
81000002  persistent   ecc-nist-p256:sha256

~ main ≡
❯ tpm2sh memory tpm:01c0000a | openssl x509 -text -noout | head -15
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1298017026 (0x4d5e2b02)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = DE, O = Infineon Technologies AG, OU = OPTIGA(TM), CN = 
Infineon OPTIGA(TM) TPM 2.0 ECC CA 042
        Validity
            Not Before: Sep 16 22:18:38 2020 GMT
            Not After : Sep 16 22:18:38 2035 GMT
        Subject:
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:a5:09:12:cd:a6:0d:79:49:2f:b0:fa:39:bf:cf:

The stack overall has grown into a micro-ecosystem of re-usable components:

1. https://crates.io/crates/tpm2sh
3. https://crates.io/crates/tpm2-tpmkey
2. https://crates.io/crates/tpm2-policy-language
4. https://crates.io/crates/tpm2-crypto
5. https://crates.io/crates/tpm2-protocol

[1] https://github.com/librasn/compiler

BR, Jarkko

Reply via email to