]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
lib: rsa: function to verify a signature against a hash
authorHeiko Stuebner <heiko.stuebner@theobroma-systems.com>
Fri, 22 May 2020 14:20:33 +0000 (16:20 +0200)
committerTom Rini <trini@konsulko.com>
Wed, 8 Jul 2020 21:21:46 +0000 (17:21 -0400)
rsa_verify() expects a memory region and wants to do the hashing itself,
but there may be cases where the hashing is done via other means,
like hashing a squashfs rootfs.

So add rsa_verify_hash() to allow verifiying a signature against
an existing hash. As this entails the same verification routines
we can just move the relevant code over from rsa_verify() and also
call rsa_verify_hash() from there.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
include/u-boot/rsa.h
lib/rsa/rsa-verify.c

index 2d3024d8b71084d0e2eadcc4fbf9193bfd8a63ec..a0bae495f0547b3b51201dbed90ac8cb38ce8e12 100644 (file)
@@ -82,6 +82,20 @@ static inline int rsa_add_verify_data(struct image_sign_info *info,
 #endif
 
 #if IMAGE_ENABLE_VERIFY
+/**
+ * rsa_verify_hash() - Verify a signature against a hash
+ *
+ * Verify a RSA PKCS1.5 signature against an expected hash.
+ *
+ * @info:      Specifies key and FIT information
+ * @hash:      Hash according to algorithm specified in @info
+ * @sig:       Signature
+ * @sig_len:   Number of bytes in signature
+ * @return 0 if verified, -ve on error
+ */
+int rsa_verify_hash(struct image_sign_info *info,
+                   const uint8_t *hash, uint8_t *sig, uint sig_len);
+
 /**
  * rsa_verify() - Verify a signature against some data
  *
@@ -108,6 +122,13 @@ int padding_pss_verify(struct image_sign_info *info,
                       const uint8_t *hash, int hash_len);
 #endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
 #else
+static inline int rsa_verify_hash(struct image_sign_info *info,
+                                 const uint8_t *hash,
+                                 uint8_t *sig, uint sig_len)
+{
+       return -ENXIO;
+}
+
 static inline int rsa_verify(struct image_sign_info *info,
                const struct image_region region[], int region_count,
                uint8_t *sig, uint sig_len)
index 61d98e6e2d5ca7486fdd5aecd8f2d8dce80a3ad4..6c4bbc46250d124ccf9c01a0341465db81138fe9 100644 (file)
@@ -478,33 +478,11 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
 }
 #endif
 
-int rsa_verify(struct image_sign_info *info,
-              const struct image_region region[], int region_count,
-              uint8_t *sig, uint sig_len)
+int rsa_verify_hash(struct image_sign_info *info,
+                   const uint8_t *hash, uint8_t *sig, uint sig_len)
 {
-       /* Reserve memory for maximum checksum-length */
-       uint8_t hash[info->crypto->key_len];
        int ret = -EACCES;
 
-       /*
-        * Verify that the checksum-length does not exceed the
-        * rsa-signature-length
-        */
-       if (info->checksum->checksum_len >
-           info->crypto->key_len) {
-               debug("%s: invlaid checksum-algorithm %s for %s\n",
-                     __func__, info->checksum->name, info->crypto->name);
-               return -EINVAL;
-       }
-
-       /* Calculate checksum with checksum-algorithm */
-       ret = info->checksum->calculate(info->checksum->name,
-                                       region, region_count, hash);
-       if (ret < 0) {
-               debug("%s: Error in checksum calculation\n", __func__);
-               return -EINVAL;
-       }
-
        if (CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) {
                /* don't rely on fdt properties */
                ret = rsa_verify_with_pkey(info, hash, sig, sig_len);
@@ -555,3 +533,33 @@ int rsa_verify(struct image_sign_info *info,
 
        return ret;
 }
+
+int rsa_verify(struct image_sign_info *info,
+              const struct image_region region[], int region_count,
+              uint8_t *sig, uint sig_len)
+{
+       /* Reserve memory for maximum checksum-length */
+       uint8_t hash[info->crypto->key_len];
+       int ret = -EACCES;
+
+       /*
+        * Verify that the checksum-length does not exceed the
+        * rsa-signature-length
+        */
+       if (info->checksum->checksum_len >
+           info->crypto->key_len) {
+               debug("%s: invlaid checksum-algorithm %s for %s\n",
+                     __func__, info->checksum->name, info->crypto->name);
+               return -EINVAL;
+       }
+
+       /* Calculate checksum with checksum-algorithm */
+       ret = info->checksum->calculate(info->checksum->name,
+                                       region, region_count, hash);
+       if (ret < 0) {
+               debug("%s: Error in checksum calculation\n", __func__);
+               return -EINVAL;
+       }
+
+       return rsa_verify_hash(info, hash, sig, sig_len);
+}