lib: rsa-sign: add rockchip rsa key hash
SPL requires key hash to verify and flash it to OTP/EFUSE.
- hash@c: n, e, c
- hash@np: n, e, np
/ {
signature {
key-dev {
required = "conf";
algo = "sha256,rsa2048";
rsa,np = <...>;
rsa,c = <...>;
rsa,modulus = <...>;
rsa,exponent-BN = <...>;
...
key-name-hint = "dev";
hash@np {
algo = "sha256";
value = <0x0934bc4d 0xfbc31ffe 0x9224d6c2 0x1a3aa280 0x881d881e 0xe2006246 0x01b9e724 0x35c03428>;
};
hash@c {
algo = "sha256";
value = <0x08962385 0x34585e06 0x0b73a496 0x374b148d 0xa2700a75 0x4aae08ad 0xb2a324a3 0x95ee6b52>;
};
};
};
...
};
But after processed by scripts/fit.sh, only one of "hash@c" and "hash@np" would be left.
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
Change-Id: Id9454100f9fdb06b30f9a4b2a7bdd180f117cb68
This commit is contained in:
parent
bf8034353d
commit
b6ea0cb4ad
|
|
@ -700,6 +700,83 @@ int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] = fdt32_to_cpu(src[len - 1 - i]);
|
||||
}
|
||||
|
||||
static int rsa_set_key_hash(void *keydest, int key_node,
|
||||
int key_len, const char *csum_algo)
|
||||
{
|
||||
const void *rsa_n, *rsa_e, *rsa_c, *rsa_np;
|
||||
void *n, *e, *c, *np;
|
||||
uint8_t value[FIT_MAX_HASH_LEN];
|
||||
char hash_c[] = "hash@c";
|
||||
char hash_np[] = "hash@np";
|
||||
char *rsa_key;
|
||||
int key_word;
|
||||
int hash_node;
|
||||
int value_len;
|
||||
int ret = -ENOSPC;
|
||||
|
||||
rsa_key = malloc(key_len * 3);
|
||||
if (!rsa_key)
|
||||
return -ENOSPC;
|
||||
|
||||
rsa_n = fdt_getprop(keydest, key_node, "rsa,modulus", NULL);
|
||||
rsa_e = fdt_getprop(keydest, key_node, "rsa,exponent-BN", NULL);
|
||||
rsa_c = fdt_getprop(keydest, key_node, "rsa,c", NULL);
|
||||
rsa_np = fdt_getprop(keydest, key_node, "rsa,np", NULL);
|
||||
if (!rsa_c || !rsa_np || !rsa_n || !rsa_e)
|
||||
goto err_nospc;
|
||||
|
||||
n = rsa_key;
|
||||
e = rsa_key + key_len;
|
||||
key_word = key_len / sizeof(uint32_t);
|
||||
rsa_convert_big_endian(n, rsa_n, key_word);
|
||||
rsa_convert_big_endian(e, rsa_e, key_word);
|
||||
|
||||
/* hash@c node: n, e, c */
|
||||
c = rsa_key + key_len * 2;
|
||||
rsa_convert_big_endian(c, rsa_c, key_word);
|
||||
hash_node = fdt_add_subnode(keydest, key_node, hash_c);
|
||||
if (hash_node < 0)
|
||||
goto err_nospc;
|
||||
ret = calculate_hash(rsa_key, key_len * 3, csum_algo, value, &value_len);
|
||||
if (ret)
|
||||
goto err_nospc;
|
||||
ret = fdt_setprop(keydest, hash_node, FIT_VALUE_PROP, value, value_len);
|
||||
if (ret)
|
||||
goto err_nospc;
|
||||
ret = fdt_setprop_string(keydest, hash_node, FIT_ALGO_PROP, csum_algo);
|
||||
if (ret < 0)
|
||||
goto err_nospc;
|
||||
|
||||
/* hash@np node: n, e, np */
|
||||
np = rsa_key + key_len * 2;
|
||||
rsa_convert_big_endian(np, rsa_np, key_word);
|
||||
hash_node = fdt_add_subnode(keydest, key_node, hash_np);
|
||||
if (hash_node < 0)
|
||||
goto err_nospc;
|
||||
|
||||
ret = calculate_hash(rsa_key, key_len * 2 + 20, csum_algo, value, &value_len);
|
||||
if (ret)
|
||||
goto err_nospc;
|
||||
ret = fdt_setprop(keydest, hash_node, FIT_VALUE_PROP, value, value_len);
|
||||
if (ret < 0)
|
||||
goto err_nospc;
|
||||
ret = fdt_setprop_string(keydest, hash_node, FIT_ALGO_PROP, csum_algo);
|
||||
|
||||
err_nospc:
|
||||
if (rsa_key)
|
||||
free(rsa_key);
|
||||
|
||||
return ret ? -ENOSPC : 0;
|
||||
}
|
||||
|
||||
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
|
||||
BIGNUM *num, int num_bits)
|
||||
{
|
||||
|
|
@ -854,6 +931,10 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
|
|||
ret = fdt_setprop_string(keydest, node, "required",
|
||||
info->require_keys);
|
||||
}
|
||||
if (!ret) {
|
||||
ret = rsa_set_key_hash(keydest, node, info->crypto->key_len,
|
||||
info->checksum->name);
|
||||
}
|
||||
done:
|
||||
BN_free(modulus);
|
||||
BN_free(r_squared);
|
||||
|
|
|
|||
Loading…
Reference in New Issue