MicrochipTech / cryptoauthlib

Library for interacting with the Crypto Authentication secure elements
Other
382 stars 221 forks source link

pkcs11_add_provider: PKCS #11 error in device #208

Closed GalaxyGorilla closed 3 years ago

GalaxyGorilla commented 3 years ago

Hey everyone,

there are already some issues here about getting the p11tool working with cryptoauthlib but those haven't helped me :(.

I'm using the ATECC508A chip with cryptoauthlib v3.3.0 and p11tool 3.6.14 without the proxy kit and I was closely following the wiki articles.

Compilation with the following flags:

-D ATCA_HAL_I2C=ON -D ATCA_PKCS11=ON -D ATCA_OPENSSL=ON -D ATCA_ATECC508A_SUPPORT=ON -D ATCA_ATECC608_SUPPORT=ON -D ATCA_BUILD_SHARED_LIBS=ON

The /var/lib/cryptoauthlib/0.conf config file (note the '1' for the bus number, I've seen problems in other issues about that):

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

# Slot 0 is the private key
# URL: pkcs11:type=private
object = private,device,0

However, I get the following error (with debug logging on):

$ p11tool -d 9999 --list-all --provider /usr/lib/libcryptoauth.so
|<2>| p11: Initializing module: /usr/lib/libcryptoauth.so
|<3>| ASSERT: pkcs11.c[gnutls_pkcs11_add_provider]:414
pkcs11_add_provider: PKCS #11 error in device
Setting log level to 9999

I'm using Erlang on top of buildroot and funnily the Erlang SSL framework has no problems so far when I integrate the cryptoauthlib shared object, but I couldn't really test it of course since the private key inside the secure element is missing. Generating a private key inside the chip is my ultimate goal.

Any hint what's wrong here?

bryan-hunt commented 3 years ago

The most obvious issue would be that the address is the address as defined by the part datasheet which uses the upper 7 bits of the byte to specify the address. If your i2c probe is showing the device as 0x60 then the address specified here would be 0xC0

An important note however is that the pkcs11 interface does not replace the configuration steps. If you have not worked through the use cases and properly configured the part you must do that first (or are not using a preconfigured part). I would recommend the Trust Platform Design Suite to start.

GalaxyGorilla commented 3 years ago

Thanks you @bryan-hunt! So there were two problems: as you mentioned the device address is 0xC0 as you explained and then also the bus number was wrong (in my case it's 0). The latter problem is more embarrassing than I'd like to admit ;).

So now I have:

$ p11tool --list-all --provider /usr/lib/libcryptoauth.so

Object 0:
        URL: pkcs11:model=ATECC508A;manufacturer=Microchip%20Technology%20Inc;serial=23071E5E685200EE;token=00ABC;object=device;type=private
        Type: Private key (EC/ECDSA)
        Label: device
        Flags: CKA_PRIVATE; CKA_SENSITIVE;
        ID:

I also --initialized the token getting:

$p11tool --list-tokens --provider /usr/lib/libcryptoauth.so
Token 0:
        URL: pkcs11:model=ATECC508A;manufacturer=Microchip%20Technology%20Inc;serial=23071E5E685200EE;token=00ABC
        Label: 00ABC
        Type: Hardware token
        Flags: RNG, uPIN uninitialized
        Manufacturer: Microchip Technology Inc
        Model: ATECC508A
        Serial: 23071E5E685200EE
        Module:

So that's cool. But generating a key still doesn't work as expected:

$ p11tool -d 9999 --login --generate-privkey=ECDSA --bits 1024 --label 'MyPrivateKey' --outfile /tmp/MyPublicKey.pub 'pkcs11:token=00ABC' --provider /usr/lib/libcryptoauth.so

|<2>| p11: Initializing module: /usr/lib/libcryptoauth.so
Generating an EC/ECDSA key...
Token '00ABC' with URL 'pkcs11:model=ATECC508A;manufacturer=Microchip%20Technology%20Inc;serial=23071E5E685200EE;token=00ABC' requires user PIN
Enter PIN: |<2>| p11: Login result = ok (0)
|<3>| ASSERT: pkcs11_privkey.c[gnutls_pkcs11_privkey_generate3]:1287
|<2>| p11: The operation failed
Error in pkcs11_generate:1355: PKCS #11 error.
Setting log level to 9999

Any clue what's wrong here? The PIN seems to be ignored (I can use whatever PIN I want).

EDIT: I ended up having two objects now (despite no command being successful!), but I can't access any of them.

Object 0:
        URL: pkcs11:model=ATECC508A;manufacturer=Microchip%20Technology%20Inc;serial=23071E5E685200EE;token=00ABC;object=device;type=private
        Type: Private key (EC/ECDSA-SECP256R1)
        Label: device
        Flags: CKA_PRIVATE; CKA_SENSITIVE;
        ID:

Object 1:
        URL: pkcs11:model=ATECC508A;manufacturer=Microchip%20Technology%20Inc;serial=23071E5E685200EE;token=00ABC;object=device;type=public
        Type: Public key (EC/ECDSA-SECP256R1)
        Label: device
        ID:

I can't --export-pubkey (The requested data were not available.) nor can I --delete them (Cannot destroy object: Unknown error).

The 'usecase' I'm working on is btw Custom Public Key Infrastructure. More context: I'm using the GRiSP2 board (a prototype, https://www.kickstarter.com/projects/peerstritzinger/grisp-2) and the used ATTEC508A just comes with the default pre-programmed config.

bryan-hunt commented 3 years ago

So first off the initialization step programs in a default configuration that is only suitable for basic experimentation and not production - it only support a limited number of use cases. I highly recommend that you follow my previous recommendation as it will reduce frustration in the long term.

Your genkey command is failing for two reasons:

However it is also not an intended use case for the pkcs11 interface and the configuration that has been programmed is a simple one.

Per the wiki reference however this should print the public key:

p11tool --provider /usr/lib/libcryptoauth.so --export-pubkey "pkcs11:token=00ABC;object=device;type=private" 
GalaxyGorilla commented 3 years ago

@bryan-hunt Thanks for pointing out my rookie mistakes! I did a lot more reading and I think I'm a bit less confused now :). Currently there's no public key because there never was a private key to begin ... because the config is not locked. AFAIK just errors are returned when data is attempted to be written with the config zone being unlocked, right?

For me the 'usual' process of setting up the device appears to work like this:

1. write configuration to the device
2. lock the configuration, which enables you to
3. write e.g. secret data to slots
4. lock the data, this ‘activates’ the configuration and in particular access policies, now you’re able to
5. execute cryptographic operations (like signing stuff in TLS)

Does that sound correct? Also, is there a 'factory reset' such that I could re-do steps 1-4 (I don't think so)? If not, is there a config you could point me to (just to safe me some work), which allows for maximum read and write capabilities such that I can still change data after step 4?

I know that 1-4 are supposed to be done at the manufacturer but we use the device also on our own prototyping boards (the chip is soldered) to prove real application concepts and also for just tinkering around (it's used by a lot of hobbyists). Hence we want to do 1-4 on our own. When products move into production then we obviously use the framework as provided by microchip.

On another note, I'm very much thinking about building an Erlang/Elixir wrapper library for cryptoauthlib such that the whole community can make use of it. There's currently a lot going on in the area of IIoT here.