Skip to content

PKCS11 TNGTLS

Bryan Hunt edited this page Mar 10, 2022 · 9 revisions

ATECC608 TNGTLS and PKCS#11

This page provides a step by step guide on how to use TNGTLS pre-provisioned devices, from Microchip Trust Platform, with PKCS#11 in a linux environment.

IMPORTANT NOTICE

Linux does not support baud rate switching for I2C which means the only supported I2C clock
frequency for cryptoauth devices is 100kHz. USING ANY OTHER FREQUENCY CONFIGURATION WILL NOT WORK.

Use with other devices on the same I2C channel may be unreliable when using the following devices:
ATSH204A, ATSHA206A, ATECC508A, ATECC608A

The following devices may be used with other I2C devices on the same channel:
ATECC608B, ECC204

When automatic low power modes are enabled (all devices prefixed with AT and optional for ECC204)
the user will have to manage access to the the i2c device so operations with the cryptoauth parts
are not interrupted.

If one is not able to ensure exclusive access to the i2c device during operations with the
cryptoauth component then they should provide it with an exclusive i2c channel for reliable
operation

Build and Install cryptoauthlib with PKCS11 support

Clone Cryptoauthlib on Linux system

$ git clone https://github.com/MicrochipTech/cryptoauthlib.git

Build Cryptoauthlib

$ cd cryptoauthlib
$ mkdir build
$ cd build
$ cmake -DBUILD_TESTS=ON -DATCA_HAL_I2C=ON -DATCA_PKCS11=ON -DATCA_TNGTLS_SUPPORT=ON -DATCA_ATECC608A_SUPPORT=ON -DATCA_OPENSSL=ON ../         
$ cmake --build .
$ sudo make install

Here -DBUILD_TESTS=ON is optional, which required to test the library. In case of TNG legacy support required, can include -DATCA_TNG_LEGACY_SUPPORT=ON For more information about cryptoauthlib configuration, check https://github.com/MicrochipTech/cryptoauthlib/wiki/Configuration

You can build and install with following command also

$ sudo cmake --build . --target install

Note: if you need to build a different configuration, you can remove cmake cache and delete the content of the build directory and you are good to re-run the commands.

Testing the I2C link

To check if the i2c connection is working use the following command

$ sudo i2cdetect -y 0

change the last digit with your bus number

Testing the Cryptoauthlib

The test application can be found under cryptoauthlib/test/

$ ./cryptoauth_test

Select a device ATECC608 and interface as i2c. You I2C bus number can be 2 or 1 depending on the hardware configuration. The TNGTLS address is 0x6A (TNGTLS)

$ 608 -i i2c 2 -a 0x6A

In Cryptoauthlib, default interface is USB HID. By providing interface, bus number and address will select proper interface and communicate with the same.

Run info command to get device revision number

$ info 

On successful execution of command, it will display device revision number.

Testing the Cryptoauthlib PKCS#11 integration

Before testing the PKCS11 i) Make sure you have installed the relevant tools and software packages. Check PKCS11-Linux-Setup guide page: https://github.com/MicrochipTech/cryptoauthlib/wiki/PKCS11-Linux-Setup

ii) Make sure the configuration is properly set. The file template is available under /varlib/cryptoauthlib/slot.conf.tmpl and rename the file to 0.conf

Please note that if you select a Trust Platform device such as TFLXTLS or TNGTLS you should not define objects! Remember to set the correct bus number based on your hardware configuration

    # Set a label for this slot (optional)
    # will default to <slot>ABC so
    # 0.conf will have a default label 00ABC
    label = MCHP

    # Configure the device interface for an enabled HAL
    # hid,i2c,<address>
    # i2c,<address>,<bus>
    # spi,<select_line>,<baud>
    interface = i2c,0x6A,0

    # Configure the device type - base part number (optional)
    # device = ATECC608A-TFLXTLS
    device = ATECC608A-TNGTLS

NOTES:

  • The label configuration helps referring to the device in a much easier way, by just specifying ..."pkcs11:token=MCHP;ob... or any other string you want to use.
  • I2C bus id shall be added after the device address

if your pkcs#11 setup is correct now, you should be able to list your token. List your token using the following command:

$ p11tool --list-tokens

Output Example:

Getting the Public key of slot 0 using P11-Kit

$ p11tool --export-pubkey "pkcs11:token=MCHP;object=device;type=private" 

Decoding the key with OpenSSL canbe done piping the two commands:

$ p11tool --export-pubkey "pkcs11:token=MCHP;object=device;type=private" | openssl pkey -pubin -text -noout

Using OpenSSL

OpenSSL can use directly the PCKS#11 engine. For example, the following command can be used to read the ECC public key of the given token:

$ openssl ec -engine pkcs11 -in "pkcs11:token=MCHP;object=device;type=private" -inform engine -pubin -noout -text

For creating a csr (ATECC608 stores certificates but here for simplicity we just use the file system) the following command can be used:

$ openssl req -engine pkcs11 -key "pkcs11:token=MCHP;object=device;type=private" -keyform engine -new -text -noout -sha256 -subj "/CN=0123xxxxxxxxxxxx01_ATECC" 

ECDSA sign and verify of a message using OpenSSL command line:

Create a message.txt file to test a sign and verify commands using OpenSSL. Use any txt editor such as vi or nano. ECDSA Sign

$ openssl dgst -sha256 -engine pkcs11 -sign "pkcs11:token=MCHP;object=device;type=private" -keyform engine -out signature.der message.txt

