blob: 7d8292ece8673980119090eec7a475824d3f3fee [file] [log] [blame]
Simon Glassfb8b1122023-06-23 13:22:06 +01001.. SPDX-License-Identifier: GPL-2.0+
2
3U-Boot FIT Signature Verification
4=================================
5
6Introduction
7------------
8
9FIT supports hashing of images so that these hashes can be checked on
10loading. This protects against corruption of the image. However it does not
11prevent the substitution of one image for another.
12
13The signature feature allows the hash to be signed with a private key such
14that it can be verified using a public key later. Provided that the private
15key is kept secret and the public key is stored in a non-volatile place,
16any image can be verified in this way.
17
18See verified-boot.txt for more general information on verified boot.
19
20
21Concepts
22--------
23
24Some familiarity with public key cryptography is assumed in this section.
25
26The procedure for signing is as follows:
27
28 - hash an image in the FIT
29 - sign the hash with a private key to produce a signature
30 - store the resulting signature in the FIT
31
32The procedure for verification is:
33
34 - read the FIT
35 - obtain the public key
36 - extract the signature from the FIT
37 - hash the image from the FIT
38 - verify (with the public key) that the extracted signature matches the
39 hash
40
41The signing is generally performed by mkimage, as part of making a firmware
42image for the device. The verification is normally done in U-Boot on the
43device.
44
45
46Algorithms
47----------
48In principle any suitable algorithm can be used to sign and verify a hash.
49U-Boot supports a few hashing and verification algorithms. See below for
50details.
51
52While it is acceptable to bring in large cryptographic libraries such as
53openssl on the host side (e.g. mkimage), it is not desirable for U-Boot.
54For the run-time verification side, it is important to keep code and data
55size as small as possible.
56
57For this reason the RSA image verification uses pre-processed public keys
58which can be used with a very small amount of code - just some extraction
59of data from the FDT and exponentiation mod n. Code size impact is a little
60under 5KB on Tegra Seaboard, for example.
61
62It is relatively straightforward to add new algorithms if required. If
63another RSA variant is needed, then it can be added with the
64U_BOOT_CRYPTO_ALGO() macro. If another algorithm is needed (such as DSA) then
65it can be placed in a directory alongside lib/rsa/, and its functions added
66using U_BOOT_CRYPTO_ALGO().
67
68
69Creating an RSA key pair and certificate
70----------------------------------------
71To create a new public/private key pair, size 2048 bits::
72
73 $ openssl genpkey -algorithm RSA -out keys/dev.key \
74 -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
75
76To create a certificate for this containing the public key::
77
78 $ openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt
79
80If you like you can look at the public key also::
81
82 $ openssl rsa -in keys/dev.key -pubout
83
84
85Device Tree Bindings
86--------------------
87The following properties are required in the FIT's signature node(s) to
88allow the signer to operate. These should be added to the .its file.
89Signature nodes sit at the same level as hash nodes and are called
90signature-1, signature-2, etc.
91
92algo
93 Algorithm name (e.g. "sha1,rsa2048")
94
95key-name-hint
96 Name of key to use for signing. The keys will normally be in
97 a single directory (parameter -k to mkimage). For a given key <name>, its
98 private key is stored in <name>.key and the certificate is stored in
99 <name>.crt.
100
101When the image is signed, the following properties are added (mandatory):
102
103value
104 The signature data (e.g. 256 bytes for 2048-bit RSA)
105
106When the image is signed, the following properties are optional:
107
108timestamp
109 Time when image was signed (standard Unix time_t format)
110
111signer-name
112 Name of the signer (e.g. "mkimage")
113
114signer-version
115 Version string of the signer (e.g. "2013.01")
116
117comment
118 Additional information about the signer or image
119
120padding
121 The padding algorithm, it may be pkcs-1.5 or pss,
122 if no value is provided we assume pkcs-1.5
123
124For config bindings (see Signed Configurations below), the following
125additional properties are optional:
126
127sign-images
128 A list of images to sign, each being a property of the conf
129 node that contains then. The default is "kernel,fdt" which means that these
130 two images will be looked up in the config and signed if present.
131
132For config bindings, these properties are added by the signer:
133
134hashed-nodes
135 A list of nodes which were hashed by the signer. Each is
136 a string - the full path to node. A typical value might be::
137
138 hashed-nodes = "/", "/configurations/conf-1", "/images/kernel",
139 "/images/kernel/hash-1", "/images/fdt-1",
140 "/images/fdt-1/hash-1";
141
142hashed-strings
143 The start and size of the string region of the FIT that was hashed
144
145Example: See :doc:`sign-images` for an example image tree source file and
146sign-configs.its for config signing.
147
148
149Public Key Storage
150------------------
151In order to verify an image that has been signed with a public key we need to
152have a trusted public key. This cannot be stored in the signed image, since
153it would be easy to alter. For this implementation we choose to store the
154public key in U-Boot's control FDT (using CONFIG_OF_CONTROL).
155
156Public keys should be stored as sub-nodes in a /signature node. Required
157properties are:
158
159algo
160 Algorithm name (e.g. "sha1,rsa2048" or "sha256,ecdsa256")
161
162Optional properties are:
163
164key-name-hint
165 Name of key used for signing. This is only a hint since it
166 is possible for the name to be changed. Verification can proceed by checking
167 all available signing keys until one matches.
168
169required
170 If present this indicates that the key must be verified for the
171 image / configuration to be considered valid. Only required keys are
172 normally verified by the FIT image booting algorithm. Valid values are
173 "image" to force verification of all images, and "conf" to force verification
174 of the selected configuration (which then relies on hashes in the images to
175 verify those).
176
177Each signing algorithm has its own additional properties.
178
179For RSA the following are mandatory:
180
181rsa,num-bits
182 Number of key bits (e.g. 2048)
183
184rsa,modulus
185 Modulus (N) as a big-endian multi-word integer
186
187rsa,exponent
188 Public exponent (E) as a 64 bit unsigned integer
189
190rsa,r-squared
191 (2^num-bits)^2 as a big-endian multi-word integer
192
193rsa,n0-inverse
194 -1 / modulus[0] mod 2^32
195
196For ECDSA the following are mandatory:
197
198ecdsa,curve
199 Name of ECDSA curve (e.g. "prime256v1")
200
201ecdsa,x-point
202 Public key X coordinate as a big-endian multi-word integer
203
204ecdsa,y-point
205 Public key Y coordinate as a big-endian multi-word integer
206
207These parameters can be added to a binary device tree using parameter -K of the
208mkimage command::
209
210 tools/mkimage -f fit.its -K control.dtb -k keys -r image.fit
211
212Here is an example of a generated device tree node::
213
214 signature {
215 key-dev {
216 required = "conf";
217 algo = "sha256,rsa2048";
218 rsa,r-squared = <0xb76d1acf 0xa1763ca5 0xeb2f126
219 0x742edc80 0xd3f42177 0x9741d9d9
220 0x35bb476e 0xff41c718 0xd3801430
221 0xf22537cb 0xa7e79960 0xae32a043
222 0x7da1427a 0x341d6492 0x3c2762f5
223 0xaac04726 0x5b262d96 0xf984e86d
224 0xb99443c7 0x17080c33 0x940f6892
225 0xd57a95d1 0x6ea7b691 0xc5038fa8
226 0x6bb48a6e 0x73f1b1ea 0x37160841
227 0xe05715ce 0xa7c45bbd 0x690d82d5
228 0x99c2454c 0x6ff117b3 0xd830683b
229 0x3f81c9cf 0x1ca38a91 0x0c3392e4
230 0xd817c625 0x7b8e9a24 0x175b89ea
231 0xad79f3dc 0x4d50d7b4 0x9d4e90f8
232 0xad9e2939 0xc165d6a4 0x0ada7e1b
233 0xfb1bf495 0xfc3131c2 0xb8c6e604
234 0xc2761124 0xf63de4a6 0x0e9565f9
235 0xc8e53761 0x7e7a37a5 0xe99dcdae
236 0x9aff7e1e 0xbd44b13d 0x6b0e6aa4
237 0x038907e4 0x8e0d6850 0xef51bc20
238 0xf73c94af 0x88bea7b1 0xcbbb1b30
239 0xd024b7f3>;
240 rsa,modulus = <0xc0711d6cb 0x9e86db7f 0x45986dbe
241 0x023f1e8c9 0xe1a4c4d0 0x8a0dfdc9
242 0x023ba0c48 0x06815f6a 0x5caa0654
243 0x07078c4b7 0x3d154853 0x40729023
244 0x0b007c8fe 0x5a3647e5 0x23b41e20
245 0x024720591 0x66915305 0x0e0b29b0
246 0x0de2ad30d 0x8589430f 0xb1590325
247 0x0fb9f5d5e 0x9eba752a 0xd88e6de9
248 0x056b3dcc6 0x9a6b8e61 0x6784f61f
249 0x000f39c21 0x5eec6b33 0xd78e4f78
250 0x0921a305f 0xaa2cc27e 0x1ca917af
251 0x06e1134f4 0xd48cac77 0x4e914d07
252 0x0f707aa5a 0x0d141f41 0x84677f1d
253 0x0ad47a049 0x028aedb6 0xd5536fcf
254 0x03fef1e4f 0x133a03d2 0xfd7a750a
255 0x0f9159732 0xd207812e 0x6a807375
256 0x06434230d 0xc8e22dad 0x9f29b3d6
257 0x07c44ac2b 0xfa2aad88 0xe2429504
258 0x041febd41 0x85d0d142 0x7b194d65
259 0x06e5d55ea 0x41116961 0xf3181dde
260 0x068bf5fbc 0x3dd82047 0x00ee647e
261 0x0d7a44ab3>;
262 rsa,exponent = <0x00 0x10001>;
263 rsa,n0-inverse = <0xb3928b85>;
264 rsa,num-bits = <0x800>;
265 key-name-hint = "dev";
266 };
267 };
268
269
270Signed Configurations
271---------------------
272While signing images is useful, it does not provide complete protection
273against several types of attack. For example, it is possible to create a
274FIT with the same signed images, but with the configuration changed such
275that a different one is selected (mix and match attack). It is also possible
276to substitute a signed image from an older FIT version into a newer FIT
277(roll-back attack).
278
279As an example, consider this FIT::
280
281 / {
282 images {
283 kernel-1 {
284 data = <data for kernel1>
285 signature-1 {
286 algo = "sha1,rsa2048";
287 value = <...kernel signature 1...>
288 };
289 };
290 kernel-2 {
291 data = <data for kernel2>
292 signature-1 {
293 algo = "sha1,rsa2048";
294 value = <...kernel signature 2...>
295 };
296 };
297 fdt-1 {
298 data = <data for fdt1>;
299 signature-1 {
300 algo = "sha1,rsa2048";
301 value = <...fdt signature 1...>
302 };
303 };
304 fdt-2 {
305 data = <data for fdt2>;
306 signature-1 {
307 algo = "sha1,rsa2048";
308 value = <...fdt signature 2...>
309 };
310 };
311 };
312 configurations {
313 default = "conf-1";
314 conf-1 {
315 kernel = "kernel-1";
316 fdt = "fdt-1";
317 };
318 conf-2 {
319 kernel = "kernel-2";
320 fdt = "fdt-2";
321 };
322 };
323 };
324
325Since both kernels are signed it is easy for an attacker to add a new
326configuration 3 with kernel 1 and fdt 2::
327
328 configurations {
329 default = "conf-1";
330 conf-1 {
331 kernel = "kernel-1";
332 fdt = "fdt-1";
333 };
334 conf-2 {
335 kernel = "kernel-2";
336 fdt = "fdt-2";
337 };
338 conf-3 {
339 kernel = "kernel-1";
340 fdt = "fdt-2";
341 };
342 };
343
344With signed images, nothing protects against this. Whether it gains an
345advantage for the attacker is debatable, but it is not secure.
346
347To solve this problem, we support signed configurations. In this case it
348is the configurations that are signed, not the image. Each image has its
349own hash, and we include the hash in the configuration signature.
350
351So the above example is adjusted to look like this::
352
353 / {
354 images {
355 kernel-1 {
356 data = <data for kernel1>
357 hash-1 {
358 algo = "sha1";
359 value = <...kernel hash 1...>
360 };
361 };
362 kernel-2 {
363 data = <data for kernel2>
364 hash-1 {
365 algo = "sha1";
366 value = <...kernel hash 2...>
367 };
368 };
369 fdt-1 {
370 data = <data for fdt1>;
371 hash-1 {
372 algo = "sha1";
373 value = <...fdt hash 1...>
374 };
375 };
376 fdt-2 {
377 data = <data for fdt2>;
378 hash-1 {
379 algo = "sha1";
380 value = <...fdt hash 2...>
381 };
382 };
383 };
384 configurations {
385 default = "conf-1";
386 conf-1 {
387 kernel = "kernel-1";
388 fdt = "fdt-1";
389 signature-1 {
390 algo = "sha1,rsa2048";
391 value = <...conf 1 signature...>;
392 };
393 };
394 conf-2 {
395 kernel = "kernel-2";
396 fdt = "fdt-2";
397 signature-1 {
398 algo = "sha1,rsa2048";
399 value = <...conf 1 signature...>;
400 };
401 };
402 };
403 };
404
405
406You can see that we have added hashes for all images (since they are no
407longer signed), and a signature to each configuration. In the above example,
408mkimage will sign configurations/conf-1, the kernel and fdt that are
409pointed to by the configuration (/images/kernel-1, /images/kernel-1/hash-1,
410/images/fdt-1, /images/fdt-1/hash-1) and the root structure of the image
411(so that it isn't possible to add or remove root nodes). The signature is
412written into /configurations/conf-1/signature-1/value. It can easily be
413verified later even if the FIT has been signed with other keys in the
414meantime.
415
416
417Details
418-------
419The signature node contains a property ('hashed-nodes') which lists all the
420nodes that the signature was made over. The image is walked in order and each
421tag processed as follows:
422
423DTB_BEGIN_NODE
424 The tag and the following name are included in the signature
425 if the node or its parent are present in 'hashed-nodes'
426
427DTB_END_NODE
428 The tag is included in the signature if the node or its parent
429 are present in 'hashed-nodes'
430
431DTB_PROPERTY
432 The tag, the length word, the offset in the string table, and
433 the data are all included if the current node is present in 'hashed-nodes'
434 and the property name is not 'data'.
435
436DTB_END
437 The tag is always included in the signature.
438
439DTB_NOP
440 The tag is included in the signature if the current node is present
441 in 'hashed-nodes'
442
443In addition, the signature contains a property 'hashed-strings' which contains
444the offset and length in the string table of the strings that are to be
445included in the signature (this is done last).
446
447IMPORTANT: To verify the signature outside u-boot, it is vital to not only
448calculate the hash of the image and verify the signature with that, but also to
449calculate the hashes of the kernel, fdt, and ramdisk images and check those
450match the hash values in the corresponding 'hash*' subnodes.
451
452
453Verification
454------------
455FITs are verified when loaded. After the configuration is selected a list
456of required images is produced. If there are 'required' public keys, then
457each image must be verified against those keys. This means that every image
458that might be used by the target needs to be signed with 'required' keys.
459
460This happens automatically as part of a bootm command when FITs are used.
461
462For Signed Configurations, the default verification behavior can be changed by
463the following optional property in /signature node in U-Boot's control FDT.
464
465required-mode
466 Valid values are "any" to allow verified boot to succeed if
467 the selected configuration is signed by any of the 'required' keys, and "all"
468 to allow verified boot to succeed if the selected configuration is signed by
469 all of the 'required' keys.
470
471This property can be added to a binary device tree using fdtput as shown in
472below examples::
473
474 fdtput -t s control.dtb /signature required-mode any
475 fdtput -t s control.dtb /signature required-mode all
476
477
478Enabling FIT Verification
479-------------------------
480In addition to the options to enable FIT itself, the following CONFIGs must
481be enabled:
482
483CONFIG_FIT_SIGNATURE
484 enable signing and verification in FITs
485
486CONFIG_RSA
487 enable RSA algorithm for signing
488
489CONFIG_ECDSA
490 enable ECDSA algorithm for signing
491
492WARNING: When relying on signed FIT images with required signature check
493the legacy image format is default disabled by not defining
494CONFIG_LEGACY_IMAGE_FORMAT
495
496
497Testing
498-------
499
500An easy way to test signing and verification is to use the test script
501provided in test/vboot/vboot_test.sh. This uses sandbox (a special version
502of U-Boot which runs under Linux) to show the operation of a 'bootm'
503command loading and verifying images.
504
505A sample run is show below::
506
507 $ make O=sandbox sandbox_config
508 $ make O=sandbox
509 $ O=sandbox ./test/vboot/vboot_test.sh
510
511
512Simple Verified Boot Test
513-------------------------
514
515Please see :doc:`verified-boot` for more information::
516
517 /home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000
518 Build keys
519 do sha1 test
520 Build FIT with signed images
521 Test Verified Boot Run: unsigned signatures:: OK
522 Sign images
523 Test Verified Boot Run: signed images: OK
524 Build FIT with signed configuration
525 Test Verified Boot Run: unsigned config: OK
526 Sign images
527 Test Verified Boot Run: signed config: OK
528 check signed config on the host
529 Signature check OK
530 OK
531 Test Verified Boot Run: signed config: OK
532 Test Verified Boot Run: signed config with bad hash: OK
533 do sha256 test
534 Build FIT with signed images
535 Test Verified Boot Run: unsigned signatures:: OK
536 Sign images
537 Test Verified Boot Run: signed images: OK
538 Build FIT with signed configuration
539 Test Verified Boot Run: unsigned config: OK
540 Sign images
541 Test Verified Boot Run: signed config: OK
542 check signed config on the host
543 Signature check OK
544 OK
545 Test Verified Boot Run: signed config: OK
546 Test Verified Boot Run: signed config with bad hash: OK
547
548 Test passed
549
550
551Software signing: keydir vs keyfile
552-----------------------------------
553
554In the simplest case, signing is done by giving mkimage the 'keyfile'. This is
555the path to a file containing the signing key.
556
557The alternative is to pass the 'keydir' argument. In this case the filename of
558the key is derived from the 'keydir' and the "key-name-hint" property in the
559FIT. In this case the "key-name-hint" property is mandatory, and the key must
560exist in "<keydir>/<key-name-hint>.<ext>" Here the extension "ext" is
561specific to the signing algorithm.
562
563
564Hardware Signing with PKCS#11 or with HSM
565-----------------------------------------
566
567Securely managing private signing keys can challenging, especially when the
568keys are stored on the file system of a computer that is connected to the
569Internet. If an attacker is able to steal the key, they can sign malicious FIT
570images which will appear genuine to your devices.
571
572An alternative solution is to keep your signing key securely stored on hardware
573device like a smartcard, USB token or Hardware Security Module (HSM) and have
574them perform the signing. PKCS#11 is standard for interfacing with these crypto
575device.
576
577Requirements:
578 - Smartcard/USB token/HSM which can work with some openssl engine
579 - openssl
580
581For pkcs11 engine usage:
582 - libp11 (provides pkcs11 engine)
583 - p11-kit (recommended to simplify setup)
584 - opensc (for smartcards and smartcard like USB devices)
585 - gnutls (recommended for key generation, p11tool)
586
587For generic HSMs respective openssl engine must be installed and locateable by
588openssl. This may require setting up LD_LIBRARY_PATH if engine is not installed
589to openssl's default search paths.
590
591PKCS11 engine support forms "key id" based on "keydir" and with
592"key-name-hint". "key-name-hint" is used as "object" name (if not defined in
593keydir). "keydir" (if defined) is used to define (prefix for) which PKCS11 source
594is being used for lookup up for the key.
595
596PKCS11 engine key ids
597 "pkcs11:<keydir>;object=<key-name-hint>;type=<public|private>"
598
599or, if keydir contains "object="
600 "pkcs11:<keydir>;type=<public|private>"
601
602or
603 "pkcs11:object=<key-name-hint>;type=<public|private>",
604
605Generic HSM engine support forms "key id" based on "keydir" and with
606"key-name-hint". If "keydir" is specified for mkimage it is used as a prefix in
607"key id" and is appended with "key-name-hint".
608
609Generic engine key ids:
610 "<keydir><key-name-hint>"
611
612or
613 "< key-name-hint>"
614
615In order to set the pin in the HSM, an environment variable "MKIMAGE_SIGN_PIN"
616can be specified.
617
618The following examples use the Nitrokey Pro using pkcs11 engine. Instructions
619for other devices may vary.
620
621Notes on pkcs11 engine setup:
622
623Make sure p11-kit, opensc are installed and that p11-kit is setup to use opensc.
624/usr/share/p11-kit/modules/opensc.module should be present on your system.
625
626
627Generating Keys On the Nitrokey::
628
629 $ gpg --card-edit
630
631 Reader ...........: Nitrokey Nitrokey Pro (xxxxxxxx0000000000000000) 00 00
632 Application ID ...: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
633 Version ..........: 2.1
634 Manufacturer .....: ZeitControl
635 Serial number ....: xxxxxxxx
636 Name of cardholder: [not set]
637 Language prefs ...: de
638 Sex ..............: unspecified
639 URL of public key : [not set]
640 Login data .......: [not set]
641 Signature PIN ....: forced
642 Key attributes ...: rsa2048 rsa2048 rsa2048
643 Max. PIN lengths .: 32 32 32
644 PIN retry counter : 3 0 3
645 Signature counter : 0
646 Signature key ....: [none]
647 Encryption key....: [none]
648 Authentication key: [none]
649 General key info..: [none]
650
651 gpg/card> generate
652 Make off-card backup of encryption key? (Y/n) n
653
654 Please note that the factory settings of the PINs are
655 PIN = '123456' Admin PIN = '12345678'
656 You should change them using the command --change-pin
657
658 What keysize do you want for the Signature key? (2048) 4096
659 The card will now be re-configured to generate a key of 4096 bits
660 Note: There is no guarantee that the card supports the requested size.
661 If the key generation does not succeed, please check the
662 documentation of your card to see what sizes are allowed.
663 What keysize do you want for the Encryption key? (2048) 4096
664 The card will now be re-configured to generate a key of 4096 bits
665 What keysize do you want for the Authentication key? (2048) 4096
666 The card will now be re-configured to generate a key of 4096 bits
667 Please specify how long the key should be valid.
668 0 = key does not expire
669 <n> = key expires in n days
670 <n>w = key expires in n weeks
671 <n>m = key expires in n months
672 <n>y = key expires in n years
673 Key is valid for? (0)
674 Key does not expire at all
675 Is this correct? (y/N) y
676
677 GnuPG needs to construct a user ID to identify your key.
678
679 Real name: John Doe
680 Email address: john.doe@email.com
681 Comment:
682 You selected this USER-ID:
683 "John Doe <john.doe@email.com>"
684
685 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
686
687
688Using p11tool to get the token URL:
689
690Depending on system configuration, gpg-agent may need to be killed first::
691
692 $ p11tool --provider /usr/lib/opensc-pkcs11.so --list-tokens
693 Token 0:
694 URL: pkcs11:model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29
695 Label: OpenPGP card (User PIN (sig))
696 Type: Hardware token
697 Manufacturer: ZeitControl
698 Model: PKCS#15 emulated
699 Serial: 000xxxxxxxxx
700 Module: (null)
701
702
703 Token 1:
704 URL: pkcs11:model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%29
705 Label: OpenPGP card (User PIN)
706 Type: Hardware token
707 Manufacturer: ZeitControl
708 Model: PKCS#15 emulated
709 Serial: 000xxxxxxxxx
710 Module: (null)
711
712Use the portion of the signature token URL after "pkcs11:" as the keydir argument (-k) to mkimage below.
713
714
715Use the URL of the token to list the private keys::
716
717 $ p11tool --login --provider /usr/lib/opensc-pkcs11.so --list-privkeys \
718 "pkcs11:model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29"
719 Token 'OpenPGP card (User PIN (sig))' with URL 'pkcs11:model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29' requires user PIN
720 Enter PIN:
721 Object 0:
722 URL: pkcs11:model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29;id=%01;object=Signature%20key;type=private
723 Type: Private key
724 Label: Signature key
725 Flags: CKA_PRIVATE; CKA_NEVER_EXTRACTABLE; CKA_SENSITIVE;
726 ID: 01
727
728Use the label, in this case "Signature key" as the key-name-hint in your FIT.
729
730Create the fitImage::
731
732 $ ./tools/mkimage -f fit-image.its fitImage
733
734
735Sign the fitImage with the hardware key::
736
737 $ ./tools/mkimage -F -k \
738 "model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29" \
739 -K u-boot.dtb -N pkcs11 -r fitImage
740
741
742Future Work
743-----------
744
745- Roll-back protection using a TPM is done using the tpm command. This can
746 be scripted, but we might consider a default way of doing this, built into
747 bootm.
748
749
750Possible Future Work
751--------------------
752
753- More sandbox tests for failure modes
754- Passwords for keys/certificates
755- Perhaps implement OAEP
756- Enhance bootm to permit scripted signature verification (so that a script
757 can verify an image but not actually boot it)
758
759
760.. sectionauthor:: Simon Glass <sjg@chromium.org>, 1-1-13