1# ECDSA signature format 2 3When the 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 (specifically, Mbed 7TLS) are fairly strict about the formatting of the ECDSA signature. 8 9There are two ways to fix this: 10 11 - Use a reversible padding scheme. This solution requires 12 at least one pad byte to always be added (to set the length). This 13 padding would be somewhat incompatible across versions (older 14 EC256 would work, while newer MCUboot code would reject old 15 signatures. The EC code would work reliably only in the new 16 combination). 17 18 - Remove the padding entirely. Depending on the tool used, this solution 19 requires some rethinking of how TLV generation is implemented so 20 that the length does not need to be known until the signature is 21 generated. These tools are usually written in higher-level 22 languages, so this change should not be difficult. 23 24 However, this will also break compatibility with older versions, 25 because images generated with newer tools will not 26 work with older versions of MCUboot. 27 28This document proposes a multi-stage approach to give a transition 29period: 30 31 1. Add a `--no-pad-sig` argument to the sign command in 32 `imgtool.py`. 33 34 Without this argument, the images are padded with the 35 existing scheme. With this argument, the ECDSA is encoded 36 without any padding. The `--pad-sig` argument is also 37 accepted, but it is already the default. 38 39 2. MCUboot will be modified to allow unpadded signatures right away. 40 The existing EC256 implementations will still work (with or 41 without padding), and the existing EC implementation will be able 42 to accept padded and unpadded signatures. 43 44 3. An Mbed TLS implementation of EC256 can be added, but it will require 45 the `--no-pad-sig` signature to be able to boot all generated 46 images. Without the argument, 3 out of 4 images generated will have 47 padding and will be considered invalid. 48 49After one or more MCUboot release cycles and announcements in the 50relevant channels, the arguments to `imgtool.py` will change: 51 52 - `--no-pad-sig` will still be accepted but will have no effect. 53 54 - `--pad-sig` will now bring back the old padding behavior. 55 56This will require an update to any scripts that will rely on the default 57behavior, but will not specify a specific version of imgtool. 58 59The signature generation in the simulator can be changed at the same 60time the boot code begins to accept unpadded signatures. The simulator is 61always run out of the same tree as the MCUboot code, so there should 62not be any compatibility issues. 63 64## Background 65 66ECDSA signatures are encoded as ASN.1, notably with the signature 67itself encoded as follows: 68 69``` 70 ECDSA-Sig-Value ::= SEQUENCE { 71 r INTEGER, 72 s INTEGER 73 } 74``` 75 76Both `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 80signature will vary by a couple of bytes, depending on whether one or 81both of these numbers have the high bit set. 82 83Originally, MCUboot added padding to the entire signature and just 84removed any trailing 0 bytes from the data block. This turned out to be fine 255 out of 256 85times, each time the last byte of the signature was non-zero, but if the 86signature ended in a zero, MCUboot would remove too many bytes and render the 87signature invalid. 88 89The correct approach here is to accept that ECDSA signatures are of 90variable length, and to make sure that we can handle them as such. 91