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
