rsa: support write public hash in spl
Signed-off-by: Jason Zhu <jason.zhu@rock-chips.com> Change-Id: I4120d0cad1cb24b45c3b281649e1eba520a11ee2
This commit is contained in:
parent
5c0419f083
commit
78263d89a3
|
@ -424,6 +424,12 @@ int fit_config_check_sig(const void *fit, int noffset, int required_keynode,
|
|||
*err_msgp = "Verification failed";
|
||||
return -1;
|
||||
}
|
||||
/* Get the secure flag here and write the secure data and the secure flag */
|
||||
#if !defined(USE_HOSTCC)
|
||||
#ifdef CONFIG_SPL_FIT_HW_CRYPTO
|
||||
rsa_burn_key_hash(&info);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
struct key_prop {
|
||||
const void *rr; /* R^2 can be treated as byte array */
|
||||
const void *modulus; /* modulus as byte array */
|
||||
uint32_t burn_key; /* The flag to burn key's hash */
|
||||
const void *public_exponent; /* public exponent as byte array */
|
||||
const void *public_exponent_BN; /* public exponent as byte array */
|
||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||
|
@ -28,6 +29,7 @@ struct key_prop {
|
|||
#else
|
||||
const void *factor_np; /* rockchip crypto v2 accelerate factor */
|
||||
#endif
|
||||
const void *hash; /* the key hash */
|
||||
uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */
|
||||
int num_bits; /* Key length in bits */
|
||||
uint32_t exp_len; /* Exponent length in number of uint8_t */
|
||||
|
|
|
@ -103,6 +103,12 @@ int padding_pkcs_15_verify(struct image_sign_info *info,
|
|||
uint8_t *msg, int msg_len,
|
||||
const uint8_t *hash, int hash_len);
|
||||
|
||||
#if !defined(USE_HOSTCC)
|
||||
#ifdef CONFIG_SPL_FIT_HW_CRYPTO
|
||||
int rsa_burn_key_hash(struct image_sign_info *info);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
|
||||
int padding_pss_verify(struct image_sign_info *info,
|
||||
uint8_t *msg, int msg_len,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <common.h>
|
||||
#include <crypto.h>
|
||||
#include <fdtdec.h>
|
||||
#include <misc.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -414,6 +415,62 @@ static int rsa_verify_key(struct image_sign_info *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rsa_get_key_prop(struct key_prop *prop, struct image_sign_info *info, int node)
|
||||
{
|
||||
const void *blob = info->fdt_blob;
|
||||
int length;
|
||||
int hash_node;
|
||||
|
||||
if (node < 0) {
|
||||
debug("%s: Skipping invalid node", __func__);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
if (!prop) {
|
||||
debug("%s: The prop is NULL", __func__);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
prop->burn_key = fdtdec_get_int(blob, node, "burn-key-hash", 0);
|
||||
|
||||
prop->num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
|
||||
|
||||
prop->n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
|
||||
|
||||
prop->public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
|
||||
if (!prop->public_exponent || length < sizeof(uint64_t))
|
||||
prop->public_exponent = NULL;
|
||||
|
||||
prop->exp_len = sizeof(uint64_t);
|
||||
prop->modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
|
||||
prop->public_exponent_BN = fdt_getprop(blob, node, "rsa,exponent-BN", NULL);
|
||||
prop->rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
|
||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||
hash_node = fdt_subnode_offset(blob, node, "hash@c");
|
||||
#else
|
||||
hash_node = fdt_subnode_offset(blob, node, "hash@np");
|
||||
#endif
|
||||
if (hash_node >= 0)
|
||||
prop->hash = fdt_getprop(blob, hash_node, "value", NULL);
|
||||
|
||||
if (!prop->num_bits || !prop->modulus) {
|
||||
debug("%s: Missing RSA key info", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||
prop->factor_c = fdt_getprop(blob, node, "rsa,c", NULL);
|
||||
if (!prop.factor_c)
|
||||
return -EFAULT;
|
||||
#else
|
||||
prop->factor_np = fdt_getprop(blob, node, "rsa,np", NULL);
|
||||
if (!prop->factor_np)
|
||||
return -EFAULT;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rsa_verify_with_keynode() - Verify a signature against some data using
|
||||
* information in node with prperties of RSA Key like modulus, exponent etc.
|
||||
|
@ -433,53 +490,13 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
|
|||
const void *hash, uint8_t *sig,
|
||||
uint sig_len, int node)
|
||||
{
|
||||
const void *blob = info->fdt_blob;
|
||||
struct key_prop prop;
|
||||
int length;
|
||||
int ret = 0;
|
||||
|
||||
if (node < 0) {
|
||||
debug("%s: Skipping invalid node", __func__);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
|
||||
|
||||
prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
|
||||
|
||||
prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
|
||||
if (!prop.public_exponent || length < sizeof(uint64_t))
|
||||
prop.public_exponent = NULL;
|
||||
|
||||
prop.exp_len = sizeof(uint64_t);
|
||||
|
||||
prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
|
||||
prop.public_exponent_BN = fdt_getprop(blob, node, "rsa,exponent-BN", NULL);
|
||||
|
||||
prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
|
||||
|
||||
if (!prop.num_bits || !prop.modulus) {
|
||||
debug("%s: Missing RSA key info", __func__);
|
||||
if (rsa_get_key_prop(&prop, info, node))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
#if !defined(USE_HOSTCC)
|
||||
#if CONFIG_IS_ENABLED(FIT_HW_CRYPTO)
|
||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||
prop.factor_c = fdt_getprop(blob, node, "rsa,c", NULL);
|
||||
if (!prop.factor_c)
|
||||
return -EFAULT;
|
||||
#else
|
||||
prop.factor_np = fdt_getprop(blob, node, "rsa,np", NULL);
|
||||
if (!prop.factor_np)
|
||||
return -EFAULT;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
ret = rsa_verify_key(info, &prop, sig, sig_len, hash,
|
||||
info->crypto->key_len);
|
||||
|
||||
return ret;
|
||||
return rsa_verify_key(info, &prop, sig, sig_len, hash,
|
||||
info->crypto->key_len);
|
||||
}
|
||||
|
||||
int rsa_verify(struct image_sign_info *info,
|
||||
|
@ -548,3 +565,121 @@ int rsa_verify(struct image_sign_info *info,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(USE_HOSTCC)
|
||||
#ifdef CONFIG_SPL_FIT_HW_CRYPTO
|
||||
int rsa_burn_key_hash(struct image_sign_info *info)
|
||||
{
|
||||
char *rsa_key;
|
||||
void *n, *e, *c;
|
||||
uint32_t key_len;
|
||||
struct udevice *dev;
|
||||
struct key_prop prop;
|
||||
char name[100] = {0};
|
||||
char secure_boot_enable = 0;
|
||||
const void *blob = info->fdt_blob;
|
||||
uint8_t digest[FIT_MAX_HASH_LEN];
|
||||
uint8_t digest_read[FIT_MAX_HASH_LEN];
|
||||
int sig_node, node, digest_len, i, ret = 0;
|
||||
|
||||
dev = misc_otp_get_device(OTP_S);
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = misc_otp_read(dev, OTP_SECURE_BOOT_ENABLE_ADDR,
|
||||
&secure_boot_enable, OTP_SECURE_BOOT_ENABLE_SIZE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (secure_boot_enable)
|
||||
return 0;
|
||||
|
||||
sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
|
||||
if (sig_node < 0) {
|
||||
debug("%s: No signature node found\n", __func__);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "key-%s", info->keyname);
|
||||
node = fdt_subnode_offset(blob, sig_node, name);
|
||||
|
||||
if (rsa_get_key_prop(&prop, info, node))
|
||||
return -1;
|
||||
|
||||
if (!(prop.burn_key))
|
||||
return -EPERM;
|
||||
|
||||
if (!prop.hash || !prop.modulus || !prop.public_exponent_BN)
|
||||
return -ENOENT;
|
||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||
if (!prop.factor_c)
|
||||
return -ENOENT;
|
||||
#else
|
||||
if (!prop.factor_np)
|
||||
return -ENOENT;
|
||||
#endif
|
||||
key_len = info->crypto->key_len;
|
||||
if (info->crypto->key_len != RSA2048_BYTES)
|
||||
return -EINVAL;
|
||||
|
||||
rsa_key = malloc(key_len * 3);
|
||||
if (!rsa_key)
|
||||
return -ENOMEM;
|
||||
|
||||
n = rsa_key;
|
||||
e = rsa_key + key_len;
|
||||
c = rsa_key + key_len * 2;
|
||||
rsa_convert_big_endian(n, (uint32_t *)prop.modulus,
|
||||
key_len / sizeof(uint32_t));
|
||||
rsa_convert_big_endian(e, (uint32_t *)prop.public_exponent_BN,
|
||||
key_len / sizeof(uint32_t));
|
||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||
rsa_convert_big_endian(c, (uint32_t *)prop.factor_c,
|
||||
key_len / sizeof(uint32_t));
|
||||
#else
|
||||
rsa_convert_big_endian(c, (uint32_t *)prop.factor_np,
|
||||
key_len / sizeof(uint32_t));
|
||||
#endif
|
||||
|
||||
ret = calculate_hash(rsa_key, key_len * 2 + OTP_RSA2048_C_SIZE,
|
||||
info->checksum->name, digest, &digest_len);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (memcmp(digest, prop.hash, digest_len) != 0) {
|
||||
printf("RSA: Compare public key fail.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* burn key hash here */
|
||||
ret = misc_otp_read(dev, OTP_RSA_HASH_ADDR, digest_read, OTP_RSA_HASH_SIZE);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < OTP_RSA_HASH_SIZE; i++) {
|
||||
if (digest_read[i]) {
|
||||
printf("RSA: The secure region has been written.\n");
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ret = misc_otp_write(dev, OTP_RSA_HASH_ADDR, digest, OTP_RSA_HASH_SIZE);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
secure_boot_enable = 0xff;
|
||||
ret = misc_otp_write(dev, OTP_SECURE_BOOT_ENABLE_ADDR,
|
||||
&secure_boot_enable, OTP_SECURE_BOOT_ENABLE_SIZE);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
printf("RSA:Write key hash successfully\n");
|
||||
|
||||
error:
|
||||
free(rsa_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue