Hi Rehan,

When using the built-in key in an application, you just refer to it by its id.

The driver wrapper receives the “slot number” from mbedtls_psa_platform_get_builtin_key as the key_buffer argument.

So if you have an opaque driver, and you want to sign with a key coming from the outside, the data flow is:
  1. The application calls psa_import_key() with the key in plaintext, receives a key id.
  2. Via psa_driver_wrapper_import_key(), the core calls the driver with the key plaintext, and obtains an opaque representation of the key (typically either a slot number/name, or the key data wrapped with a secret key).
  3. The application calls psa_sign_message() with the key id.
  4. The core looks up the key id in the key store and finds the key's location and the opaque representation of the key.
  5. Via psa_driver_wrapper_sign_message(), the core calls the driver, passing the opaque representation of the key.

With a built-in key, you don't have steps 1 and 2: the key already exists. And step 4 is replaced by: the core calls mbedtls_psa_platform_get_builtin_key() to find the key location and the opaque representation. Steps 3 and 5 are unchanged.

There is an example in the unit tests, not with psa_sign_message() but with psa_export_public_key():

I hope this helps. We are working on documentation and examples for driver support, but I'm afraid it's going to take a while before we reach built-in keys.

Best regards,

--
Gilles Peskine
Mbed TLS developer and PSA Crypto architect

On 26/01/2023 17:02, Rehan Malak via mbed-tls wrote:
Dear MbedTLS dev,

I am writing an opaque driver (equivalent of PSA_CRYPTO_TEST_DRIVER_LOCATION/PSA_KEY_PERSISTENCE_READ_ONLY in the test suite) with the PSA API compiled with MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS.

But I am not sure if I have to use "psa_import_key" before "psa_driver_wrapper_sign_message" or if I have to "read/generate" the builtin key on the fly, at each psa_driver_wrapper_* operation ?

Would it be possible to add this example in the test suite ? Or explain how builtin key + opaque driver is supposed to be used with, for example, "psa_driver_wrapper_sign_message" ?

I put more details below.

Thank you in advance,
Best regards,
 
Rehan

#############################################################################

I would like to write an example doing :

I) psa_sign_message (ECDSA SECP256R1 SHA-256)
II) psa_export_public_key
III) psa_verify_message (with the public key from II)

I am following the examples provided by the test suite, especially :

1) sign_message transparent driver: calculate in driver ECDSA SECP256R1 SHA-256
using the API :
  - psa_import_key
  - psa_sign_message
with the attributes :
  - key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)

2) PSA opaque driver builtin pubkey export: secp256r1
using the API :
  - psa_export_public_key
with the attributes :
  - key_id = MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1
  - key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)
and the driver code :
  - platform_builtin_keys.c : mbedtls_psa_platform_get_builtin_key()    (PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION)
  - test_driver_key_management.c : mbedtls_test_opaque_export_public_key()

3) verify_message transparent driver: calculate in driver ECDSA SECP256R1 SHA-256
using the API :
  - psa_import_key
  - psa_verify_message
with the attributes :
  - key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)

It seems to me that II)=2) and 3) should be pretty similar to III) because I assume that neither transparent vs opaque, nor PSA_KEY_TYPE_ECC_KEY_PAIR vs PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE, is gonna change much here.

But the signature I) is less clear... Has the built-in key feature been thought such that the read-only key is read each time we call a different PSA API function ?

Long story short, an "opaque driver + builtin keys" equivalent of the "sign_message transparent driver: calculate in driver ECDSA SECP256R1 SHA-256" example in the test-suite would be really helpful :)