You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mynewt.apache.org by marko kiiskila <ma...@runtime.io> on 2016/04/04 21:49:08 UTC

Image signatures

Hi,

I started work on signed images, and there’s few things I’m wondering how to go about.

The way this would work is that you would start by creating a RSA key-pair (2048 bits).

You’d sign the image by computing RSA signature over the image hash (SHA256), and store
it a TLV at the end of the image. Bootloader would be built with the public key of this
image signing key, and it would verify it before allowing the image to boot.

The impact of this on the bootloader is ~7k of additional text, so it’s use should be optional.
That comes from code to parse the public key and RSA itself. And the public key itself.

The image header contains a flag that says that this image contains this kind of signature,
as well as the total length of all TLVs in the end. Image hash is computed over this header.

Signature data itself is stored in PKCS 1.5 format.

I also added a keyid field, and you can use this to facilitate the use of multiple image signing
keys. You could use this to facilitate the use of image signing keys of different security
level. I.e. you would have a separate image signing key for building ‘production’ builds as
opposed to ‘development’ builds.

Production signing key would be stored somewhere safe with controlled access, while
development key could have more lax restrictions. Then you’d have different bootloader
versions, dev boot loaders would allow it to boot images that are signed with production keys,
or with development keys. Production boot loaders would only allow it to boot images signed
with production keys only.

This way you can do in-house development/QA using images signed with dev keys, without
having to worry about those images being bootable by products in the field.

On to my questions:
1) Any reviews of this code would be much appreciated! Bugs in this code would be (very) bad.
2) How should this be incorporated into build system? Specifically, how to control
- whether bootloader expects signed images, and if so, whether it’s a dev bootloader, or
  production bootloader?
- where should the public key for bootloader be stored? Note that this probably would be
  per-product specific.

Comments, suggestions are welcome

Re: Image signatures

Posted by aditi hilbert <ad...@runtime.io>.
Marko,

That’s true :( 10s is very long!
Some perf numbers are here if you want some reference later on.
http://www.cryptopp.com/benchmarks.html <http://www.cryptopp.com/benchmarks.html>

thanks,
aditi

> On Apr 6, 2016, at 6:47 PM, marko kiiskila <ma...@runtime.io> wrote:
> 
> I added ECC224, as this should be equivalent to RSA 2048 security-wise.
> 
> It appears that with mbedTLS the ECC size is bigger though. 14k, to be exact.
> 
> I did not go through that rigorous of size reduction for this though, as ECC signature
> verification takes much longer than with RSA.
> It takes ~10 seconds to verify image signature, which has a significant
> impact on bootup time :)
> 
> I can’t believe I forgot about this property of ECC. But it’s been few years since I used it.
> 
>> On Apr 4, 2016, at 3:37 PM, Aditi <ad...@runtime.io> wrote:
>> 
>> EC operations would be significantly smaller. They key size equivalent to RSA 2048 but would be 256 bits in EC. So that could be another option.
>> 
>> Thanks,
>> Aditi
>> 
>> Sent from my iPhone
>> 
>>> On Apr 4, 2016, at 12:49 PM, marko kiiskila <ma...@runtime.io> wrote:
>>> 
>>> Hi,
>>> 
>>> I started work on signed images, and there’s few things I’m wondering how to go about.
>>> 
>>> The way this would work is that you would start by creating a RSA key-pair (2048 bits).
>>> 
>>> You’d sign the image by computing RSA signature over the image hash (SHA256), and store
>>> it a TLV at the end of the image. Bootloader would be built with the public key of this
>>> image signing key, and it would verify it before allowing the image to boot.
>>> 
>>> The impact of this on the bootloader is ~7k of additional text, so it’s use should be optional.
>>> That comes from code to parse the public key and RSA itself. And the public key itself.
>>> 
>>> The image header contains a flag that says that this image contains this kind of signature,
>>> as well as the total length of all TLVs in the end. Image hash is computed over this header.
>>> 
>>> Signature data itself is stored in PKCS 1.5 format.
>>> 
>>> I also added a keyid field, and you can use this to facilitate the use of multiple image signing
>>> keys. You could use this to facilitate the use of image signing keys of different security
>>> level. I.e. you would have a separate image signing key for building ‘production’ builds as
>>> opposed to ‘development’ builds.
>>> 
>>> Production signing key would be stored somewhere safe with controlled access, while
>>> development key could have more lax restrictions. Then you’d have different bootloader
>>> versions, dev boot loaders would allow it to boot images that are signed with production keys,
>>> or with development keys. Production boot loaders would only allow it to boot images signed
>>> with production keys only.
>>> 
>>> This way you can do in-house development/QA using images signed with dev keys, without
>>> having to worry about those images being bootable by products in the field.
>>> 
>>> On to my questions:
>>> 1) Any reviews of this code would be much appreciated! Bugs in this code would be (very) bad.
>>> 2) How should this be incorporated into build system? Specifically, how to control
>>> - whether bootloader expects signed images, and if so, whether it’s a dev bootloader, or
>>> production bootloader?
>>> - where should the public key for bootloader be stored? Note that this probably would be
>>> per-product specific.
>>> 
>>> Comments, suggestions are welcome
> 


