Commit 646257d1f4004855d486024527a4784bf57c4c4d
Committed by
Tom Rini
1 parent
2842c1c242
Exists in
v2017.01-smarct4x
and in
40 other branches
rsa: add sha256-rsa2048 algorithm
based on patch from andreas@oetken.name: http://patchwork.ozlabs.org/patch/294318/ commit message: I currently need support for rsa-sha256 signatures in u-boot and found out that the code for signatures is not very generic. Thus adding of different hash-algorithms for rsa-signatures is not easy to do without copy-pasting the rsa-code. I attached a patch for how I think it could be better and included support for rsa-sha256. This is a fast first shot. aditionally work: - removed checkpatch warnings - removed compiler warnings - rebased against current head Signed-off-by: Heiko Schocher <hs@denx.de> Cc: andreas@oetken.name Cc: Simon Glass <sjg@chromium.org>
Showing 16 changed files with 450 additions and 180 deletions Side-by-side Diff
- common/image-sig.c
- doc/uImage.FIT/signature.txt
- include/image.h
- include/rsa-checksum.h
- include/rsa.h
- lib/rsa/Makefile
- lib/rsa/rsa-checksum.c
- lib/rsa/rsa-sign.c
- lib/rsa/rsa-verify.c
- test/vboot/sign-configs-sha1.its
- test/vboot/sign-configs-sha256.its
- test/vboot/sign-configs.its
- test/vboot/sign-images-sha1.its
- test/vboot/sign-images-sha256.its
- test/vboot/sign-images.its
- test/vboot/vboot_test.sh
common/image-sig.c
... | ... | @@ -14,15 +14,53 @@ |
14 | 14 | #endif /* !USE_HOSTCC*/ |
15 | 15 | #include <image.h> |
16 | 16 | #include <rsa.h> |
17 | +#include <rsa-checksum.h> | |
17 | 18 | |
18 | 19 | #define IMAGE_MAX_HASHED_NODES 100 |
19 | 20 | |
21 | +#ifdef USE_HOSTCC | |
22 | +__attribute__((weak)) void *get_blob(void) | |
23 | +{ | |
24 | + return NULL; | |
25 | +} | |
26 | +#endif | |
27 | + | |
28 | +struct checksum_algo checksum_algos[] = { | |
29 | + { | |
30 | + "sha1", | |
31 | + SHA1_SUM_LEN, | |
32 | +#if IMAGE_ENABLE_SIGN | |
33 | + EVP_sha1, | |
34 | +#else | |
35 | + sha1_calculate, | |
36 | + padding_sha1_rsa2048, | |
37 | +#endif | |
38 | + }, | |
39 | + { | |
40 | + "sha256", | |
41 | + SHA256_SUM_LEN, | |
42 | +#if IMAGE_ENABLE_SIGN | |
43 | + EVP_sha256, | |
44 | +#else | |
45 | + sha256_calculate, | |
46 | + padding_sha256_rsa2048, | |
47 | +#endif | |
48 | + } | |
49 | +}; | |
20 | 50 | struct image_sig_algo image_sig_algos[] = { |
21 | 51 | { |
22 | 52 | "sha1,rsa2048", |
23 | 53 | rsa_sign, |
24 | 54 | rsa_add_verify_data, |
25 | 55 | rsa_verify, |
56 | + &checksum_algos[0], | |
57 | + }, | |
58 | + { | |
59 | + "sha256,rsa2048", | |
60 | + rsa_sign, | |
61 | + rsa_add_verify_data, | |
62 | + rsa_verify, | |
63 | + &checksum_algos[1], | |
26 | 64 | } |
27 | 65 | }; |
28 | 66 |
doc/uImage.FIT/signature.txt
... | ... | @@ -346,7 +346,9 @@ |
346 | 346 | |
347 | 347 | Please see doc/uImage.FIT/verified-boot.txt for more information |
348 | 348 | |
349 | +/home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000 | |
349 | 350 | Build keys |
351 | +do sha1 test | |
350 | 352 | Build FIT with signed images |
351 | 353 | Test Verified Boot Run: unsigned signatures:: OK |
352 | 354 | Sign images |
353 | 355 | |
... | ... | @@ -355,9 +357,19 @@ |
355 | 357 | Test Verified Boot Run: unsigned config: OK |
356 | 358 | Sign images |
357 | 359 | Test Verified Boot Run: signed config: OK |
360 | +Test Verified Boot Run: signed config with bad hash: OK | |
361 | +do sha256 test | |
362 | +Build FIT with signed images | |
363 | +Test Verified Boot Run: unsigned signatures:: OK | |
364 | +Sign images | |
365 | +Test Verified Boot Run: signed images: OK | |
366 | +Build FIT with signed configuration | |
367 | +Test Verified Boot Run: unsigned config: OK | |
368 | +Sign images | |
369 | +Test Verified Boot Run: signed config: OK | |
370 | +Test Verified Boot Run: signed config with bad hash: OK | |
358 | 371 | |
359 | 372 | Test passed |
360 | - | |
361 | 373 | |
362 | 374 | Future Work |
363 | 375 | ----------- |
include/image.h
... | ... | @@ -833,6 +833,7 @@ |
833 | 833 | # ifdef USE_HOSTCC |
834 | 834 | # define IMAGE_ENABLE_SIGN 1 |
835 | 835 | # define IMAGE_ENABLE_VERIFY 0 |
836 | +# include <openssl/evp.h> | |
836 | 837 | #else |
837 | 838 | # define IMAGE_ENABLE_SIGN 0 |
838 | 839 | # define IMAGE_ENABLE_VERIFY 1 |
... | ... | @@ -872,6 +873,23 @@ |
872 | 873 | int size; |
873 | 874 | }; |
874 | 875 | |
876 | +#if IMAGE_ENABLE_VERIFY | |
877 | +# include <rsa-checksum.h> | |
878 | +#endif | |
879 | +struct checksum_algo { | |
880 | + const char *name; | |
881 | + const int checksum_len; | |
882 | +#if IMAGE_ENABLE_SIGN | |
883 | + const EVP_MD *(*calculate)(void); | |
884 | +#else | |
885 | +#if IMAGE_ENABLE_VERIFY | |
886 | + void (*calculate)(const struct image_region region[], | |
887 | + int region_count, uint8_t *checksum); | |
888 | + const uint8_t *rsa_padding; | |
889 | +#endif | |
890 | +#endif | |
891 | +}; | |
892 | + | |
875 | 893 | struct image_sig_algo { |
876 | 894 | const char *name; /* Name of algorithm */ |
877 | 895 | |
... | ... | @@ -922,6 +940,9 @@ |
922 | 940 | int (*verify)(struct image_sign_info *info, |
923 | 941 | const struct image_region region[], int region_count, |
924 | 942 | uint8_t *sig, uint sig_len); |
943 | + | |
944 | + /* pointer to checksum algorithm */ | |
945 | + struct checksum_algo *checksum; | |
925 | 946 | }; |
926 | 947 | |
927 | 948 | /** |
include/rsa-checksum.h
1 | +/* | |
2 | + * Copyright (c) 2013, Andreas Oetken. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | +*/ | |
6 | + | |
7 | +#ifndef _RSA_CHECKSUM_H | |
8 | +#define _RSA_CHECKSUM_H | |
9 | + | |
10 | +#include <errno.h> | |
11 | +#include <image.h> | |
12 | +#include <sha1.h> | |
13 | +#include <sha256.h> | |
14 | + | |
15 | +extern const uint8_t padding_sha256_rsa2048[]; | |
16 | +extern const uint8_t padding_sha1_rsa2048[]; | |
17 | + | |
18 | +void sha256_calculate(const struct image_region region[], int region_count, | |
19 | + uint8_t *checksum); | |
20 | +void sha1_calculate(const struct image_region region[], int region_count, | |
21 | + uint8_t *checksum); | |
22 | + | |
23 | +#endif |
include/rsa.h
... | ... | @@ -15,6 +15,20 @@ |
15 | 15 | #include <errno.h> |
16 | 16 | #include <image.h> |
17 | 17 | |
18 | +/** | |
19 | + * struct rsa_public_key - holder for a public key | |
20 | + * | |
21 | + * An RSA public key consists of a modulus (typically called N), the inverse | |
22 | + * and R^2, where R is 2^(# key bits). | |
23 | + */ | |
24 | + | |
25 | +struct rsa_public_key { | |
26 | + uint len; /* len of modulus[] in number of uint32_t */ | |
27 | + uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */ | |
28 | + uint32_t *modulus; /* modulus as little endian array */ | |
29 | + uint32_t *rr; /* R^2 as little endian array */ | |
30 | +}; | |
31 | + | |
18 | 32 | #if IMAGE_ENABLE_SIGN |
19 | 33 | /** |
20 | 34 | * sign() - calculate and return signature for given input data |
lib/rsa/Makefile
lib/rsa/rsa-checksum.c
1 | +/* | |
2 | + * Copyright (c) 2013, Andreas Oetken. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <fdtdec.h> | |
9 | +#include <rsa.h> | |
10 | +#include <sha1.h> | |
11 | +#include <sha256.h> | |
12 | +#include <asm/byteorder.h> | |
13 | +#include <asm/errno.h> | |
14 | +#include <asm/unaligned.h> | |
15 | + | |
16 | +#define RSA2048_BYTES 256 | |
17 | + | |
18 | +/* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */ | |
19 | + | |
20 | +const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = { | |
21 | +0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
22 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
23 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
24 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
25 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
26 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
27 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
28 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
29 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
30 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
31 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
32 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
33 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
34 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
35 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
36 | +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30, | |
37 | +0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, | |
38 | +0x00, 0x04, 0x20 | |
39 | +}; | |
40 | + | |
41 | +const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = { | |
42 | + 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
43 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
44 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
45 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
46 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
47 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
48 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
49 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
50 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
51 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
52 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
53 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
54 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
55 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
56 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
57 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
58 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
59 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
60 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
61 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
62 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
63 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
64 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
65 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
66 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
67 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
68 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
69 | + 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30, | |
70 | + 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, | |
71 | + 0x05, 0x00, 0x04, 0x14 | |
72 | +}; | |
73 | + | |
74 | +void sha1_calculate(const struct image_region region[], int region_count, | |
75 | + uint8_t *checksum) | |
76 | +{ | |
77 | + sha1_context ctx; | |
78 | + uint32_t i; | |
79 | + i = 0; | |
80 | + | |
81 | + sha1_starts(&ctx); | |
82 | + for (i = 0; i < region_count; i++) | |
83 | + sha1_update(&ctx, region[i].data, region[i].size); | |
84 | + sha1_finish(&ctx, checksum); | |
85 | +} | |
86 | + | |
87 | +void sha256_calculate(const struct image_region region[], int region_count, | |
88 | + uint8_t *checksum) | |
89 | +{ | |
90 | + sha256_context ctx; | |
91 | + uint32_t i; | |
92 | + i = 0; | |
93 | + | |
94 | + sha256_starts(&ctx); | |
95 | + for (i = 0; i < region_count; i++) | |
96 | + sha256_update(&ctx, region[i].data, region[i].size); | |
97 | + sha256_finish(&ctx, checksum); | |
98 | +} |
lib/rsa/rsa-sign.c
... | ... | @@ -159,8 +159,9 @@ |
159 | 159 | EVP_cleanup(); |
160 | 160 | } |
161 | 161 | |
162 | -static int rsa_sign_with_key(RSA *rsa, const struct image_region region[], | |
163 | - int region_count, uint8_t **sigp, uint *sig_size) | |
162 | +static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo, | |
163 | + const struct image_region region[], int region_count, | |
164 | + uint8_t **sigp, uint *sig_size) | |
164 | 165 | { |
165 | 166 | EVP_PKEY *key; |
166 | 167 | EVP_MD_CTX *context; |
... | ... | @@ -192,7 +193,7 @@ |
192 | 193 | goto err_create; |
193 | 194 | } |
194 | 195 | EVP_MD_CTX_init(context); |
195 | - if (!EVP_SignInit(context, EVP_sha1())) { | |
196 | + if (!EVP_SignInit(context, checksum_algo->calculate())) { | |
196 | 197 | ret = rsa_err("Signer setup failed"); |
197 | 198 | goto err_sign; |
198 | 199 | } |
... | ... | @@ -242,7 +243,8 @@ |
242 | 243 | ret = rsa_get_priv_key(info->keydir, info->keyname, &rsa); |
243 | 244 | if (ret) |
244 | 245 | goto err_priv; |
245 | - ret = rsa_sign_with_key(rsa, region, region_count, sigp, sig_len); | |
246 | + ret = rsa_sign_with_key(rsa, info->algo->checksum, region, | |
247 | + region_count, sigp, sig_len); | |
246 | 248 | if (ret) |
247 | 249 | goto err_sign; |
248 | 250 |
lib/rsa/rsa-verify.c
... | ... | @@ -8,23 +8,11 @@ |
8 | 8 | #include <fdtdec.h> |
9 | 9 | #include <rsa.h> |
10 | 10 | #include <sha1.h> |
11 | +#include <sha256.h> | |
11 | 12 | #include <asm/byteorder.h> |
12 | 13 | #include <asm/errno.h> |
13 | 14 | #include <asm/unaligned.h> |
14 | 15 | |
15 | -/** | |
16 | - * struct rsa_public_key - holder for a public key | |
17 | - * | |
18 | - * An RSA public key consists of a modulus (typically called N), the inverse | |
19 | - * and R^2, where R is 2^(# key bits). | |
20 | - */ | |
21 | -struct rsa_public_key { | |
22 | - uint len; /* Length of modulus[] in number of uint32_t */ | |
23 | - uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */ | |
24 | - uint32_t *modulus; /* modulus as little endian array */ | |
25 | - uint32_t *rr; /* R^2 as little endian array */ | |
26 | -}; | |
27 | - | |
28 | 16 | #define UINT64_MULT32(v, multby) (((uint64_t)(v)) * ((uint32_t)(multby))) |
29 | 17 | |
30 | 18 | #define RSA2048_BYTES (2048 / 8) |
... | ... | @@ -36,39 +24,6 @@ |
36 | 24 | /* This is the maximum signature length that we support, in bits */ |
37 | 25 | #define RSA_MAX_SIG_BITS 2048 |
38 | 26 | |
39 | -static const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = { | |
40 | - 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
41 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
42 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
43 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
44 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
45 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
46 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
47 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
48 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
49 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
50 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
51 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
52 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
53 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
54 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
55 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
56 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
57 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
58 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
59 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
60 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
61 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
62 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
63 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
64 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
65 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
66 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
67 | - 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30, | |
68 | - 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, | |
69 | - 0x05, 0x00, 0x04, 0x14 | |
70 | -}; | |
71 | - | |
72 | 27 | /** |
73 | 28 | * subtract_modulus() - subtract modulus from the given value |
74 | 29 | * |
75 | 30 | |
... | ... | @@ -209,13 +164,14 @@ |
209 | 164 | } |
210 | 165 | |
211 | 166 | static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig, |
212 | - const uint32_t sig_len, const uint8_t *hash) | |
167 | + const uint32_t sig_len, const uint8_t *hash, | |
168 | + struct checksum_algo *algo) | |
213 | 169 | { |
214 | 170 | const uint8_t *padding; |
215 | 171 | int pad_len; |
216 | 172 | int ret; |
217 | 173 | |
218 | - if (!key || !sig || !hash) | |
174 | + if (!key || !sig || !hash || !algo) | |
219 | 175 | return -EIO; |
220 | 176 | |
221 | 177 | if (sig_len != (key->len * sizeof(uint32_t))) { |
... | ... | @@ -223,6 +179,8 @@ |
223 | 179 | return -EINVAL; |
224 | 180 | } |
225 | 181 | |
182 | + debug("Checksum algorithm: %s", algo->name); | |
183 | + | |
226 | 184 | /* Sanity check for stack size */ |
227 | 185 | if (sig_len > RSA_MAX_SIG_BITS / 8) { |
228 | 186 | debug("Signature length %u exceeds maximum %d\n", sig_len, |
... | ... | @@ -238,9 +196,8 @@ |
238 | 196 | if (ret) |
239 | 197 | return ret; |
240 | 198 | |
241 | - /* Determine padding to use depending on the signature type. */ | |
242 | - padding = padding_sha1_rsa2048; | |
243 | - pad_len = RSA2048_BYTES - SHA1_SUM_LEN; | |
199 | + padding = algo->rsa_padding; | |
200 | + pad_len = RSA2048_BYTES - algo->checksum_len; | |
244 | 201 | |
245 | 202 | /* Check pkcs1.5 padding bytes. */ |
246 | 203 | if (memcmp(buf, padding, pad_len)) { |
... | ... | @@ -309,7 +266,7 @@ |
309 | 266 | } |
310 | 267 | |
311 | 268 | debug("key length %d\n", key.len); |
312 | - ret = rsa_verify_key(&key, sig, sig_len, hash); | |
269 | + ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum); | |
313 | 270 | if (ret) { |
314 | 271 | printf("%s: RSA failed to verify: %d\n", __func__, ret); |
315 | 272 | return ret; |
316 | 273 | |
317 | 274 | |
318 | 275 | |
... | ... | @@ -323,23 +280,31 @@ |
323 | 280 | uint8_t *sig, uint sig_len) |
324 | 281 | { |
325 | 282 | const void *blob = info->fdt_blob; |
326 | - uint8_t hash[SHA1_SUM_LEN]; | |
283 | + /* Reserve memory for maximum checksum-length */ | |
284 | + uint8_t hash[RSA2048_BYTES]; | |
327 | 285 | int ndepth, noffset; |
328 | 286 | int sig_node, node; |
329 | 287 | char name[100]; |
330 | - sha1_context ctx; | |
331 | - int ret, i; | |
288 | + int ret; | |
332 | 289 | |
290 | + /* | |
291 | + * Verify that the checksum-length does not exceed the | |
292 | + * rsa-signature-length | |
293 | + */ | |
294 | + if (info->algo->checksum->checksum_len > RSA2048_BYTES) { | |
295 | + debug("%s: invlaid checksum-algorithm %s for RSA2048\n", | |
296 | + __func__, info->algo->checksum->name); | |
297 | + return -EINVAL; | |
298 | + } | |
299 | + | |
333 | 300 | sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME); |
334 | 301 | if (sig_node < 0) { |
335 | 302 | debug("%s: No signature node found\n", __func__); |
336 | 303 | return -ENOENT; |
337 | 304 | } |
338 | 305 | |
339 | - sha1_starts(&ctx); | |
340 | - for (i = 0; i < region_count; i++) | |
341 | - sha1_update(&ctx, region[i].data, region[i].size); | |
342 | - sha1_finish(&ctx, hash); | |
306 | + /* Calculate checksum with checksum-algorithm */ | |
307 | + info->algo->checksum->calculate(region, region_count, hash); | |
343 | 308 | |
344 | 309 | /* See if we must use a particular key */ |
345 | 310 | if (info->required_keynode != -1) { |
test/vboot/sign-configs-sha1.its
1 | +/dts-v1/; | |
2 | + | |
3 | +/ { | |
4 | + description = "Chrome OS kernel image with one or more FDT blobs"; | |
5 | + #address-cells = <1>; | |
6 | + | |
7 | + images { | |
8 | + kernel@1 { | |
9 | + data = /incbin/("test-kernel.bin"); | |
10 | + type = "kernel_noload"; | |
11 | + arch = "sandbox"; | |
12 | + os = "linux"; | |
13 | + compression = "none"; | |
14 | + load = <0x4>; | |
15 | + entry = <0x8>; | |
16 | + kernel-version = <1>; | |
17 | + hash@1 { | |
18 | + algo = "sha1"; | |
19 | + }; | |
20 | + }; | |
21 | + fdt@1 { | |
22 | + description = "snow"; | |
23 | + data = /incbin/("sandbox-kernel.dtb"); | |
24 | + type = "flat_dt"; | |
25 | + arch = "sandbox"; | |
26 | + compression = "none"; | |
27 | + fdt-version = <1>; | |
28 | + hash@1 { | |
29 | + algo = "sha1"; | |
30 | + }; | |
31 | + }; | |
32 | + }; | |
33 | + configurations { | |
34 | + default = "conf@1"; | |
35 | + conf@1 { | |
36 | + kernel = "kernel@1"; | |
37 | + fdt = "fdt@1"; | |
38 | + signature@1 { | |
39 | + algo = "sha1,rsa2048"; | |
40 | + key-name-hint = "dev"; | |
41 | + sign-images = "fdt", "kernel"; | |
42 | + }; | |
43 | + }; | |
44 | + }; | |
45 | +}; |
test/vboot/sign-configs-sha256.its
1 | +/dts-v1/; | |
2 | + | |
3 | +/ { | |
4 | + description = "Chrome OS kernel image with one or more FDT blobs"; | |
5 | + #address-cells = <1>; | |
6 | + | |
7 | + images { | |
8 | + kernel@1 { | |
9 | + data = /incbin/("test-kernel.bin"); | |
10 | + type = "kernel_noload"; | |
11 | + arch = "sandbox"; | |
12 | + os = "linux"; | |
13 | + compression = "none"; | |
14 | + load = <0x4>; | |
15 | + entry = <0x8>; | |
16 | + kernel-version = <1>; | |
17 | + hash@1 { | |
18 | + algo = "sha256"; | |
19 | + }; | |
20 | + }; | |
21 | + fdt@1 { | |
22 | + description = "snow"; | |
23 | + data = /incbin/("sandbox-kernel.dtb"); | |
24 | + type = "flat_dt"; | |
25 | + arch = "sandbox"; | |
26 | + compression = "none"; | |
27 | + fdt-version = <1>; | |
28 | + hash@1 { | |
29 | + algo = "sha256"; | |
30 | + }; | |
31 | + }; | |
32 | + }; | |
33 | + configurations { | |
34 | + default = "conf@1"; | |
35 | + conf@1 { | |
36 | + kernel = "kernel@1"; | |
37 | + fdt = "fdt@1"; | |
38 | + signature@1 { | |
39 | + algo = "sha256,rsa2048"; | |
40 | + key-name-hint = "dev"; | |
41 | + sign-images = "fdt", "kernel"; | |
42 | + }; | |
43 | + }; | |
44 | + }; | |
45 | +}; |
test/vboot/sign-configs.its
1 | -/dts-v1/; | |
2 | - | |
3 | -/ { | |
4 | - description = "Chrome OS kernel image with one or more FDT blobs"; | |
5 | - #address-cells = <1>; | |
6 | - | |
7 | - images { | |
8 | - kernel@1 { | |
9 | - data = /incbin/("test-kernel.bin"); | |
10 | - type = "kernel_noload"; | |
11 | - arch = "sandbox"; | |
12 | - os = "linux"; | |
13 | - compression = "none"; | |
14 | - load = <0x4>; | |
15 | - entry = <0x8>; | |
16 | - kernel-version = <1>; | |
17 | - hash@1 { | |
18 | - algo = "sha1"; | |
19 | - }; | |
20 | - }; | |
21 | - fdt@1 { | |
22 | - description = "snow"; | |
23 | - data = /incbin/("sandbox-kernel.dtb"); | |
24 | - type = "flat_dt"; | |
25 | - arch = "sandbox"; | |
26 | - compression = "none"; | |
27 | - fdt-version = <1>; | |
28 | - hash@1 { | |
29 | - algo = "sha1"; | |
30 | - }; | |
31 | - }; | |
32 | - }; | |
33 | - configurations { | |
34 | - default = "conf@1"; | |
35 | - conf@1 { | |
36 | - kernel = "kernel@1"; | |
37 | - fdt = "fdt@1"; | |
38 | - signature@1 { | |
39 | - algo = "sha1,rsa2048"; | |
40 | - key-name-hint = "dev"; | |
41 | - sign-images = "fdt", "kernel"; | |
42 | - }; | |
43 | - }; | |
44 | - }; | |
45 | -}; |
test/vboot/sign-images-sha1.its
1 | +/dts-v1/; | |
2 | + | |
3 | +/ { | |
4 | + description = "Chrome OS kernel image with one or more FDT blobs"; | |
5 | + #address-cells = <1>; | |
6 | + | |
7 | + images { | |
8 | + kernel@1 { | |
9 | + data = /incbin/("test-kernel.bin"); | |
10 | + type = "kernel_noload"; | |
11 | + arch = "sandbox"; | |
12 | + os = "linux"; | |
13 | + compression = "none"; | |
14 | + load = <0x4>; | |
15 | + entry = <0x8>; | |
16 | + kernel-version = <1>; | |
17 | + signature@1 { | |
18 | + algo = "sha1,rsa2048"; | |
19 | + key-name-hint = "dev"; | |
20 | + }; | |
21 | + }; | |
22 | + fdt@1 { | |
23 | + description = "snow"; | |
24 | + data = /incbin/("sandbox-kernel.dtb"); | |
25 | + type = "flat_dt"; | |
26 | + arch = "sandbox"; | |
27 | + compression = "none"; | |
28 | + fdt-version = <1>; | |
29 | + signature@1 { | |
30 | + algo = "sha1,rsa2048"; | |
31 | + key-name-hint = "dev"; | |
32 | + }; | |
33 | + }; | |
34 | + }; | |
35 | + configurations { | |
36 | + default = "conf@1"; | |
37 | + conf@1 { | |
38 | + kernel = "kernel@1"; | |
39 | + fdt = "fdt@1"; | |
40 | + }; | |
41 | + }; | |
42 | +}; |
test/vboot/sign-images-sha256.its
1 | +/dts-v1/; | |
2 | + | |
3 | +/ { | |
4 | + description = "Chrome OS kernel image with one or more FDT blobs"; | |
5 | + #address-cells = <1>; | |
6 | + | |
7 | + images { | |
8 | + kernel@1 { | |
9 | + data = /incbin/("test-kernel.bin"); | |
10 | + type = "kernel_noload"; | |
11 | + arch = "sandbox"; | |
12 | + os = "linux"; | |
13 | + compression = "none"; | |
14 | + load = <0x4>; | |
15 | + entry = <0x8>; | |
16 | + kernel-version = <1>; | |
17 | + signature@1 { | |
18 | + algo = "sha256,rsa2048"; | |
19 | + key-name-hint = "dev"; | |
20 | + }; | |
21 | + }; | |
22 | + fdt@1 { | |
23 | + description = "snow"; | |
24 | + data = /incbin/("sandbox-kernel.dtb"); | |
25 | + type = "flat_dt"; | |
26 | + arch = "sandbox"; | |
27 | + compression = "none"; | |
28 | + fdt-version = <1>; | |
29 | + signature@1 { | |
30 | + algo = "sha256,rsa2048"; | |
31 | + key-name-hint = "dev"; | |
32 | + }; | |
33 | + }; | |
34 | + }; | |
35 | + configurations { | |
36 | + default = "conf@1"; | |
37 | + conf@1 { | |
38 | + kernel = "kernel@1"; | |
39 | + fdt = "fdt@1"; | |
40 | + }; | |
41 | + }; | |
42 | +}; |
test/vboot/sign-images.its
1 | -/dts-v1/; | |
2 | - | |
3 | -/ { | |
4 | - description = "Chrome OS kernel image with one or more FDT blobs"; | |
5 | - #address-cells = <1>; | |
6 | - | |
7 | - images { | |
8 | - kernel@1 { | |
9 | - data = /incbin/("test-kernel.bin"); | |
10 | - type = "kernel_noload"; | |
11 | - arch = "sandbox"; | |
12 | - os = "linux"; | |
13 | - compression = "none"; | |
14 | - load = <0x4>; | |
15 | - entry = <0x8>; | |
16 | - kernel-version = <1>; | |
17 | - signature@1 { | |
18 | - algo = "sha1,rsa2048"; | |
19 | - key-name-hint = "dev"; | |
20 | - }; | |
21 | - }; | |
22 | - fdt@1 { | |
23 | - description = "snow"; | |
24 | - data = /incbin/("sandbox-kernel.dtb"); | |
25 | - type = "flat_dt"; | |
26 | - arch = "sandbox"; | |
27 | - compression = "none"; | |
28 | - fdt-version = <1>; | |
29 | - signature@1 { | |
30 | - algo = "sha1,rsa2048"; | |
31 | - key-name-hint = "dev"; | |
32 | - }; | |
33 | - }; | |
34 | - }; | |
35 | - configurations { | |
36 | - default = "conf@1"; | |
37 | - conf@1 { | |
38 | - kernel = "kernel@1"; | |
39 | - fdt = "fdt@1"; | |
40 | - }; | |
41 | - }; | |
42 | -}; |
test/vboot/vboot_test.sh
... | ... | @@ -61,47 +61,57 @@ |
61 | 61 | |
62 | 62 | pushd ${dir} >/dev/null |
63 | 63 | |
64 | -# Compile our device tree files for kernel and U-Boot (CONFIG_OF_CONTROL) | |
65 | -dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb | |
66 | -dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb | |
64 | +function do_test { | |
65 | + echo do $sha test | |
66 | + # Compile our device tree files for kernel and U-Boot | |
67 | + dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb | |
68 | + dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb | |
67 | 69 | |
68 | -# Create a number kernel image with zeroes | |
69 | -head -c 5000 /dev/zero >test-kernel.bin | |
70 | + # Create a number kernel image with zeroes | |
71 | + head -c 5000 /dev/zero >test-kernel.bin | |
70 | 72 | |
71 | -# Build the FIT, but don't sign anything yet | |
72 | -echo Build FIT with signed images | |
73 | -${mkimage} -D "${dtc}" -f sign-images.its test.fit >${tmp} | |
73 | + # Build the FIT, but don't sign anything yet | |
74 | + echo Build FIT with signed images | |
75 | + ${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp} | |
74 | 76 | |
75 | -run_uboot "unsigned signatures:" "dev-" | |
77 | + run_uboot "unsigned signatures:" "dev-" | |
76 | 78 | |
77 | -# Sign images with our dev keys | |
78 | -echo Sign images | |
79 | -${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp} | |
79 | + # Sign images with our dev keys | |
80 | + echo Sign images | |
81 | + ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \ | |
82 | + -r test.fit >${tmp} | |
80 | 83 | |
81 | -run_uboot "signed images" "dev+" | |
84 | + run_uboot "signed images" "dev+" | |
82 | 85 | |
83 | 86 | |
84 | -# Create a fresh .dtb without the public keys | |
85 | -dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb | |
87 | + # Create a fresh .dtb without the public keys | |
88 | + dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb | |
86 | 89 | |
87 | -echo Build FIT with signed configuration | |
88 | -${mkimage} -D "${dtc}" -f sign-configs.its test.fit >${tmp} | |
90 | + echo Build FIT with signed configuration | |
91 | + ${mkimage} -D "${dtc}" -f sign-configs-$sha.its test.fit >${tmp} | |
89 | 92 | |
90 | -run_uboot "unsigned config" "sha1+ OK" | |
93 | + run_uboot "unsigned config" $sha"+ OK" | |
91 | 94 | |
92 | -# Sign images with our dev keys | |
93 | -echo Sign images | |
94 | -${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp} | |
95 | + # Sign images with our dev keys | |
96 | + echo Sign images | |
97 | + ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \ | |
98 | + -r test.fit >${tmp} | |
95 | 99 | |
96 | -run_uboot "signed config" "dev+" | |
100 | + run_uboot "signed config" "dev+" | |
97 | 101 | |
98 | -# Increment the first byte of the signature, which should cause failure | |
99 | -sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value) | |
100 | -newbyte=$(printf %x $((0x${sig:0:2} + 1))) | |
101 | -sig="${newbyte} ${sig:2}" | |
102 | -fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig} | |
102 | + # Increment the first byte of the signature, which should cause failure | |
103 | + sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value) | |
104 | + newbyte=$(printf %x $((0x${sig:0:2} + 1))) | |
105 | + sig="${newbyte} ${sig:2}" | |
106 | + fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig} | |
103 | 107 | |
104 | -run_uboot "signed config with bad hash" "Bad Data Hash" | |
108 | + run_uboot "signed config with bad hash" "Bad Data Hash" | |
109 | +} | |
110 | + | |
111 | +sha=sha1 | |
112 | +do_test | |
113 | +sha=sha256 | |
114 | +do_test | |
105 | 115 | |
106 | 116 | popd >/dev/null |
107 | 117 |