ECDSA Verify

$ openssl dgst -sha256 -engine pkcs11 -verify "pkcs11:token=MCHP;object=device;type=private" -keyform engine -signature signature.der message.txt

Output Example of sign and verify:

engine "pks11" set.
Verified OK

You can modify slightly the message and show that the verify will fail. In this case openssl output is:

engine "pks11" set.
Verification Failure

The public key of the given device can be taken from the manifest file or it can be extracted from the device usingthe following command:

$ openssl ec -engine pkcs11 -in "pkcs11:token=MCHP;object=device;type=private" -inform engine -pubin -pubout -out pub-key.pem

The public key can be read to double check from the device:

$ openssl ec -engine pkcs11 -in "pkcs11:token=MCHP;object=device;type=private" -inform engine -pubin -pubout -noout -text

Public key from saved file:

$ openssl ec -in pub-key.pem -pubin -pubout -noout -text

The pub-key.pem file can be used to verify the message on any other host using the following command:

$ openssl dgst -sha256 -verify pub-key.pem -signature signature.der message.txt

Reading Certificates from TNGTLS device using PKCS11

Make sure you set the PKCS11 configuration properly for TNGTLS device in 0.conf file Specifically make sure you are using device = ATECC608A-TNGTLS

ECC Key pair available on slot0 can be used as described in the previous sections.

Certificates can be accessible now using p11tool

$ p11tool --list-all-certs 'pkcs11:token=MCHP;type=cert'

or

$ p11tool --list-all-certs 'pkcs11:manufacturer=Microchip%20Technology%20Inc'

Full certificate chain can be extracted with following command:

$ p11tool --export-chain "pkcs11:token=MCHP;object=device;type=cert"

Decoding the signer certificate

$ p11tool --export-stapled 'pkcs11:token=MCHP;object=signer;type=cert' | openssl x509 -text -noout

Decoding the device certificate

$ p11tool --export-stapled 'pkcs11:token=MCHP;object=device;type=cert' | openssl x509 -text -noout

Connecting to the AWS Cloud using TNGTLS

AWS IoT Core example

Install trustplatform design suite https://www.microchip.com/design-centers/security-ics/trust-platform

  • Create your manifest file Run /TrustnGO/00_resource_generation/TNGTLS_manifest_file_generation.ipynb jupyter notebook

  • Upload your manifest file to AWS IoT Run /TrustnGO/05_cloud_connect/notebook/aws/TNGTLS_aws_connect.ipynb jupyter notebook

On successful aws cli configure, will provide iot endpoint address, which will be used later here.

If you don't have a Manifest file you can also provision the IoT thing and certificate manually using the IAM web interface of AWS IoT Core. This second approach is recommended only for proof of concept purposes. Uploading the Manifest file is by far more scalable.

The command suggested by AWS team is available here: https://docs.aws.amazon.com/iot/latest/developerguide/http.html#codeexample https://docs.aws.amazon.com/it_it/iot/latest/developerguide/protocols.html#protocol-port-mapping

This connection test is based on HTTPS APIs, supported by AWS IoT Core. You can use either wget or cURL to perform this test, depending on your linux setup.

Get the CA certificate for server authentication

$ wget https://www.amazontrust.com/repository/AmazonRootCA3.pem

or

$ curl https://www.amazontrust.com/repository/AmazonRootCA3.pem --output AmazonRootCA3.pem

TNGTLS device certificates are signed by an intermediate Signer and by a Root CA generated internally by Microchip. Different AWS users may use different devices signed by the same CA in different AWS IoT Core accounts. This scenario is supported by AWS IoT Core thanks to the Multi Account Registration feature. In order to make sure that the front-end servers of AWS route your request to Your account and properly terminate the TLS mutual handshake, you need to specify the endpoint URL using SNI. Notes about SNI can be found here: https://docs.aws.amazon.com/it_it/iot/latest/developerguide/protocols.html#protocol-port-mapping

wget handles SNI transparently in all requests, instead cURL requires to use the --resolve option. The two examples below show how you can post a message in AWS IoT Core using HTTPS APIs and TLS mutual authentication.

Make sure that the publish command is in line with the policy assigned to the thing. In this case we used a simple “open all” policy applicable for testing purposes ONLY. It's up to you to post on the allowed topic and in line with the configured topics.

To Publish message to AWS IoT Cloud using PKCS11 and wget use

# Replace iot_endpoint with actual iot endpoint address (got in previous step)
$ wget "https://<iot_endpoint>:8443/topics/test/topic?qos=1" \
  --ca-cert=./AmazonRootCA3.pem \
  --certificate="pkcs11:token=MCHP;object=device;type=cert" \
  --private-key="pkcs11:token=MCHP;object=device;type=private" \
  --post-data="{ \"message\": \"Hello, world\" }"

To Publish message to AWS IoT Cloud using PKCS11 and cURL use

# Replace iot_endpoint with actual iot endpoint address (got in previous step)
$ curl --verbose --tlsv1.2 \
    --cacert AmazonRootCA3.pem \
    --engine pkcs11 \
    --cert "pkcs11:token=MCHP;object=device;type=cert" \
    --key "pkcs11:token=MCHP;object=device;type=private" \
    --request POST --data "{ \"message\": \"Hello, world\" }" \
    --resolve <iot_endpoint>:8443:<iot_endpoint>
    https://<iot_endpoint>:8443/topics/test/topic?qos=1

Replace <iot_endpoint> with your enpoint address.

  • On AWS web console you should see:
Clone this wiki locally