Commit da29f2991d75fc8aa3289407a0e686a4a22f8c9e

Authored by Andrew Duda
Committed by Tom Rini
1 parent 5300a4f933

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

... ... @@ -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 };
... ... @@ -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
... ... @@ -21,6 +21,9 @@
21 21  
22 22 #define SHA1_SUM_POS -0x20
23 23 #define SHA1_SUM_LEN 20
  24 +#define SHA1_DER_LEN 15
  25 +
  26 +extern const uint8_t sha1_der_prefix[];
24 27  
25 28 /**
26 29 * \brief SHA-1 context structure
include/u-boot/sha256.h
... ... @@ -2,6 +2,9 @@
2 2 #define _SHA256_H
3 3  
4 4 #define SHA256_SUM_LEN 32
  5 +#define SHA256_DER_LEN 19
  6 +
  7 +extern const uint8_t sha256_der_prefix[];
5 8  
6 9 /* Reset watchdog each time we process this many bytes */
7 10 #define CHUNKSZ_SHA256 (64 * 1024)
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 }
... ... @@ -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 */
... ... @@ -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 */