#ifndef USE_HOSTCC
#include <common.h>
#include <fdtdec.h>
+#include <log.h>
#include <malloc.h>
#include <asm/types.h>
#include <asm/byteorder.h>
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);
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)
}
#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
*
}
#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.
*
* 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;
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;
}
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);
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;
}
}
#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);
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,
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