mcu-tools / mcuboot

Secure boot for 32-bit Microcontrollers!
Apache License 2.0
1.35k stars 678 forks source link

Add HSM support to imgtool #599

Open d3zd3z opened 4 years ago

d3zd3z commented 4 years ago

Add support for an HSM to imgtool so that the private keys can be managed, and don't have to live in the filesystem. This can be developed using softhsm. Derived from #219.

schultetwin commented 3 years ago

I'm willing to help do the development work for this ticket! I'd suggest the following changes:

class KeyBackend A new interface will be added to imgtool that is KeyBackend. It will provide the following interface:

class KeyBackend:
    def key_size():
        """Returns the keysize in bits. Only used for RSA keys"""
    def public_bytes(self, encoding, format):
        """Returns the bytes of the public key in the proper format and encoding"""
    def private_bytes(self, encoding, format):
        """Returns the bytes of the private key in the proper format and encoding"""
    def sign(self, payload, signature_algorithm):
        """Signs the payload. signature_type indicates how it should be signed. i.e.: ecdsa_sh256 (still need to determine how to name these)"""
    def verify(self, signature, payload, signature_algorithm):
        """Verify the signature with the payload"""

The current KeyClass objects will take a KeyBackend type as part of their __init__.

imgtool will come with a built-in KeyBackend for "python-cryptography". It will offer a mechanism to register new plugins via: https://packaging.python.org/guides/creating-and-discovering-plugins/#using-package-metadata. This will allow anyone to create their own HSM implementation.

**CLI API*** All commands that accept a --key argument will also accept a --key-storage argument. The valid arguments to --key-storage would the choices from one of the KeyBackend plugins that are registered?

Thoughts? I'll likely put-up a PR in a few weeks, but am more than open to throw it all out and take on a different design.

d3zd3z commented 3 years ago

This seems like a reasonable way to approach this. I would recommend having an implementation using something like softhsm that is readily available for other developers to use and test.

github-actions[bot] commented 2 years ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

amoskopp commented 2 years ago

@d3zd3z I have added HSM support to imgtool.py using Nitrokey HSM: https://github.com/grandcentrix/mcuboot/commits/nitrokey-hsm-support

Edit: Please explain what would need to be changed to upstream this.

d3zd3z commented 2 years ago

re HSM support:

The only thing that stands out to me is the searching all of "/usr" for the hsm library. The directory can be quite large, and there is no particular reason that something being found would actually be the desired library. I'd suggest having either an environment variable or an argument. How is this normally done for PKCS#11 python apps?

Otherwise, feel free to add a pull request to the main MCUboot repo and we can take a look at it there.

d3zd3z commented 2 years ago

1329 provides some of what is needed for this, especially when those making images don't have direct access to the key.

amoskopp commented 2 years ago

The only thing that stands out to me is the searching all of "/usr" for the hsm library. The directory can be quite large, and there is no particular reason that something being found would actually be the desired library.

There is a reason for that, the soname is not used by any other library. Besides, this thing just does not work if the wrong library is loaded.

I'd suggest having either an environment variable or an argument. How is this normally done for PKCS#11 python apps?

In general for tools, the path is given, or – more commonly – the library is searched for similarly to what I did here. In fact, other software have worked on that uses Python and PKCS#11 searches for the library in the same way.

amoskopp commented 2 years ago

1329 provides some of what is needed for this, especially when those making images don't have direct access to the key.

I doubt that #1329 is useful for me. I try to rebase now.

nickrbogdanov commented 1 year ago

The only thing that stands out to me is the searching all of "/usr" for the hsm library

FWIW the performance hit on an 11th gen NUC is 4s:

$ sync ; sudo sysctl -w vm.drop_caches=3
vm.drop_caches = 3
$ time find /usr -name opensc-pkcs11.so
/usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so
/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so

real    0m4.000s
user    0m0.207s
sys 0m0.690s

This isn't great, but if that's how the python-pkcs11 library is currently designed to be used, I'd suggest taking this code as-is and working to improve it in the future. If we can enhance the upstream library to use p11kit, it can enumerate the PKCS#11 modules without performing an exhaustive search.

rretanubun commented 7 months ago

@nmoskopp : Thanks for sharing! FYI: I got the work you shared rebased on mcuboot v2.0.0: https://github.com/rretanubun/mcuboot/commits/imgtool-pkcs11-signing/ tested on NitroKey HSM2