[Cryptography] Minimal secure boot
Patrick Chkoreff
pc at fexl.com
Fri Jun 14 08:39:51 EDT 2019
sebastien riou wrote on 6/12/19 6:34 PM:
> Some notation used in the rational:
> - Generate an RSA2048 key pair
> - d: private exponent
> - n: modulus
> - e: public exponent, fixed to 5
> - store n and e in the ROM
> - at build time:
> - digest = sha256 over the software image
> - c = PKCS1_15_pad(digest)
> - sig = mod_exp(c,d,n)
> - append sig to code
> - at boot:
> - get code and sig
> - digest = sha256 over software image
> - expected = mod_exp(sig,e,n)
> - launch execution of software image only if PKCS1_15_pad(digest) ==
> expected
Might you save some code space, and gain some efficiency, by using DJB's
Curve25519-based signatures? The keys are small but give you high
security. You might also avoid issues such as choice of exponent in RSA.
Here are some links to code that I adapted from Daniel J. Bernstein's
http://tweetnacl.cr.yp.to/.
1. The nacl_sign_seal routine creates a signature:
https://github.com/chkoreff/Fexl/blob/master/src/nacl.c#L703
2. The nacl_sign_open routine verifies a signature:
https://github.com/chkoreff/Fexl/blob/master/src/nacl.c#L787
3. Those routines rely on SHA512, defined here:
https://github.com/chkoreff/Fexl/blob/master/src/sha512.c#L128
Turns out SHA512 is actually *faster* than SHA256 due to its use of a
full 64-bit word instead of 32-bit.
4. The secret key for signing (or encryption) is an arbitrary string of
32 random bytes (256 bits). There is a deterministic routine which maps
a secret key to its corresponding public key:
https://github.com/chkoreff/Fexl/blob/master/src/nacl.c#L633
5. The nacl_sign_seal and nacl_sign_open routines have certain padding
protocols, which I have captured in a module which wraps the core Nacl
routines inside a "string" data type (i.e. pointer to fixed length + data):
5a. The nacl_sign_seal routine is called with a buffer that has an extra
64 bytes at the front for the signature:
https://github.com/chkoreff/Fexl/blob/master/src/crypto.c#L163
5b. The nacl_sign_open routine requires two buffers:
https://github.com/chkoreff/Fexl/blob/master/src/crypto.c#L186
NOTE: It occurs to me that the TweetNacl routines as currently written
take in a pointer to an arbitrarily long message, which it then hashes
itself with SHA512. Perhaps they could be refactored to take in ONLY a
pointer to a fixed 64 byte hash, which is computed outside the "seal"
and "open" routines, as a separate pre-computation. That would make the
calling interface entirely fixed-size, and avoid the need for copying
messages and allocating separate dynamically sized buffers.
I would like to see if I could do that while preserving the test output
here:
https://github.com/chkoreff/Fexl/blob/master/src/test/run.out#L2420
-- Patrick
More information about the cryptography
mailing list