The checksum algorithm table is shared by RSA and ECDSA, but its DER
prefix fields are used only by RSA PKCS#1 v1.5 padding verification.
Keeping those prefixes in the software hash implementations also ties
signature metadata to a particular hash backend and duplicates it between
the legacy and MbedTLS shims.

Keep the SHA-1, SHA-256, SHA-384 and SHA-512 DigestInfo prefixes in the RSA
verifier instead. Select the prefix by checksum name when checking PKCS#1
v1.5 padding, include every algorithm in host tools and only configured
algorithms in target builds, and reject padding which is too short for the
required eight-byte padding string.

Remove the DER fields from the generic checksum descriptor and remove the
now-unneeded constants from the hash implementations. ECDSA-only and
hardware-hash-only builds then carry no RSA-specific DigestInfo data.

Signed-off-by: James Hilliard <[email protected]>
---
Changes v6 -> v7:
  - New patch
---
 boot/image-sig.c        |  8 ------
 include/image.h         |  2 --
 include/u-boot/sha1.h   |  3 ---
 include/u-boot/sha256.h |  3 ---
 include/u-boot/sha512.h |  6 -----
 lib/mbedtls/sha1.c      |  5 ----
 lib/mbedtls/sha256.c    |  6 -----
 lib/mbedtls/sha512.c    | 12 ---------
 lib/rsa/rsa-verify.c    | 67 ++++++++++++++++++++++++++++++++++++++++++++++---
 lib/sha1.c              |  5 ----
 lib/sha256.c            |  6 -----
 lib/sha512.c            | 12 ---------
 tools/image-sig-host.c  |  8 ------
 13 files changed, 63 insertions(+), 80 deletions(-)

