Merge https://source.denx.de/u-boot/custodians/u-boot-sunxi
[platform/kernel/u-boot.git] / lib / rsa / rsa-verify.c
index 80e8173..3840764 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef USE_HOSTCC
 #include <common.h>
 #include <fdtdec.h>
+#include <log.h>
 #include <malloc.h>
 #include <asm/types.h>
 #include <asm/byteorder.h>
@@ -94,7 +95,7 @@ int padding_pkcs_15_verify(struct image_sign_info *info,
        return 0;
 }
 
-#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+#ifdef CONFIG_FIT_RSASSA_PSS
 static void u32_i2osp(uint32_t val, uint8_t *buf)
 {
        buf[0] = (uint8_t)((val >> 24) & 0xff);
@@ -193,6 +194,19 @@ out:
        return ret;
 }
 
+/*
+ * padding_pss_verify() - verify the pss padding of a signature
+ *
+ * Only works with a rsa_pss_saltlen:-2 (default value) right now
+ * saltlen:-1 "set the salt length to the digest length" is currently
+ * not supported.
+ *
+ * @info:      Specifies key and FIT information
+ * @msg:       byte array of message, len equal to msg_len
+ * @msg_len:   Message length
+ * @hash:      Pointer to the expected hash
+ * @hash_len:  Length of the hash
+ */
 int padding_pss_verify(struct image_sign_info *info,
                       uint8_t *msg, int msg_len,
                       const uint8_t *hash, int hash_len)
@@ -284,7 +298,7 @@ out:
 }
 #endif
 
-#if CONFIG_IS_ENABLED(FIT_SIGNATURE) || IS_ENABLED(CONFIG_RSA_VERIFY_WITH_PKEY)
+#if CONFIG_IS_ENABLED(FIT_SIGNATURE) || CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)
 /**
  * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
@@ -358,7 +372,7 @@ static int rsa_verify_key(struct image_sign_info *info,
 }
 #endif
 
-#ifdef CONFIG_RSA_VERIFY_WITH_PKEY
+#if CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)
 /**
  * rsa_verify_with_pkey() - Verify a signature against some data using
  * only modulus and exponent as RSA key properties.
@@ -373,8 +387,8 @@ static int rsa_verify_key(struct image_sign_info *info,
  *
  * Return      0 if verified, -ve on error
  */
-static int rsa_verify_with_pkey(struct image_sign_info *info,
-                               const void *hash, uint8_t *sig, uint sig_len)
+int rsa_verify_with_pkey(struct image_sign_info *info,
+                        const void *hash, uint8_t *sig, uint sig_len)
 {
        struct key_prop *prop;
        int ret;
@@ -394,8 +408,8 @@ static int rsa_verify_with_pkey(struct image_sign_info *info,
        return ret;
 }
 #else
-static int rsa_verify_with_pkey(struct image_sign_info *info,
-                               const void *hash, uint8_t *sig, uint sig_len)
+int rsa_verify_with_pkey(struct image_sign_info *info,
+                        const void *hash, uint8_t *sig, uint sig_len)
 {
        return -EACCES;
 }
@@ -425,12 +439,20 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
        struct key_prop prop;
        int length;
        int ret = 0;
+       const char *algo;
 
        if (node < 0) {
                debug("%s: Skipping invalid node", __func__);
                return -EBADF;
        }
 
+       algo = fdt_getprop(blob, node, "algo", NULL);
+       if (strcmp(info->name, algo)) {
+               debug("%s: Wrong algo: have %s, expected %s", __func__,
+                     info->name, algo);
+               return -EFAULT;
+       }
+
        prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
 
        prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
@@ -445,7 +467,7 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
 
        prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
 
-       if (!prop.num_bits || !prop.modulus) {
+       if (!prop.num_bits || !prop.modulus || !prop.rr) {
                debug("%s: Missing RSA key info", __func__);
                return -EFAULT;
        }
@@ -464,34 +486,12 @@ 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 (IS_ENABLED(CONFIG_RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) {
+       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);
 
@@ -525,10 +525,10 @@ int rsa_verify(struct image_sign_info *info,
                        return ret;
 
                /* No luck, so try each of the keys in turn */
-               for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node,
+               for (ndepth = 0, noffset = fdt_next_node(blob, sig_node,
                                                         &ndepth);
                     (noffset >= 0) && (ndepth > 0);
-                    noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
+                    noffset = fdt_next_node(blob, noffset, &ndepth)) {
                        if (ndepth == 1 && noffset != node) {
                                ret = rsa_verify_with_keynode(info, hash,
                                                              sig, sig_len,
@@ -541,3 +541,49 @@ 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;
+
+       /*
+        * Verify that the checksum-length does not exceed the
+        * rsa-signature-length
+        */
+       if (info->checksum->checksum_len >
+           info->crypto->key_len) {
+               debug("%s: invalid 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);
+}
+
+#ifndef USE_HOSTCC
+
+U_BOOT_CRYPTO_ALGO(rsa2048) = {
+       .name = "rsa2048",
+       .key_len = RSA2048_BYTES,
+       .verify = rsa_verify,
+};
+
+U_BOOT_CRYPTO_ALGO(rsa4096) = {
+       .name = "rsa4096",
+       .key_len = RSA4096_BYTES,
+       .verify = rsa_verify,
+};
+
+#endif