Re: Image signatures

Posted by marko kiiskila <ma...@runtime.io>.
I added ECC224, as this should be equivalent to RSA 2048 security-wise.

It appears that with mbedTLS the ECC size is bigger though. 14k, to be exact.

I did not go through that rigorous of size reduction for this though, as ECC signature
verification takes much longer than with RSA.
It takes ~10 seconds to verify image signature, which has a significant
impact on bootup time :)

I can’t believe I forgot about this property of ECC. But it’s been few years since I used it.

> On Apr 4, 2016, at 3:37 PM, Aditi <ad...@runtime.io> wrote:
> 
> EC operations would be significantly smaller. They key size equivalent to RSA 2048 but would be 256 bits in EC. So that could be another option.
> 
> Thanks,
> Aditi
> 
> Sent from my iPhone
> 
>> On Apr 4, 2016, at 12:49 PM, marko kiiskila <ma...@runtime.io> wrote:
>> 
>> Hi,
>> 
>> I started work on signed images, and there’s few things I’m wondering how to go about.
>> 
>> The way this would work is that you would start by creating a RSA key-pair (2048 bits).
>> 
>> You’d sign the image by computing RSA signature over the image hash (SHA256), and store
>> it a TLV at the end of the image. Bootloader would be built with the public key of this
>> image signing key, and it would verify it before allowing the image to boot.
>> 
>> The impact of this on the bootloader is ~7k of additional text, so it’s use should be optional.
>> That comes from code to parse the public key and RSA itself. And the public key itself.
>> 
>> The image header contains a flag that says that this image contains this kind of signature,
>> as well as the total length of all TLVs in the end. Image hash is computed over this header.
>> 
>> Signature data itself is stored in PKCS 1.5 format.
>> 
>> I also added a keyid field, and you can use this to facilitate the use of multiple image signing
>> keys. You could use this to facilitate the use of image signing keys of different security
>> level. I.e. you would have a separate image signing key for building ‘production’ builds as
>> opposed to ‘development’ builds.
>> 
>> Production signing key would be stored somewhere safe with controlled access, while
>> development key could have more lax restrictions. Then you’d have different bootloader
>> versions, dev boot loaders would allow it to boot images that are signed with production keys,
>> or with development keys. Production boot loaders would only allow it to boot images signed
>> with production keys only.
>> 
>> This way you can do in-house development/QA using images signed with dev keys, without
>> having to worry about those images being bootable by products in the field.
>> 
>> On to my questions:
>> 1) Any reviews of this code would be much appreciated! Bugs in this code would be (very) bad.
>> 2) How should this be incorporated into build system? Specifically, how to control
>> - whether bootloader expects signed images, and if so, whether it’s a dev bootloader, or
>> production bootloader?
>> - where should the public key for bootloader be stored? Note that this probably would be
>> per-product specific.
>> 
>> Comments, suggestions are welcome


Re: Image signatures

Posted by Aditi <ad...@runtime.io>.
EC operations would be significantly smaller. They key size equivalent to RSA 2048 but would be 256 bits in EC. So that could be another option.

Thanks,
Aditi

Sent from my iPhone

