tillitis / tkey-verification

Vendor signing and user verification of TKey genuineness
https://www.tillitis.se
GNU General Public License v2.0
42 stars 2 forks source link

Tillitis TKey Verification

tkey-verification is a tool used for signing a TKey identity and verifying that it still has the same identity as it did when it was provisioned, typically by Tillitis the original vendor.

Note well: If your TKey has been provisioned by you or someone else, like your IT department, you will need to run their version of the tkey-verification program instead of this one.

Installation

Official instructions on Tillitis' web.

You can download a release of the tool at:

https://github.com/tillitis/tkey-verification/releases

Or do:

$ go install github.com/tillitis/tkey-verification/cmd/tkey-verification@latest

if you have a Go compiler. Please note that if you install like this you won't get the tag in --version.

Terminology

Security Protocol

During provisioning

  1. Retrieve the UDI from the device under verification.
  2. Run the signer with a specific tag on the device under verification. This creates a unique key pair.
  3. Retrieve signer public key from the device under verification.
  4. Ask signer to sign a random challenge.
  5. Verify the signature of the random challenge with the retrieved public key to let the device prove that it has the corresponding private key.
  6. Ask signer for a digest of the firmware binary (in ROM). Consult the internal firmware database to verify that the TKey, according to its hardware revision, is running the expected firmware.
  7. Sign a message consisting of the UDI, firmware digest, and signer public key, with a vendor signature.
  8. Publish the Verification file, which includes the UDI, the tag and digest of the signer program used, the vendor signature, and the timestamp when signature was made.

Verifying

  1. Retrieve the UDI from the device under verification.
  2. Get the Verification file with the vendor signature, signer tag and digest for this UDI.
  3. Run the signer with the same tag and digest on the device under verification.
  4. Retrive the signer public key.
  5. Ask signer to sign a random challenge.
  6. Verify the signature of the random challenge with the signer public key thus proving that the device under verification has access to the corresponding private key.
  7. Ask signer for a digest of the firmware binary (in ROM). Consult the internal firmware database to verify that the TKey, according to its hardware revision, is running the expected firmware.
  8. Recreate the message of UDI, firmware digest and signer public key. Verify the vendor signature of the message, thus proving that the UDI, the firmware, and this private/public key pair was the same during vendor signing.

Note that the exact same signer binary that was used for producing the signer signature during provisioning must be used when verifying it. If a different signer is used then the device private/public key will not match, even if the TKey is the same. A verifier must check the "hash" field and complain if it does not have a signer binary with the same digest.

Building tkey-verification

Build the tkey-verification tool with the test file containing public key(s) for vendor signing/verify.

$ cp test-vendor-signing-pubkeys.txt cmd/tkey-verification/vendor-signing-pubkeys.txt
$ make

See below if you need to get hold of a different public key.

The device apps used for signing is included in binary form under cmd/tkey-verification/bins/. See more info under Building included device apps if you want to build them yourself.

Maintainance

See Implementation notes for more in-depth notes on the program.

Building included device apps

The device apps used for signing is included in binary form under cmd/tkey-verification/bins/.

Reproducible versions of the device app verisigner binary included in this repo can be built from earlier verisigner tags. Checkout the wanted tag and follow the instructions there.

The signer binary can be built reproducible from the tags mentioned in the bins directory. Please note that you have to build without touch requirement.

Certificates

For your convenience we include a test CA and some test certificates in certs. They expire 10 years after being generated.

If you need to rebuild CA, server, and client certs you can use any ordinary X.509 certificate tools like GnuTLS's certtool or OpenSSL to generate your certificates.

You can also install the small certstrap tool and run:

$ make certs

Testing

For the complete set of commands, see the manual page tkey-verification(1).

Creating the vendor public keys file

The vendor's public key is built into the tkey-verification binary from a text file.

For each public key, the tag and hash digest of the device app used when extracting the public key is also provided. The signing server needs this so that its TKey can have the correct private key when signing. Note that these tags per public key are independent from and can be different from the tag used for device signing.

A test file is provided in test-vendor-signing-pubkeys.txt. It contains the default public key of our QEMU machine, which is generated when running verisigner v0.0.3.

If you want to use some other key(s) this is how:

If you're just testing start a QEMU as a signing endpoint. See above.

Get the public key from the TKey in the signing server. We provide a command in tkey-verification, show-pubkey, for that. The path to the app binary to use must be given as an argument.

Example:

./tkey-verification show-pubkey --port /dev/pts/10 --app cmd/tkey-verification/bins/signer-v1.0.1.bin
Public Key, app tag, and app hash for vendor-signing-pubkeys.txt follows on stdout:
03a7bd3be67cb466869904ec14b9974ebcc6e593abdc4151315ace2511b9c94d signer-v1.0.1 cd3c4f433f84648428113bd0a0cc407b2150e925a51b478006321e5a903c1638ce807138d1cc1f8f03cfb6236a87de0febde3ce0ddf177208e5483d1c169bac4

Enter that line into a file, for instance other-pubkey.txt. Then build everything with this file:

$ cat other-pubkey.txt >> cmd/tkey-verification/vendor-signing-pubkeys.txt
$ make

Verification file

The computer running tkey-verification serve-sign generates files in a directory signatures/ which is named after the Unique Device Identifier (in hex), for example signatures/0133704100000015. This file is needed in order to be able to verify a TKey.

The file contains:

Example file content:

{
  "timestamp": "2023-03-03T09:31:51Z",
  "apptag": "verisigner-v0.0.1",
  "apphash": "9598910ec9ebe2504a5f894de6f8e0677dc94c156c7bd6f7e805a35354b3c85daa4ca66ab93f4d75221b501def457b4cafc933c6cdcf16d1eb8ccba6cccf6630",
  "signature": "db4e7a72b720b33f6d4887df0f9dcdd6988ca8adb6b0042d8e8c92b5be3e4e39d908f166d093f3ab20880102d43a2b0c8e31178ab7cdb59977dcf7204116cc0c"
}

Releases of tkey-verification and reproducible builds

tkey-verification is released with the help of GoReleaser, see .goreleaser.yaml in the root of the repo.

Currently this has to be done on a computer running Darwin, at least for Tillitis' official releases. The reason is that tkeyclient needs CGO enabled for Darwin to enumerate USB-devices, and that the Darwin binary is signed with Tillitis' Apple Developer Certificate, which at the moment also needs to be done using Darwin. We are looking into solutions for both those points.

You should be able to build a binary that is a exact copy of our release binaries if you use the same Go compiler, at least for the statically linked Linux and Windows binaries.

Please see the official releases for digests and details about the build environment.

Note that tar.gz and such files are not reproducible since they contain a timestamp.

For the universal Darwin file, the signature produced by Tillitis needs to be removed before it can be compared to one not built and released by Tillitis. This can be done using codesign --remove-signature path/to/binary, at least on a Darwin machine.

The releases are published at https://github.com/tillitis/tkey-verification/releases with the binaries and checksum files.

Release v0.0.2-v0.0.3 were built with make podman and the release-builds directory contains digests of released versions.