Commit da29f2991d75fc8aa3289407a0e686a4a22f8c9e
Committed by
Tom Rini
1 parent
5300a4f933
Exists in
v2017.01-smarct4x
and in
25 other branches
rsa: Verify RSA padding programatically
Padding verification was done against static SHA/RSA pair arrays which take up a lot of static memory, are mostly 0xff, and cannot be reused for additional SHA/RSA pairings. The padding can be easily computed according to PKCS#1v2.1 as: EM = 0x00 || 0x01 || PS || 0x00 || T where PS is (emLen - tLen - 3) octets of 0xff and T is DER encoding of the hash. Store DER prefix in checksum_algo and create rsa_verify_padding function to handle verification of a message for any SHA/RSA pairing. Signed-off-by: Andrew Duda <aduda@meraki.com> Signed-off-by: aduda <aduda@meraki.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Showing 9 changed files with 61 additions and 131 deletions Side-by-side Diff
common/image-sig.c
... | ... | @@ -34,32 +34,35 @@ |
34 | 34 | { |
35 | 35 | "sha1", |
36 | 36 | SHA1_SUM_LEN, |
37 | + SHA1_DER_LEN, | |
38 | + sha1_der_prefix, | |
37 | 39 | RSA2048_BYTES, |
38 | 40 | #if IMAGE_ENABLE_SIGN |
39 | 41 | EVP_sha1, |
40 | 42 | #endif |
41 | 43 | hash_calculate, |
42 | - padding_sha1_rsa2048, | |
43 | 44 | }, |
44 | 45 | { |
45 | 46 | "sha256", |
46 | 47 | SHA256_SUM_LEN, |
48 | + SHA256_DER_LEN, | |
49 | + sha256_der_prefix, | |
47 | 50 | RSA2048_BYTES, |
48 | 51 | #if IMAGE_ENABLE_SIGN |
49 | 52 | EVP_sha256, |
50 | 53 | #endif |
51 | 54 | hash_calculate, |
52 | - padding_sha256_rsa2048, | |
53 | 55 | }, |
54 | 56 | { |
55 | 57 | "sha256", |
56 | 58 | SHA256_SUM_LEN, |
59 | + SHA256_DER_LEN, | |
60 | + sha256_der_prefix, | |
57 | 61 | RSA4096_BYTES, |
58 | 62 | #if IMAGE_ENABLE_SIGN |
59 | 63 | EVP_sha256, |
60 | 64 | #endif |
61 | 65 | hash_calculate, |
62 | - padding_sha256_rsa4096, | |
63 | 66 | } |
64 | 67 | |
65 | 68 | }; |
include/image.h
... | ... | @@ -1070,6 +1070,8 @@ |
1070 | 1070 | struct checksum_algo { |
1071 | 1071 | const char *name; |
1072 | 1072 | const int checksum_len; |
1073 | + const int der_len; | |
1074 | + const uint8_t *der_prefix; | |
1073 | 1075 | const int key_len; |
1074 | 1076 | #if IMAGE_ENABLE_SIGN |
1075 | 1077 | const EVP_MD *(*calculate_sign)(void); |
... | ... | @@ -1077,7 +1079,6 @@ |
1077 | 1079 | int (*calculate)(const char *name, |
1078 | 1080 | const struct image_region region[], |
1079 | 1081 | int region_count, uint8_t *checksum); |
1080 | - const uint8_t *rsa_padding; | |
1081 | 1082 | }; |
1082 | 1083 | |
1083 | 1084 | struct image_sig_algo { |
include/u-boot/rsa-checksum.h
... | ... | @@ -12,10 +12,6 @@ |
12 | 12 | #include <u-boot/sha1.h> |
13 | 13 | #include <u-boot/sha256.h> |
14 | 14 | |
15 | -extern const uint8_t padding_sha256_rsa4096[]; | |
16 | -extern const uint8_t padding_sha256_rsa2048[]; | |
17 | -extern const uint8_t padding_sha1_rsa2048[]; | |
18 | - | |
19 | 15 | /** |
20 | 16 | * hash_calculate() - Calculate hash over the data |
21 | 17 | * |
include/u-boot/sha1.h
include/u-boot/sha256.h
lib/rsa/rsa-checksum.c
... | ... | @@ -13,129 +13,8 @@ |
13 | 13 | #include <hash.h> |
14 | 14 | #else |
15 | 15 | #include "fdt_host.h" |
16 | -#include <u-boot/sha1.h> | |
17 | -#include <u-boot/sha256.h> | |
18 | 16 | #endif |
19 | 17 | #include <u-boot/rsa.h> |
20 | - | |
21 | -/* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */ | |
22 | - | |
23 | -const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = { | |
24 | -0x00, 0x01, 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, 0xff, 0xff, 0xff, 0xff, | |
37 | -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
38 | -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
39 | -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30, | |
40 | -0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, | |
41 | -0x00, 0x04, 0x20 | |
42 | -}; | |
43 | - | |
44 | -const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = { | |
45 | - 0x00, 0x01, 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, 0xff, 0xff, 0xff, 0xff, | |
70 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
71 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
72 | - 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30, | |
73 | - 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, | |
74 | - 0x05, 0x00, 0x04, 0x14 | |
75 | -}; | |
76 | - | |
77 | -const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = { | |
78 | - 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
79 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
80 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
81 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
82 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
83 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
84 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
85 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
86 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
87 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
88 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
89 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
90 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
91 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
92 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
93 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
94 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
95 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
96 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
97 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
98 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
99 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
100 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
101 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
102 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
103 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
104 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
105 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
106 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
107 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
108 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
109 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
110 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
111 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
112 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
113 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
114 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
115 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
116 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
117 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
118 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
119 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
120 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
121 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
122 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
123 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
124 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
125 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
126 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
127 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
128 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
129 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
130 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
131 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
132 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
133 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
134 | - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
135 | - 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30, | |
136 | - 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, | |
137 | - 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 | |
138 | -}; | |
139 | 18 | |
140 | 19 | int hash_calculate(const char *name, |
141 | 20 | const struct image_region region[], |
lib/rsa/rsa-verify.c
... | ... | @@ -25,6 +25,40 @@ |
25 | 25 | #define RSA_DEFAULT_PUBEXP 65537 |
26 | 26 | |
27 | 27 | /** |
28 | + * rsa_verify_padding() - Verify RSA message padding is valid | |
29 | + * | |
30 | + * Verify a RSA message's padding is consistent with PKCS1.5 | |
31 | + * padding as described in the RSA PKCS#1 v2.1 standard. | |
32 | + * | |
33 | + * @msg: Padded message | |
34 | + * @pad_len: Number of expected padding bytes | |
35 | + * @algo: Checksum algo structure having information on DER encoding etc. | |
36 | + * @return 0 on success, != 0 on failure | |
37 | + */ | |
38 | +static int rsa_verify_padding(const uint8_t *msg, const int pad_len, | |
39 | + struct checksum_algo *algo) | |
40 | +{ | |
41 | + int ff_len; | |
42 | + int ret; | |
43 | + | |
44 | + /* first byte must be 0x00 */ | |
45 | + ret = *msg++; | |
46 | + /* second byte must be 0x01 */ | |
47 | + ret |= *msg++ ^ 0x01; | |
48 | + /* next ff_len bytes must be 0xff */ | |
49 | + ff_len = pad_len - algo->der_len - 3; | |
50 | + ret |= *msg ^ 0xff; | |
51 | + ret |= memcmp(msg, msg+1, ff_len-1); | |
52 | + msg += ff_len; | |
53 | + /* next byte must be 0x00 */ | |
54 | + ret |= *msg++; | |
55 | + /* next der_len bytes must match der_prefix */ | |
56 | + ret |= memcmp(msg, algo->der_prefix, algo->der_len); | |
57 | + | |
58 | + return ret; | |
59 | +} | |
60 | + | |
61 | +/** | |
28 | 62 | * rsa_verify_key() - Verify a signature against some data using RSA Key |
29 | 63 | * |
30 | 64 | * Verify a RSA PKCS1.5 signature against an expected hash using |
31 | 65 | |
... | ... | @@ -83,11 +117,11 @@ |
83 | 117 | return ret; |
84 | 118 | } |
85 | 119 | |
86 | - padding = algo->rsa_padding; | |
87 | 120 | pad_len = algo->key_len - algo->checksum_len; |
88 | 121 | |
89 | 122 | /* Check pkcs1.5 padding bytes. */ |
90 | - if (memcmp(buf, padding, pad_len)) { | |
123 | + ret = rsa_verify_padding(buf, pad_len, algo); | |
124 | + if (ret) { | |
91 | 125 | debug("In RSAVerify(): Padding check failed!\n"); |
92 | 126 | return -EINVAL; |
93 | 127 | } |
lib/sha1.c
... | ... | @@ -26,6 +26,11 @@ |
26 | 26 | #include <watchdog.h> |
27 | 27 | #include <u-boot/sha1.h> |
28 | 28 | |
29 | +const uint8_t sha1_der_prefix[SHA1_DER_LEN] = { | |
30 | + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, | |
31 | + 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 | |
32 | +}; | |
33 | + | |
29 | 34 | /* |
30 | 35 | * 32-bit integer manipulation macros (big endian) |
31 | 36 | */ |
lib/sha256.c
... | ... | @@ -15,6 +15,12 @@ |
15 | 15 | #include <watchdog.h> |
16 | 16 | #include <u-boot/sha256.h> |
17 | 17 | |
18 | +const uint8_t sha256_der_prefix[SHA256_DER_LEN] = { | |
19 | + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, | |
20 | + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, | |
21 | + 0x00, 0x04, 0x20 | |
22 | +}; | |
23 | + | |
18 | 24 | /* |
19 | 25 | * 32-bit integer manipulation macros (big endian) |
20 | 26 | */ |