[PATCH RFC v2 0/5] Add support for ECDSA image signing (with test)

Alexandru Gagniuc
2020-12-30T21:00:22Z

# Introduction

This series is part of a larger effort to implement verified boot
on STM32MP1.The purpose of this series is to let people know I'm
looking into ECDSA.

## Purpose and intent

The ROM code on the STM32MP requires an ECDSA-signed FSBL. Maintaining
verified boot through FIT images would require switching to an RSA key
after SPL. This would be stupid, so this series is focused on enabling
ECDSA signing. The use case that I am focused on is signing an
existing FIT image:

mkimage -F some-existing.fit --signing-key some/key.pem

I don't care about signing while assembling the FIT. The reason is
that I want the machine that builds things to be separate from the
machine that has access to the super-secret-key.pem.

Astute readers may have noticed the "uselessness" of this series due
to the lack of a device-side implementation. I don't plan to write out
the algorithm for ECDSA, but instead use the CRYP engine of the stm32mp,
or the ROM services. This is a matter for another series.

# Implementation

I initially tried to model this after the RSA implementation
(rsa-sign.c), but that didn't go well for a few reasons:
(a) The openssl/libcrypto API is a pain in the ass
(b) The RSA path doesn't have a way to pass a specific key file.

On point (a), I don't want to spend too much time battling a C API for
crypto. I find pyCryptodomex to be vastly superior, but that is not
available for mkimage. I am thus focusing on the simple case of
key in, signature out.

On point (b), the RSA path takes the FDT property 'key-name-hint' to
decide which key file to read from disk. In the context of "which fdt
node describes my signing key", this makes sense. On the other hand,
'key-name-hint' is also used as the basename of where the key is on the
filesystem. This leads to some funny search paths, such as

"some/dir/(null).key"

So I am using the -K option to mkimage as the _full_ path to the key
file. It doesn't have to be named .key, it doesn't have to be named
.crt, and it doesn't have to exist in a particular directory (as is
the case for the RSA path). Take that as is for here -- we can discuss
the merits of this in a separate thread.

A bonus point is that I have decided to keep signin/verifying in the
same source file. This allows me to reuse some helper functions. I'm
only adding 300 lines of code, so I don't see the point in splitting
it up.

# Testing

test/py/tests/test_fit_ecdsa.py is implementing a test for mkimage. It
lets mkimage run wild, tehn verifies the signature against
pyCryptodomex -- see earlier point on for I didn't use openssl.

Alexandru Gagniuc (5):
lib: Rename rsa-checksum.c to hash-checksum.c
lib/rsa: Make fdt_add_bignum() available outside of RSA code
lib: Add support for ECDSA image signing
doc: signature.txt: Document devicetree format for ECDSA keys
test/py: ecdsa: Add test for mkimage ECDSA signing

common/image-fit-sig.c | 2 +-
common/image-sig.c | 16 +-
doc/uImage.FIT/signature.txt | 7 +-
include/image.h | 2 +-
include/u-boot/ecdsa.h | 27 ++
include/u-boot/fdt-libcrypto.h | 15 +
.../{rsa-checksum.h => hash-checksum.h} | 0
lib/Makefile | 1 +
lib/crypto/pkcs7_verify.c | 2 +-
lib/crypto/x509_public_key.c | 2 +-
lib/ecdsa/ecdsa-libcrypto.c | 300 ++++++++++++++++++
lib/fdt-libcrypto.c | 72 +++++
lib/{rsa/rsa-checksum.c => hash-checksum.c} | 3 +-
lib/rsa/Makefile | 2 +-
lib/rsa/rsa-sign.c | 65 +---
test/py/tests/test_fit_ecdsa.py | 111 +++++++
tools/Makefile | 7 +-
17 files changed, 559 insertions(+), 75 deletions(-)
create mode 100644 include/u-boot/ecdsa.h
create mode 100644 include/u-boot/fdt-libcrypto.h
rename include/u-boot/{rsa-checksum.h => hash-checksum.h} (100%)
create mode 100644 lib/ecdsa/ecdsa-libcrypto.c
create mode 100644 lib/fdt-libcrypto.c
rename lib/{rsa/rsa-checksum.c => hash-checksum.c} (96%)
create mode 100644 test/py/tests/test_fit_ecdsa.py

--
2.26.2