diff --git a/boot/image-sig.c b/boot/image-sig.c
index 4eab017bc2d..80a9c4325bd 100644
--- a/boot/image-sig.c
+++ b/boot/image-sig.c
@@ -18,8 +18,6 @@ struct checksum_algo checksum_algos[] = {
        {
                .name = "sha1",
                .checksum_len = SHA1_SUM_LEN,
-               .der_len = SHA1_DER_LEN,
-               .der_prefix = sha1_der_prefix,
                .calculate = hash_calculate,
        },
 #endif
@@ -27,8 +25,6 @@ struct checksum_algo checksum_algos[] = {
        {
                .name = "sha256",
                .checksum_len = SHA256_SUM_LEN,
-               .der_len = SHA256_DER_LEN,
-               .der_prefix = sha256_der_prefix,
                .calculate = hash_calculate,
        },
 #endif
@@ -36,8 +32,6 @@ struct checksum_algo checksum_algos[] = {
        {
                .name = "sha384",
                .checksum_len = SHA384_SUM_LEN,
-               .der_len = SHA384_DER_LEN,
-               .der_prefix = sha384_der_prefix,
                .calculate = hash_calculate,
        },
 #endif
@@ -45,8 +39,6 @@ struct checksum_algo checksum_algos[] = {
        {
                .name = "sha512",
                .checksum_len = SHA512_SUM_LEN,
-               .der_len = SHA512_DER_LEN,
-               .der_prefix = sha512_der_prefix,
                .calculate = hash_calculate,
        },
 #endif
diff --git a/include/image.h b/include/image.h
index 6edcb1995bf..b7086528e47 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1660,8 +1660,6 @@ struct image_region {
 struct checksum_algo {
        const char *name;
        const int checksum_len;
-       const int der_len;
-       const uint8_t *der_prefix;
 #if IMAGE_ENABLE_SIGN
        const EVP_MD *(*calculate_sign)(void);
 #endif
diff --git a/include/u-boot/sha1.h b/include/u-boot/sha1.h
index c2d62e9cf0f..7a167130dae 100644
--- a/include/u-boot/sha1.h
+++ b/include/u-boot/sha1.h
@@ -28,7 +28,6 @@ extern "C" {
 
 #define SHA1_SUM_POS   -0x20
 #define SHA1_SUM_LEN   20
-#define SHA1_DER_LEN   15
 
 #define SHA1_DEF_CHUNK_SZ 0x10000
 
@@ -36,8 +35,6 @@ extern "C" {
 #define K_OPAD_VAL 0x5C
 #define K_PAD_LEN 64
 
-extern const uint8_t sha1_der_prefix[];
-
 #if CONFIG_IS_ENABLED(MBEDTLS_LIB_CRYPTO)
 typedef mbedtls_sha1_context sha1_context;
 #else
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h
index 2d86508332e..4137b0c5851 100644
--- a/include/u-boot/sha256.h
+++ b/include/u-boot/sha256.h
@@ -13,9 +13,6 @@
 
 #define SHA224_SUM_LEN 28
 #define SHA256_SUM_LEN 32
-#define SHA256_DER_LEN 19
-
-extern const uint8_t sha256_der_prefix[];
 
 /* Reset watchdog each time we process this many bytes */
 #define CHUNKSZ_SHA256 (64 * 1024)
diff --git a/include/u-boot/sha512.h b/include/u-boot/sha512.h
index 92660d93357..d186238d856 100644
--- a/include/u-boot/sha512.h
+++ b/include/u-boot/sha512.h
@@ -9,9 +9,7 @@
 #endif
 
 #define SHA384_SUM_LEN          48
-#define SHA384_DER_LEN          19
 #define SHA512_SUM_LEN          64
-#define SHA512_DER_LEN          19
 #define SHA512_BLOCK_SIZE       128
 
 #define CHUNKSZ_SHA384 (16 * 1024)
@@ -28,8 +26,6 @@ typedef struct {
 } sha512_context;
 #endif
 
-extern const uint8_t sha512_der_prefix[];
-
 void sha512_starts(sha512_context * ctx);
 void sha512_update(sha512_context *ctx, const uint8_t *input, uint32_t length);
 void sha512_finish(sha512_context * ctx, uint8_t digest[SHA512_SUM_LEN]);
@@ -37,8 +33,6 @@ void sha512_finish(sha512_context * ctx, uint8_t 
digest[SHA512_SUM_LEN]);
 void sha512_csum_wd(const unsigned char *input, unsigned int ilen,
                unsigned char *output, unsigned int chunk_sz);
 
-extern const uint8_t sha384_der_prefix[];
-
 void sha384_starts(sha512_context * ctx);
 void sha384_update(sha512_context *ctx, const uint8_t *input, uint32_t length);
 void sha384_finish(sha512_context * ctx, uint8_t digest[SHA384_SUM_LEN]);
diff --git a/lib/mbedtls/sha1.c b/lib/mbedtls/sha1.c
index 2aee5037795..3dbec314e11 100644
--- a/lib/mbedtls/sha1.c
+++ b/lib/mbedtls/sha1.c
@@ -11,11 +11,6 @@
 #include <string.h>
 #include <u-boot/sha1.h>
 
-const u8 sha1_der_prefix[SHA1_DER_LEN] = {
-       0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
-       0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
-};
-
 void sha1_starts(sha1_context *ctx)
 {
        mbedtls_sha1_init(ctx);
diff --git a/lib/mbedtls/sha256.c b/lib/mbedtls/sha256.c
index 59edcb517df..d4b97a1c16d 100644
--- a/lib/mbedtls/sha256.c
+++ b/lib/mbedtls/sha256.c
@@ -16,12 +16,6 @@
 #include <mbedtls/hkdf.h>
 #endif
 
-const u8 sha256_der_prefix[SHA256_DER_LEN] = {
-       0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-       0x00, 0x04, 0x20
-};
-
 void sha256_starts(sha256_context *ctx)
 {
        mbedtls_sha256_init(ctx);
diff --git a/lib/mbedtls/sha512.c b/lib/mbedtls/sha512.c
index 5615248cb91..308edcbd635 100644
--- a/lib/mbedtls/sha512.c
+++ b/lib/mbedtls/sha512.c
@@ -11,18 +11,6 @@
 #include <compiler.h>
 #include <u-boot/sha512.h>
 
-const u8 sha384_der_prefix[SHA384_DER_LEN] = {
-       0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
-       0x00, 0x04, 0x30
-};
-
-const u8 sha512_der_prefix[SHA512_DER_LEN] = {
-       0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
-       0x00, 0x04, 0x40
-};
-
 void sha384_starts(sha512_context *ctx)
 {
        mbedtls_sha512_init(ctx);
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 3169c3a6dd1..5b70c971c31 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -25,6 +25,56 @@
 /* Default public exponent for backward compatibility */
 #define RSA_DEFAULT_PUBEXP     65537
 
+static const unsigned char rsa_sha1_der_prefix[] = {
+       0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+       0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
+};
+
+static const unsigned char rsa_sha256_der_prefix[] = {
+       0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+       0x00, 0x04, 0x20
+};
+
+static const unsigned char rsa_sha384_der_prefix[] = {
+       0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
+       0x00, 0x04, 0x30
+};
+
+static const unsigned char rsa_sha512_der_prefix[] = {
+       0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+       0x00, 0x04, 0x40
+};
+
+static int rsa_get_digest_info(const char *name,
+                              const unsigned char **der_prefix)
+{
+       if ((tools_build() || CONFIG_IS_ENABLED(SHA1)) &&
+           !strcmp(name, "sha1")) {
+               *der_prefix = rsa_sha1_der_prefix;
+               return sizeof(rsa_sha1_der_prefix);
+       }
+       if ((tools_build() || CONFIG_IS_ENABLED(SHA256)) &&
+           !strcmp(name, "sha256")) {
+               *der_prefix = rsa_sha256_der_prefix;
+               return sizeof(rsa_sha256_der_prefix);
+       }
+       if ((tools_build() || CONFIG_IS_ENABLED(SHA384)) &&
+           !strcmp(name, "sha384")) {
+               *der_prefix = rsa_sha384_der_prefix;
+               return sizeof(rsa_sha384_der_prefix);
+       }
+       if ((tools_build() || CONFIG_IS_ENABLED(SHA512)) &&
+           !strcmp(name, "sha512")) {
+               *der_prefix = rsa_sha512_der_prefix;
+               return sizeof(rsa_sha512_der_prefix);
+       }
+
+       return -EINVAL;
+}
+
 /**
  * rsa_verify_padding() - Verify RSA message padding is valid
  *
@@ -33,28 +83,37 @@
  *
  * @msg:       Padded message
  * @pad_len:   Number of expected padding bytes
- * @algo:      Checksum algo structure having information on DER encoding etc.
+ * @algo:      Checksum algorithm used to select the DigestInfo prefix
  * Return: 0 on success, != 0 on failure
  */
 static int rsa_verify_padding(const uint8_t *msg, const int pad_len,
-                             struct checksum_algo *algo)
+                             const struct checksum_algo *algo)
 {
+       const unsigned char *der_prefix;
+       int der_len;
        int ff_len;
        int ret;
 
+       der_len = rsa_get_digest_info(algo->name, &der_prefix);
+       if (der_len < 0)
+               return der_len;
+
+       ff_len = pad_len - der_len - 3;
+       if (ff_len < 8)
+               return -EINVAL;
+
        /* first byte must be 0x00 */
        ret = *msg++;
        /* second byte must be 0x01 */
        ret |= *msg++ ^ 0x01;
        /* next ff_len bytes must be 0xff */
-       ff_len = pad_len - algo->der_len - 3;
        ret |= *msg ^ 0xff;
        ret |= memcmp(msg, msg+1, ff_len-1);
        msg += ff_len;
        /* next byte must be 0x00 */
        ret |= *msg++;
        /* next der_len bytes must match der_prefix */
-       ret |= memcmp(msg, algo->der_prefix, algo->der_len);
+       ret |= memcmp(msg, der_prefix, der_len);
 
        return ret;
 }
diff --git a/lib/sha1.c b/lib/sha1.c
index be502c6126b..4f35850b384 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -24,11 +24,6 @@
 
 #include <linux/compiler_attributes.h>
 
-const uint8_t sha1_der_prefix[SHA1_DER_LEN] = {
-       0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
-       0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
-};
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
diff --git a/lib/sha256.c b/lib/sha256.c
index c2e77c854b9..b99f8105c8d 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -13,12 +13,6 @@
 
 #include <linux/compiler_attributes.h>
 
-const uint8_t sha256_der_prefix[SHA256_DER_LEN] = {
-       0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-       0x00, 0x04, 0x20
-};
-
 /*
  * 32-bit integer manipulation macros (big endian)
  */
diff --git a/lib/sha512.c b/lib/sha512.c
index 0e75c1a943b..06d9b5564f9 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -16,18 +16,6 @@
 #include <compiler.h>
 #include <u-boot/sha512.h>
 
-const uint8_t sha384_der_prefix[SHA384_DER_LEN] = {
-       0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
-       0x00, 0x04, 0x30
-};
-
-const uint8_t sha512_der_prefix[SHA512_DER_LEN] = {
-       0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-       0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
-       0x00, 0x04, 0x40
-};
-
 #define SHA384_H0      0xcbbb9d5dc1059ed8ULL
 #define SHA384_H1      0x629a292a367cd507ULL
 #define SHA384_H2      0x9159015a3070dd17ULL
diff --git a/tools/image-sig-host.c b/tools/image-sig-host.c
index 5285263c616..758f14337ed 100644
--- a/tools/image-sig-host.c
+++ b/tools/image-sig-host.c
@@ -16,32 +16,24 @@ struct checksum_algo checksum_algos[] = {
        {
                .name = "sha1",
                .checksum_len = SHA1_SUM_LEN,
-               .der_len = SHA1_DER_LEN,
-               .der_prefix = sha1_der_prefix,
                .calculate_sign = EVP_sha1,
                .calculate = hash_calculate,
        },
        {
                .name = "sha256",
                .checksum_len = SHA256_SUM_LEN,
-               .der_len = SHA256_DER_LEN,
-               .der_prefix = sha256_der_prefix,
                .calculate_sign = EVP_sha256,
                .calculate = hash_calculate,
        },
        {
                .name = "sha384",
                .checksum_len = SHA384_SUM_LEN,
-               .der_len = SHA384_DER_LEN,
-               .der_prefix = sha384_der_prefix,
                .calculate_sign = EVP_sha384,
                .calculate = hash_calculate,
        },
        {
                .name = "sha512",
                .checksum_len = SHA512_SUM_LEN,
-               .der_len = SHA512_DER_LEN,
-               .der_prefix = sha512_der_prefix,
                .calculate_sign = EVP_sha512,
                .calculate = hash_calculate,
        },

-- 
2.53.0

Reply via email to