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