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";
|
*err_msgp = "Verification failed";
|
||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
struct key_prop {
|
struct key_prop {
|
||||||
const void *rr; /* R^2 can be treated as byte array */
|
const void *rr; /* R^2 can be treated as byte array */
|
||||||
const void *modulus; /* modulus 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; /* public exponent as byte array */
|
||||||
const void *public_exponent_BN; /* public exponent as byte array */
|
const void *public_exponent_BN; /* public exponent as byte array */
|
||||||
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
#ifdef CONFIG_ROCKCHIP_CRYPTO_V1
|
||||||
|
|
@ -28,6 +29,7 @@ struct key_prop {
|
||||||
#else
|
#else
|
||||||
const void *factor_np; /* rockchip crypto v2 accelerate factor */
|
const void *factor_np; /* rockchip crypto v2 accelerate factor */
|
||||||
#endif
|
#endif
|
||||||
|
const void *hash; /* the key hash */
|
||||||
uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */
|
uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */
|
||||||
int num_bits; /* Key length in bits */
|
int num_bits; /* Key length in bits */
|
||||||
uint32_t exp_len; /* Exponent length in number of uint8_t */
|
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,
|
uint8_t *msg, int msg_len,
|
||||||
const uint8_t *hash, int hash_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
|
#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
|
||||||
int padding_pss_verify(struct image_sign_info *info,
|
int padding_pss_verify(struct image_sign_info *info,
|
||||||
uint8_t *msg, int msg_len,
|
uint8_t *msg, int msg_len,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <crypto.h>
|
#include <crypto.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
|
#include <misc.h>
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
|
@ -414,6 +415,62 @@ static int rsa_verify_key(struct image_sign_info *info,
|
||||||
return 0;
|
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
|
* rsa_verify_with_keynode() - Verify a signature against some data using
|
||||||
* information in node with prperties of RSA Key like modulus, exponent etc.
|
* 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,
|
const void *hash, uint8_t *sig,
|
||||||
uint sig_len, int node)
|
uint sig_len, int node)
|
||||||
{
|
{
|
||||||
const void *blob = info->fdt_blob;
|
|
||||||
struct key_prop prop;
|
struct key_prop prop;
|
||||||
int length;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (node < 0) {
|
if (rsa_get_key_prop(&prop, info, node))
|
||||||
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__);
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(USE_HOSTCC)
|
return rsa_verify_key(info, &prop, sig, sig_len, hash,
|
||||||
#if CONFIG_IS_ENABLED(FIT_HW_CRYPTO)
|
info->crypto->key_len);
|
||||||
#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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int rsa_verify(struct image_sign_info *info,
|
int rsa_verify(struct image_sign_info *info,
|
||||||
|
|
@ -548,3 +565,121 @@ int rsa_verify(struct image_sign_info *info,
|
||||||
|
|
||||||
return ret;
|
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