Hello,
Arm is seeking early feedback on a proposed interface for cryptographic
drivers that can be plugged into an implementation of the PSA
Cryptography API. A copy of the current specification is attached. You
can find the current draft of the specification of this interface at
https://github.com/gilles-peskine-arm/mbedtls/blob/psa-unified-driver-proto…
Please note that this is work in progress. The document is not complete
yet. At this stage, it is intended to offer a general overview of the
design, not as an implementable specification. Our intention is to
continue refining this design, however we may change it based on the
feedback that we will receive and there is even a small chance that we
will abandon it.
The primary intent of this specification is to allow manufacturers of
cryptographic hardware to distribute drivers that can be added to a
pure-software, portable implementation of the PSA Cryptography API such
as Mbed TLS. The interface was designed to support three types of hardware:
* Cryptographic accelerators that operate on a key which is provided in
cleartext at the beginning of the operation. This type of driver can
also be used to plug in software engines.
* Protected environments that operate on a wrapped key which is stored
outside the protected environment.
* Protected environments that have internal key storage and operate on
keys designated by an identifier.
Concretely, a driver manufacturer would distribute:
* A JSON file specifying the driver's capabilities.
* C headers declaring the types and functions provided by the driver.
* The implementation of the functions provided by the driver, either in
the form of C source code or in the form of compiled code.
Then when an application uses a key:
* If the key is in the memory or local storage of the PSA crypto
subsystem and a driver is available for the requested cryptographic
mechanism, the core (e.g. Mbed TLS) dispatches the cryptographic
operation to the driver.
* If the key is in local storage and no driver is available, the core
performs the cryptographic operation itself.
* If the key is in some other location (as specified by its lifetime),
the core invokes the protected environment driver corresponding to that
location.
This proposal supersedes the previous drafts “PSA cryptographic
accelerator interface” (psa_crypto_accel.h) and “PSA secure element
driver interface” (crypto_se_driver.h).
We intend to implement this specification in Mbed TLS in such a way that
a platform distributor can combine drivers and distribute C source code,
object files or a mixture of the two in their system development kit. In
the long term, the accelerator interface defined here will replace the
current MBEDTLS_xxx_ALT mechanism.
Comments are welcome through the following venues:
* Public email to the psa-crypto or mbed-tls mailing list at
TrustedFirmware.
* Public comments on GitHub on the pull request
https://github.com/ARMmbed/mbedtls/pull/3313 .
* Private email to <mbed-crypto(a)arm.com>. These emails will only be
shared inside Arm. We may use your feedback to influence the design of
PSA Crypto, but your identity and the specifics will be kept confidential.
We do not have a specific deadline for feedback, however we intend to
start implementing this interface in Mbed TLS in June 2020, so feedback
received later will have a reduced chance of influencing the design if
it would entail major changes.
Best regards,
--
Gilles Peskine
Mbed TLS developer and PSA Cryptography architect
Hi,
There is an issue in version 1.0.0 of the PSA Crypto API, that can result in severe inefficiency in key generation in some circumstances. It is also possible that the definition could be interpreted differently in different implementations, which is a major interoperability issue for key derivation algorithms.
As a result, Arm would like to clarify this operation, ideally in a way that eliminates the inefficiency. Please let me know if you have an implementation of the PSA Crypto API, and whether this proposed change would affect it.
In section 10.5.3, the definition of psa_key_derivation_output_key() for several key types is inefficient for Weierstrass elliptic curves and Diffie-Hellman groups whose size is not a multiple of 8. The definition does not follow the cited NIST specifications (although this is not a compliance issue since these NIST specifications apply to random generation, not to deterministic derivation).
The current specification states:
> this function draws a byte string of length ceiling(bits/8) bytes. If the resulting byte string is acceptable, it becomes the key, otherwise the drawn bytes are discarded. This process is repeated until an acceptable byte string is drawn.
This is secure, but it is inefficient if some bits are always 0 (or always 1) in acceptable results. In practice, for L-bit curves where L is not a multiple of 8 (for example sec521r1), this leads to rejecting many candidates because their most significant bits are not 0.
The NIST process (e.g. https://doi.org/10.6028/NIST.SP.800-56Ar3 §5.6.1.2.2 step 4) is similar, but involves drawing L bits from the RNG, not ceiling(L/8).
The input to this function is a byte stream generator. It wouldn't make sense to consume a number of bits that isn't a whole number of bytes. However, forcing top bits to 0 would make sense, and would be more efficient and closer to the NIST process.
Arm proposes to modify the definition to require that the tops bits (ceiling(bits/8)*8 - bits) are set to zero when drawing bytes from the generated stream, prior to the byte string being tested for acceptability. This would be an incompatible change for any implementation that had support for deriving affected keys, which discarded byte strings that had any of the top bits set to one.
Regards,
Andrew Thoelke
Software Systems Architect | Arm
. . . . . . . . . . . . . . . . . . . . . . . . . . .
m. +44 7766 990101
Arm.com
Hi Kevin,
The separation between the secure and non-secure world is designed to
keep the code in the secure world as small as possible. I don't think
there'll ever be enough justification to include base64 encoding in the
secure world.
The current PSA crypto API was designed to be mostly simple wrappers
around calls to the secure world. We (Arm) are considering extending it
with some higher-level functions designed to remain in the normal world.
This would include key formats such as SubjectPublicKeyInfo, and PEM
encoding. I can't make any promises as to when or even if this will
happen. At the moment, all we have to offer is the existing mbedtls
functions.
--
Gilles Peskine
Mbed TLS developer and PSA crypto API designer
P.S. When I'm working on Mbed TLS and using a shell prompt to calculate
or verify values (usually with openssl or python/cryptodome), I usually
use hex/binary conversion, and DER to encode asymmetric keys.
On 14/05/2020 13:56, Kevin Townsend via psa-crypto wrote:
> Hi,
>
> Working on some cryptography demos for Zephyr, now that TF-M support
> was fully merged in for the upcoming 2.3 release, I've put some test
> code together that:
>
> - Generates a permanent persistent key (prime256v1)
> - Displays the public key based on the private key above (in hex format)
> - Calculates the SHA256 hash of a payload
> - Signs the hash with the persistent key
> - Verifies the signature using the public key
> - Destroys the key
>
> https://gist.github.com/microbuilder/a326cc6b935f87f413d89e44f9d3de05
>
> An important part of the hash/sign/verify workflow is of course
> verifying the signature on the receiving end, which requires access to
> the public key generated on the device (perhaps a new key was randomly
> generated when the device first boots, etc.).
>
> We can currently derive the public key in DER format with the existing
> API, but it seems like a helper function to convert to PEM would make
> this export process easier, since you could then just copy and paste
> the text output directly for provisioning or debug purposes.
> mbedcrypto 3.1.0 already has a library/pem.c utility function for this
> that could be exposed: mbedtls_pem_write_buffer
>
> In general, I think enabling the import and export of PEM data, not
> just DER, would make the process of dealing with keys during
> provisioning easier.
>
> I didn't find any references to PEM in the PSA Cryptography API, but
> perhaps I'm missing some obvious already existing means to convert to
> PEM, or is this something other people see any value in having?
>
> Being able to copy and paste PEM data (versus DER which can't be
> copy/pasted), then save it as a file, for example, would make working
> with openssl easier, such as the commands described here where we
> could use the extracted PEM data to verify the signed data from the
> command line:
> https://gist.github.com/microbuilder/a326cc6b935f87f413d89e44f9d3de05#file-…
>
> Any thoughts on the idea, or perhaps it's already been added and I'm
> simply missing it?
>
> It's easy to add this at the NS application level as well, of course,
> but it does seem like a useful enough operation that it should be
> available in S world when requesting key data.
>
> Best regards,
> Kevin Townsend
>
Hi,
Working on some cryptography demos for Zephyr, now that TF-M support was
fully merged in for the upcoming 2.3 release, I've put some test code
together that:
- Generates a permanent persistent key (prime256v1)
- Displays the public key based on the private key above (in hex format)
- Calculates the SHA256 hash of a payload
- Signs the hash with the persistent key
- Verifies the signature using the public key
- Destroys the key
https://gist.github.com/microbuilder/a326cc6b935f87f413d89e44f9d3de05
An important part of the hash/sign/verify workflow is of course verifying
the signature on the receiving end, which requires access to the public key
generated on the device (perhaps a new key was randomly generated when the
device first boots, etc.).
We can currently derive the public key in DER format with the existing API,
but it seems like a helper function to convert to PEM would make this
export process easier, since you could then just copy and paste the text
output directly for provisioning or debug purposes. mbedcrypto 3.1.0
already has a library/pem.c utility function for this that could be
exposed: mbedtls_pem_write_buffer
In general, I think enabling the import and export of PEM data, not just
DER, would make the process of dealing with keys during provisioning easier.
I didn't find any references to PEM in the PSA Cryptography API, but
perhaps I'm missing some obvious already existing means to convert to PEM,
or is this something other people see any value in having?
Being able to copy and paste PEM data (versus DER which can't be
copy/pasted), then save it as a file, for example, would make working with
openssl easier, such as the commands described here where we could use the
extracted PEM data to verify the signed data from the command line:
https://gist.github.com/microbuilder/a326cc6b935f87f413d89e44f9d3de05#file-…
Any thoughts on the idea, or perhaps it's already been added and I'm simply
missing it?
It's easy to add this at the NS application level as well, of course, but
it does seem like a useful enough operation that it should be available in
S world when requesting key data.
Best regards,
Kevin Townsend