summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2016-01-29 09:15:06 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-02-04 08:29:16 +0100
commit0b57bfb12f013c01980ecf3fa5c70b2366450d2c (patch)
treefa5046e92e64519e178b3963a62f8f87f8070e24 /scripts
parent310b4a4ce3a35a379affe18e556c9294c6735d0a (diff)
downloadbarebox-0b57bfb12f013c01980ecf3fa5c70b2366450d2c.tar.gz
barebox-0b57bfb12f013c01980ecf3fa5c70b2366450d2c.tar.xz
scripts: imx-image: Support adding a Super Root Key to the image
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/imx/Makefile4
-rw-r--r--scripts/imx/imx-image.c130
-rw-r--r--scripts/imx/imx.h1
3 files changed, 135 insertions, 0 deletions
diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
index 688365922c..d9f0c51298 100644
--- a/scripts/imx/Makefile
+++ b/scripts/imx/Makefile
@@ -7,6 +7,10 @@ HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0`
HOSTLOADLIBES_imx-usb-loader = `pkg-config --libs libusb-1.0`
HOSTCFLAGS_imx-image.o = -I$(srctree)
+ifdef CONFIG_ARCH_IMX_IMXIMAGE_SSL_SUPPORT
+HOSTCFLAGS_imx-image.o += -DIMXIMAGE_SSL_SUPPORT
+HOSTLOADLIBES_imx-image = `pkg-config --libs openssl`
+endif
imx-usb-loader-objs := imx-usb-loader.o imx.o
imx-image-objs := imx-image.o imx.o
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index d804ab4322..b627b8c2c5 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -72,6 +72,130 @@ static uint32_t bb_header[] = {
0x55555555,
};
+struct hab_rsa_public_key {
+ uint8_t rsa_exponent[4]; /* RSA public exponent */
+ uint32_t rsa_modulus; /* RSA modulus pointer */
+ uint16_t exponent_size; /* Exponent size in bytes */
+ uint16_t modulus_size; /* Modulus size in bytes*/
+ uint8_t init_flag; /* Indicates if key initialized */
+};
+
+#ifdef IMXIMAGE_SSL_SUPPORT
+#define PUBKEY_ALGO_LEN 2048
+
+#include <openssl/x509v3.h>
+#include <openssl/bn.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+
+static int extract_key(const char *certfile, uint8_t **modulus, int *modulus_len,
+ uint8_t **exponent, int *exponent_len)
+{
+ char buf[PUBKEY_ALGO_LEN];
+ int pubkey_algonid;
+ const char *sslbuf;
+ EVP_PKEY *pkey;
+ FILE *fp;
+ X509 *cert;
+ RSA *rsa_key;
+
+ fp = fopen(certfile, "r");
+ if (!fp) {
+ fprintf(stderr, "unable to open certfile: %s\n", certfile);
+ return -errno;
+ }
+
+ cert = PEM_read_X509(fp, NULL, NULL, NULL);
+ if (!cert) {
+ fprintf(stderr, "unable to parse certificate in: %s\n", certfile);
+ fclose(fp);
+ return -errno;
+ }
+
+ fclose(fp);
+
+ pubkey_algonid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm);
+ if (pubkey_algonid == NID_undef) {
+ fprintf(stderr, "unable to find specified public key algorithm name.\n");
+ return -EINVAL;
+ }
+
+ if (pubkey_algonid != NID_rsaEncryption)
+ return -EINVAL;
+
+ sslbuf = OBJ_nid2ln(pubkey_algonid);
+ strncpy(buf, sslbuf, PUBKEY_ALGO_LEN);
+
+ pkey = X509_get_pubkey(cert);
+ if (!pkey) {
+ fprintf(stderr, "unable to extract public key from certificate");
+ return -EINVAL;
+ }
+
+ rsa_key = pkey->pkey.rsa;
+ if (!rsa_key) {
+ fprintf(stderr, "unable to extract RSA public key");
+ return -EINVAL;
+ }
+
+ *modulus_len = BN_num_bytes(rsa_key->n);
+ *modulus = malloc(*modulus_len);
+ BN_bn2bin(rsa_key->n, *modulus);
+
+ *exponent_len = BN_num_bytes(rsa_key->e);
+ *exponent = malloc(*exponent_len);
+ BN_bn2bin(rsa_key->e, *exponent);
+
+ EVP_PKEY_free(pkey);
+ X509_free(cert);
+
+ return 0;
+}
+
+static int add_srk(void *buf, int offset, uint32_t loadaddr, const char *srkfile)
+{
+ struct imx_flash_header *hdr = buf + offset;
+ struct hab_rsa_public_key *key = buf + 0xc00;
+ uint8_t *exponent = NULL, *modulus = NULL, *modulus_dest;
+ int exponent_len = 0, modulus_len = 0;
+ int ret;
+
+ hdr->super_root_key = loadaddr + 0xc00;
+
+ key->init_flag = 1;
+ key->exponent_size = htole16(3);
+
+ ret = extract_key(srkfile, &modulus, &modulus_len, &exponent, &exponent_len);
+ if (ret)
+ return ret;
+
+ modulus_dest = (void *)(key + 1);
+
+ memcpy(modulus_dest, modulus, modulus_len);
+
+ key->modulus_size = htole16(modulus_len);
+ key->rsa_modulus = htole32(hdr->super_root_key + sizeof(*key));
+
+ if (exponent_len > 4)
+ return -EINVAL;
+
+ key->exponent_size = exponent_len;
+ memcpy(&key->rsa_exponent, exponent, key->exponent_size);
+
+ return 0;
+}
+#else
+static int add_srk(void *buf, int offset, uint32_t loadaddr, const char *srkfile)
+{
+ fprintf(stderr, "This version of imx-image is compiled without SSL support\n");
+
+ return -EINVAL;
+}
+#endif /* IMXIMAGE_SSL_SUPPORT */
+
static int add_header_v1(struct config_data *data, void *buf)
{
struct imx_flash_header *hdr;
@@ -430,6 +554,12 @@ int main(int argc, char *argv[])
switch (data.header_version) {
case 1:
add_header_v1(&data, buf);
+ if (data.srkfile) {
+ ret = add_srk(buf, data.image_dcd_offset, data.image_load_addr,
+ data.srkfile);
+ if (ret)
+ exit(1);
+ }
break;
case 2:
add_header_v2(&data, buf);
diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h
index 6e2f43b3ed..bc7d4ee4fa 100644
--- a/scripts/imx/imx.h
+++ b/scripts/imx/imx.h
@@ -57,6 +57,7 @@ struct config_data {
uint32_t image_size;
uint32_t load_size;
char *outfile;
+ char *srkfile;
int header_version;
int cpu_type;
int (*check)(struct config_data *data, uint32_t cmd, uint32_t addr, uint32_t mask);