| From 1e0921b292481b097c612ec581d333ca4c0612dd Mon Sep 17 00:00:00 2001 |
| From: KH Hung <kh.hung@mediatek.com> |
| Date: Tue, 19 Feb 2019 13:35:15 +0800 |
| Subject: [PATCH] 201807-secure-boot-ECC-support |
| |
| --- |
| Kconfig | 1 + |
| common/image-sig.c | 23 ++- |
| include/image.h | 1 + |
| include/u-boot/ecc.h | 63 +++++++ |
| lib/Kconfig | 2 + |
| lib/Makefile | 3 + |
| lib/ecc/Kconfig | 8 + |
| lib/ecc/Makefile | 3 + |
| lib/ecc/ecc-sig.c | 413 +++++++++++++++++++++++++++++++++++++++++++ |
| lib/ecc/ecc-verify.c | 26 +++ |
| tools/Makefile | 7 +- |
| 11 files changed, 548 insertions(+), 2 deletions(-) |
| create mode 100644 include/u-boot/ecc.h |
| create mode 100644 lib/ecc/Kconfig |
| create mode 100644 lib/ecc/Makefile |
| create mode 100644 lib/ecc/ecc-sig.c |
| create mode 100644 lib/ecc/ecc-verify.c |
| |
| diff --git a/Kconfig b/Kconfig |
| index 513f23cb4c..a9b15d2cfc 100644 |
| --- a/Kconfig |
| +++ b/Kconfig |
| @@ -271,6 +271,7 @@ config FIT_SIGNATURE |
| depends on DM |
| select RSA |
| select HASH |
| + select ECC |
| help |
| This option enables signature verification of FIT uImages, |
| using a hash signed and verified using RSA. If |
| diff --git a/common/image-sig.c b/common/image-sig.c |
| index acbd1297e4..2ba1eac9fc 100644 |
| --- a/common/image-sig.c |
| +++ b/common/image-sig.c |
| @@ -14,6 +14,7 @@ DECLARE_GLOBAL_DATA_PTR; |
| #include <image.h> |
| #include <u-boot/rsa.h> |
| #include <u-boot/rsa-checksum.h> |
| +#include <u-boot/ecc.h> |
| |
| #define IMAGE_MAX_HASHED_NODES 100 |
| |
| @@ -115,8 +116,28 @@ struct crypto_algo crypto_algos[] = { |
| .sign = rsassa_pss_sign, |
| .add_verify_data = rsa_add_verify_data, |
| .verify = rsa_verify, |
| + }, |
| + { |
| + .name = "nistp256", |
| + .key_len = ECC256_BYTES, |
| + .sign = ecc_sign, |
| + .add_verify_data = ecc_add_verify_data, |
| + .verify = ecc_verify, |
| + }, |
| + { |
| + .name = "nistp384", |
| + .key_len = ECC384_BYTES, |
| + .sign = ecc_sign, |
| + .add_verify_data = ecc_add_verify_data, |
| + .verify = ecc_verify, |
| + }, |
| + { |
| + .name = "nistp521", |
| + .key_len = ECC521_BYTES, |
| + .sign = ecc_sign, |
| + .add_verify_data = ecc_add_verify_data, |
| + .verify = ecc_verify, |
| } |
| - |
| }; |
| |
| struct checksum_algo *image_get_checksum_algo(const char *full_name) |
| diff --git a/include/image.h b/include/image.h |
| index 475af42a7a..3bde55763b 100644 |
| --- a/include/image.h |
| +++ b/include/image.h |
| @@ -37,6 +37,7 @@ struct fdt_region; |
| #define CONFIG_SHA256 |
| #define CONFIG_SHA384 |
| #define CONFIG_SHA512 |
| +#define CONFIG_ECC |
| |
| #define IMAGE_ENABLE_IGNORE 0 |
| #define IMAGE_INDENT_STRING "" |
| diff --git a/include/u-boot/ecc.h b/include/u-boot/ecc.h |
| new file mode 100644 |
| index 0000000000..e3b564effd |
| --- /dev/null |
| +++ b/include/u-boot/ecc.h |
| @@ -0,0 +1,63 @@ |
| +
|
| +#ifndef _ECC_H
|
| +#define _ECC_H
|
| +
|
| +#include <errno.h>
|
| +#include <image.h>
|
| +
|
| +#define ECC256_BYTES (32)
|
| +#define ECC384_BYTES (48)
|
| +#define ECC521_BYTES (66)
|
| +
|
| +/**
|
| + * sign() - calculate and return signature for given input data
|
| + *
|
| + * @info: Specifies key and FIT information
|
| + * @data: Pointer to the input data
|
| + * @data_len: Data length
|
| + * @sigp: Set to an allocated buffer holding the signature
|
| + * @sig_len: Set to length of the calculated hash
|
| + *
|
| + * This computes input data signature according to selected algorithm.
|
| + * Resulting signature value is placed in an allocated buffer, the
|
| + * pointer is returned as *sigp. The length of the calculated
|
| + * signature is returned via the sig_len pointer argument. The caller
|
| + * should free *sigp.
|
| + *
|
| + * @return: 0, on success, -ve on error
|
| + */
|
| +int ecc_sign(struct image_sign_info *info,
|
| + const struct image_region region[],
|
| + int region_count, uint8_t **sigp, uint *sig_len);
|
| +
|
| +/**
|
| + * add_verify_data() - Add verification information to FDT
|
| + *
|
| + * Add public key information to the FDT node, suitable for
|
| + * verification at run-time. The information added depends on the
|
| + * algorithm being used.
|
| + *
|
| + * @info: Specifies key and FIT information
|
| + * @keydest: Destination FDT blob for public key data
|
| + * @return: 0, on success, -ENOSPC if the keydest FDT blob ran out of space,
|
| + other -ve value on error
|
| +*/
|
| +int ecc_add_verify_data(struct image_sign_info *info, void *keydest);
|
| +
|
| +/**
|
| + * rsa_verify() - Verify a signature against some data
|
| + *
|
| + * Verify a RSA PKCS1.5 signature against an expected hash.
|
| + *
|
| + * @info: Specifies key and FIT information
|
| + * @data: Pointer to the input data
|
| + * @data_len: Data length
|
| + * @sig: Signature
|
| + * @sig_len: Number of bytes in signature
|
| + * @return 0 if verified, -ve on error
|
| + */
|
| +int ecc_verify(struct image_sign_info *info,
|
| + const struct image_region region[], int region_count,
|
| + uint8_t *sig, uint sig_len);
|
| +
|
| +#endif
|
| diff --git a/lib/Kconfig b/lib/Kconfig |
| index c3bed74860..c2c8160651 100644 |
| --- a/lib/Kconfig |
| +++ b/lib/Kconfig |
| @@ -174,6 +174,8 @@ config AES |
| |
| source lib/rsa/Kconfig |
| |
| +source lib/ecc/Kconfig |
| + |
| config TPM |
| bool "Trusted Platform Module (TPM) Support" |
| depends on DM |
| diff --git a/lib/Makefile b/lib/Makefile |
| index b3560729a3..3d9edde6bd 100644 |
| --- a/lib/Makefile |
| +++ b/lib/Makefile |
| @@ -50,10 +50,13 @@ endif |
| |
| obj-$(CONFIG_RSA) += rsa/ |
| obj-$(CONFIG_SHA1) += sha1.o |
| +obj-$(CONFIG_SHA1) += sha4.o |
| obj-$(CONFIG_SHA256) += sha256.o |
| obj-$(CONFIG_SHA384) += sha384.o |
| obj-$(CONFIG_SHA512) += sha512.o |
| |
| +obj-$(CONFIG_ECC) += ecc/ |
| + |
| obj-$(CONFIG_$(SPL_)ZLIB) += zlib/ |
| obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o |
| obj-$(CONFIG_$(SPL_)LZO) += lzo/ |
| diff --git a/lib/ecc/Kconfig b/lib/ecc/Kconfig |
| new file mode 100644 |
| index 0000000000..bd6f99aa19 |
| --- /dev/null |
| +++ b/lib/ecc/Kconfig |
| @@ -0,0 +1,8 @@ |
| +config ECC |
| + bool "Use ECC Library" |
| + help |
| + ECC support. This enables the ECC algorithm used for FIT image |
| + verification in U-Boot. |
| + The signing part is build into mkimage regardless of this |
| + option. The software based modular exponentiation is built into |
| + mkimage irrespective of this option. |
| diff --git a/lib/ecc/Makefile b/lib/ecc/Makefile |
| new file mode 100644 |
| index 0000000000..b63aaff164 |
| --- /dev/null |
| +++ b/lib/ecc/Makefile |
| @@ -0,0 +1,3 @@ |
| + |
| +obj-$(CONFIG_ECC) += ecc-sig.o |
| +obj-$(CONFIG_ECC) += ecc-verify.o |
| diff --git a/lib/ecc/ecc-sig.c b/lib/ecc/ecc-sig.c |
| new file mode 100644 |
| index 0000000000..582c69e17a |
| --- /dev/null |
| +++ b/lib/ecc/ecc-sig.c |
| @@ -0,0 +1,413 @@ |
| +
|
| +#include "mkimage.h"
|
| +#include <stdio.h>
|
| +#include <string.h>
|
| +#include <image.h>
|
| +#include <time.h>
|
| +#include <openssl/bn.h>
|
| +#include <openssl/ec.h>
|
| +#include <openssl/pem.h>
|
| +#include <openssl/err.h>
|
| +#include <openssl/ssl.h>
|
| +#include <openssl/evp.h>
|
| +#include <openssl/engine.h>
|
| +
|
| +static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
|
| + BIGNUM *num, int num_bits)
|
| +{
|
| + int nwords = num_bits / 32;
|
| + int size;
|
| + uint32_t *buf, *ptr;
|
| + BIGNUM *tmp, *big2, *big32, *big2_32;
|
| + BN_CTX *ctx;
|
| + int ret;
|
| +
|
| + tmp = BN_new();
|
| + big2 = BN_new();
|
| + big32 = BN_new();
|
| + big2_32 = BN_new();
|
| +
|
| + /*
|
| + * Note: This code assumes that all of the above succeed, or all fail.
|
| + * In practice memory allocations generally do not fail (unless the
|
| + * process is killed), so it does not seem worth handling each of these
|
| + * as a separate case. Technicaly this could leak memory on failure,
|
| + * but a) it won't happen in practice, and b) it doesn't matter as we
|
| + * will immediately exit with a failure code.
|
| + */
|
| + if (!tmp || !big2 || !big32 || !big2_32) {
|
| + fprintf(stderr, "Out of memory (bignum)\n");
|
| + return -ENOMEM;
|
| + }
|
| + ctx = BN_CTX_new();
|
| + if (!tmp) {
|
| + fprintf(stderr, "Out of memory (bignum context)\n");
|
| + return -ENOMEM;
|
| + }
|
| + BN_set_word(big2, 2L);
|
| + BN_set_word(big32, 32L);
|
| + BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */
|
| +
|
| + size = nwords * sizeof(uint32_t);
|
| + buf = malloc(size);
|
| + if (!buf) {
|
| + fprintf(stderr, "Out of memory (%d bytes)\n", size);
|
| + return -ENOMEM;
|
| + }
|
| +
|
| + /* Write out modulus as big endian array of integers */
|
| + for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
|
| + BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
|
| + *ptr = cpu_to_fdt32(BN_get_word(tmp));
|
| + BN_rshift(num, num, 32); /* N = N/B */
|
| + }
|
| +
|
| + /*
|
| + * We try signing with successively increasing size values, so this
|
| + * might fail several times
|
| + */
|
| + ret = fdt_setprop(blob, noffset, prop_name, buf, size);
|
| +
|
| + free(buf);
|
| + BN_free(tmp);
|
| + BN_free(big2);
|
| + BN_free(big32);
|
| + BN_free(big2_32);
|
| +
|
| + return ret ? -FDT_ERR_NOSPACE : 0;
|
| +}
|
| +
|
| +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
|
| +{
|
| + EC_KEY *dtmp;
|
| + if (!key)
|
| + return NULL;
|
| + dtmp = EVP_PKEY_get1_EC_KEY(key);
|
| + EVP_PKEY_free(key);
|
| + if (!dtmp)
|
| + return NULL;
|
| + if (eckey) {
|
| + EC_KEY_free(*eckey);
|
| + *eckey = dtmp;
|
| + }
|
| + return dtmp;
|
| +}
|
| +
|
| +/**
|
| + * ec_pem_get_priv_key() - read a private key from a .key file
|
| + *
|
| + * @keydir: Directory containing the key
|
| + * @name Name of key file (will have a .key extension)
|
| + * @rsap Returns EC object, or NULL on failure
|
| + * @return 0 if ok, -ve on error (in which case *ecp will be set to NULL)
|
| + */
|
| +static int ec_pem_get_priv_key(const char *keydir, const char *name,
|
| + EC_KEY **ecp)
|
| +{
|
| + char path[1024];
|
| + EC_KEY *ec;
|
| + FILE *f;
|
| + EVP_PKEY *pktmp;
|
| +
|
| + *ecp = NULL;
|
| + snprintf(path, sizeof(path), "%s/%s_priv.key", keydir, name);
|
| + f = fopen(path, "r");
|
| + if (!f) {
|
| + fprintf(stderr, "Couldn't open EC private key: '%s': %s\n",
|
| + path, strerror(errno));
|
| + return -ENOENT;
|
| + }
|
| +
|
| + pktmp = PEM_read_PrivateKey(f, 0, NULL, path);
|
| + ec = pkey_get_eckey(pktmp, ecp);
|
| + if (!ec) {
|
| + fprintf(stderr, "Failure reading EC private key\n");
|
| + fclose(f);
|
| + return -EPROTO;
|
| + }
|
| + fclose(f);
|
| + *ecp = ec;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +/**
|
| + * ec_pem_get_pub_key() - read a public key from a .key file
|
| + *
|
| + * @keydir: Directory containing the key
|
| + * @name Name of key file (will have a .key extension)
|
| + * @pub_key Returns BIGNUM object, or NULL on failure
|
| + * @return 0 if ok, -ve on error (in which case *pub_key will be set to NULL)
|
| + */
|
| +static int ec_pem_get_pub_key(const char *keydir, const char *name, BIGNUM **pub_key)
|
| +{
|
| + char path[1024];
|
| + EC_KEY *ec;
|
| + FILE *f;
|
| + unsigned char *pub_k_cp = NULL;
|
| + int ret;
|
| +
|
| + snprintf(path, sizeof(path), "%s/%s_public.key", keydir, name);
|
| + f = fopen(path, "r");
|
| + if (!f) {
|
| + fprintf(stderr, "Couldn't open EC public key: '%s': %s\n",
|
| + path, strerror(errno));
|
| + return -ENOENT;
|
| + }
|
| +
|
| + ec = PEM_read_EC_PUBKEY(f, 0, NULL, path);
|
| +
|
| + if (!ec) {
|
| + fprintf(stderr, "Failure reading EC public key\n");
|
| + fclose(f);
|
| + return -EPROTO;
|
| + }
|
| + fclose(f);
|
| +
|
| + /* Transform from EC_POINT to char */
|
| + ret = i2o_ECPublicKey(ec, &pub_k_cp);
|
| + if (ret == 0) {
|
| + return -1;
|
| + } else {
|
| + /* Transform from char to BIGNUM */
|
| + *pub_key = BN_bin2bn(pub_k_cp, ret , NULL);
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +int ecc_add_verify_data(struct image_sign_info *info, void *keydest)
|
| +{
|
| + BIGNUM *pub_key;
|
| + int parent, node;
|
| + char name[100];
|
| + int ret=0;
|
| + int bits;
|
| +
|
| + // get public key
|
| + ret = ec_pem_get_pub_key(info->keydir, info->keyname, &pub_key);
|
| +
|
| + if (ret)
|
| + goto err_get_pub_key;
|
| +
|
| + parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME);
|
| + if (parent == -FDT_ERR_NOTFOUND) {
|
| + parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME);
|
| + if (parent < 0) {
|
| + ret = parent;
|
| + if (ret != -FDT_ERR_NOSPACE) {
|
| + fprintf(stderr, "Couldn't create signature node: %s\n",
|
| + fdt_strerror(parent));
|
| + }
|
| + }
|
| + }
|
| + if (ret)
|
| + goto done;
|
| +
|
| + /* Either create or overwrite the named key node */
|
| + snprintf(name, sizeof(name), "key-%s", info->keyname);
|
| + node = fdt_subnode_offset(keydest, parent, name);
|
| + if (node == -FDT_ERR_NOTFOUND) {
|
| + node = fdt_add_subnode(keydest, parent, name);
|
| + if (node < 0) {
|
| + ret = node;
|
| + if (ret != -FDT_ERR_NOSPACE) {
|
| + fprintf(stderr, "Could not create key subnode: %s\n",
|
| + fdt_strerror(node));
|
| + }
|
| + }
|
| + } else if (node < 0) {
|
| + fprintf(stderr, "Cannot select keys parent: %s\n",
|
| + fdt_strerror(node));
|
| + ret = node;
|
| + }
|
| +
|
| + if (!ret) {
|
| + ret = fdt_setprop_string(keydest, node, "key-name-hint", info->keyname);
|
| + }
|
| +
|
| + if (!ret) {
|
| + bits = info->crypto->key_len * 16;
|
| + ret = fdt_add_bignum(keydest, node, "ecc,public-key", pub_key, bits);
|
| + }
|
| + if (!ret) {
|
| + ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP, info->name);
|
| + }
|
| + if (!ret && info->require_keys) {
|
| + ret = fdt_setprop_string(keydest, node, "required", info->require_keys);
|
| + }
|
| +done:
|
| + BN_free(pub_key);
|
| + if (ret) {
|
| + ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
|
| + }
|
| +
|
| +err_get_pub_key:
|
| +
|
| +
|
| + return ret;
|
| +}
|
| +
|
| +static int ec_sign_with_key(EC_KEY *ec, struct checksum_algo *checksum_algo,
|
| + const struct image_region region[], int region_count,
|
| + uint8_t **sigp, uint *sig_size)
|
| +{
|
| + EVP_PKEY *key;
|
| + EVP_PKEY_CTX *keyctx;
|
| + EVP_MD_CTX *context;
|
| + int size, ret = 0;
|
| + uint8_t *sig;
|
| + int i;
|
| +
|
| + key = EVP_PKEY_new();
|
| + if (!key) {
|
| + fprintf(stderr, "EVP_PKEY object creation failed \n");
|
| + return -1;
|
| + }
|
| +
|
| + if (!EVP_PKEY_set1_EC_KEY(key, ec)) {
|
| + fprintf(stderr, "EVP key setup failed \n");
|
| + ret = -1;
|
| + goto err_set;
|
| + }
|
| +
|
| + keyctx = EVP_PKEY_CTX_new(key, NULL);
|
| + if (!keyctx) {
|
| + fprintf(stderr, "EVP_PKEY_CTX object creation failed \n");
|
| + ret = -1;
|
| + goto err_set;
|
| + }
|
| +
|
| + size = EVP_PKEY_size(key);
|
| + sig = malloc(size);
|
| + if (!sig) {
|
| + fprintf(stderr, "Out of memory for signature (%d bytes)\n", size);
|
| + ret = -ENOMEM;
|
| + goto err_alloc;
|
| + }
|
| +
|
| + context = EVP_MD_CTX_create();
|
| + if (!context) {
|
| + fprintf(stderr, "EVP context creation failed \n");
|
| + ret = -1;
|
| + goto err_create;
|
| + }
|
| + EVP_MD_CTX_init(context);
|
| + if (!EVP_DigestSignInit(context, &keyctx, checksum_algo->calculate_sign(), NULL, key)) {
|
| + fprintf(stderr, "Signer setup failed \n");
|
| + ret = -1;
|
| + goto err_sign;
|
| + }
|
| +
|
| + for (i = 0; i < region_count; i++) {
|
| +
|
| + if (!EVP_DigestSignUpdate(context, region[i].data, region[i].size)) {
|
| + fprintf(stderr, "Signing data failed \n");
|
| + ret = -1;
|
| + goto err_sign;
|
| + }
|
| + }
|
| +
|
| + if (!EVP_DigestSignFinal(context, sig, (size_t *)sig_size)) {
|
| + fprintf(stderr, "Could not obtain signature \n");
|
| + ret = -1;
|
| + goto err_sign;
|
| + }
|
| +
|
| +#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
| + EVP_MD_CTX_cleanup(context);
|
| +#else
|
| + EVP_MD_CTX_reset(context);
|
| +#endif
|
| + EVP_MD_CTX_destroy(context);
|
| + EVP_PKEY_free(key);
|
| +
|
| + fprintf(stderr, "Got signature: %d bytes, expected %d\n", *sig_size, size);
|
| + *sigp = sig;
|
| + *sig_size = size;
|
| +
|
| + return 0;
|
| +
|
| +err_sign:
|
| + EVP_MD_CTX_destroy(context);
|
| +err_create:
|
| + free(sig);
|
| +err_alloc:
|
| +err_set:
|
| + EVP_PKEY_free(key);
|
| + return ret;
|
| +}
|
| +
|
| +int ecc_sign(struct image_sign_info *info,
|
| + const struct image_region region[], int region_count,
|
| + uint8_t **sigp, uint *sig_len)
|
| +{
|
| + EC_KEY *ec;
|
| + int ret = 0;
|
| +
|
| + /* To read private key from pem */
|
| + ret = ec_pem_get_priv_key(info->keydir, info->keyname, &ec);
|
| +
|
| + if (ret) {
|
| + fprintf(stderr, "Failure reading EC private key\n");
|
| + goto err_priv;
|
| + }
|
| +
|
| + /* To signature */
|
| + ret = ec_sign_with_key(ec, info->checksum, region,
|
| + region_count, sigp, sig_len);
|
| + if (ret) {
|
| + goto err_sign;
|
| + }
|
| +
|
| +
|
| +err_sign:
|
| +
|
| +err_priv:
|
| +
|
| + return ret;
|
| +}
|
| +
|
| +/**
|
| + * ec_pem_get_pub_key_by_path() - read a public key from a .key file
|
| + *
|
| + * @path Path of key file (will have a .key extension)
|
| + * @pub_key Returns BIGNUM object, or NULL on failure
|
| + * @return 0 if ok, -ve on error (in which case *pub_key will be set to NULL)
|
| + */
|
| +static int ec_pem_get_pub_key_by_path(const char *keydir, const char *name, BIGNUM **pub_key)
|
| +{
|
| + char path[1024];
|
| + EC_KEY *ec;
|
| + FILE *f;
|
| + unsigned char *pub_k_cp = NULL;
|
| + int ret;
|
| +
|
| + snprintf(path, sizeof(path), "%s/tier_public.key", keydir);
|
| + f = fopen(path, "r");
|
| + if (!f) {
|
| + fprintf(stderr, "Couldn't open EC public key: '%s': %s\n",
|
| + path, strerror(errno));
|
| + return -ENOENT;
|
| + }
|
| +
|
| + ec = PEM_read_EC_PUBKEY(f, 0, NULL, path);
|
| +
|
| + if (!ec) {
|
| + fprintf(stderr, "Failure reading EC public key\n");
|
| + fclose(f);
|
| + return -EPROTO;
|
| + }
|
| + fclose(f);
|
| +
|
| + /* Transform from EC_POINT to char */
|
| + ret = i2o_ECPublicKey(ec, &pub_k_cp);
|
| + if (ret == 0) {
|
| + return -1;
|
| + } else {
|
| + /* Transform from char to BIGNUM */
|
| + *pub_key = BN_bin2bn(pub_k_cp, ret , NULL);
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| diff --git a/lib/ecc/ecc-verify.c b/lib/ecc/ecc-verify.c |
| new file mode 100644 |
| index 0000000000..49251a3f11 |
| --- /dev/null |
| +++ b/lib/ecc/ecc-verify.c |
| @@ -0,0 +1,26 @@ |
| +
|
| +#ifndef USE_HOSTCC
|
| +#include <common.h>
|
| +#include <fdtdec.h>
|
| +#include <asm/types.h>
|
| +#include <asm/byteorder.h>
|
| +#include <linux/errno.h>
|
| +#include <asm/types.h>
|
| +#include <asm/unaligned.h>
|
| +#include <dm.h>
|
| +#else
|
| +#include "fdt_host.h"
|
| +//#include "mkimage.h"
|
| +#include <fdt_support.h>
|
| +#endif
|
| +
|
| +#include <u-boot/ecc.h>
|
| +
|
| +
|
| +int ecc_verify(struct image_sign_info *info,
|
| + const struct image_region region[], int region_count,
|
| + uint8_t *sig, uint sig_len)
|
| +{
|
| +
|
| + return 0;
|
| +}
|
| diff --git a/tools/Makefile b/tools/Makefile |
| index ae6451178b..4ed3489a79 100644 |
| --- a/tools/Makefile |
| +++ b/tools/Makefile |
| @@ -75,6 +75,9 @@ RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \ |
| rsa-sign.o rsa-verify.o rsa-checksum.o \ |
| rsa-mod-exp.o) |
| |
| +ECC_OBJS-$(CONFIG_ECC) := $(addprefix lib/ecc/, \ |
| + ecc-sig.o ecc-verify.o) |
| + |
| ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o rksd.o rkspi.o |
| |
| # common objs for dumpimage and mkimage |
| @@ -116,7 +119,8 @@ dumpimage-mkimage-objs := aisimage.o \ |
| $(LIBFDT_OBJS) \ |
| gpimage.o \ |
| gpimage-common.o \ |
| - $(RSA_OBJS-y) |
| + $(RSA_OBJS-y) \ |
| + $(ECC_OBJS-y) |
| |
| dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o |
| mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o |
| @@ -155,6 +159,7 @@ ifeq ($(HOSTOS),darwin) |
| HOSTCFLAGS_mxsimage.o += -Wno-deprecated-declarations |
| HOSTCFLAGS_image-sig.o += -Wno-deprecated-declarations |
| HOSTCFLAGS_rsa-sign.o += -Wno-deprecated-declarations |
| +HOSTCFLAGS_ecc-sig.o += -Wno-deprecated-declarations |
| endif |
| endif |
| |
| -- |
| 2.18.0 |
| |