Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dbus-parsec with NXP secureobj library #223

Closed
paulhowardarm opened this issue Aug 17, 2020 · 4 comments · Fixed by #241
Closed

Support dbus-parsec with NXP secureobj library #223

paulhowardarm opened this issue Aug 17, 2020 · 4 comments · Fixed by #241
Assignees
Labels
enhancement New feature or request

Comments

@paulhowardarm
Copy link
Collaborator

Summary

Provide the required functionality to support the dbus-parsec integration on platforms such as NXP Layerscape 1046a. This means enhancing the existing PKCS#11 provider so that it can use non-PKCS#11 functions for public key operations.

Detail

NXP's secure object library (libsecureobj.o) has a PKCS#11 front-end, so the PKCS#11 Parsec provider can already be used to connect with it on supported platforms. However, the PKCS#11 coverage on this platform is limited to signing and decryption operations with private keys. The corresponding public key operations (for encryption and verification) are absent.

Parsec needs a way of fulfilling the entire set of private and public key operations using a mixture of PKCS#11 functionality and MBed Crypto functionality. There currently isn't a Parsec provider that is architected to switch between different methods in this way. All of the existing providers are uniform in the sense that they expect all operations to be fulfilled by a single back-end API in the software stack that connects with the hardware.

PKCS#11 is explicitly an opt-in standard, so it is entirely reasonable for an implementation to only provide partial coverage of the API. Parsec might encounter other PKCS#11 libraries, not just the NXP one, where the coverage is limited in this way. Public keys by definition do not need hardware protection, so it might be a common pattern for public key operations to be absent in the library. It would be good for Parsec to work with implementations like this.

There are various options for doing this:

  • Import the rust-psa-crypto crate directly into the PKCS#11 provider, and use it to supply the primitives that are not available in the connected PKCS#11 library. This would require making a PKCS#11 C_GetFunctionList call in the connected library to see which operations are supported, and then switching over to PSA Crypto calls as needed.
  • Fork the PKCS#11 provider to create an NXP-specific version, which imports the rust-psa-crypto crate and uses it for the functions that we know are needed. (Basically the same as the option above, but with more hard-coding and without inspecting the C_GetFunctionList data - might be simpler to implement?)
  • Create a new hybrid provider for the secure object platform, which delegates functionality to the PKCS#11 and MBed Crypto providers respectively. This possibly requires very little code because it can re-use all of the code in the existing providers. It just becomes a veneer or adaptive provider, created specifically for this purpose.
@paulhowardarm paulhowardarm added the enhancement New feature or request label Aug 17, 2020
@hug-dev
Copy link
Member

hug-dev commented Aug 17, 2020

PKCS#11 is explicitly an opt-in standard, so it is entirely reasonable for an implementation to only provide partial coverage of the API. Parsec might encounter other PKCS#11 libraries, not just the NXP one, where the coverage is limited in this way. Public keys by definition do not need hardware protection, so it might be a common pattern for public key operations to be absent in the library. It would be good for Parsec to work with implementations like this.

I agree with that but wondering if this is a problem to solve inside the Parsec service or in the client? If some operations are not supported by a provider, the PsaNotSupported status code should be returned in which case the client can choose to use another provider.

This would require making a PKCS#11 C_GetFunctionList call in the connected library to see which operations are supported, and then switching over to PSA Crypto calls as needed.

The rust-pkcs11 crate that we use already call C_GetFunctionList as part of its initialisation. It might return an error if not all operations are implemented. We can discuss changes there to make it work even if some functions are not supported.

@paulhowardarm
Copy link
Collaborator Author

I think the client is the wrong place to do this work, not least because it then means the logic would have to be replicated in every per-language client library, and there would need to be a lot of intelligence in the client to understand how to treat PsaNotSupported and whether or not that means migrating the operation to a different provider. (That same error code might mean that the operation cannot be supported in PSA at all, regardless of provider use). It also means explicitly modelling the capabilities of the platform as being composed of multiple providers, with the client needing awareness of what those providers are doing and why. That's a lot of leakage of detail. It is admittedly very similar to what my proposed "hybrid provider" would have to do, but at least putting it in a provider means that we only need to write the logic once, and the client library can still do everything agnostically once the service has been deployed.

If you consider the specific case of private vs. public keys. If I provision a key-pair in the PKCS#11 provider, but then I try to use its public key and get PsaNotSupported, the client library now needs to understand that it has to export the public key and import it into a different provider (Mbed Crypto), and then call the operation there instead. I think this is spreading platform knowledge through too many parts of the system.

@ionut-arm
Copy link
Member

Quick question: Is the "dual support" meant exclusively for public key operations? If so, we'll need to check explicitly for that instead of routing all ops to Mbed Crypto if they fail with some given code.

@paulhowardarm
Copy link
Collaborator Author

I don't think it would ever make sense to allow all operations to be re-routed. If nothing else, this could create a very misleading impression of how a client's private keys are being stored if they have notionally set up a hardware provider but it's actually invisibly failing over to software. The immediate specific requirement is to create a dual model that allows NXPs secureobj library to be driven through PKCS#11, with Mbed Crypto being used to plug the gaps on the public key side. This might then lead to a longer term consideration about how the PKCS#11 provider should work, given that similar opt-in mechanics might exist elsewhere, but I think there does always need to be a baseline assumption about a minimal level of support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants