blob: e60c7aa4ba4ad3f62538c5cd9bf105d4d9c20e4e [file] [log] [blame] [view]
David Brown8f057ca2019-12-12 16:19:55 -07001# ECDSA signature format
2
3When ECDSA SECP256R1 (EC256) signature support was added to MCUboot, a
4shortcut was taken, and these signatures were padded to make them
5always a fixed length. Unfortunately, this padding was done in a way
6that is not easily reversible. Some crypto libraries are fairly
7strict about the formatting of the ECDSA signature (specifically, mbed
8TLS). This currently means that the ECDSA SECP224R1 (EC) signature
9checking code will fail to boot about 1 out of every 256 images,
10because the signature itself will end in a 0x00 byte, and the code
11will remove too much data, invalidating the signature.
12
13There are a couple of ways to fix this:
14
15 1. Use a reversible padding scheme. This will work, but requires
16 at least one pad byte always be added (to set the length). This
17 padding would be somewhat incompatible across versions (older
18 EC256 would work, newer mcuboot code would reject old
19 signatures. EC code would only reliably work in the new
20 combination).
21
22 2. Remove the padding entirely. Depending on which tool, this will
23 require some rethinking of how TLV generation is implemented so
24 that the length does not need to be known until the signature is
25 generated. These tools are all written in higher-level
26 languages and this change should not be difficult.
27
David Brownbf3a3a92019-12-17 16:08:33 -070028 However, this will also break compatibility with older versions,
29 specifically in that images generated with newer tools will not
David Brown8f057ca2019-12-12 16:19:55 -070030 work with older versions of MCUboot.
31
32This document proposes a multi-stage approach, to give a transition
33period.
34
David Brown3639aca2019-12-17 16:10:49 -070035 - First, add a `--no-pad-sig` argument to the sign command in
David Brown8f057ca2019-12-12 16:19:55 -070036 `imgtool.py`. Without this, the images will be padded with the
37 existing scheme, and with the argument, the ecdsa will be encoded
David Brown3639aca2019-12-17 16:10:49 -070038 without any padding. The `--pad-sig` argument will also be
39 accepted, but this will initially be the default.
David Brown8f057ca2019-12-12 16:19:55 -070040
41 - MCUboot will be modified to allow unpadded signatures right away.
42 The existing EC256 implementations will still work (with or
43 without padding), and the existing EC implementation will begin
David Brownbf3a3a92019-12-17 16:08:33 -070044 accepting padded and unpadded signatures.
David Brown8f057ca2019-12-12 16:19:55 -070045
46 - An mbed TLS implementation of EC256 can be added, but will require
David Brown3639aca2019-12-17 16:10:49 -070047 the `--no-pad-sig` signature to be able to boot all generated
David Brown8f057ca2019-12-12 16:19:55 -070048 images (without the argument 3 of out 4 images generated will have
49 padding, and be considered invalid).
50
51After one or more MCUboot release cycles, and announcements over
David Brownbf3a3a92019-12-17 16:08:33 -070052relevant channels, the arguments to `imgtool.py` will change:
David Brown8f057ca2019-12-12 16:19:55 -070053
David Brown3639aca2019-12-17 16:10:49 -070054 - `--no-pad-sig` will still be accepted, but have no effect.
David Brown8f057ca2019-12-12 16:19:55 -070055
David Brown3639aca2019-12-17 16:10:49 -070056 - `--pad-sig` will now bring back the old padding behavior.
David Brown8f057ca2019-12-12 16:19:55 -070057
David Brown3639aca2019-12-17 16:10:49 -070058This will require a change to any scripts that are relying on a
59default, but not specifying a specific version of imgtool.
David Brown8f057ca2019-12-12 16:19:55 -070060
61The signature generation in the simulator can be changed at the same
62time the boot code begins to accept unpadded signatures. The sim is
63always run out of the same tree as the mcuboot code, so there should
64not be any compatibility issues.
65
66## Background
67
68ECDSA signatures are encoded as ASN.1, notably with the signature
69itself being encoded as:
70
71 ECDSA-Sig-Value ::= SEQUENCE {
72 r INTEGER,
73 s INTEGER
74 }
75
76where both `r` and `s` are 256-bit numbers. Because these are
77unsigned numbers that are being encoded in ASN.1 as signed values, if
78the high bit of the number is set, the DER encoded representation will
79require 33 bytes instead of 32. This means that the length of the
David Brownbf3a3a92019-12-17 16:08:33 -070080signature will vary by a couple of bytes, depending on whether one of
David Brown8f057ca2019-12-12 16:19:55 -070081both of these numbers has the high bit set.
82
83Originally, MCUboot added padding to the entire signature, and just
David Brownbf3a3a92019-12-17 16:08:33 -070084removed any trailing 0 bytes from the data block. This would be fine 255/256
David Brown8f057ca2019-12-12 16:19:55 -070085times, when the last byte of the signature was non-zero, but if the
86signature ended in a zero, it would remove too many bytes, and the
87signature would be considered invalid.
88
89The correct approach here is to accept that ECDSA signatures are
90variable length, and make sure that we can handle them as such.