> On Apr 4, 2016, at 12:49 PM, marko kiiskila <ma...@runtime.io> wrote:
> 
> Hi,
> 
> I started work on signed images, and there’s few things I’m wondering how to go about.
> 
> The way this would work is that you would start by creating a RSA key-pair (2048 bits).
> 
> You’d sign the image by computing RSA signature over the image hash (SHA256), and store
> it a TLV at the end of the image. Bootloader would be built with the public key of this
> image signing key, and it would verify it before allowing the image to boot.
> 
> The impact of this on the bootloader is ~7k of additional text, so it’s use should be optional.
> That comes from code to parse the public key and RSA itself. And the public key itself.
> 
> The image header contains a flag that says that this image contains this kind of signature,
> as well as the total length of all TLVs in the end. Image hash is computed over this header.
> 
> Signature data itself is stored in PKCS 1.5 format.
> 
> I also added a keyid field, and you can use this to facilitate the use of multiple image signing
> keys. You could use this to facilitate the use of image signing keys of different security
> level. I.e. you would have a separate image signing key for building ‘production’ builds as
> opposed to ‘development’ builds.
> 
> Production signing key would be stored somewhere safe with controlled access, while
> development key could have more lax restrictions. Then you’d have different bootloader
> versions, dev boot loaders would allow it to boot images that are signed with production keys,
> or with development keys. Production boot loaders would only allow it to boot images signed
> with production keys only.
> 
> This way you can do in-house development/QA using images signed with dev keys, without
> having to worry about those images being bootable by products in the field.
> 
> On to my questions:
> 1) Any reviews of this code would be much appreciated! Bugs in this code would be (very) bad.
> 2) How should this be incorporated into build system? Specifically, how to control
> - whether bootloader expects signed images, and if so, whether it’s a dev bootloader, or
>  production bootloader?
> - where should the public key for bootloader be stored? Note that this probably would be
>  per-product specific.
> 
> Comments, suggestions are welcome

Re: Image signatures

Posted by marko kiiskila <ma...@runtime.io>.
> On Apr 4, 2016, at 12:49 PM, marko kiiskila <ma...@runtime.io> wrote:
> 
> Hi,
> 
> I started work on signed images, and there’s few things I’m wondering how to go about.
> 
> The way this would work is that you would start by creating a RSA key-pair (2048 bits).
> 
> You’d sign the image by computing RSA signature over the image hash (SHA256), and store
> it a TLV at the end of the image. Bootloader would be built with the public key of this
> image signing key, and it would verify it before allowing the image to boot.
> 
> The impact of this on the bootloader is ~7k of additional text, so it’s use should be optional.
> That comes from code to parse the public key and RSA itself. And the public key itself.
> 
> The image header contains a flag that says that this image contains this kind of signature,
> as well as the total length of all TLVs in the end. Image hash is computed over this header.
> 
> Signature data itself is stored in PKCS 1.5 format.
> 
> I also added a keyid field, and you can use this to facilitate the use of multiple image signing
> keys. You could use this to facilitate the use of image signing keys of different security
> level. I.e. you would have a separate image signing key for building ‘production’ builds as
> opposed to ‘development’ builds.
> 
> Production signing key would be stored somewhere safe with controlled access, while
> development key could have more lax restrictions. Then you’d have different bootloader
> versions, dev boot loaders would allow it to boot images that are signed with production keys,
> or with development keys. Production boot loaders would only allow it to boot images signed
> with production keys only.
> 
> This way you can do in-house development/QA using images signed with dev keys, without
> having to worry about those images being bootable by products in the field.
> 
> On to my questions:
> 1) Any reviews of this code would be much appreciated! Bugs in this code would be (very) bad.
> 2) How should this be incorporated into build system? Specifically, how to control
> - whether bootloader expects signed images, and if so, whether it’s a dev bootloader, or
>  production bootloader?
> - where should the public key for bootloader be stored? Note that this probably would be
>  per-product specific.

E.g. we could store public key(s) in a package which exports 2 symbols: pointer to array
of keys, and the number of elements in that given array. It would export feature ‘IMAGE_KEYS’.

Then, if you’re building a bootloader with such a package included, then image signatures
are required.

This way user could check this in, and manage it’s inclusion in the bootloader any which
they want. I.e. could depend on the target, BSP, app or any other.