-
Notifications
You must be signed in to change notification settings - Fork 18
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
Create a new provisioning example #25
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reviewed the documentation so far. More precisely I've reviewed everything except main.c
. I'll review main.c
later.
provisioning/README.md
Outdated
@@ -0,0 +1,109 @@ | |||
# Mbed Crypto provisioning example application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name and the short description of the example are misleading. There are three ways you can provision a device onto a trust network:
- Generate a key off-device, import it onto the device, and enter it into the device database.
- Generate a key on-device, export it from the device, and enter it into the device database.
- Already have a key on the device, export it and enter it into the device database.
(Above, “key” can refer to either the private key or its public key in different parts of the same sentence.)
This application covers both on-device generation and an already-existing key, but not import. This is a useful example, but the description does a bad job of setting the context.
The name is misleading because “provisioning” could apply to a key or to a device. Provisioning a key is not covered at all: that would mean importing a key, which the example does not do. Instead the example uses a key that has already been provisioned. The example performs a part of the process of provisioning a device, so it's misleading to call it just “provisioning”. This is an example of simple (challengeless) on-boarding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example could do importing, but our ATECC608A driver doesn't yet implement this so I had to remove that bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another name we use for this sort of application has been "Factory Configuration". I rejected that name because there are multiple factories involved and it wasn't clear which factory was being referenced. We could use with more clear and consistent terminology here.
provisioning/main.c
Outdated
#include "mbed_assert.h" | ||
|
||
/* The slot number for the device private key stored in the secure element by | ||
* the secure element factory. Note: If, for example, your SE has a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment as Gilles' in a different place - at this stage noone would assume that if there's a pre-provisioned key in slot 0, the slot number cannot be 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That depends on the reader's background. If they're familiar with the PSA crypto API but not with the secure element interface, they might assume that 0 = invalid/unset, because that's usually true in the API. So it would be worth stating something like “Note that unlike most numerical values in the PSA Crypto API, 0 is a valid value for a slot number. Like many other secure elements, the ATECC608A numbers its slots from 0 to N-1 (and specifically for the ATECC608A, N=16).”
Stating that slot numbers are not key ids belongs in a separate sentence. It's completely unrelated to whether 0 is a valid value.
|
||
/* Set device private key attributes. */ | ||
/* Note: It is not necessary to hard-code the physical slot number within | ||
* the secure element. The secure element driver can automatically allocate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understood this sentence a bit differently than intended: hard-coding within the secure element sounds like embedding some kind of a number inside the secure element. Maybe it should be
hard-code the number of the physical secure element slot
?
provisioning/main.c
Outdated
mbedtls_pk_free(&pk); | ||
} | ||
|
||
/* The secure element factory put a device private key pair (not attestation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments look more like a draft of reminders for you. What is their purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the note about the TLS application. Moved the comment to a better place and added a new one.
provisioning/main.c
Outdated
free(output); | ||
} | ||
|
||
void generate_csr(psa_key_id_t key_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function also prints csr's. Maybe generate_print_csr
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed main.c
, completing my previous review.
provisioning/main.c
Outdated
#include "mbed_assert.h" | ||
|
||
/* The slot number for the device private key stored in the secure element by | ||
* the secure element factory. Note: If, for example, your SE has a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That depends on the reader's background. If they're familiar with the PSA crypto API but not with the secure element interface, they might assume that 0 = invalid/unset, because that's usually true in the API. So it would be worth stating something like “Note that unlike most numerical values in the PSA Crypto API, 0 is a valid value for a slot number. Like many other secure elements, the ATECC608A numbers its slots from 0 to N-1 (and specifically for the ATECC608A, N=16).”
Stating that slot numbers are not key ids belongs in a separate sentence. It's completely unrelated to whether 0 is a valid value.
7404a73
to
f6f7a5c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased to address review feedback
provisioning/main.c
Outdated
mbedtls_pk_free(&pk); | ||
} | ||
|
||
/* The secure element factory put a device private key pair (not attestation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the note about the TLS application. Moved the comment to a better place and added a new one.
f6f7a5c
to
abf44d8
Compare
Updated to address more comments and add some further refinements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to have this example tested in CI, we'll need a tests/provisioning.log
file for the CI to compare against. Otherwise we can't test this automatically.
Add a device provisioning example that works with two different types of secure element keys: - Keys already stored in the secure element (in physical slot 0 in our example), placed there by the secure element vendor or another secure facility before coming to the assembly house. - Keys generated within the secure element during assembly (into physical slot 2 in our example) The provisiong example fulfils the need post-device-assembly to notify Mbed Crypto about which keys are present where, so that applications can use those keys. Mbed Crypto will remember this information across reboots, so after provisioning, another application can be flashed onto the device which can use these keys.
Automatically create and print a certificate signing request. This makes it convenient to create device certificates using never-left-the-device, PSA-managed private keys. Include instructions on how to create and verify a device certificate in the README.
It is a common source of failure that the provisioning data is overwritten when programming a new flash image. In a new troubleshooting section in the README, add a recommendation to upgrade the DAPLink version to a version that supports partial image updates.
abf44d8
to
3397325
Compare
Add the expected example output so that we can automatically test that the example is working as intended.
3397325
to
480daf0
Compare
Crypto. How does Mbed Crypto know the key exists? We can tell Mbed Crypto by | ||
running a factory device provisionining application, which is typically | ||
separate from the primary application and may be run as a final device assembly | ||
step. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading this paragraph, I understand that this document is going to show me how to use a pre-provisioned key. So when I reach the section “Generate a new key within a secure element”, I understand it as a step on the path to using a pre-provisioned key, which is puzzling because I don't see why you'd need to generate a key.
Please rewrite this paragraph not to be misleading.
For registering keys already present within a secure element, Mbed Crypto | ||
provides a function to inform Mbed Crypto about the existence of the key: | ||
`mbedtls_psa_register_se_key()`. This function adds the necessary metadata to | ||
persistent storage so that the secure element keys can be used by an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this sentence is fine on its own, it's a bit weird to transition from “key” singular to “keys” plural. Also the sentence would be easier to read in the active voice.
|
||
With `psa_set_key_slot_number()`, you can specify which physical secure element | ||
slot the key is in. This function operates on a key attributes structure. Fill | ||
in any other necessary attributes and then call `mbedtls_psa_register_se_key()` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
“any other necessary attributes” makes it seem that just setting the slot number can be enough, but it never is. Lifetime and key id are always necessary, usage policy most of the time. Type and size may or may not be necessary depending on whether the hardware already has this information (e.g. in the slot configuration). Either change it to “other necessary attributes” or list the attributes.
number. | ||
|
||
For generated keys, unlike pre-existing secure element keys, calling | ||
`psa_set_key_slot_number()` is not required. The driver will select a valid and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not required in general, but it's required with this particular driver since this particular driver does not implement slot number allocation.
* secure element by this example provisioning application. */ | ||
#define EXAMPLE_GENERATED_KEY_ID 18 | ||
|
||
/* Mbed TLS needs a CSPRNG to generate a CSR. Provide it a callback which uses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/* Mbed TLS needs a CSPRNG to generate a CSR. Provide it a callback which uses | |
/* Mbed TLS needs a random generator to generate a CSR. Provide it a callback which uses |
The random generator is used for a random challenge and for blinding. A PRNG would not work for either use.
|
||
/* Set device private key attributes. */ | ||
/* Note that it is not necessary to specify the physical slot number within | ||
* the secure element. The secure element driver can automatically allocate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A driver can do it, but the driver we have now doesn't do it. So it isn't necessary in general, but it's necessary for this particular (version of this particular) driver.
/* We also want to generate our own key entirely within the secure element | ||
* during the factory device provisioning stage in device assembly. Ask | ||
* Mbed Crypto to generate this key for us. */ | ||
printf("\tGenerating keys within the secure element... "); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker, but it's a bit weird that the message says “generating keys” but the function is generate_key
singular. And the registration above uses plural both in the message and in the function name, but actually only registers one key (ok, technically a key pair, but technically a key pair is a single key object).
Teach how to manufacture a PSA Crypto device with provisioned keys through a provisioning example that could ostensibly be used in a device factory.