diff --git a/common/image-sig.c b/common/image-sig.c index 2dbfec5062..97f4b558f1 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -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; } diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h index ae78773bb8..cb99ac6e61 100644 --- a/include/u-boot/rsa-mod-exp.h +++ b/include/u-boot/rsa-mod-exp.h @@ -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 */ diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h index a1dad7194e..e2438ab473 100644 --- a/include/u-boot/rsa.h +++ b/include/u-boot/rsa.h @@ -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, diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 8fb3726327..ecd9020a5e 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -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