mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [RFC 0/4] FIT Support
@ 2015-03-12 14:39 Jan Luebbe
  2015-03-12 14:39 ` [RFC 1/4] digest: Make filename arguments const Jan Luebbe
                   ` (5 more replies)
  0 siblings, 6 replies; 59+ messages in thread
From: Jan Luebbe @ 2015-03-12 14:39 UTC (permalink / raw)
  To: barebox

Hi,

this is the current work-in-progress state of my FIT support patches.
The FIT loading code has basically been rewritten from scratch, as the
original U-Boot code uses libfdt and barebox's DT support works on an
in-memory tree.

These patches apply on v2015.03.0.
The two patches from Sascha are required for the basic RSA support.
The third patch adds FIT support.
The fourth patch contains some test data to use in the sandbox.

$ ./barebox -i key.dtb -i sign-configs.itb 
add file key.dtb()
add file sign-configs.itb()

barebox 2015.03.0-00005-g574d35e191f7-dirty #81 Thu Mar 12 14:57:13 CET 2015

Board: barebox sandbox
...
Hit any key to stop autoboot:  3
barebox@barebox sandbox:/ oftree -l /dev/fd0
barebox@barebox sandbox:/ bootm /dev/fd1    

Loading open firmware Device Tree flattened Binary '/dev/fd1'
FIT '/dev/fd1': 'Chrome OS kernel image with one or more FDT blobs'
FIT configuration 'conf@1' (no description)
sig OK
FIT image 'kernel@1' (no description)
hash OK
FIT image 'fdt@1': 'snow'
hash OK

Jan Luebbe (2):
  FIT: add FIT image support
  FIT: add test config and data [do not merge]

Sascha Hauer (2):
  digest: Make filename arguments const
  Add rsa support

 arch/arm/lib/bootm.c                   |  74 +++++
 arch/sandbox/configs/sandbox_defconfig |  33 +-
 commands/Kconfig                       |   8 +
 common/Kconfig                         |   7 +
 common/Makefile                        |   1 +
 common/digest.c                        |   8 +-
 common/image-fit.c                     | 585 +++++++++++++++++++++++++++++++++
 crypto/Kconfig                         |   3 +
 crypto/Makefile                        |   1 +
 crypto/rsa.c                           | 411 +++++++++++++++++++++++
 include/asm-generic/errno.h            |   5 +
 include/digest.h                       |   8 +-
 include/image-fit.h                    |  42 +++
 include/rsa.h                          |  54 +++
 key.dtb                                | Bin 0 -> 1023 bytes
 key.dts                                |  27 ++
 sign-configs.itb                       | Bin 0 -> 2453 bytes
 17 files changed, 1247 insertions(+), 20 deletions(-)
 create mode 100644 common/image-fit.c
 create mode 100644 crypto/rsa.c
 create mode 100644 include/image-fit.h
 create mode 100644 include/rsa.h
 create mode 100644 key.dtb
 create mode 100644 key.dts
 create mode 100644 sign-configs.itb

-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [RFC 1/4] digest: Make filename arguments const
  2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
@ 2015-03-12 14:39 ` Jan Luebbe
  2015-03-13  7:40   ` Sascha Hauer
  2015-03-12 14:39 ` [RFC 2/4] Add rsa support Jan Luebbe
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 59+ messages in thread
From: Jan Luebbe @ 2015-03-12 14:39 UTC (permalink / raw)
  To: barebox

From: Sascha Hauer <s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/digest.c  | 8 ++++----
 include/digest.h | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/common/digest.c b/common/digest.c
index 51be2ca4148b..7187b0f23d81 100644
--- a/common/digest.c
+++ b/common/digest.c
@@ -59,7 +59,7 @@ void digest_unregister(struct digest *d)
 }
 EXPORT_SYMBOL(digest_unregister);
 
-struct digest* digest_get_by_name(char* name)
+struct digest* digest_get_by_name(const char *name)
 {
 	struct digest* d;
 
@@ -87,7 +87,7 @@ struct digest *digest_get(enum hash_algo algo)
 }
 EXPORT_SYMBOL_GPL(digest_get);
 
-int digest_file_window(struct digest *d, char *filename,
+int digest_file_window(struct digest *d, const char *filename,
 		       unsigned char *hash,
 		       ulong start, ulong size)
 {
@@ -157,7 +157,7 @@ out:
 }
 EXPORT_SYMBOL_GPL(digest_file_window);
 
-int digest_file(struct digest *d, char *filename,
+int digest_file(struct digest *d, const char *filename,
 		       unsigned char *hash)
 {
 	struct stat st;
@@ -172,7 +172,7 @@ int digest_file(struct digest *d, char *filename,
 }
 EXPORT_SYMBOL_GPL(digest_file);
 
-int digest_file_by_name(char *algo, char *filename,
+int digest_file_by_name(char *algo, const char *filename,
 		       unsigned char *hash)
 {
 	struct digest *d;
diff --git a/include/digest.h b/include/digest.h
index 62f6248d0768..4727c72efc55 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -63,15 +63,15 @@ struct digest
 int digest_register(struct digest *d);
 void digest_unregister(struct digest *d);
 
-struct digest* digest_get_by_name(char* name);
+struct digest* digest_get_by_name(const char *name);
 struct digest *digest_get(enum hash_algo);
 
-int digest_file_window(struct digest *d, char *filename,
+int digest_file_window(struct digest *d, const char *filename,
 		       unsigned char *hash,
 		       ulong start, ulong size);
-int digest_file(struct digest *d, char *filename,
+int digest_file(struct digest *d, const char *filename,
 		       unsigned char *hash);
-int digest_file_by_name(char *algo, char *filename,
+int digest_file_by_name(char *algo, const char *filename,
 		       unsigned char *hash);
 
 #endif /* __SH_ST_DEVICES_H__ */
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [RFC 2/4] Add rsa support
  2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
  2015-03-12 14:39 ` [RFC 1/4] digest: Make filename arguments const Jan Luebbe
@ 2015-03-12 14:39 ` Jan Luebbe
  2015-03-12 17:47   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-12 14:39 ` [RFC 3/4] FIT: add FIT image support Jan Luebbe
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 59+ messages in thread
From: Jan Luebbe @ 2015-03-12 14:39 UTC (permalink / raw)
  To: barebox

From: Sascha Hauer <s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 crypto/Kconfig              |   3 +
 crypto/Makefile             |   1 +
 crypto/rsa.c                | 411 ++++++++++++++++++++++++++++++++++++++++++++
 include/asm-generic/errno.h |   5 +
 include/rsa.h               |  54 ++++++
 5 files changed, 474 insertions(+)
 create mode 100644 crypto/rsa.c
 create mode 100644 include/rsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4bd8dcf359f8..fa9ba491b79b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -25,3 +25,6 @@ config SHA256
 	bool "SHA256"
 
 endif
+
+config RSA
+	bool
diff --git a/crypto/Makefile b/crypto/Makefile
index 7c5b035b73de..44be124aa368 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_MD5)	+= md5.o
 obj-$(CONFIG_SHA1)	+= sha1.o
 obj-$(CONFIG_SHA224)	+= sha2.o
 obj-$(CONFIG_SHA256)	+= sha2.o
+obj-$(CONFIG_RSA)	+= rsa.o
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 000000000000..6a0c7b8a15cc
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <of.h>
+#include <digest.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <errno.h>
+#include <rsa.h>
+#include <asm/types.h>
+#include <asm/unaligned.h>
+
+#define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
+
+#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
+#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
+
+/* Default public exponent for backward compatibility */
+#define RSA_DEFAULT_PUBEXP	65537
+
+/* This is the minimum/maximum key size we support, in bits */
+#define RSA_MIN_KEY_BITS	1024
+#define RSA_MAX_KEY_BITS	4096
+
+/**
+ * subtract_modulus() - subtract modulus from the given value
+ *
+ * @key:	Key containing modulus to subtract
+ * @num:	Number to subtract modulus from, as little endian word array
+ */
+static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
+{
+	int64_t acc = 0;
+	uint i;
+
+	for (i = 0; i < key->len; i++) {
+		acc += (uint64_t)num[i] - key->modulus[i];
+		num[i] = (uint32_t)acc;
+		acc >>= 32;
+	}
+}
+
+/**
+ * greater_equal_modulus() - check if a value is >= modulus
+ *
+ * @key:	Key containing modulus to check
+ * @num:	Number to check against modulus, as little endian word array
+ * @return 0 if num < modulus, 1 if num >= modulus
+ */
+static int greater_equal_modulus(const struct rsa_public_key *key,
+				 uint32_t num[])
+{
+	int i;
+
+	for (i = (int)key->len - 1; i >= 0; i--) {
+		if (num[i] < key->modulus[i])
+			return 0;
+		if (num[i] > key->modulus[i])
+			return 1;
+	}
+
+	return 1;  /* equal */
+}
+
+/**
+ * montgomery_mul_add_step() - Perform montgomery multiply-add step
+ *
+ * Operation: montgomery result[] += a * b[] / n0inv % modulus
+ *
+ * @key:	RSA key
+ * @result:	Place to put result, as little endian word array
+ * @a:		Multiplier
+ * @b:		Multiplicand, as little endian word array
+ */
+static void montgomery_mul_add_step(const struct rsa_public_key *key,
+		uint32_t result[], const uint32_t a, const uint32_t b[])
+{
+	uint64_t acc_a, acc_b;
+	uint32_t d0;
+	uint i;
+
+	acc_a = (uint64_t)a * b[0] + result[0];
+	d0 = (uint32_t)acc_a * key->n0inv;
+	acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
+	for (i = 1; i < key->len; i++) {
+		acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
+		acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
+				(uint32_t)acc_a;
+		result[i - 1] = (uint32_t)acc_b;
+	}
+
+	acc_a = (acc_a >> 32) + (acc_b >> 32);
+
+	result[i - 1] = (uint32_t)acc_a;
+
+	if (acc_a >> 32)
+		subtract_modulus(key, result);
+}
+
+/**
+ * montgomery_mul() - Perform montgomery mutitply
+ *
+ * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
+ *
+ * @key:	RSA key
+ * @result:	Place to put result, as little endian word array
+ * @a:		Multiplier, as little endian word array
+ * @b:		Multiplicand, as little endian word array
+ */
+static void montgomery_mul(const struct rsa_public_key *key,
+		uint32_t result[], uint32_t a[], const uint32_t b[])
+{
+	uint i;
+
+	for (i = 0; i < key->len; ++i)
+		result[i] = 0;
+	for (i = 0; i < key->len; ++i)
+		montgomery_mul_add_step(key, result, a[i], b);
+}
+
+/**
+ * num_pub_exponent_bits() - Number of bits in the public exponent
+ *
+ * @key:	RSA key
+ * @num_bits:	Storage for the number of public exponent bits
+ */
+static int num_public_exponent_bits(const struct rsa_public_key *key,
+		int *num_bits)
+{
+	uint64_t exponent;
+	int exponent_bits;
+	const uint max_bits = (sizeof(exponent) * 8);
+
+	exponent = key->exponent;
+	exponent_bits = 0;
+
+	if (!exponent) {
+		*num_bits = exponent_bits;
+		return 0;
+	}
+
+	for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits)
+		if (!(exponent >>= 1)) {
+			*num_bits = exponent_bits;
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+/**
+ * is_public_exponent_bit_set() - Check if a bit in the public exponent is set
+ *
+ * @key:	RSA key
+ * @pos:	The bit position to check
+ */
+static int is_public_exponent_bit_set(const struct rsa_public_key *key,
+		int pos)
+{
+	return key->exponent & (1ULL << pos);
+}
+
+/**
+ * pow_mod() - in-place public exponentiation
+ *
+ * @key:	RSA key
+ * @inout:	Big-endian word array containing value and result
+ */
+static int pow_mod(const struct rsa_public_key *key, void *__inout)
+{
+	uint32_t *inout = __inout;
+	uint32_t *result, *ptr;
+	uint i;
+	int j, k;
+	uint32_t val[RSA_MAX_KEY_BITS / 32], acc[RSA_MAX_KEY_BITS / 32], tmp[RSA_MAX_KEY_BITS / 32];
+	uint32_t a_scaled[RSA_MAX_KEY_BITS / 32];
+
+	/* Sanity check for stack size - key->len is in 32-bit words */
+	if (key->len > RSA_MAX_KEY_BITS / 32) {
+		debug("RSA key words %u exceeds maximum %d\n", key->len,
+		      RSA_MAX_KEY_BITS / 32);
+		return -EINVAL;
+	}
+
+	result = tmp;  /* Re-use location. */
+
+	/* Convert from big endian byte array to little endian word array. */
+	for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--)
+		val[i] = get_unaligned_be32(ptr);
+
+	if (0 != num_public_exponent_bits(key, &k))
+		return -EINVAL;
+
+	if (k < 2) {
+		debug("Public exponent is too short (%d bits, minimum 2)\n",
+		      k);
+		return -EINVAL;
+	}
+
+	if (!is_public_exponent_bit_set(key, 0)) {
+		debug("LSB of RSA public exponent must be set.\n");
+		return -EINVAL;
+	}
+
+	/* the bit at e[k-1] is 1 by definition, so start with: C := M */
+	montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */
+	/* retain scaled version for intermediate use */
+	memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0]));
+
+	for (j = k - 2; j > 0; --j) {
+		montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
+
+		if (is_public_exponent_bit_set(key, j)) {
+			/* acc = tmp * val / R mod n */
+			montgomery_mul(key, acc, tmp, a_scaled);
+		} else {
+			/* e[j] == 0, copy tmp back to acc for next operation */
+			memcpy(acc, tmp, key->len * sizeof(acc[0]));
+		}
+	}
+
+	/* the bit at e[0] is always 1 */
+	montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
+	montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */
+	memcpy(result, acc, key->len * sizeof(result[0]));
+
+	/* Make sure result < mod; result is at most 1x mod too large. */
+	if (greater_equal_modulus(key, result))
+		subtract_modulus(key, result);
+
+	/* Convert to bigendian byte array */
+	for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
+		put_unaligned_be32(result[i], ptr);
+	return 0;
+}
+
+/*
+ * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
+ */
+static const u8 RSA_digest_info_MD5[] = {
+	0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
+	0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */
+	0x05, 0x00, 0x04, 0x10
+};
+
+static const u8 RSA_digest_info_SHA1[] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+	0x2B, 0x0E, 0x03, 0x02, 0x1A,
+	0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 RSA_digest_info_RIPE_MD_160[] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+	0x2B, 0x24, 0x03, 0x02, 0x01,
+	0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 RSA_digest_info_SHA224[] = {
+	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
+	0x05, 0x00, 0x04, 0x1C
+};
+
+static const u8 RSA_digest_info_SHA256[] = {
+	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+	0x05, 0x00, 0x04, 0x20
+};
+
+static const u8 RSA_digest_info_SHA384[] = {
+	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
+	0x05, 0x00, 0x04, 0x30
+};
+
+static const u8 RSA_digest_info_SHA512[] = {
+	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+	0x05, 0x00, 0x04, 0x40
+};
+
+static const struct {
+	const u8 *data;
+	size_t size;
+} RSA_ASN1_templates[] = {
+#define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) }
+	[HASH_ALGO_MD5]		= _(MD5),
+	[HASH_ALGO_SHA1]	= _(SHA1),
+	[HASH_ALGO_RIPE_MD_160]	= _(RIPE_MD_160),
+	[HASH_ALGO_SHA256]	= _(SHA256),
+	[HASH_ALGO_SHA384]	= _(SHA384),
+	[HASH_ALGO_SHA512]	= _(SHA512),
+	[HASH_ALGO_SHA224]	= _(SHA224),
+#undef _
+};
+
+int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,
+			  const uint32_t sig_len, const uint8_t *hash,
+			  enum hash_algo algo)
+{
+	int ret;
+	uint8_t buf[RSA_MAX_SIG_BITS / 8];
+	int i;
+	unsigned PS_end, T_offset;
+	const u8 *asn1_template = RSA_ASN1_templates[algo].data;
+	size_t asn1_size = RSA_ASN1_templates[algo].size;
+	struct digest *d = digest_get(algo);
+
+	if (!d)
+		return -EOPNOTSUPP;
+
+	if (sig_len != (key->len * sizeof(uint32_t))) {
+		debug("Signature is of incorrect length %d, should be %d\n", sig_len,
+				key->len * sizeof(uint32_t));
+		return -EINVAL;
+	}
+
+	/* Sanity check for stack size */
+	if (sig_len > RSA_MAX_SIG_BITS / 8) {
+		debug("Signature length %u exceeds maximum %d\n", sig_len,
+		      RSA_MAX_SIG_BITS / 8);
+		return -EINVAL;
+	}
+
+	memcpy(buf, sig, sig_len);
+
+	ret = pow_mod(key, buf);
+	if (ret)
+		return ret;
+
+	T_offset = sig_len - (asn1_size + d->length);
+
+	PS_end = T_offset - 1;
+	if (buf[PS_end] != 0x00) {
+		pr_err(" = -EBADMSG [EM[T-1] == %02u]", buf[PS_end]);
+		return -EBADMSG;
+	}
+
+	for (i = 2; i < PS_end; i++) {
+		if (buf[i] != 0xff) {
+			pr_err(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, buf[i]);
+			return -EBADMSG;
+		}
+	}
+
+	if (memcmp(asn1_template, buf + T_offset, asn1_size) != 0) {
+		pr_err(" = -EBADMSG [EM[T] ASN.1 mismatch]");
+		return -EBADMSG;
+	}
+
+	if (memcmp(hash, buf + T_offset + asn1_size, d->length) != 0) {
+		pr_err(" = -EKEYREJECTED [EM[T] hash mismatch]");
+		return -EKEYREJECTED;
+	}
+
+	return 0;
+}
+
+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]);
+}
+
+int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key)
+{
+	const void *modulus, *rr;
+	const uint64_t *public_exponent;
+	int length;
+
+	of_property_read_u32(node, "rsa,num-bits", &key->len);
+	of_property_read_u32(node, "rsa,n0-inverse", &key->n0inv);
+
+	public_exponent = of_get_property(node, "rsa,exponent", &length);
+	if (!public_exponent || length < sizeof(*public_exponent))
+		key->exponent = RSA_DEFAULT_PUBEXP;
+	else
+		key->exponent = fdt64_to_cpu(*public_exponent);
+
+	modulus = of_get_property(node, "rsa,modulus", NULL);
+	rr = of_get_property(node, "rsa,r-squared", NULL);
+
+	if (!key->len || !modulus || !rr) {
+		debug("%s: Missing RSA key info", __func__);
+		return -EFAULT;
+	}
+
+	/* Sanity check for stack size */
+	if (key->len > RSA_MAX_KEY_BITS || key->len < RSA_MIN_KEY_BITS) {
+		debug("RSA key bits %u outside allowed range %d..%d\n",
+		      key->len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
+		return -EFAULT;
+	}
+
+	key->len /= sizeof(uint32_t) * 8;
+
+	key->modulus = xzalloc(RSA_MAX_KEY_BITS / 8);
+	key->rr = xzalloc(RSA_MAX_KEY_BITS / 8);
+
+	rsa_convert_big_endian(key->modulus, modulus, key->len);
+	rsa_convert_big_endian(key->rr, rr, key->len);
+
+	return 0;
+}
diff --git a/include/asm-generic/errno.h b/include/asm-generic/errno.h
index bbf493c373ae..b239831bc703 100644
--- a/include/asm-generic/errno.h
+++ b/include/asm-generic/errno.h
@@ -126,6 +126,11 @@
 
 #define	ENOMEDIUM	123	/* No medium found */
 #define	EMEDIUMTYPE	124	/* Wrong medium type */
+#define	ECANCELED	125	/* Operation Canceled */
+#define	ENOKEY		126	/* Required key not available */
+#define	EKEYEXPIRED	127	/* Key has expired */
+#define	EKEYREVOKED	128	/* Key has been revoked */
+#define	EKEYREJECTED	129	/* Key was rejected by service */
 
 /* Should never be seen by user programs */
 #define ERESTARTSYS	512
diff --git a/include/rsa.h b/include/rsa.h
new file mode 100644
index 000000000000..feb8c3120023
--- /dev/null
+++ b/include/rsa.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _RSA_H
+#define _RSA_H
+
+#include <errno.h>
+#include <digest.h>
+
+/**
+ * struct rsa_public_key - holder for a public key
+ *
+ * An RSA public key consists of a modulus (typically called N), the inverse
+ * and R^2, where R is 2^(# key bits).
+ */
+
+struct rsa_public_key {
+	uint len;		/* len of modulus[] in number of uint32_t */
+	uint32_t n0inv;		/* -1 / modulus[0] mod 2^32 */
+	uint32_t *modulus;	/* modulus as little endian array */
+	uint32_t *rr;		/* R^2 as little endian array */
+	uint64_t exponent;	/* public exponent */
+};
+
+/**
+ * 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 rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,
+			  const uint32_t sig_len, const uint8_t *hash,
+			  enum hash_algo algo);
+
+/* This is the maximum signature length that we support, in bits */
+#define RSA_MAX_SIG_BITS	4096
+
+int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key);
+
+#endif
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [RFC 3/4] FIT: add FIT image support
  2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
  2015-03-12 14:39 ` [RFC 1/4] digest: Make filename arguments const Jan Luebbe
  2015-03-12 14:39 ` [RFC 2/4] Add rsa support Jan Luebbe
@ 2015-03-12 14:39 ` Jan Luebbe
  2015-03-12 18:19   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-12-29 10:18   ` Yegor Yefremov
  2015-03-12 14:39 ` [RFC 4/4] FIT: add test config and data [do not merge] Jan Luebbe
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 59+ messages in thread
From: Jan Luebbe @ 2015-03-12 14:39 UTC (permalink / raw)
  To: barebox

The FIT image format was defined for U-Boot and has been adopted by the
depthcharge project as well. It is intended to be a replacement for the
uimage format and has been extended to support signing of kernel,
initramfs and devicetree images. This patch adds support for booting FIT
images to barebox.

To verify signed images, the RSA public key data must be available in
the internal device tree. Currently only signature verification on
configurations (which contains hashes of all referenced images) are
implemented, as this is the most useful use case and reduces the
complexity of the implementation.

The host tool (mkimage) to sign images has not yet been imported from U-Boot.

Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
---
 arch/arm/lib/bootm.c |  74 +++++++
 commands/Kconfig     |   8 +
 common/Kconfig       |   7 +
 common/Makefile      |   1 +
 common/image-fit.c   | 585 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/image-fit.h  |  42 ++++
 6 files changed, 717 insertions(+)
 create mode 100644 common/image-fit.c
 create mode 100644 include/image-fit.h

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 8327c3f5603a..6d30c594bdc2 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -552,6 +552,78 @@ BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs
 BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage");
 #endif
 
+#include <image-fit.h>
+
+static int do_bootm_arm_fit(struct image_data *data)
+{
+	struct fit_handle *handle;
+	int ret;
+	unsigned long mem_free;
+	unsigned long mem_start, mem_size;
+
+	handle = fit_open(data->os_file, data->os_num, data->verbose);
+	if (!handle)
+		return -EINVAL;
+
+	ret = sdram_start_and_size(&mem_start, &mem_size);
+	if (ret)
+		return ret;
+
+	/* no support for custom load address */
+	data->os_address = mem_start + PAGE_ALIGN(handle->kernel_size * 4);
+	data->os_res = request_sdram_region("fit-kernel", data->os_address, handle->kernel_size);
+	if (!data->os_res) {
+		pr_err("Cannot request region 0x%08lx - 0x%08lx\n",
+				data->os_address, handle->kernel_size);
+		ret = -ENOMEM;
+		goto err_out;
+	}
+	memcpy((void *)data->os_res->start, handle->kernel, handle->kernel_size);
+
+	/*
+	 * Put oftree/initrd close behind compressed kernel image to avoid
+	 * placing it outside of the kernels lowmem.
+	 */
+	if (handle->initrd_size) {
+		data->initrd_address = PAGE_ALIGN(data->os_res->end + SZ_1M);
+		data->initrd_res = request_sdram_region("fit-initrd", data->initrd_address, handle->initrd_size);
+		if (!data->initrd_res) {
+			ret = -ENOMEM;
+			goto err_out;
+		}
+		memcpy((void *)data->initrd_res->start, handle->initrd, handle->initrd_size);
+	}
+
+	data->of_root_node = of_unflatten_dtb(handle->oftree);
+	if (!data->of_root_node) {
+		pr_err("unable to unflatten devicetree\n");
+		ret = -EINVAL;
+		goto err_out;
+	}
+
+	/*
+	 * Put devicetree right after initrd if present or after the kernel
+	 * if not.
+	 */
+	if (data->initrd_res)
+		mem_free = PAGE_ALIGN(data->initrd_res->end);
+	else
+		mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M);
+
+	return __do_bootm_linux(data, mem_free, 0);
+
+err_out:
+	if (handle)
+		fit_close(handle);
+	return ret;
+}
+
+static struct image_handler arm_fit_handler = {
+        .name = "FIT image",
+        .bootm = do_bootm_arm_fit,
+        .filetype = filetype_oftree,
+};
+
 static struct binfmt_hook binfmt_aimage_hook = {
 	.type = filetype_aimage,
 	.exec = "bootm",
@@ -577,6 +649,8 @@ static int armlinux_register_image_handler(void)
 		register_image_handler(&aimage_handler);
 		binfmt_register(&binfmt_aimage_hook);
 	}
+	if (IS_BUILTIN(CONFIG_CMD_BOOTM_FITIMAGE))
+	        register_image_handler(&arm_fit_handler);
 	binfmt_register(&binfmt_arm_zimage_hook);
 	binfmt_register(&binfmt_barebox_hook);
 
diff --git a/commands/Kconfig b/commands/Kconfig
index e4f68e7bda31..8d8fd46c15ec 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -402,6 +402,14 @@ config CMD_BOOTM_AIMAGE
 	help
 	  Support using Android Images.
 
+config CMD_BOOTM_FITIMAGE
+	bool
+	prompt "FIT image support"
+	select FITIMAGE
+	depends on CMD_BOOTM && (ARM || SANDBOX)
+	help
+	  Support using FIT Images.
+
 config CMD_BOOTU
 	tristate
 	default y
diff --git a/common/Kconfig b/common/Kconfig
index d4373431aae8..9dd0b65ef8ae 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -66,6 +66,13 @@ config UIMAGE
 	select CRC32
 	bool
 
+config FITIMAGE
+	bool
+	select OFTREE
+	select SHA1
+	select SHA256
+	select RSA
+
 config LOGBUF
 	bool
 
diff --git a/common/Makefile b/common/Makefile
index ee5dca70236e..a8008292f0d8 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_RESET_SOURCE)	+= reset_source.o
 obj-$(CONFIG_SHELL_HUSH)	+= hush.o
 obj-$(CONFIG_SHELL_SIMPLE)	+= parser.o
 obj-$(CONFIG_UIMAGE)		+= image.o uimage.o
+obj-$(CONFIG_FITIMAGE)		+= image-fit.o
 obj-$(CONFIG_MENUTREE)		+= menutree.o
 obj-$(CONFIG_EFI_GUID)		+= efi-guid.o
 obj-$(CONFIG_EFI_DEVICEPATH)	+= efi-devicepath.o
diff --git a/common/image-fit.c b/common/image-fit.c
new file mode 100644
index 000000000000..77df5e5f4205
--- /dev/null
+++ b/common/image-fit.c
@@ -0,0 +1,585 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) Jan Lübbe, 2014
+ */
+
+#include <common.h>
+#include <init.h>
+#include <boot.h>
+#include <libfile.h>
+#include <fdt.h>
+#include <digest.h>
+#include <of.h>
+#include <fs.h>
+#include <malloc.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+#include <errno.h>
+#include <linux/err.h>
+#include <stringlist.h>
+#include <rsa.h>
+#include <image-fit.h>
+
+#define FDT_MAX_DEPTH	32
+#define FDT_MAX_PATH_LEN 200
+
+#define CHECK_LEVEL_NONE 0
+#define CHECK_LEVEL_HASH 1
+#define CHECK_LEVEL_SIG 2
+#define CHECK_LEVEL_MAX 3
+
+static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int size)
+{
+	dt += size;
+	dt = ALIGN(dt, 4);
+
+	if (dt > f->off_dt_struct + f->size_dt_struct)
+		return 0;
+
+	return dt;
+}
+
+static char *dt_string(struct fdt_header *f, char *strstart, uint32_t ofs)
+{
+	if (ofs > f->size_dt_strings)
+		return NULL;
+	else
+		return strstart + ofs;
+}
+
+static int of_read_string_list(struct device_node *np, const char *name, struct string_list *sl)
+{
+	struct property *prop;
+	const char *s;
+
+	of_property_for_each_string(np, name, prop, s) {
+		string_list_add(sl, s);
+	}
+
+	return prop ? 0 : -EINVAL;
+}
+
+static int fit_digest(void *fit, struct digest *digest,
+		struct string_list *inc_nodes, struct string_list *exc_props,
+		uint32_t hashed_strings_start, uint32_t hashed_strings_size)
+{
+	struct fdt_header *fdt = fit;
+	uint32_t dt_struct;
+	void *dt_strings;
+	struct fdt_header f;
+	int stack[FDT_MAX_DEPTH];
+	char path[FDT_MAX_PATH_LEN];
+	char *end;
+	uint32_t tag;
+	int start = -1;
+	int depth = -1;
+	int want = 0;
+
+	f.totalsize = fdt32_to_cpu(fdt->totalsize);
+	f.off_dt_struct = fdt32_to_cpu(fdt->off_dt_struct);
+	f.size_dt_struct = fdt32_to_cpu(fdt->size_dt_struct);
+	f.off_dt_strings = fdt32_to_cpu(fdt->off_dt_strings);
+	f.size_dt_strings = fdt32_to_cpu(fdt->size_dt_strings);
+
+	if (hashed_strings_start > f.size_dt_strings ||
+	    hashed_strings_size > f.size_dt_strings ||
+	    hashed_strings_start + hashed_strings_size > f.size_dt_strings) {
+		pr_err("%s: hashed-strings too large\n", __func__);
+		return -EINVAL;
+	}
+
+	dt_struct = f.off_dt_struct;
+	dt_strings = (void *)fdt + f.off_dt_strings;
+
+	end = path;
+	*end = '\0';
+
+	do {
+		const struct fdt_property *fdt_prop;
+		const struct fdt_node_header *fnh;
+		const char *name;
+		int include = 0;
+		int stop_at = 0;
+		int offset = dt_struct;
+		int maxlen, len;
+
+		tag = be32_to_cpu(*(uint32_t *)(fit + dt_struct));
+
+		switch (tag) {
+		case FDT_BEGIN_NODE:
+			fnh = fit + dt_struct;
+			name = fnh->name;
+			maxlen = (unsigned long)fdt + f.off_dt_struct +
+				f.size_dt_struct - (unsigned long)name;
+
+			len = strnlen(name, maxlen + 1);
+			if (len > maxlen)
+				return -ESPIPE;
+
+			dt_struct = dt_struct_advance(&f, dt_struct,
+					sizeof(struct fdt_node_header) + len + 1);
+
+			depth++;
+			if (depth == FDT_MAX_DEPTH)
+				return -ESPIPE;
+			if (end - path + 2 + len >= FDT_MAX_PATH_LEN)
+				return -ESPIPE;
+			if (end != path + 1)
+				*end++ = '/';
+			strcpy(end, name);
+			end += len;
+			stack[depth] = want;
+			if (want == 1)
+				stop_at = offset;
+			if (string_list_contains(inc_nodes, path))
+				want = 2;
+			else if (want)
+				want--;
+			else
+				stop_at = offset;
+			include = want;
+
+			break;
+
+		case FDT_END_NODE:
+			dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
+
+			include = want;
+			want = stack[depth--];
+			while (end > path && *--end != '/')
+				;
+			*end = '\0';
+
+			break;
+
+		case FDT_PROP:
+			fdt_prop = fit + dt_struct;
+			len = fdt32_to_cpu(fdt_prop->len);
+
+			name = dt_string(&f, dt_strings, fdt32_to_cpu(fdt_prop->nameoff));
+			if (!name)
+				return -ESPIPE;
+
+			dt_struct = dt_struct_advance(&f, dt_struct,
+					sizeof(struct fdt_property) + len);
+
+			include = want >= 2;
+			stop_at = offset;
+			if (string_list_contains(exc_props, name))
+				include = 0;
+
+			break;
+
+		case FDT_NOP:
+			dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
+
+			include = want >= 2;
+			stop_at = offset;
+
+			break;
+
+		case FDT_END:
+			dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
+
+			include = 1;
+
+			break;
+
+		default:
+			pr_err("%s: Unknown tag 0x%08X\n", __func__, tag);
+			return -EINVAL;
+		}
+
+		if (!dt_struct)
+			return -ESPIPE;
+
+		pr_debug("%s: include %d, want %d, offset 0x%x, len 0x%x\n",
+			path, include, want, offset, dt_struct-offset);
+
+		if (include && start == -1)
+			start = offset;
+
+		if (!include && start != -1) {
+			pr_debug("region: 0x%p+0x%x\n", fit+start, offset-start);
+			digest->update(digest, fit+start, offset-start);
+			start = -1;
+		}
+	} while (tag != FDT_END);
+
+	pr_debug("region: 0x%p+0x%x\n", fit+start, dt_struct-start);
+	digest->update(digest, fit+start, dt_struct-start);
+
+	pr_debug("strings: 0x%p+0x%x\n", dt_strings+hashed_strings_start, hashed_strings_size);
+	digest->update(digest, dt_strings+hashed_strings_start, hashed_strings_size);
+
+	return 0;
+}
+
+/*
+ * The consistency of the FTD structure was already checked by of_unflatten_dtb()
+ */
+static int fit_verify_signature(struct device_node *sig_node, void *fit)
+{
+	uint32_t hashed_strings_start, hashed_strings_size;
+	struct string_list inc_nodes, exc_props;
+	struct rsa_public_key key = {};
+	struct digest *digest;
+	int sig_len;
+	const char *algo_name, *key_name, *sig_value;
+	char *key_path;
+	struct device_node *key_node;
+	enum hash_algo algo;
+	void *hash;
+	int ret;
+
+	if (of_property_read_string(sig_node, "algo", &algo_name)) {
+		pr_err("algo not found\n");
+		ret = -EINVAL;
+		goto out;
+	}
+	if (strcmp(algo_name, "sha1,rsa2048") == 0) {
+		algo = HASH_ALGO_SHA1;
+	} else {
+		pr_err("unknown algo %s\n", algo_name);
+		ret = -EINVAL;
+		goto out;
+	}
+	digest = digest_get(algo);
+	if (!digest) {
+		pr_err("unsupported algo %s\n", algo_name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	sig_value = of_get_property(sig_node, "value", &sig_len);
+	if (!sig_value) {
+		pr_err("signature value not found\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (of_property_read_string(sig_node, "key-name-hint", &key_name)) {
+		pr_err("key name not found\n");
+		ret = -EINVAL;
+		goto out;
+	}
+	key_path = asprintf("/signature/key-%s", key_name);
+	if (!key_name) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	key_node = of_find_node_by_path(key_path);
+	free(key_path);
+	if (!key_node) {
+		pr_info("failed to find key node\n");
+		ret = -ENOENT;
+		goto out;
+	}
+
+	ret = rsa_of_read_key(key_node, &key);
+	if (ret) {
+		pr_info("failed to read key\n");
+		ret = -ENOENT;
+		goto out;
+	}
+
+	if (of_property_read_u32_index(sig_node, "hashed-strings", 0, &hashed_strings_start)) {
+		pr_err("%s: hashed-strings start not found\n", __func__);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (of_property_read_u32_index(sig_node, "hashed-strings", 1, &hashed_strings_size)) {
+		pr_err("%s: hashed-strings size not found\n", __func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	string_list_init(&inc_nodes);
+	string_list_init(&exc_props);
+
+	if (of_read_string_list(sig_node, "hashed-nodes", &inc_nodes))
+	{
+		pr_err("%s: hashed-nodes invalid\n", __func__);
+		ret = -EINVAL;
+		goto out_sl;
+	}
+
+	string_list_add(&exc_props, "data");
+
+	digest->init(digest);
+	ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start, hashed_strings_size);
+	hash = xzalloc(digest->length);
+	digest->final(digest, hash);
+
+	ret = rsa_verify(&key, sig_value, sig_len, hash, algo); 
+	if (ret) {
+		pr_info("sig BAD\n");
+		ret = CHECK_LEVEL_NONE;
+	} else {
+		pr_info("sig OK\n");
+		ret = CHECK_LEVEL_SIG;
+	}
+
+	free(hash);
+out_sl:
+	string_list_free(&inc_nodes);
+	string_list_free(&exc_props);
+out:
+	return ret;
+}
+
+static int fit_verify_hash(struct device_node *hash, const void *data, int data_len)
+{
+	struct digest *d;
+	const char *algo;
+	const char *value_read;
+	char *value_calc;
+	int hash_len;
+
+	value_read = of_get_property(hash, "value", &hash_len);
+	if (!value_read) {
+		pr_err("value not found\n");
+		return CHECK_LEVEL_NONE;
+	}
+
+	if (of_property_read_string(hash, "algo", &algo)) {
+		pr_err("algo not found\n");
+		return -EINVAL;
+	}
+
+	d = digest_get_by_name(algo);
+	if (!d) {
+		pr_err("unsupported algo %s\n", algo);
+		return -EINVAL;
+	}
+
+	if (hash_len != d->length) {
+		pr_err("invalid hash length %d\n", hash_len);
+		return -EINVAL;
+	}
+
+	value_calc = xmalloc(hash_len);
+	
+	d->init(d);
+	d->update(d, data, data_len);
+	d->final(d, value_calc);
+
+	if (memcmp(value_read, value_calc, hash_len)) {
+		pr_info("hash BAD\n");
+		return CHECK_LEVEL_NONE;
+	} else {
+		pr_info("hash OK\n");
+		return CHECK_LEVEL_HASH;
+	}
+}
+
+static int fit_open_image(struct fit_handle *handle, const char* unit)
+{
+	struct device_node *image = NULL, *hash;
+	const char *type = NULL, *desc;
+	const void *data;
+	int data_len;
+	int ret, level;
+
+	image = of_get_child_by_name(handle->root, "images");
+	if (!image)
+		return -ENOENT;
+
+	image = of_get_child_by_name(image, unit);
+	if (!image)
+		return -ENOENT;
+
+	if (of_property_read_string(image, "description", &desc)) {
+		pr_info("FIT image '%s' (no description)\n", unit);
+	} else {
+		pr_info("FIT image '%s': '%s'\n", unit, desc);
+	}
+
+	of_property_read_string(image, "type", &type);
+	if (!type)
+		return -EINVAL;
+
+	data = of_get_property(image, "data", &data_len);
+	if (!data) {
+		pr_err("data not found\n");
+		return -EINVAL;
+	}
+
+	level = CHECK_LEVEL_MAX;
+	for_each_child_of_node(image, hash) {
+		if (handle->verbose)
+			of_print_nodes(hash, 0);
+		ret = fit_verify_hash(hash, data, data_len);
+		if (ret < 0)
+			return ret;
+		level = min(level, ret);
+	}
+	if (level == CHECK_LEVEL_MAX) {
+		return -EINVAL;
+	}
+
+	if (level == CHECK_LEVEL_HASH) {
+		if (strcmp(type, "kernel") == 0 ||
+			strcmp(type, "kernel_noload") == 0) {
+			handle->kernel = data;
+			handle->kernel_size = data_len;
+		} else if (strcmp(type, "flat_dt") == 0) {
+			handle->oftree = data;
+			handle->oftree_size = data_len;
+		} else if (strcmp(type, "ramdisk") == 0) {
+			handle->initrd = data;
+			handle->initrd_size = data_len;
+		} else {
+			pr_info("unknown image type %s, ignoring\n", type);
+		}
+	}
+
+	return level;
+}
+
+static int fit_open_configuration(struct fit_handle *handle, int num)
+{
+	struct device_node *conf_node = NULL, *sig_node;
+	char unit_name[10];
+	const char *unit, *desc;
+	int ret, level;
+
+	conf_node = of_get_child_by_name(handle->root, "configurations");
+	if (!conf_node)
+		return -ENOENT;
+
+	if (num) {
+		snprintf(unit_name, sizeof(unit_name), "conf@%d", num);
+		unit = unit_name;
+	} else if (of_property_read_string(conf_node, "default", &unit)) {
+		unit = "conf@1";
+	}
+
+	conf_node = of_get_child_by_name(conf_node, unit);
+	if (!conf_node) {
+		pr_err("FIT configuration '%s' not found\n", unit);
+		return -ENOENT;
+	}
+
+	if (of_property_read_string(conf_node, "description", &desc)) {
+		pr_info("FIT configuration '%s' (no description)\n", unit);
+	} else {
+		pr_info("FIT configuration '%s': '%s'\n", unit, desc);
+	}
+
+	level = CHECK_LEVEL_MAX;
+	for_each_child_of_node(conf_node, sig_node) {
+		if (handle->verbose)
+			of_print_nodes(sig_node, 0);
+		ret = fit_verify_signature(sig_node, handle->fit);
+		if (ret < 0)
+			return ret;
+		level = min(level, ret);
+	}
+	if (level == CHECK_LEVEL_MAX)
+		return -EINVAL;
+
+	if (level != CHECK_LEVEL_SIG)
+		return -EINVAL;
+
+	if (of_property_read_string(conf_node, "kernel", &unit) == 0)
+		level = min(level, fit_open_image(handle, unit));
+	else
+		return -ENOENT;
+	
+	if (of_property_read_string(conf_node, "fdt", &unit) == 0)
+		level = min(level, fit_open_image(handle, unit));
+	
+	if (of_property_read_string(conf_node, "ramdisk", &unit) == 0)
+		level = min(level, fit_open_image(handle, unit));
+
+	if (level != CHECK_LEVEL_HASH)
+		return -EINVAL;
+
+	return 0;
+}
+
+struct fit_handle *fit_open(const char *filename, int num, bool verbose)
+{
+	struct fit_handle *handle = NULL;
+	const char *desc;
+
+	handle = xzalloc(sizeof(struct fit_handle));
+
+	handle->verbose = verbose;
+
+	handle->fit = read_file(filename, &handle->size);
+	if (!handle->fit) {
+		pr_err("unable to read %s: %s\n", filename, strerror(errno));
+		goto err;
+	}
+
+	handle->root = of_unflatten_dtb(handle->fit);
+	if (IS_ERR(handle->root)) {
+		goto err;
+	}
+
+	if (of_property_read_string(handle->root, "description", &desc)) {
+		pr_info("FIT '%s' (no description)\n", filename);
+	} else {
+		pr_info("FIT '%s': '%s'\n", filename, desc);
+	}
+
+	if (fit_open_configuration(handle, num))
+		goto err;
+
+	return handle;
+err:
+	if (handle->root)
+		of_delete_node(handle->root);
+	if (handle->fit)
+		free(handle->fit);
+	free(handle);
+
+	return NULL;
+}
+
+void fit_close(struct fit_handle *handle)
+{
+	if (handle->root)
+		of_delete_node(handle->root);
+	if (handle->fit)
+		free(handle->fit);
+	free(handle);
+}
+
+#ifdef CONFIG_SANDBOX
+static int do_bootm_sandbox_fit(struct image_data *data)
+{
+	struct fit_handle *handle;
+	handle = fit_open(data->os_file, data->os_num, data->verbose);
+	if (handle)
+		fit_close(handle);
+	return 0;
+}
+
+static struct image_handler sandbox_fit_handler = {
+	.name = "FIT image",
+	.bootm = do_bootm_sandbox_fit,
+	.filetype = filetype_oftree,
+};
+
+static int sandbox_fit_register(void)
+{
+	return register_image_handler(&sandbox_fit_handler);
+}
+late_initcall(sandbox_fit_register);
+#endif
+
diff --git a/include/image-fit.h b/include/image-fit.h
new file mode 100644
index 000000000000..bcbc859ead37
--- /dev/null
+++ b/include/image-fit.h
@@ -0,0 +1,42 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) Jan Lübbe, 2014
+ */
+
+#ifndef __IMAGE_FIT_H__
+#define __IMAGE_FIT_H__
+
+#include <linux/types.h>
+
+struct fit_handle {
+	void *fit;
+	size_t size;
+
+	bool verbose;
+
+	struct device_node *root;
+
+	const void *kernel;
+	unsigned long kernel_size;
+	const void *oftree;
+	unsigned long oftree_size;
+	const void *initrd;
+	unsigned long initrd_size;
+};
+
+struct fit_handle *fit_open(const char *filename, int num, bool verbose);
+void fit_close(struct fit_handle *handle);
+
+#endif	/* __IMAGE_FIT_H__ */
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [RFC 4/4] FIT: add test config and data [do not merge]
  2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
                   ` (2 preceding siblings ...)
  2015-03-12 14:39 ` [RFC 3/4] FIT: add FIT image support Jan Luebbe
@ 2015-03-12 14:39 ` Jan Luebbe
  2015-03-12 14:51 ` [RFC] digest: Add enum Jan Luebbe
  2015-11-11 11:39 ` [RFC 0/4] FIT Support Yegor Yefremov
  5 siblings, 0 replies; 59+ messages in thread
From: Jan Luebbe @ 2015-03-12 14:39 UTC (permalink / raw)
  To: barebox

Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
---
 arch/sandbox/configs/sandbox_defconfig |  33 +++++++++++++++++++++------------
 key.dtb                                | Bin 0 -> 1023 bytes
 key.dts                                |  27 +++++++++++++++++++++++++++
 sign-configs.itb                       | Bin 0 -> 2453 bytes
 4 files changed, 48 insertions(+), 12 deletions(-)
 create mode 100644 key.dtb
 create mode 100644 key.dts
 create mode 100644 sign-configs.itb

diff --git a/arch/sandbox/configs/sandbox_defconfig b/arch/sandbox/configs/sandbox_defconfig
index 7ce256950192..ec9d729127cb 100644
--- a/arch/sandbox/configs/sandbox_defconfig
+++ b/arch/sandbox/configs/sandbox_defconfig
@@ -5,25 +5,34 @@ CONFIG_PARTITION=y
 CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
 CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/sandbox/board/env"
 CONFIG_DEBUG_INFO=y
-CONFIG_CMD_EDIT=y
-CONFIG_CMD_SLEEP=y
-CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+CONFIG_CMD_BOOTM_FITIMAGE=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_PARTITION=y
 CONFIG_CMD_EXPORT=y
 CONFIG_CMD_PRINTENV=y
-CONFIG_CMD_READLINE=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
 CONFIG_CMD_TFTP=y
-CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_CRC=y
 CONFIG_CMD_FLASH=y
-# CONFIG_CMD_BOOTM is not set
-CONFIG_CMD_RESET=y
-CONFIG_CMD_GO=y
-CONFIG_CMD_TIMEOUT=y
-CONFIG_CMD_PARTITION=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
 CONFIG_NET=y
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_PING=y
 CONFIG_DRIVER_NET_TAP=y
 # CONFIG_SPI is not set
 CONFIG_FS_CRAMFS=y
 CONFIG_FS_TFTP=y
+CONFIG_DIGEST=y
diff --git a/key.dtb b/key.dtb
new file mode 100644
index 0000000000000000000000000000000000000000..9a3294e9f0b2ad30362127b9cc4e0d7e67d2f7b6
GIT binary patch
literal 1023
zcmcb>`|m9S1M`0d1_lctodcvbfLIWS1%Ma?CIiJyAWRgJ5z1o*(kxImNDRj32eOg*
z(nx$xAX~@HGejXIwYUVx1_6*hkiAApiAAYN`4u{8nI*a<2zkch%=Em(lG377kZPdW
z*{PMfDXC>3Hb^fo5Ze}KBpT`z6(<@Qm;n6)20%HmQ=PU1Z(bo{!?H7Tdz#ejmnRlI
z*Li3@Va_e-M)%VlOm~iQ_kP?u?UU4(@X|fcChNYldzd?OrF@m3aRtk)SzFdUW!+!?
zl-;3HSLVh<<+sd5o02*7=SzIKV|d40?ad2ceWi~DtZ5tFYN8q6C^<MSWBIrCh{QFH
z<~t|qZHnHpg+vMT7Kz<|8F1LSjOBJ)ZR)RsY<s!Zy<d9r{$t+BeG)#$+t@m%cJJJx
z_}*LU{(1{}GymD2jc0s$;lik<CTroiYs={yo;k|v3oi1ov<X&aZ#%rNLiDE`)6^N~
z)q|Nb?-ai;T)=uN?}Os3d3Hbc<+@sAs$6zFbLsfMM1hp~$t$yUop)(32ZjbLECOzJ
zyk9$KTknPl+iL5pC88Hp0~fF!l4webd1B%d{h)k7#oH58YEyH$%r}=S*E%vvzvEIl
zo8#>*V=*n`#cf5u&q5*JI&8RS8~vQaDY?4xN5_TL2G1AY%>Ee>H*s%{<MF%mn50ge
zlzndS;9cpeYajPaS{D-Wn~_7Q(#OzzTZ_bkXA8tl{pP>9v}P}Vb>2z!>x;GZbD5V!
zD@U%<UeYa@ZFr^U&+@lF<ZhHaekJf&_~z@YXFWbX=zPuc_U-ReDiPMtd|MvvXZ@qT
z@}vPP-_{1vJ0i(%TI?IwiiUrhx;>li-_^MM-&#?dBi{rqy}D%eiM)?zCY@t1nqDk*
zL~5!3yui7K?nA<Yfdfd#fKv%0N?OgV>}-1oRRc=f6%1gd@U-0uO?ON{IS^({&d4uL
z%>%Na{KTBh#NyOq7$2mDQ#mmur6{$yST{K}C#RS}xj3^b70S-cD@iRXDlI6{EdVC|
zyb^}o{FKxjhUEO*g2a-{q?}ZS#GLee24KS0Dbg)2ECnh`0rP<BN^?q!!R*wEg8V#?
nW{|Qx1KrHLvecsDR0y{;S2roMq?iGeY4Q?tQ*|?db}|3}pHW%$

literal 0
HcmV?d00001

diff --git a/key.dts b/key.dts
new file mode 100644
index 000000000000..c6f1e7cd4699
--- /dev/null
+++ b/key.dts
@@ -0,0 +1,27 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <0x1>;
+	#size-cells = <0x1>;
+	interrupt-parent = <0x1>;
+	model = "FIT Test";
+	compatible = "barebox,fit-test";
+
+	signature {
+		key-dev {
+			algo = "sha1,rsa2048";
+			rsa,r-squared = <0xb453b3a8 0x143c04b9 0x69b7661a 0x9be9c8a2 0xe72ce137 0x909cda1b 0x8147cb88 0x2dcc50b 0x8df1b596 0xf21af457 0x75bce693 0x2dee3ee1 0x6d99a91f 0x7a113378 0x49a9ab4 0xaee505bf 0x77e50740 0x792d1cd8 0x9123ed03 0x72b26308 0x2f9f18f4 0xdc31dc37 0x26ece84d 0x2f22f170 0x566b146 0x7c5b01ec 0x224042a6 0x4feadc4 0x18d60883 0xdcc87f3c 0x72ee0654 0x5a108d72 0x16dfe950 0xc3437604 0xdb867d65 0xfac106bd 0xaaeefa5 0xc9dfe30d 0x938e184c 0xc7860689 0x958bb9b4 0x21ef4b1a 0xdfaf381f 0x364f9bf3 0x3398f4e8 0x44012626 0x1d3841ba 0xb4cbd849 0x6c23af70 0xd10c0486 0x117a6bb6 0xc3be7815 0xf91e0295 0x98cf2753 0x269dc73 0xef71a005 0xca6ef021 0x9a9e3ef8 0xbe6d4538 0x6924d341 0xccd2c7fe 0x6110649f 0x63a96b2d 0x43ba2ba7>;
+			rsa,modulus = <0xd988efad 0x9cb68db0 0x583d7b3b 0xd57415d0 0x2551a005 0xc2188262 0x5ce4344c 0x5be077a0 0x78edc894 0x7d656d0a 0x37b37723 0x7d41011b 0xee0a24cd 0x6c4b4b1c 0x389668e8 0xdb214ef3 0x1254f688 0x3c0b9b32 0xf99c0919 0xab79f888 0xd0ab30e7 0xa3d96bf9 0x585e91bd 0x6c41c7dd 0x9e021ac8 0xc91de730 0xe0ee75aa 0xd6f1bc92 0xae5458fb 0x1082279 0x4c3137b6 0x8418a0e6 0xa017354e 0x9fecd2ac 0xbd0f7b6e 0xc927d7a3 0x2b2f6d03 0xa45b2359 0xaa2ba48b 0x196b31d4 0x8cfca7ed 0xf81ed874 0xe3ea10e3 0x13d9ebd5 0xcd48f1e0 0x89eb04ed 0xedfbca24 0x583be64d 0x84e2bf05 0xfc27a9c9 0x30050eb5 0x8015dc14 0x63ec843f 0x81ad1557 0xf295b76b 0x6fed55e 0x6ffb2a5a 0xb359ec52 0xa5d5a4ab 0xc86ef1cc 0x92ce0772 0x97731ac4 0x1aa54f9e 0x519dc2df>;
+			rsa,exponent = <0x0 0x10001>;
+			rsa,n0-inverse = <0x798986e1>;
+			rsa,num-bits = <0x800>;
+			key-name-hint = "dev";
+		};
+	};
+
+	chosen {
+	};
+
+	aliases {
+	};
+};
diff --git a/sign-configs.itb b/sign-configs.itb
new file mode 100644
index 0000000000000000000000000000000000000000..fd4c0c984102d384835d1eaf40cd27c542a5e71e
GIT binary patch
literal 2453
zcmeHHTWl0n7(QFKl~T3=TN(@+$C4@#hMiptw4^q)pwKi;C2eUR49)4z*`2YoGrMzU
zw=U7hi>4|NXu<<lf~GZc(T0l&4YY|=FqS~5LMX^3F$N-pOSEb*hT{Lvr52-!55}jS
z<eUF;{_|hYnUTQwZ9;Ol6GF-e$zB6=K42DLCIHt3(0jb2alSrRcm${)u&wds;T)hS
zhXG`zVj6KK)Hew2%+#4CsBs!&LWgQ8f}u0PFon2bGU3HljY6Adv~fJ-oJW5%02sq(
zA9FT+j;9qN(Br~b0$^@k`)a<ns;>N%nZMM&^+Uz-_0ku^r_ZE^8b+R(Q}p)0Vb?Yv
z?HwPjx}h0V1_dniGYwF}sV=t}uX;MHXQ8I*DO>YrZlboq@N6*GasX1V7nQ)HKTlo-
zyj_bzx#DJzdxe1Ru018qwLkjbnf^iVHwD|vwpMOBQ|F$|2HL<C>eZVCGQt;?Ew2ga
z2ki*gjSi%+P$vNXZC@}~A*xZURkncr$9`ZOQHSB75iGC17U2KO`s^Abh8|U8DU({N
zp*!=(c#i^P+;bb?o5bUOE<pR6dxEp%lltc4YD}kA%4CisJd1r82H--9I;?ddNP-Wi
zV~cPw=-ker<M<&d=nmUcPUQ4gg=hHLcYEEKc$X%>r(%#l4NIZY#UV+Qq$SIq6Jwze
zm1%i6yo839in3~28M5H0dmiifFy3zG1}xTr<00KoUg=NH>hqs!{HW{s#n}t1Y9MC*
zjJ%WT_cvNg>iY)|kBxqPfOJ;hPnl28UN(O9>{G{gHcY$xSa#E~b)jwN{8HYW>zj*D
zzQ0?V-k+)H8b7=B+F)riF}G@C?3Taa!fSz?BYM#y<?b6}t<{%rjeSy-dvwjYeY>By
z^X&Y==Bz8P*SsJ#Ukfm;I#m66bkFS4l`U60Yl`pPxxVgZkCZoRWj^kFH(B^?a((ZE
z<d&Dd+<0?n$H998(PI~r6$dUArb%D;#1UU-eoN2D??XHIf<C2x)6ZWO1U57s>dsld
zIcsNG&x%XG9&d|`)>STj@BFT&uE*yY^}n4+{zP}(=&jwq#pwkJ0JY!MB9qgwR9c43
zfrazN-gn3>?a6t-yb0qa&iqhqzd`RUBF&W<kC<u#Zz`EbW!Yq$ixH-2oXFIo#L6TX
zp=LxO1}70Co<IXMw*Ns)x6F*|UraO8-l1B|AP{##A+sn=X%l%kDP=^R#+j(7x<&9p
zi|*gjQsazUG@c-7s->8{$4uMU<Gnz5O_>bO8j2vUz%5hNW9}c>E_v!R)q$xF{4X8&
E1I{~<CjbBd

literal 0
HcmV?d00001

-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [RFC] digest: Add enum
  2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
                   ` (3 preceding siblings ...)
  2015-03-12 14:39 ` [RFC 4/4] FIT: add test config and data [do not merge] Jan Luebbe
@ 2015-03-12 14:51 ` Jan Luebbe
  2015-03-12 17:50   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-11-11 11:39 ` [RFC 0/4] FIT Support Yegor Yefremov
  5 siblings, 1 reply; 59+ messages in thread
From: Jan Luebbe @ 2015-03-12 14:51 UTC (permalink / raw)
  To: barebox

From: Sascha Hauer <s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

This is also needed as the first patch for the FIT support series. It seems
I can't count to 5.

 common/digest.c  | 12 ++++++++++++
 crypto/md5.c     |  1 +
 crypto/sha1.c    |  1 +
 crypto/sha2.c    |  2 ++
 include/digest.h | 24 ++++++++++++++++++++++++
 5 files changed, 40 insertions(+)

diff --git a/common/digest.c b/common/digest.c
index ae414ba5d599..51be2ca4148b 100644
--- a/common/digest.c
+++ b/common/digest.c
@@ -75,6 +75,18 @@ struct digest* digest_get_by_name(char* name)
 }
 EXPORT_SYMBOL_GPL(digest_get_by_name);
 
+struct digest *digest_get(enum hash_algo algo)
+{
+	struct digest* d;
+
+	list_for_each_entry(d, &digests, list)
+		if (d->algo == algo)
+			return d;
+	return NULL;
+
+}
+EXPORT_SYMBOL_GPL(digest_get);
+
 int digest_file_window(struct digest *d, char *filename,
 		       unsigned char *hash,
 		       ulong start, ulong size)
diff --git a/crypto/md5.c b/crypto/md5.c
index 6c4ca1dd59b8..87728338708e 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -305,6 +305,7 @@ static struct md5 m = {
 		.update = digest_md5_update,
 		.final = digest_md5_final,
 		.length = 16,
+		.algo = HASH_ALGO_MD5,
 	}
 };
 
diff --git a/crypto/sha1.c b/crypto/sha1.c
index 58d14a8b3f39..29fcdbae59a7 100644
--- a/crypto/sha1.c
+++ b/crypto/sha1.c
@@ -326,6 +326,7 @@ static struct sha1 m = {
 		.update = digest_sha1_update,
 		.final = digest_sha1_final,
 		.length = SHA1_SUM_LEN,
+		.algo = HASH_ALGO_SHA1,
 	}
 };
 
diff --git a/crypto/sha2.c b/crypto/sha2.c
index 00a1af3419c6..72d43015687c 100644
--- a/crypto/sha2.c
+++ b/crypto/sha2.c
@@ -316,6 +316,7 @@ static struct sha2 m224 = {
 		.update = digest_sha2_update,
 		.final = digest_sha2_final,
 		.length = SHA224_SUM_LEN,
+		.algo = HASH_ALGO_SHA224,
 	}
 };
 #endif
@@ -337,6 +338,7 @@ static struct sha2 m256 = {
 		.update = digest_sha2_update,
 		.final = digest_sha2_final,
 		.length = SHA256_SUM_LEN,
+		.algo = HASH_ALGO_SHA256,
 	}
 };
 #endif
diff --git a/include/digest.h b/include/digest.h
index 8563c10128fe..62f6248d0768 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -21,6 +21,27 @@
 
 #include <linux/list.h>
 
+enum hash_algo {
+	HASH_ALGO_MD4,
+	HASH_ALGO_MD5,
+	HASH_ALGO_SHA1,
+	HASH_ALGO_RIPE_MD_160,
+	HASH_ALGO_SHA256,
+	HASH_ALGO_SHA384,
+	HASH_ALGO_SHA512,
+	HASH_ALGO_SHA224,
+	HASH_ALGO_RIPE_MD_128,
+	HASH_ALGO_RIPE_MD_256,
+	HASH_ALGO_RIPE_MD_320,
+	HASH_ALGO_WP_256,
+	HASH_ALGO_WP_384,
+	HASH_ALGO_WP_512,
+	HASH_ALGO_TGR_128,
+	HASH_ALGO_TGR_160,
+	HASH_ALGO_TGR_192,
+	HASH_ALGO__LAST
+};
+
 struct digest
 {
 	char *name;
@@ -31,6 +52,8 @@ struct digest
 
 	unsigned int length;
 
+	enum hash_algo algo;
+
 	struct list_head list;
 };
 
@@ -41,6 +64,7 @@ int digest_register(struct digest *d);
 void digest_unregister(struct digest *d);
 
 struct digest* digest_get_by_name(char* name);
+struct digest *digest_get(enum hash_algo);
 
 int digest_file_window(struct digest *d, char *filename,
 		       unsigned char *hash,
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-12 14:39 ` [RFC 2/4] Add rsa support Jan Luebbe
@ 2015-03-12 17:47   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13  9:35     ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-12 17:47 UTC (permalink / raw)
  To: Jan Luebbe; +Cc: barebox

On 15:39 Thu 12 Mar     , Jan Luebbe wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  crypto/Kconfig              |   3 +
>  crypto/Makefile             |   1 +
>  crypto/rsa.c                | 411 ++++++++++++++++++++++++++++++++++++++++++++
>  include/asm-generic/errno.h |   5 +
>  include/rsa.h               |  54 ++++++
>  5 files changed, 474 insertions(+)
>  create mode 100644 crypto/rsa.c
>  create mode 100644 include/rsa.h

as state in my previous e-mail I will a keystore support

but this dt format to handle no please

we need to use the standard format as in the kernel or openssl

DER and x509

specially x509 as if we want to be able to add key at runtime we need to sign
them we the trusted RO keys

For the implementation of RSA I use the polarssl one and plan to add
the kernel one

and this implementation is limited to 4096 the polarssl one is not

Best Regards,
J.

> 
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index 4bd8dcf359f8..fa9ba491b79b 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -25,3 +25,6 @@ config SHA256
>  	bool "SHA256"
>  
>  endif
> +
> +config RSA
> +	bool
> diff --git a/crypto/Makefile b/crypto/Makefile
> index 7c5b035b73de..44be124aa368 100644
> --- a/crypto/Makefile
> +++ b/crypto/Makefile
> @@ -5,3 +5,4 @@ obj-$(CONFIG_MD5)	+= md5.o
>  obj-$(CONFIG_SHA1)	+= sha1.o
>  obj-$(CONFIG_SHA224)	+= sha2.o
>  obj-$(CONFIG_SHA256)	+= sha2.o
> +obj-$(CONFIG_RSA)	+= rsa.o
> diff --git a/crypto/rsa.c b/crypto/rsa.c
> new file mode 100644
> index 000000000000..6a0c7b8a15cc
> --- /dev/null
> +++ b/crypto/rsa.c
> @@ -0,0 +1,411 @@
> +/*
> + * Copyright (c) 2013, Google Inc.
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <malloc.h>
> +#include <of.h>
> +#include <digest.h>
> +#include <asm/types.h>
> +#include <asm/byteorder.h>
> +#include <errno.h>
> +#include <rsa.h>
> +#include <asm/types.h>
> +#include <asm/unaligned.h>
> +
> +#define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
> +
> +#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
> +#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
> +
> +/* Default public exponent for backward compatibility */
> +#define RSA_DEFAULT_PUBEXP	65537
> +
> +/* This is the minimum/maximum key size we support, in bits */
> +#define RSA_MIN_KEY_BITS	1024
> +#define RSA_MAX_KEY_BITS	4096
> +
> +/**
> + * subtract_modulus() - subtract modulus from the given value
> + *
> + * @key:	Key containing modulus to subtract
> + * @num:	Number to subtract modulus from, as little endian word array
> + */
> +static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
> +{
> +	int64_t acc = 0;
> +	uint i;
> +
> +	for (i = 0; i < key->len; i++) {
> +		acc += (uint64_t)num[i] - key->modulus[i];
> +		num[i] = (uint32_t)acc;
> +		acc >>= 32;
> +	}
> +}
> +
> +/**
> + * greater_equal_modulus() - check if a value is >= modulus
> + *
> + * @key:	Key containing modulus to check
> + * @num:	Number to check against modulus, as little endian word array
> + * @return 0 if num < modulus, 1 if num >= modulus
> + */
> +static int greater_equal_modulus(const struct rsa_public_key *key,
> +				 uint32_t num[])
> +{
> +	int i;
> +
> +	for (i = (int)key->len - 1; i >= 0; i--) {
> +		if (num[i] < key->modulus[i])
> +			return 0;
> +		if (num[i] > key->modulus[i])
> +			return 1;
> +	}
> +
> +	return 1;  /* equal */
> +}
> +
> +/**
> + * montgomery_mul_add_step() - Perform montgomery multiply-add step
> + *
> + * Operation: montgomery result[] += a * b[] / n0inv % modulus
> + *
> + * @key:	RSA key
> + * @result:	Place to put result, as little endian word array
> + * @a:		Multiplier
> + * @b:		Multiplicand, as little endian word array
> + */
> +static void montgomery_mul_add_step(const struct rsa_public_key *key,
> +		uint32_t result[], const uint32_t a, const uint32_t b[])
> +{
> +	uint64_t acc_a, acc_b;
> +	uint32_t d0;
> +	uint i;
> +
> +	acc_a = (uint64_t)a * b[0] + result[0];
> +	d0 = (uint32_t)acc_a * key->n0inv;
> +	acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
> +	for (i = 1; i < key->len; i++) {
> +		acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
> +		acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
> +				(uint32_t)acc_a;
> +		result[i - 1] = (uint32_t)acc_b;
> +	}
> +
> +	acc_a = (acc_a >> 32) + (acc_b >> 32);
> +
> +	result[i - 1] = (uint32_t)acc_a;
> +
> +	if (acc_a >> 32)
> +		subtract_modulus(key, result);
> +}
> +
> +/**
> + * montgomery_mul() - Perform montgomery mutitply
> + *
> + * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
> + *
> + * @key:	RSA key
> + * @result:	Place to put result, as little endian word array
> + * @a:		Multiplier, as little endian word array
> + * @b:		Multiplicand, as little endian word array
> + */
> +static void montgomery_mul(const struct rsa_public_key *key,
> +		uint32_t result[], uint32_t a[], const uint32_t b[])
> +{
> +	uint i;
> +
> +	for (i = 0; i < key->len; ++i)
> +		result[i] = 0;
> +	for (i = 0; i < key->len; ++i)
> +		montgomery_mul_add_step(key, result, a[i], b);
> +}
> +
> +/**
> + * num_pub_exponent_bits() - Number of bits in the public exponent
> + *
> + * @key:	RSA key
> + * @num_bits:	Storage for the number of public exponent bits
> + */
> +static int num_public_exponent_bits(const struct rsa_public_key *key,
> +		int *num_bits)
> +{
> +	uint64_t exponent;
> +	int exponent_bits;
> +	const uint max_bits = (sizeof(exponent) * 8);
> +
> +	exponent = key->exponent;
> +	exponent_bits = 0;
> +
> +	if (!exponent) {
> +		*num_bits = exponent_bits;
> +		return 0;
> +	}
> +
> +	for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits)
> +		if (!(exponent >>= 1)) {
> +			*num_bits = exponent_bits;
> +			return 0;
> +		}
> +
> +	return -EINVAL;
> +}
> +
> +/**
> + * is_public_exponent_bit_set() - Check if a bit in the public exponent is set
> + *
> + * @key:	RSA key
> + * @pos:	The bit position to check
> + */
> +static int is_public_exponent_bit_set(const struct rsa_public_key *key,
> +		int pos)
> +{
> +	return key->exponent & (1ULL << pos);
> +}
> +
> +/**
> + * pow_mod() - in-place public exponentiation
> + *
> + * @key:	RSA key
> + * @inout:	Big-endian word array containing value and result
> + */
> +static int pow_mod(const struct rsa_public_key *key, void *__inout)
> +{
> +	uint32_t *inout = __inout;
> +	uint32_t *result, *ptr;
> +	uint i;
> +	int j, k;
> +	uint32_t val[RSA_MAX_KEY_BITS / 32], acc[RSA_MAX_KEY_BITS / 32], tmp[RSA_MAX_KEY_BITS / 32];
> +	uint32_t a_scaled[RSA_MAX_KEY_BITS / 32];
> +
> +	/* Sanity check for stack size - key->len is in 32-bit words */
> +	if (key->len > RSA_MAX_KEY_BITS / 32) {
> +		debug("RSA key words %u exceeds maximum %d\n", key->len,
> +		      RSA_MAX_KEY_BITS / 32);
> +		return -EINVAL;
> +	}
> +
> +	result = tmp;  /* Re-use location. */
> +
> +	/* Convert from big endian byte array to little endian word array. */
> +	for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--)
> +		val[i] = get_unaligned_be32(ptr);
> +
> +	if (0 != num_public_exponent_bits(key, &k))
> +		return -EINVAL;
> +
> +	if (k < 2) {
> +		debug("Public exponent is too short (%d bits, minimum 2)\n",
> +		      k);
> +		return -EINVAL;
> +	}
> +
> +	if (!is_public_exponent_bit_set(key, 0)) {
> +		debug("LSB of RSA public exponent must be set.\n");
> +		return -EINVAL;
> +	}
> +
> +	/* the bit at e[k-1] is 1 by definition, so start with: C := M */
> +	montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */
> +	/* retain scaled version for intermediate use */
> +	memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0]));
> +
> +	for (j = k - 2; j > 0; --j) {
> +		montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
> +
> +		if (is_public_exponent_bit_set(key, j)) {
> +			/* acc = tmp * val / R mod n */
> +			montgomery_mul(key, acc, tmp, a_scaled);
> +		} else {
> +			/* e[j] == 0, copy tmp back to acc for next operation */
> +			memcpy(acc, tmp, key->len * sizeof(acc[0]));
> +		}
> +	}
> +
> +	/* the bit at e[0] is always 1 */
> +	montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
> +	montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */
> +	memcpy(result, acc, key->len * sizeof(result[0]));
> +
> +	/* Make sure result < mod; result is at most 1x mod too large. */
> +	if (greater_equal_modulus(key, result))
> +		subtract_modulus(key, result);
> +
> +	/* Convert to bigendian byte array */
> +	for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
> +		put_unaligned_be32(result[i], ptr);
> +	return 0;
> +}
> +
> +/*
> + * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
> + */
> +static const u8 RSA_digest_info_MD5[] = {
> +	0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
> +	0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */
> +	0x05, 0x00, 0x04, 0x10
> +};
> +
> +static const u8 RSA_digest_info_SHA1[] = {
> +	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
> +	0x2B, 0x0E, 0x03, 0x02, 0x1A,
> +	0x05, 0x00, 0x04, 0x14
> +};
> +
> +static const u8 RSA_digest_info_RIPE_MD_160[] = {
> +	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
> +	0x2B, 0x24, 0x03, 0x02, 0x01,
> +	0x05, 0x00, 0x04, 0x14
> +};
> +
> +static const u8 RSA_digest_info_SHA224[] = {
> +	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
> +	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
> +	0x05, 0x00, 0x04, 0x1C
> +};
> +
> +static const u8 RSA_digest_info_SHA256[] = {
> +	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
> +	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
> +	0x05, 0x00, 0x04, 0x20
> +};
> +
> +static const u8 RSA_digest_info_SHA384[] = {
> +	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
> +	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
> +	0x05, 0x00, 0x04, 0x30
> +};
> +
> +static const u8 RSA_digest_info_SHA512[] = {
> +	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
> +	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
> +	0x05, 0x00, 0x04, 0x40
> +};
> +
> +static const struct {
> +	const u8 *data;
> +	size_t size;
> +} RSA_ASN1_templates[] = {
> +#define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) }
> +	[HASH_ALGO_MD5]		= _(MD5),
> +	[HASH_ALGO_SHA1]	= _(SHA1),
> +	[HASH_ALGO_RIPE_MD_160]	= _(RIPE_MD_160),
> +	[HASH_ALGO_SHA256]	= _(SHA256),
> +	[HASH_ALGO_SHA384]	= _(SHA384),
> +	[HASH_ALGO_SHA512]	= _(SHA512),
> +	[HASH_ALGO_SHA224]	= _(SHA224),
> +#undef _
> +};
> +
> +int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,
> +			  const uint32_t sig_len, const uint8_t *hash,
> +			  enum hash_algo algo)
> +{
> +	int ret;
> +	uint8_t buf[RSA_MAX_SIG_BITS / 8];
> +	int i;
> +	unsigned PS_end, T_offset;
> +	const u8 *asn1_template = RSA_ASN1_templates[algo].data;
> +	size_t asn1_size = RSA_ASN1_templates[algo].size;
> +	struct digest *d = digest_get(algo);
> +
> +	if (!d)
> +		return -EOPNOTSUPP;
> +
> +	if (sig_len != (key->len * sizeof(uint32_t))) {
> +		debug("Signature is of incorrect length %d, should be %d\n", sig_len,
> +				key->len * sizeof(uint32_t));
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check for stack size */
> +	if (sig_len > RSA_MAX_SIG_BITS / 8) {
> +		debug("Signature length %u exceeds maximum %d\n", sig_len,
> +		      RSA_MAX_SIG_BITS / 8);
> +		return -EINVAL;
> +	}
> +
> +	memcpy(buf, sig, sig_len);
> +
> +	ret = pow_mod(key, buf);
> +	if (ret)
> +		return ret;
> +
> +	T_offset = sig_len - (asn1_size + d->length);
> +
> +	PS_end = T_offset - 1;
> +	if (buf[PS_end] != 0x00) {
> +		pr_err(" = -EBADMSG [EM[T-1] == %02u]", buf[PS_end]);
> +		return -EBADMSG;
> +	}
> +
> +	for (i = 2; i < PS_end; i++) {
> +		if (buf[i] != 0xff) {
> +			pr_err(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, buf[i]);
> +			return -EBADMSG;
> +		}
> +	}
> +
> +	if (memcmp(asn1_template, buf + T_offset, asn1_size) != 0) {
> +		pr_err(" = -EBADMSG [EM[T] ASN.1 mismatch]");
> +		return -EBADMSG;
> +	}
> +
> +	if (memcmp(hash, buf + T_offset + asn1_size, d->length) != 0) {
> +		pr_err(" = -EKEYREJECTED [EM[T] hash mismatch]");
> +		return -EKEYREJECTED;
> +	}
> +
> +	return 0;
> +}
> +
> +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]);
> +}
> +
> +int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key)
> +{
> +	const void *modulus, *rr;
> +	const uint64_t *public_exponent;
> +	int length;
> +
> +	of_property_read_u32(node, "rsa,num-bits", &key->len);
> +	of_property_read_u32(node, "rsa,n0-inverse", &key->n0inv);
> +
> +	public_exponent = of_get_property(node, "rsa,exponent", &length);
> +	if (!public_exponent || length < sizeof(*public_exponent))
> +		key->exponent = RSA_DEFAULT_PUBEXP;
> +	else
> +		key->exponent = fdt64_to_cpu(*public_exponent);
> +
> +	modulus = of_get_property(node, "rsa,modulus", NULL);
> +	rr = of_get_property(node, "rsa,r-squared", NULL);
> +
> +	if (!key->len || !modulus || !rr) {
> +		debug("%s: Missing RSA key info", __func__);
> +		return -EFAULT;
> +	}
> +
> +	/* Sanity check for stack size */
> +	if (key->len > RSA_MAX_KEY_BITS || key->len < RSA_MIN_KEY_BITS) {
> +		debug("RSA key bits %u outside allowed range %d..%d\n",
> +		      key->len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
> +		return -EFAULT;
> +	}
> +
> +	key->len /= sizeof(uint32_t) * 8;
> +
> +	key->modulus = xzalloc(RSA_MAX_KEY_BITS / 8);
> +	key->rr = xzalloc(RSA_MAX_KEY_BITS / 8);
> +
> +	rsa_convert_big_endian(key->modulus, modulus, key->len);
> +	rsa_convert_big_endian(key->rr, rr, key->len);
> +
> +	return 0;
> +}
> diff --git a/include/asm-generic/errno.h b/include/asm-generic/errno.h
> index bbf493c373ae..b239831bc703 100644
> --- a/include/asm-generic/errno.h
> +++ b/include/asm-generic/errno.h
> @@ -126,6 +126,11 @@
>  
>  #define	ENOMEDIUM	123	/* No medium found */
>  #define	EMEDIUMTYPE	124	/* Wrong medium type */
> +#define	ECANCELED	125	/* Operation Canceled */
> +#define	ENOKEY		126	/* Required key not available */
> +#define	EKEYEXPIRED	127	/* Key has expired */
> +#define	EKEYREVOKED	128	/* Key has been revoked */
> +#define	EKEYREJECTED	129	/* Key was rejected by service */
>  
>  /* Should never be seen by user programs */
>  #define ERESTARTSYS	512
> diff --git a/include/rsa.h b/include/rsa.h
> new file mode 100644
> index 000000000000..feb8c3120023
> --- /dev/null
> +++ b/include/rsa.h
> @@ -0,0 +1,54 @@
> +/*
> + * Copyright (c) 2013, Google Inc.
> + *
> + * (C) Copyright 2008 Semihalf
> + *
> + * (C) Copyright 2000-2006
> + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#ifndef _RSA_H
> +#define _RSA_H
> +
> +#include <errno.h>
> +#include <digest.h>
> +
> +/**
> + * struct rsa_public_key - holder for a public key
> + *
> + * An RSA public key consists of a modulus (typically called N), the inverse
> + * and R^2, where R is 2^(# key bits).
> + */
> +
> +struct rsa_public_key {
> +	uint len;		/* len of modulus[] in number of uint32_t */
> +	uint32_t n0inv;		/* -1 / modulus[0] mod 2^32 */
> +	uint32_t *modulus;	/* modulus as little endian array */
> +	uint32_t *rr;		/* R^2 as little endian array */
> +	uint64_t exponent;	/* public exponent */
> +};
> +
> +/**
> + * 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 rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,
> +			  const uint32_t sig_len, const uint8_t *hash,
> +			  enum hash_algo algo);
> +
> +/* This is the maximum signature length that we support, in bits */
> +#define RSA_MAX_SIG_BITS	4096
> +
> +int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key);
> +
> +#endif
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC] digest: Add enum
  2015-03-12 14:51 ` [RFC] digest: Add enum Jan Luebbe
@ 2015-03-12 17:50   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13  9:54     ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-12 17:50 UTC (permalink / raw)
  To: Jan Luebbe; +Cc: barebox

On 15:51 Thu 12 Mar     , Jan Luebbe wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> 
> This is also needed as the first patch for the FIT support series. It seems
> I can't count to 5.
> 
>  common/digest.c  | 12 ++++++++++++
>  crypto/md5.c     |  1 +
>  crypto/sha1.c    |  1 +
>  crypto/sha2.c    |  2 ++
>  include/digest.h | 24 ++++++++++++++++++++++++

do as in the kernel use the string as we may want to add hw IP

Best Regadrs,
J.
>  5 files changed, 40 insertions(+)
> 
> diff --git a/common/digest.c b/common/digest.c
> index ae414ba5d599..51be2ca4148b 100644
> --- a/common/digest.c
> +++ b/common/digest.c
> @@ -75,6 +75,18 @@ struct digest* digest_get_by_name(char* name)
>  }
>  EXPORT_SYMBOL_GPL(digest_get_by_name);
>  
> +struct digest *digest_get(enum hash_algo algo)
> +{
> +	struct digest* d;
> +
> +	list_for_each_entry(d, &digests, list)
> +		if (d->algo == algo)
> +			return d;
> +	return NULL;
> +
> +}
> +EXPORT_SYMBOL_GPL(digest_get);
> +
>  int digest_file_window(struct digest *d, char *filename,
>  		       unsigned char *hash,
>  		       ulong start, ulong size)
> diff --git a/crypto/md5.c b/crypto/md5.c
> index 6c4ca1dd59b8..87728338708e 100644
> --- a/crypto/md5.c
> +++ b/crypto/md5.c
> @@ -305,6 +305,7 @@ static struct md5 m = {
>  		.update = digest_md5_update,
>  		.final = digest_md5_final,
>  		.length = 16,
> +		.algo = HASH_ALGO_MD5,
>  	}
>  };
>  
> diff --git a/crypto/sha1.c b/crypto/sha1.c
> index 58d14a8b3f39..29fcdbae59a7 100644
> --- a/crypto/sha1.c
> +++ b/crypto/sha1.c
> @@ -326,6 +326,7 @@ static struct sha1 m = {
>  		.update = digest_sha1_update,
>  		.final = digest_sha1_final,
>  		.length = SHA1_SUM_LEN,
> +		.algo = HASH_ALGO_SHA1,
>  	}
>  };
>  
> diff --git a/crypto/sha2.c b/crypto/sha2.c
> index 00a1af3419c6..72d43015687c 100644
> --- a/crypto/sha2.c
> +++ b/crypto/sha2.c
> @@ -316,6 +316,7 @@ static struct sha2 m224 = {
>  		.update = digest_sha2_update,
>  		.final = digest_sha2_final,
>  		.length = SHA224_SUM_LEN,
> +		.algo = HASH_ALGO_SHA224,
>  	}
>  };
>  #endif
> @@ -337,6 +338,7 @@ static struct sha2 m256 = {
>  		.update = digest_sha2_update,
>  		.final = digest_sha2_final,
>  		.length = SHA256_SUM_LEN,
> +		.algo = HASH_ALGO_SHA256,
>  	}
>  };
>  #endif
> diff --git a/include/digest.h b/include/digest.h
> index 8563c10128fe..62f6248d0768 100644
> --- a/include/digest.h
> +++ b/include/digest.h
> @@ -21,6 +21,27 @@
>  
>  #include <linux/list.h>
>  
> +enum hash_algo {
> +	HASH_ALGO_MD4,
> +	HASH_ALGO_MD5,
> +	HASH_ALGO_SHA1,
> +	HASH_ALGO_RIPE_MD_160,
> +	HASH_ALGO_SHA256,
> +	HASH_ALGO_SHA384,
> +	HASH_ALGO_SHA512,
> +	HASH_ALGO_SHA224,
> +	HASH_ALGO_RIPE_MD_128,
> +	HASH_ALGO_RIPE_MD_256,
> +	HASH_ALGO_RIPE_MD_320,
> +	HASH_ALGO_WP_256,
> +	HASH_ALGO_WP_384,
> +	HASH_ALGO_WP_512,
> +	HASH_ALGO_TGR_128,
> +	HASH_ALGO_TGR_160,
> +	HASH_ALGO_TGR_192,
> +	HASH_ALGO__LAST
> +};
> +
>  struct digest
>  {
>  	char *name;
> @@ -31,6 +52,8 @@ struct digest
>  
>  	unsigned int length;
>  
> +	enum hash_algo algo;
> +
>  	struct list_head list;
>  };
>  
> @@ -41,6 +64,7 @@ int digest_register(struct digest *d);
>  void digest_unregister(struct digest *d);
>  
>  struct digest* digest_get_by_name(char* name);
> +struct digest *digest_get(enum hash_algo);
>  
>  int digest_file_window(struct digest *d, char *filename,
>  		       unsigned char *hash,
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-12 14:39 ` [RFC 3/4] FIT: add FIT image support Jan Luebbe
@ 2015-03-12 18:19   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13  9:28     ` Jan Lübbe
  2015-12-29 10:18   ` Yegor Yefremov
  1 sibling, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-12 18:19 UTC (permalink / raw)
  To: Jan Luebbe; +Cc: barebox

On 15:39 Thu 12 Mar     , Jan Luebbe wrote:
> The FIT image format was defined for U-Boot and has been adopted by the
> depthcharge project as well. It is intended to be a replacement for the
> uimage format and has been extended to support signing of kernel,
> initramfs and devicetree images. This patch adds support for booting FIT
> images to barebox.
> 
> To verify signed images, the RSA public key data must be available in
> the internal device tree. Currently only signature verification on
> configurations (which contains hashes of all referenced images) are
> implemented, as this is the most useful use case and reduces the
> complexity of the implementation.
> 
> The host tool (mkimage) to sign images has not yet been imported from U-Boot.
> 
> Signed-off-by: Jan Luebbe <jlu@pengutronix.de>

please do not send a new version except for fix

I'm going to re-integrate it with the keystore & co

and sha1,rsa2048 is considered weak in term of security
and worse md4/md5

for barebox I would only use
at least sha256 with rs2048 or sha512 with rsa4096

and as soon as SHA-2 is ready we should take a look to switch to it instead of
SHA-1(this is all the curreent shaxxx of today)

cf FIPS specs
> ---
>  arch/arm/lib/bootm.c |  74 +++++++
>  commands/Kconfig     |   8 +
>  common/Kconfig       |   7 +
>  common/Makefile      |   1 +
>  common/image-fit.c   | 585 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/image-fit.h  |  42 ++++
>  6 files changed, 717 insertions(+)
>  create mode 100644 common/image-fit.c
>  create mode 100644 include/image-fit.h
> 
> diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
> index 8327c3f5603a..6d30c594bdc2 100644
> --- a/arch/arm/lib/bootm.c
> +++ b/arch/arm/lib/bootm.c
> @@ -552,6 +552,78 @@ BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs
>  BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage");
>  #endif
>  
> +#include <image-fit.h>
> +
> +static int do_bootm_arm_fit(struct image_data *data)
> +{
> +	struct fit_handle *handle;
> +	int ret;
> +	unsigned long mem_free;
> +	unsigned long mem_start, mem_size;
> +
> +	handle = fit_open(data->os_file, data->os_num, data->verbose);
> +	if (!handle)
> +		return -EINVAL;
> +
> +	ret = sdram_start_and_size(&mem_start, &mem_size);
> +	if (ret)
> +		return ret;
> +
> +	/* no support for custom load address */
> +	data->os_address = mem_start + PAGE_ALIGN(handle->kernel_size * 4);
> +	data->os_res = request_sdram_region("fit-kernel", data->os_address, handle->kernel_size);
> +	if (!data->os_res) {
> +		pr_err("Cannot request region 0x%08lx - 0x%08lx\n",
> +				data->os_address, handle->kernel_size);
> +		ret = -ENOMEM;
> +		goto err_out;
> +	}
> +	memcpy((void *)data->os_res->start, handle->kernel, handle->kernel_size);
> +
> +	/*
> +	 * Put oftree/initrd close behind compressed kernel image to avoid
> +	 * placing it outside of the kernels lowmem.
> +	 */
> +	if (handle->initrd_size) {
> +		data->initrd_address = PAGE_ALIGN(data->os_res->end + SZ_1M);
> +		data->initrd_res = request_sdram_region("fit-initrd", data->initrd_address, handle->initrd_size);
> +		if (!data->initrd_res) {
> +			ret = -ENOMEM;
> +			goto err_out;
> +		}
> +		memcpy((void *)data->initrd_res->start, handle->initrd, handle->initrd_size);
> +	}
> +
> +	data->of_root_node = of_unflatten_dtb(handle->oftree);
> +	if (!data->of_root_node) {
> +		pr_err("unable to unflatten devicetree\n");
> +		ret = -EINVAL;
> +		goto err_out;
> +	}
> +
> +	/*
> +	 * Put devicetree right after initrd if present or after the kernel
> +	 * if not.
> +	 */
> +	if (data->initrd_res)
> +		mem_free = PAGE_ALIGN(data->initrd_res->end);
> +	else
> +		mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M);
> +
> +	return __do_bootm_linux(data, mem_free, 0);
> +
> +err_out:
> +	if (handle)
> +		fit_close(handle);
> +	return ret;
> +}
> +
> +static struct image_handler arm_fit_handler = {
> +        .name = "FIT image",
> +        .bootm = do_bootm_arm_fit,
> +        .filetype = filetype_oftree,
> +};
> +
>  static struct binfmt_hook binfmt_aimage_hook = {
>  	.type = filetype_aimage,
>  	.exec = "bootm",
> @@ -577,6 +649,8 @@ static int armlinux_register_image_handler(void)
>  		register_image_handler(&aimage_handler);
>  		binfmt_register(&binfmt_aimage_hook);
>  	}
> +	if (IS_BUILTIN(CONFIG_CMD_BOOTM_FITIMAGE))
> +	        register_image_handler(&arm_fit_handler);
>  	binfmt_register(&binfmt_arm_zimage_hook);
>  	binfmt_register(&binfmt_barebox_hook);
>  
> diff --git a/commands/Kconfig b/commands/Kconfig
> index e4f68e7bda31..8d8fd46c15ec 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -402,6 +402,14 @@ config CMD_BOOTM_AIMAGE
>  	help
>  	  Support using Android Images.
>  
> +config CMD_BOOTM_FITIMAGE
> +	bool
> +	prompt "FIT image support"
> +	select FITIMAGE
> +	depends on CMD_BOOTM && (ARM || SANDBOX)
> +	help
> +	  Support using FIT Images.
> +
>  config CMD_BOOTU
>  	tristate
>  	default y
> diff --git a/common/Kconfig b/common/Kconfig
> index d4373431aae8..9dd0b65ef8ae 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -66,6 +66,13 @@ config UIMAGE
>  	select CRC32
>  	bool
>  
> +config FITIMAGE
> +	bool
> +	select OFTREE
> +	select SHA1
> +	select SHA256
> +	select RSA
> +
>  config LOGBUF
>  	bool
>  
> diff --git a/common/Makefile b/common/Makefile
> index ee5dca70236e..a8008292f0d8 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_RESET_SOURCE)	+= reset_source.o
>  obj-$(CONFIG_SHELL_HUSH)	+= hush.o
>  obj-$(CONFIG_SHELL_SIMPLE)	+= parser.o
>  obj-$(CONFIG_UIMAGE)		+= image.o uimage.o
> +obj-$(CONFIG_FITIMAGE)		+= image-fit.o
>  obj-$(CONFIG_MENUTREE)		+= menutree.o
>  obj-$(CONFIG_EFI_GUID)		+= efi-guid.o
>  obj-$(CONFIG_EFI_DEVICEPATH)	+= efi-devicepath.o
> diff --git a/common/image-fit.c b/common/image-fit.c
> new file mode 100644
> index 000000000000..77df5e5f4205
> --- /dev/null
> +++ b/common/image-fit.c
> @@ -0,0 +1,585 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> + *
> + * Copyright (C) Jan Lübbe, 2014
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <boot.h>
> +#include <libfile.h>
> +#include <fdt.h>
> +#include <digest.h>
> +#include <of.h>
> +#include <fs.h>
> +#include <malloc.h>
> +#include <linux/ctype.h>
> +#include <asm/byteorder.h>
> +#include <errno.h>
> +#include <linux/err.h>
> +#include <stringlist.h>
> +#include <rsa.h>
> +#include <image-fit.h>
> +
> +#define FDT_MAX_DEPTH	32
> +#define FDT_MAX_PATH_LEN 200
> +
> +#define CHECK_LEVEL_NONE 0
> +#define CHECK_LEVEL_HASH 1
> +#define CHECK_LEVEL_SIG 2
> +#define CHECK_LEVEL_MAX 3
> +
> +static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int size)
> +{
> +	dt += size;
> +	dt = ALIGN(dt, 4);
> +
> +	if (dt > f->off_dt_struct + f->size_dt_struct)
> +		return 0;
> +
> +	return dt;
> +}
> +
> +static char *dt_string(struct fdt_header *f, char *strstart, uint32_t ofs)
> +{
> +	if (ofs > f->size_dt_strings)
> +		return NULL;
> +	else
> +		return strstart + ofs;
> +}
> +
> +static int of_read_string_list(struct device_node *np, const char *name, struct string_list *sl)
> +{
> +	struct property *prop;
> +	const char *s;
> +
> +	of_property_for_each_string(np, name, prop, s) {
> +		string_list_add(sl, s);
> +	}
> +
> +	return prop ? 0 : -EINVAL;
> +}
> +
> +static int fit_digest(void *fit, struct digest *digest,
> +		struct string_list *inc_nodes, struct string_list *exc_props,
> +		uint32_t hashed_strings_start, uint32_t hashed_strings_size)
> +{
> +	struct fdt_header *fdt = fit;
> +	uint32_t dt_struct;
> +	void *dt_strings;
> +	struct fdt_header f;
> +	int stack[FDT_MAX_DEPTH];
> +	char path[FDT_MAX_PATH_LEN];
> +	char *end;
> +	uint32_t tag;
> +	int start = -1;
> +	int depth = -1;
> +	int want = 0;
> +
> +	f.totalsize = fdt32_to_cpu(fdt->totalsize);
> +	f.off_dt_struct = fdt32_to_cpu(fdt->off_dt_struct);
> +	f.size_dt_struct = fdt32_to_cpu(fdt->size_dt_struct);
> +	f.off_dt_strings = fdt32_to_cpu(fdt->off_dt_strings);
> +	f.size_dt_strings = fdt32_to_cpu(fdt->size_dt_strings);
> +
> +	if (hashed_strings_start > f.size_dt_strings ||
> +	    hashed_strings_size > f.size_dt_strings ||
> +	    hashed_strings_start + hashed_strings_size > f.size_dt_strings) {
> +		pr_err("%s: hashed-strings too large\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	dt_struct = f.off_dt_struct;
> +	dt_strings = (void *)fdt + f.off_dt_strings;
> +
> +	end = path;
> +	*end = '\0';
> +
> +	do {
> +		const struct fdt_property *fdt_prop;
> +		const struct fdt_node_header *fnh;
> +		const char *name;
> +		int include = 0;
> +		int stop_at = 0;
> +		int offset = dt_struct;
> +		int maxlen, len;
> +
> +		tag = be32_to_cpu(*(uint32_t *)(fit + dt_struct));
> +
> +		switch (tag) {
> +		case FDT_BEGIN_NODE:
> +			fnh = fit + dt_struct;
> +			name = fnh->name;
> +			maxlen = (unsigned long)fdt + f.off_dt_struct +
> +				f.size_dt_struct - (unsigned long)name;
> +
> +			len = strnlen(name, maxlen + 1);
> +			if (len > maxlen)
> +				return -ESPIPE;
> +
> +			dt_struct = dt_struct_advance(&f, dt_struct,
> +					sizeof(struct fdt_node_header) + len + 1);
> +
> +			depth++;
> +			if (depth == FDT_MAX_DEPTH)
> +				return -ESPIPE;
> +			if (end - path + 2 + len >= FDT_MAX_PATH_LEN)
> +				return -ESPIPE;
> +			if (end != path + 1)
> +				*end++ = '/';
> +			strcpy(end, name);
> +			end += len;
> +			stack[depth] = want;
> +			if (want == 1)
> +				stop_at = offset;
> +			if (string_list_contains(inc_nodes, path))
> +				want = 2;
> +			else if (want)
> +				want--;
> +			else
> +				stop_at = offset;
> +			include = want;
> +
> +			break;
> +
> +		case FDT_END_NODE:
> +			dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
> +
> +			include = want;
> +			want = stack[depth--];
> +			while (end > path && *--end != '/')
> +				;
> +			*end = '\0';
> +
> +			break;
> +
> +		case FDT_PROP:
> +			fdt_prop = fit + dt_struct;
> +			len = fdt32_to_cpu(fdt_prop->len);
> +
> +			name = dt_string(&f, dt_strings, fdt32_to_cpu(fdt_prop->nameoff));
> +			if (!name)
> +				return -ESPIPE;
> +
> +			dt_struct = dt_struct_advance(&f, dt_struct,
> +					sizeof(struct fdt_property) + len);
> +
> +			include = want >= 2;
> +			stop_at = offset;
> +			if (string_list_contains(exc_props, name))
> +				include = 0;
> +
> +			break;
> +
> +		case FDT_NOP:
> +			dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
> +
> +			include = want >= 2;
> +			stop_at = offset;
> +
> +			break;
> +
> +		case FDT_END:
> +			dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
> +
> +			include = 1;
> +
> +			break;
> +
> +		default:
> +			pr_err("%s: Unknown tag 0x%08X\n", __func__, tag);
> +			return -EINVAL;
> +		}
> +
> +		if (!dt_struct)
> +			return -ESPIPE;
> +
> +		pr_debug("%s: include %d, want %d, offset 0x%x, len 0x%x\n",
> +			path, include, want, offset, dt_struct-offset);
> +
> +		if (include && start == -1)
> +			start = offset;
> +
> +		if (!include && start != -1) {
> +			pr_debug("region: 0x%p+0x%x\n", fit+start, offset-start);
> +			digest->update(digest, fit+start, offset-start);
> +			start = -1;
> +		}
> +	} while (tag != FDT_END);
> +
> +	pr_debug("region: 0x%p+0x%x\n", fit+start, dt_struct-start);
> +	digest->update(digest, fit+start, dt_struct-start);
> +
> +	pr_debug("strings: 0x%p+0x%x\n", dt_strings+hashed_strings_start, hashed_strings_size);
> +	digest->update(digest, dt_strings+hashed_strings_start, hashed_strings_size);
> +
> +	return 0;
> +}
> +
> +/*
> + * The consistency of the FTD structure was already checked by of_unflatten_dtb()
> + */
> +static int fit_verify_signature(struct device_node *sig_node, void *fit)
> +{
> +	uint32_t hashed_strings_start, hashed_strings_size;
> +	struct string_list inc_nodes, exc_props;
> +	struct rsa_public_key key = {};
> +	struct digest *digest;
> +	int sig_len;
> +	const char *algo_name, *key_name, *sig_value;
> +	char *key_path;
> +	struct device_node *key_node;
> +	enum hash_algo algo;
> +	void *hash;
> +	int ret;
> +
> +	if (of_property_read_string(sig_node, "algo", &algo_name)) {
> +		pr_err("algo not found\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +	if (strcmp(algo_name, "sha1,rsa2048") == 0) {
> +		algo = HASH_ALGO_SHA1;
we need to parse this to call "rsa(sha1)"

when you request to checkit against the availlable keys
we will pass the keysize 2048 but the digest_algo will not care
about the keysize except at run time

> +	} else {
> +		pr_err("unknown algo %s\n", algo_name);
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +	digest = digest_get(algo);
> +	if (!digest) {
> +		pr_err("unsupported algo %s\n", algo_name);
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	sig_value = of_get_property(sig_node, "value", &sig_len);
> +	if (!sig_value) {
> +		pr_err("signature value not found\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	if (of_property_read_string(sig_node, "key-name-hint", &key_name)) {
> +		pr_err("key name not found\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +	key_path = asprintf("/signature/key-%s", key_name);
> +	if (!key_name) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +	key_node = of_find_node_by_path(key_path);
> +	free(key_path);
> +	if (!key_node) {
> +		pr_info("failed to find key node\n");
> +		ret = -ENOENT;
> +		goto out;
> +	}
> +
> +	ret = rsa_of_read_key(key_node, &key);
> +	if (ret) {
> +		pr_info("failed to read key\n");
> +		ret = -ENOENT;
> +		goto out;
> +	}
> +
> +	if (of_property_read_u32_index(sig_node, "hashed-strings", 0, &hashed_strings_start)) {
> +		pr_err("%s: hashed-strings start not found\n", __func__);
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +	if (of_property_read_u32_index(sig_node, "hashed-strings", 1, &hashed_strings_size)) {
> +		pr_err("%s: hashed-strings size not found\n", __func__);
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	string_list_init(&inc_nodes);
> +	string_list_init(&exc_props);
> +
> +	if (of_read_string_list(sig_node, "hashed-nodes", &inc_nodes))
> +	{
> +		pr_err("%s: hashed-nodes invalid\n", __func__);
> +		ret = -EINVAL;
> +		goto out_sl;
> +	}
> +
> +	string_list_add(&exc_props, "data");
> +
> +	digest->init(digest);
> +	ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start, hashed_strings_size);
> +	hash = xzalloc(digest->length);
> +	digest->final(digest, hash);
> +
> +	ret = rsa_verify(&key, sig_value, sig_len, hash, algo); 
> +	if (ret) {
> +		pr_info("sig BAD\n");
> +		ret = CHECK_LEVEL_NONE;
> +	} else {
> +		pr_info("sig OK\n");
> +		ret = CHECK_LEVEL_SIG;
> +	}
> +
> +	free(hash);
> +out_sl:
> +	string_list_free(&inc_nodes);
> +	string_list_free(&exc_props);
> +out:
> +	return ret;
all this key code will be move to the keystore so the generic code should
never known about the key format
> +}
> +
> +static int fit_verify_hash(struct device_node *hash, const void *data, int data_len)
> +{
> +	struct digest *d;
> +	const char *algo;
> +	const char *value_read;
> +	char *value_calc;
> +	int hash_len;
> +
> +	value_read = of_get_property(hash, "value", &hash_len);
> +	if (!value_read) {
> +		pr_err("value not found\n");
> +		return CHECK_LEVEL_NONE;
> +	}
> +
> +	if (of_property_read_string(hash, "algo", &algo)) {
> +		pr_err("algo not found\n");
> +		return -EINVAL;
> +	}
> +
> +	d = digest_get_by_name(algo);
> +	if (!d) {
> +		pr_err("unsupported algo %s\n", algo);
> +		return -EINVAL;
> +	}
> +
> +	if (hash_len != d->length) {
> +		pr_err("invalid hash length %d\n", hash_len);
> +		return -EINVAL;
> +	}
> +
> +	value_calc = xmalloc(hash_len);
> +	
> +	d->init(d);
> +	d->update(d, data, data_len);
> +	d->final(d, value_calc);
> +
> +	if (memcmp(value_read, value_calc, hash_len)) {
> +		pr_info("hash BAD\n");
> +		return CHECK_LEVEL_NONE;
> +	} else {
> +		pr_info("hash OK\n");
> +		return CHECK_LEVEL_HASH;
> +	}
> +}
> +
> +static int fit_open_image(struct fit_handle *handle, const char* unit)
> +{
> +	struct device_node *image = NULL, *hash;
> +	const char *type = NULL, *desc;
> +	const void *data;
> +	int data_len;
> +	int ret, level;
> +
> +	image = of_get_child_by_name(handle->root, "images");
> +	if (!image)
> +		return -ENOENT;
> +
> +	image = of_get_child_by_name(image, unit);
> +	if (!image)
> +		return -ENOENT;
> +
> +	if (of_property_read_string(image, "description", &desc)) {
> +		pr_info("FIT image '%s' (no description)\n", unit);
> +	} else {
> +		pr_info("FIT image '%s': '%s'\n", unit, desc);
> +	}
> +
> +	of_property_read_string(image, "type", &type);
> +	if (!type)
> +		return -EINVAL;
> +
> +	data = of_get_property(image, "data", &data_len);
> +	if (!data) {
> +		pr_err("data not found\n");
> +		return -EINVAL;
> +	}
> +
> +	level = CHECK_LEVEL_MAX;
> +	for_each_child_of_node(image, hash) {
> +		if (handle->verbose)an
> +			of_print_nodes(hash, 0);
> +		ret = fit_verify_hash(hash, data, data_len);
this is wrong only check what you need to use the read do not care
to speed up the boot

> +		if (ret < 0)
> +			return ret;
> +		level = min(level, ret);
> +	}
> +	if (level == CHECK_LEVEL_MAX) {
> +		return -EINVAL;
> +	}
> +
> +	if (level == CHECK_LEVEL_HASH) {
> +		if (strcmp(type, "kernel") == 0 ||
> +			strcmp(type, "kernel_noload") == 0) {
> +			handle->kernel = data;
> +			handle->kernel_size = data_len;
> +		} else if (strcmp(type, "flat_dt") == 0) {
> +			handle->oftree = data;
> +			handle->oftree_size = data_len;
> +		} else if (strcmp(type, "ramdisk") == 0) {
> +			handle->initrd = data;
> +			handle->initrd_size = data_len;
> +		} else {
> +			pr_info("unknown image type %s, ignoring\n", type);
> +		}
> +	}
> +
> +	return level;
> +}
> +
> +static int fit_open_configuration(struct fit_handle *handle, int num)
> +{
> +	struct device_node *conf_node = NULL, *sig_node;
> +	char unit_name[10];
> +	const char *unit, *desc;
> +	int ret, level;
> +
> +	conf_node = of_get_child_by_name(handle->root, "configurations");
> +	if (!conf_node)
> +		return -ENOENT;
> +
> +	if (num) {
> +		snprintf(unit_name, sizeof(unit_name), "conf@%d", num);
> +		unit = unit_name;
> +	} else if (of_property_read_string(conf_node, "default", &unit)) {
> +		unit = "conf@1";
> +	}
> +
> +	conf_node = of_get_child_by_name(conf_node, unit);
> +	if (!conf_node) {
> +		pr_err("FIT configuration '%s' not found\n", unit);
> +		return -ENOENT;
> +	}
> +
> +	if (of_property_read_string(conf_node, "description", &desc)) {
> +		pr_info("FIT configuration '%s' (no description)\n", unit);
> +	} else {
> +		pr_info("FIT configuration '%s': '%s'\n", unit, desc);
> +	}
> +
> +	level = CHECK_LEVEL_MAX;
> +	for_each_child_of_node(conf_node, sig_node) {
> +		if (handle->verbose)
> +			of_print_nodes(sig_node, 0);
> +		ret = fit_verify_signature(sig_node, handle->fit);
> +		if (ret < 0)
> +			return ret;
> +		level = min(level, ret);
> +	}
> +	if (level == CHECK_LEVEL_MAX)
> +		return -EINVAL;
> +
> +	if (level != CHECK_LEVEL_SIG)
> +		return -EINVAL;
> +
> +	if (of_property_read_string(conf_node, "kernel", &unit) == 0)
> +		level = min(level, fit_open_image(handle, unit));
> +	else
> +		return -ENOENT;
> +	
> +	if (of_property_read_string(conf_node, "fdt", &unit) == 0)
> +		level = min(level, fit_open_image(handle, unit));
> +	
> +	if (of_property_read_string(conf_node, "ramdisk", &unit) == 0)
> +		level = min(level, fit_open_image(handle, unit));
> +
> +	if (level != CHECK_LEVEL_HASH)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +struct fit_handle *fit_open(const char *filename, int num, bool verbose)
> +{
> +	struct fit_handle *handle = NULL;
> +	const char *desc;
> +
> +	handle = xzalloc(sizeof(struct fit_handle));
> +
> +	handle->verbose = verbose;
> +
> +	handle->fit = read_file(filename, &handle->size);
> +	if (!handle->fit) {
> +		pr_err("unable to read %s: %s\n", filename, strerror(errno));
> +		goto err;
> +	}
> +
> +	handle->root = of_unflatten_dtb(handle->fit);
> +	if (IS_ERR(handle->root)) {
> +		goto err;
> +	}
> +
> +	if (of_property_read_string(handle->root, "description", &desc)) {
> +		pr_info("FIT '%s' (no description)\n", filename);
> +	} else {
> +		pr_info("FIT '%s': '%s'\n", filename, desc);
> +	}
> +
> +	if (fit_open_configuration(handle, num))
> +		goto err;
> +
> +	return handle;
> +err:
> +	if (handle->root)
> +		of_delete_node(handle->root);
> +	if (handle->fit)
> +		free(handle->fit);
> +	free(handle);
> +
> +	return NULL;
> +}
> +
> +void fit_close(struct fit_handle *handle)
> +{
> +	if (handle->root)
> +		of_delete_node(handle->root);
> +	if (handle->fit)
> +		free(handle->fit);
> +	free(handle);
> +}
> +
> +#ifdef CONFIG_SANDBOX
> +static int do_bootm_sandbox_fit(struct image_data *data)
> +{
> +	struct fit_handle *handle;
> +	handle = fit_open(data->os_file, data->os_num, data->verbose);
> +	if (handle)
> +		fit_close(handle);
> +	return 0;
> +}
> +
> +static struct image_handler sandbox_fit_handler = {
> +	.name = "FIT image",
> +	.bootm = do_bootm_sandbox_fit,
> +	.filetype = filetype_oftree,
we need a specific filtype to check if it's really a fit
do not like this idea to use it a generic oftree as you could run do this
./toto.dtb

and it will try to boot it any fdt file
> +};
> +
> +static int sandbox_fit_register(void)
> +{
> +	return register_image_handler(&sandbox_fit_handler);
> +}
> +late_initcall(sandbox_fit_register);
> +#endif
> +
> diff --git a/include/image-fit.h b/include/image-fit.h
> new file mode 100644
> index 000000000000..bcbc859ead37
> --- /dev/null
> +++ b/include/image-fit.h
> @@ -0,0 +1,42 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> + *
> + * Copyright (C) Jan Lübbe, 2014
> + */
> +
> +#ifndef __IMAGE_FIT_H__
> +#define __IMAGE_FIT_H__
> +
> +#include <linux/types.h>
> +
> +struct fit_handle {
> +	void *fit;
> +	size_t size;
> +
> +	bool verbose;
> +
> +	struct device_node *root;
> +
> +	const void *kernel;
> +	unsigned long kernel_size;
> +	const void *oftree;
> +	unsigned long oftree_size;
> +	const void *initrd;
> +	unsigned long initrd_size;
> +};
> +
> +struct fit_handle *fit_open(const char *filename, int num, bool verbose);
> +void fit_close(struct fit_handle *handle);
> +
> +#endif	/* __IMAGE_FIT_H__ */
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 1/4] digest: Make filename arguments const
  2015-03-12 14:39 ` [RFC 1/4] digest: Make filename arguments const Jan Luebbe
@ 2015-03-13  7:40   ` Sascha Hauer
  0 siblings, 0 replies; 59+ messages in thread
From: Sascha Hauer @ 2015-03-13  7:40 UTC (permalink / raw)
  To: Jan Luebbe; +Cc: barebox

On Thu, Mar 12, 2015 at 03:39:56PM +0100, Jan Luebbe wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  common/digest.c  | 8 ++++----
>  include/digest.h | 8 ++++----
>  2 files changed, 8 insertions(+), 8 deletions(-)

Already rebased onto Jean-Christophes latest changes and applied.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-12 18:19   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13  9:28     ` Jan Lübbe
  2015-03-13 10:05       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13  9:28 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Do, 2015-03-12 at 19:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> please do not send a new version except for fix
> 
> I'm going to re-integrate it with the keystore & co

Could you describe your keystore design?

> and sha1,rsa2048 is considered weak in term of security
> and worse md4/md5
> 
> for barebox I would only use
> at least sha256 with rs2048 or sha512 with rsa4096

Yes, of course. These were only used as an example and it's trivial to
switch to other hash algos or RSA key sizes. Also, the FIT format can
easily be extended to support ECC/Curve25519.

In some cases, where the SoC's ROM code only supports RSA2048 with SHA1,
using stronger settings in Barebox doesn't increase security. So there
we want to use the same settings as the ROM code.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-12 17:47   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13  9:35     ` Jan Lübbe
  2015-03-13  9:56       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13  9:35 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Do, 2015-03-12 at 18:47 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> as state in my previous e-mail I will a keystore support
> 
> but this dt format to handle no please
> 
> we need to use the standard format as in the kernel or openssl
> 
> DER and x509
> 
> specially x509 as if we want to be able to add key at runtime we need
> to sign them we the trusted RO keys
> 
> For the implementation of RSA I use the polarssl one and plan to add
> the kernel one
> 
> and this implementation is limited to 4096 the polarssl one is not

Having an ASN1 parser for DER/x509 is a huge amount of complexity I
would not want in a bootloader. Just take a look at the problems the
SSL-CAs and browsers had with different interpretations of the same
cert.

The FIT format (and corresponding public key in the bootloader's DT) has
been adopted by depthcharge and u-boot, because it handles the
requirements and nothing more.

What is your use-case for which you need to add keys at runtime?

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC] digest: Add enum
  2015-03-12 17:50   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13  9:54     ` Jan Lübbe
  2015-03-13 10:10       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13  9:54 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Do, 2015-03-12 at 18:50 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> do as in the kernel use the string as we may want to add hw IP

You mean we should add a priority instead? The kernel also has separate
names for the algorithm and for the driver.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13  9:35     ` Jan Lübbe
@ 2015-03-13  9:56       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:06         ` Sascha Hauer
  2015-03-13 10:10         ` Jan Lübbe
  0 siblings, 2 replies; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13  9:56 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 10:35 Fri 13 Mar     , Jan Lübbe wrote:
> On Do, 2015-03-12 at 18:47 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > as state in my previous e-mail I will a keystore support
> > 
> > but this dt format to handle no please
> > 
> > we need to use the standard format as in the kernel or openssl
> > 
> > DER and x509
> > 
> > specially x509 as if we want to be able to add key at runtime we need
> > to sign them we the trusted RO keys
> > 
> > For the implementation of RSA I use the polarssl one and plan to add
> > the kernel one
> > 
> > and this implementation is limited to 4096 the polarssl one is not
> 
> Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> would not want in a bootloader. Just take a look at the problems the
> SSL-CAs and browsers had with different interpretations of the same
> cert.

der is nothing few under lines

x509 a few more as it's based on DER
> 
> The FIT format (and corresponding public key in the bootloader's DT) has
> been adopted by depthcharge and u-boot, because it handles the
> requirements and nothing more.

if you want to add this format you can but via the keychain loader not in the
code as today you do have soc such as imx that store the key in OTP as DER

and u-boot is not the best reference EVER.
> 
> What is your use-case for which you need to add keys at runtime?

simple you want to allow user to put their own key
or use a CA to handle allowed key

if you want to replace grub this is critical

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13  9:28     ` Jan Lübbe
@ 2015-03-13 10:05       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:21         ` Jan Lübbe
  2015-03-13 11:33         ` Marc Kleine-Budde
  0 siblings, 2 replies; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 10:05 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 10:28 Fri 13 Mar     , Jan Lübbe wrote:
> On Do, 2015-03-12 at 19:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > please do not send a new version except for fix
> > 
> > I'm going to re-integrate it with the keystore & co
> 
> Could you describe your keystore design?

I'll send the patch series soon

code is better than 1000s of words

with DER support and the fit
> 
> > and sha1,rsa2048 is considered weak in term of security
> > and worse md4/md5
> > 
> > for barebox I would only use
> > at least sha256 with rs2048 or sha512 with rsa4096
> 
> Yes, of course. These were only used as an example and it's trivial to
> switch to other hash algos or RSA key sizes. Also, the FIT format can
> easily be extended to support ECC/Curve25519.

very slow vs rsa, but as we will use a generic framework we will just need to
add the algo

if you can break rsa4096, the chance you can break ECC are high too
> 
> In some cases, where the SoC's ROM code only supports RSA2048 with SHA1,
> using stronger settings in Barebox doesn't increase security. So there
> we want to use the same settings as the ROM code.

agreed but I refuse to allow it unless we have no choice
and emit a warning

and even I'll prefer to use stonger, yes this will increase the security.
As a secure boot is as strong as it's weak link

but this will not reduce it either

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13  9:56       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 10:06         ` Sascha Hauer
  2015-03-13 10:12           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:10         ` Jan Lübbe
  1 sibling, 1 reply; 59+ messages in thread
From: Sascha Hauer @ 2015-03-13 10:06 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fri, Mar 13, 2015 at 10:56:54AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 10:35 Fri 13 Mar     , Jan Lübbe wrote:
> > On Do, 2015-03-12 at 18:47 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > as state in my previous e-mail I will a keystore support
> > > 
> > > but this dt format to handle no please
> > > 
> > > we need to use the standard format as in the kernel or openssl
> > > 
> > > DER and x509
> > > 
> > > specially x509 as if we want to be able to add key at runtime we need
> > > to sign them we the trusted RO keys
> > > 
> > > For the implementation of RSA I use the polarssl one and plan to add
> > > the kernel one
> > > 
> > > and this implementation is limited to 4096 the polarssl one is not
> > 
> > Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> > would not want in a bootloader. Just take a look at the problems the
> > SSL-CAs and browsers had with different interpretations of the same
> > cert.
> 
> der is nothing few under lines

Could you please write something that even remotely makes sense so we
can translate it here?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC] digest: Add enum
  2015-03-13  9:54     ` Jan Lübbe
@ 2015-03-13 10:10       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 18:50         ` Robert Schwebel
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 10:10 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 10:54 Fri 13 Mar     , Jan Lübbe wrote:
> On Do, 2015-03-12 at 18:50 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > do as in the kernel use the string as we may want to add hw IP
> 
> You mean we should add a priority instead? The kernel also has separate
> names for the algorithm and for the driver.

yes when we add hw ip we will have to do so too
as we maybe enable the hw driver but the device as in multiple image build
such as imx

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13  9:56       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:06         ` Sascha Hauer
@ 2015-03-13 10:10         ` Jan Lübbe
  2015-03-13 10:25           ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13 10:10 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fr, 2015-03-13 at 10:56 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> > would not want in a bootloader. Just take a look at the problems the
> > SSL-CAs and browsers had with different interpretations of the same
> > cert.
> 
> der is nothing few under lines

Sorry, I can't parse this.

> x509 a few more as it's based on DER

Could you show me that code?

> > The FIT format (and corresponding public key in the bootloader's DT) has
> > been adopted by depthcharge and u-boot, because it handles the
> > requirements and nothing more.
> 
> if you want to add this format you can but via the keychain loader not in the
> code as today you do have soc such as imx that store the key in OTP as DER

The IMX does not store keys in OTP. It stores a SHA(1 or 256) hash over
a table of "super root keys". This is irrelevant for barebox, as this is
already handled by the ROM code.

> and u-boot is not the best reference EVER.

Depthcharge is much more relevant here, as it's used as a coreboot
payload on chromebooks.

> > What is your use-case for which you need to add keys at runtime?
> 
> simple you want to allow user to put their own key
> or use a CA to handle allowed key
>
> if you want to replace grub this is critical

We have customers which require that do not allow runtime loading of
keys. So it should be possible to disable runtime loading at compile
time. 

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 10:06         ` Sascha Hauer
@ 2015-03-13 10:12           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:22             ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 10:12 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

On 11:06 Fri 13 Mar     , Sascha Hauer wrote:
> On Fri, Mar 13, 2015 at 10:56:54AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 10:35 Fri 13 Mar     , Jan Lübbe wrote:
> > > On Do, 2015-03-12 at 18:47 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > as state in my previous e-mail I will a keystore support
> > > > 
> > > > but this dt format to handle no please
> > > > 
> > > > we need to use the standard format as in the kernel or openssl
> > > > 
> > > > DER and x509
> > > > 
> > > > specially x509 as if we want to be able to add key at runtime we need
> > > > to sign them we the trusted RO keys
> > > > 
> > > > For the implementation of RSA I use the polarssl one and plan to add
> > > > the kernel one
> > > > 
> > > > and this implementation is limited to 4096 the polarssl one is not
> > > 
> > > Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> > > would not want in a bootloader. Just take a look at the problems the
> > > SSL-CAs and browsers had with different interpretations of the same
> > > cert.
> > 
> > der is nothing few under lines
> 
> Could you please write something that even remotely makes sense so we
> can translate it here?

sorry mutt via ssh lost some character when typing

der is few 100s line of code that's all

and x509 just a few more

as I do not plan to support all the options of x509 specially the non
standard one

Best Regards,
J.
> 
> Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 10:05       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 10:21         ` Jan Lübbe
  2015-03-13 14:28           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 11:33         ` Marc Kleine-Budde
  1 sibling, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13 10:21 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fr, 2015-03-13 at 11:05 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 10:28 Fri 13 Mar     , Jan Lübbe wrote:
> > On Do, 2015-03-12 at 19:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > please do not send a new version except for fix
> > > 
> > > I'm going to re-integrate it with the keystore & co
> > 
> > Could you describe your keystore design?
> 
> I'll send the patch series soon
> 
> code is better than 1000s of words
> 
> with DER support and the fit

Thanks.

> > > and sha1,rsa2048 is considered weak in term of security
> > > and worse md4/md5
> > > 
> > > for barebox I would only use
> > > at least sha256 with rs2048 or sha512 with rsa4096
> > 
> > Yes, of course. These were only used as an example and it's trivial to
> > switch to other hash algos or RSA key sizes. Also, the FIT format can
> > easily be extended to support ECC/Curve25519.
> 
> very slow vs rsa, but as we will use a generic framework we will just need to
> add the algo
> 
> if you can break rsa4096, the chance you can break ECC are high too

Please see http://ed25519.cr.yp.to/ and
http://cr.yp.to/papers.html#rwsota. Curve22519 is very fast and has some
benefits over RSA.

I'm not arguing that either RSA or ECC are better for verified boot, we
should just keep in mind that supporting ECC later should fit the
design.

> > In some cases, where the SoC's ROM code only supports RSA2048 with SHA1,
> > using stronger settings in Barebox doesn't increase security. So there
> > we want to use the same settings as the ROM code.
> 
> agreed but I refuse to allow it unless we have no choice
> and emit a warning

I'm fine with a warning in Kconfig or during compile time. 

> and even I'll prefer to use stonger, yes this will increase the security.
> As a secure boot is as strong as it's weak link

It's not the job of barebox to define security policies, it must fit
well into the larger security design, which may require compromises.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 10:12           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 10:22             ` Jan Lübbe
  2015-03-13 10:26               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13 10:22 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fr, 2015-03-13 at 11:12 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> 
> sorry mutt via ssh lost some character when typing
> 
> der is few 100s line of code that's all
> 
> and x509 just a few more
> 
> as I do not plan to support all the options of x509 specially the non
> standard one

Do you intend to reject unknown/unimplemented parts of x509? Or just
ignore them?

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 10:10         ` Jan Lübbe
@ 2015-03-13 10:25           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:43             ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 10:25 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:10 Fri 13 Mar     , Jan Lübbe wrote:
> On Fr, 2015-03-13 at 10:56 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> > > would not want in a bootloader. Just take a look at the problems the
> > > SSL-CAs and browsers had with different interpretations of the same
> > > cert.
> > 
> > der is nothing few under lines
> 
> Sorry, I can't parse this.
> 
> > x509 a few more as it's based on DER
> 
> Could you show me that code?
let me finish to clean it
and rebase it
> 
> > > The FIT format (and corresponding public key in the bootloader's DT) has
> > > been adopted by depthcharge and u-boot, because it handles the
> > > requirements and nothing more.
> > 
> > if you want to add this format you can but via the keychain loader not in the
> > code as today you do have soc such as imx that store the key in OTP as DER
> 
> The IMX does not store keys in OTP. It stores a SHA(1 or 256) hash over
> a table of "super root keys". This is irrelevant for barebox, as this is
> already handled by the ROM code.
it's does as you can use it as hw IP to check the kernel

yes you store a hash but you do can use it in barebox.

other SoC (i can mention the name NDA) does store the key in the OTP of the
SoC programmed at production time of the SoC itself.
with HW RSA accelerator
> 
> > and u-boot is not the best reference EVER.
> 
> Depthcharge is much more relevant here, as it's used as a coreboot
> payload on chromebooks.

does not make it more relevant is the term of key format

the Standard are x509, PGP and der/pem for ages

and as said we can support it but make it the only one NO WAY
> 
> > > What is your use-case for which you need to add keys at runtime?
> > 
> > simple you want to allow user to put their own key
> > or use a CA to handle allowed key
> >
> > if you want to replace grub this is critical
> 
> We have customers which require that do not allow runtime loading of
> keys. So it should be possible to disable runtime loading at compile
> time. 
yeah of cource but the feature need to be here IMHO

and honestly to respect the opensource if you allow this you MIGHT be
compliant with GPLv3

it's more user friendly
For my own customer I always recommand to have a board uniq key that you
can provide to each end customer upon request to it can install it's own
linux. Even if the key is not replaceble.

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 10:22             ` Jan Lübbe
@ 2015-03-13 10:26               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 10:26 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:22 Fri 13 Mar     , Jan Lübbe wrote:
> On Fr, 2015-03-13 at 11:12 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > 
> > sorry mutt via ssh lost some character when typing
> > 
> > der is few 100s line of code that's all
> > 
> > and x509 just a few more
> > 
> > as I do not plan to support all the options of x509 specially the non
> > standard one
> 
> Do you intend to reject unknown/unimplemented parts of x509? Or just
> ignore them?
ignore it

Best Regards,
J.
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 10:25           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 10:43             ` Jan Lübbe
  2015-03-13 15:49               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13 10:43 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fr, 2015-03-13 at 11:25 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 11:10 Fri 13 Mar     , Jan Lübbe wrote:
> > On Fr, 2015-03-13 at 10:56 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> > > > would not want in a bootloader. Just take a look at the problems the
> > > > SSL-CAs and browsers had with different interpretations of the same
> > > > cert.
> > > 
> > > der is nothing few under lines
> > 
> > Sorry, I can't parse this.
> > 
> > > x509 a few more as it's based on DER
> > 
> > Could you show me that code?
> let me finish to clean it
> and rebase it

Sure.

> > > > The FIT format (and corresponding public key in the bootloader's DT) has
> > > > been adopted by depthcharge and u-boot, because it handles the
> > > > requirements and nothing more.
> > > 
> > > if you want to add this format you can but via the keychain loader not in the
> > > code as today you do have soc such as imx that store the key in OTP as DER
> > 
> > The IMX does not store keys in OTP. It stores a SHA(1 or 256) hash over
> > a table of "super root keys". This is irrelevant for barebox, as this is
> > already handled by the ROM code.
> it's does as you can use it as hw IP to check the kernel

RSA checking in HABv4 (i.e. MX6) is done in software by the ROM code.
For the first step we should only support RSA in software to keep the
complexity down.

> yes you store a hash but you do can use it in barebox.

Yes, you could use it in barebox. What is the use case where you would
do this instead of having the key compiled-in (and verified together
with the code by the ROM)?

> other SoC (i can mention the name NDA) does store the key in the OTP of the
> SoC programmed at production time of the SoC itself.
> with HW RSA accelerator

OK, please leave HW RSA as a future step.

> > > and u-boot is not the best reference EVER.
> > 
> > Depthcharge is much more relevant here, as it's used as a coreboot
> > payload on chromebooks.
> 
> does not make it more relevant is the term of key format
> 
> the Standard are x509, PGP and der/pem for ages
> 
> and as said we can support it but make it the only one NO WAY

I'd prefer PGP to x509 anyway. ;)

If we can have x509 and FIT (with key in DT) without too much additional
complexity and have each optional at compile time, I'm not against it.
I'll wait for your code.

> > > > What is your use-case for which you need to add keys at runtime?
> > > 
> > > simple you want to allow user to put their own key
> > > or use a CA to handle allowed key
> > >
> > > if you want to replace grub this is critical
> > 
> > We have customers which require that do not allow runtime loading of
> > keys. So it should be possible to disable runtime loading at compile
> > time. 
> yeah of cource but the feature need to be here IMHO

OK.

> and honestly to respect the opensource if you allow this you MIGHT be
> compliant with GPLv3

s/compliant/non-compliant/ ?

How you need to handle that in practice depends on the context of the
whole system.

> it's more user friendly
> For my own customer I always recommand to have a board uniq key that you
> can provide to each end customer upon request to it can install it's own
> linux. Even if the key is not replaceble.

Yes, that's nice if the production work flow in the factory can do this,
but it's not always possible.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 10:05       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 10:21         ` Jan Lübbe
@ 2015-03-13 11:33         ` Marc Kleine-Budde
  2015-03-13 15:54           ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 1 reply; 59+ messages in thread
From: Marc Kleine-Budde @ 2015-03-13 11:33 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD, Jan Lübbe; +Cc: barebox


[-- Attachment #1.1: Type: text/plain, Size: 2044 bytes --]

On 03/13/2015 11:05 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 10:28 Fri 13 Mar     , Jan Lübbe wrote:
>> On Do, 2015-03-12 at 19:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>> please do not send a new version except for fix
>>>
>>> I'm going to re-integrate it with the keystore & co
>>
>> Could you describe your keystore design?
> 
> I'll send the patch series soon
> 
> code is better than 1000s of words
> 
> with DER support and the fit
>>
>>> and sha1,rsa2048 is considered weak in term of security
>>> and worse md4/md5
>>>
>>> for barebox I would only use
>>> at least sha256 with rs2048 or sha512 with rsa4096
>>
>> Yes, of course. These were only used as an example and it's trivial to
>> switch to other hash algos or RSA key sizes. Also, the FIT format can
>> easily be extended to support ECC/Curve25519.
> 
> very slow vs rsa, but as we will use a generic framework we will just need to
> add the algo
> 
> if you can break rsa4096, the chance you can break ECC are high too

If you want to open the box, today you would probably not break
rsa2048/sha1 (unless you have huge calculation power) but look for
implementation weaknesses, like bugs or side channel attacks.

>> In some cases, where the SoC's ROM code only supports RSA2048 with SHA1,
>> using stronger settings in Barebox doesn't increase security. So there
>> we want to use the same settings as the ROM code.
> 
> agreed but I refuse to allow it unless we have no choice
> and emit a warning
> 
> and even I'll prefer to use stonger, yes this will increase the security.
> As a secure boot is as strong as it's weak link
> 
> but this will not reduce it either

Adding unneeded complexity might not the best move here.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 149 bytes --]

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 10:21         ` Jan Lübbe
@ 2015-03-13 14:28           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 15:41             ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 14:28 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:21 Fri 13 Mar     , Jan Lübbe wrote:
> On Fr, 2015-03-13 at 11:05 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 10:28 Fri 13 Mar     , Jan Lübbe wrote:
> > > On Do, 2015-03-12 at 19:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > please do not send a new version except for fix
> > > > 
> > > > I'm going to re-integrate it with the keystore & co
> > > 
> > > Could you describe your keystore design?
> > 
> > I'll send the patch series soon
> > 
> > code is better than 1000s of words
> > 
> > with DER support and the fit
> 
> Thanks.
> 
> > > > and sha1,rsa2048 is considered weak in term of security
> > > > and worse md4/md5
> > > > 
> > > > for barebox I would only use
> > > > at least sha256 with rs2048 or sha512 with rsa4096
> > > 
> > > Yes, of course. These were only used as an example and it's trivial to
> > > switch to other hash algos or RSA key sizes. Also, the FIT format can
> > > easily be extended to support ECC/Curve25519.
> > 
> > very slow vs rsa, but as we will use a generic framework we will just need to
> > add the algo
> > 
> > if you can break rsa4096, the chance you can break ECC are high too
> 
> Please see http://ed25519.cr.yp.to/ and
> http://cr.yp.to/papers.html#rwsota. Curve22519 is very fast and has some
> benefits over RSA.

I known this curve but I did not yet test it on barebox

remember on arm it's not as performent as on x86

and the ECC have advantage over RSA but the speed on my last test on ARM use
more power than RSA and was slower
> 
> I'm not arguing that either RSA or ECC are better for verified boot, we
> should just keep in mind that supporting ECC later should fit the
> design.

agreed that why I work on a framework to hide the algo at every level
key/signature verification, everywhere.

SO we do not care if it's a software implementation or a hardware one
and which algo
> 
> > > In some cases, where the SoC's ROM code only supports RSA2048 with SHA1,
> > > using stronger settings in Barebox doesn't increase security. So there
> > > we want to use the same settings as the ROM code.
> > 
> > agreed but I refuse to allow it unless we have no choice
> > and emit a warning
> 
> I'm fine with a warning in Kconfig or during compile time. 
> 
> > and even I'll prefer to use stonger, yes this will increase the security.
> > As a secure boot is as strong as it's weak link
> 
> It's not the job of barebox to define security policies, it must fit
> well into the larger security design, which may require compromises.

I disagree, disable by default non secure feature is require to pass
secure boot certification

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 14:28           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 15:41             ` Jan Lübbe
  2015-03-13 16:08               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-13 15:41 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fr, 2015-03-13 at 15:28 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > It's not the job of barebox to define security policies, it must fit
> > well into the larger security design, which may require compromises.
> 
> I disagree, disable by default non secure feature is require to pass
> secure boot certification

Is there a specific certification you are targeting?

How do you intend to handle console access in verified boot mode?
Allowing access to md/mw would break any security.

I was thinking about switching off access to the HW AES keys as soon as
a prompt appears. At least on MX28/MX6 that's possible and important.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 10:43             ` Jan Lübbe
@ 2015-03-13 15:49               ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 10:00                 ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 15:49 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:43 Fri 13 Mar     , Jan Lübbe wrote:
> On Fr, 2015-03-13 at 11:25 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 11:10 Fri 13 Mar     , Jan Lübbe wrote:
> > > On Fr, 2015-03-13 at 10:56 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > > Having an ASN1 parser for DER/x509 is a huge amount of complexity I
> > > > > would not want in a bootloader. Just take a look at the problems the
> > > > > SSL-CAs and browsers had with different interpretations of the same
> > > > > cert.
> > > > 
> > > > der is nothing few under lines
> > > 
> > > Sorry, I can't parse this.
> > > 
> > > > x509 a few more as it's based on DER
> > > 
> > > Could you show me that code?
> > let me finish to clean it
> > and rebase it
> 
> Sure.
> 
> > > > > The FIT format (and corresponding public key in the bootloader's DT) has
> > > > > been adopted by depthcharge and u-boot, because it handles the
> > > > > requirements and nothing more.
> > > > 
> > > > if you want to add this format you can but via the keychain loader not in the
> > > > code as today you do have soc such as imx that store the key in OTP as DER
> > > 
> > > The IMX does not store keys in OTP. It stores a SHA(1 or 256) hash over
> > > a table of "super root keys". This is irrelevant for barebox, as this is
> > > already handled by the ROM code.
> > it's does as you can use it as hw IP to check the kernel
> 
> RSA checking in HABv4 (i.e. MX6) is done in software by the ROM code.
> For the first step we should only support RSA in software to keep the
> complexity down.
> 
> > yes you store a hash but you do can use it in barebox.
> 
> Yes, you could use it in barebox. What is the use case where you would
> do this instead of having the key compiled-in (and verified together
> with the code by the ROM)?

yes let the rom code handle it if you want, it will be a HW implementation
specific to IMX with HABv4

The framework must not be limited to FIT only but FIT is just one of secure
boot supported
> 
> > other SoC (i can mention the name NDA) does store the key in the OTP of the
> > SoC programmed at production time of the SoC itself.
> > with HW RSA accelerator
> 
> OK, please leave HW RSA as a future step.

The current framework is already ready for this mostly
> 
> > > > and u-boot is not the best reference EVER.
> > > 
> > > Depthcharge is much more relevant here, as it's used as a coreboot
> > > payload on chromebooks.
> > 
> > does not make it more relevant is the term of key format
> > 
> > the Standard are x509, PGP and der/pem for ages
> > 
> > and as said we can support it but make it the only one NO WAY
> 
> I'd prefer PGP to x509 anyway. ;)
I do prefer PGP too but unfortunately it's not a flexibal format
> 
> If we can have x509 and FIT (with key in DT) without too much additional
> complexity and have each optional at compile time, I'm not against it.
> I'll wait for your code.
> 
> > > > > What is your use-case for which you need to add keys at runtime?
> > > > 
> > > > simple you want to allow user to put their own key
> > > > or use a CA to handle allowed key
> > > >
> > > > if you want to replace grub this is critical
> > > 
> > > We have customers which require that do not allow runtime loading of
> > > keys. So it should be possible to disable runtime loading at compile
> > > time. 
> > yeah of cource but the feature need to be here IMHO
> 
> OK.
> 
> > and honestly to respect the opensource if you allow this you MIGHT be
> > compliant with GPLv3
> 
> s/compliant/non-compliant/ ?
compliant we had layer checking it for one of my client in the pase, I'll ask
for the result
> 
> How you need to handle that in practice depends on the context of the
> whole system.
> 
> > it's more user friendly
> > For my own customer I always recommand to have a board uniq key that you
> > can provide to each end customer upon request to it can install it's own
> > linux. Even if the key is not replaceble.
> 
> Yes, that's nice if the production work flow in the factory can do this,
> but it's not always possible.

if you use x509 you can

you just need to have a unique ID on the HW and then use a x509 object to
store it. then signed it with you CA. As only validated keys can be used,
you can easly give a generated key for a specific HW.
And this key will be valid only for this HW.

Already did it in the past

on u-boot and barebox

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 11:33         ` Marc Kleine-Budde
@ 2015-03-13 15:54           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-13 16:06             ` Marc Kleine-Budde
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 15:54 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: barebox

On 12:33 Fri 13 Mar     , Marc Kleine-Budde wrote:
> On 03/13/2015 11:05 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 10:28 Fri 13 Mar     , Jan Lübbe wrote:
> >> On Do, 2015-03-12 at 19:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>> please do not send a new version except for fix
> >>>
> >>> I'm going to re-integrate it with the keystore & co
> >>
> >> Could you describe your keystore design?
> > 
> > I'll send the patch series soon
> > 
> > code is better than 1000s of words
> > 
> > with DER support and the fit
> >>
> >>> and sha1,rsa2048 is considered weak in term of security
> >>> and worse md4/md5
> >>>
> >>> for barebox I would only use
> >>> at least sha256 with rs2048 or sha512 with rsa4096
> >>
> >> Yes, of course. These were only used as an example and it's trivial to
> >> switch to other hash algos or RSA key sizes. Also, the FIT format can
> >> easily be extended to support ECC/Curve25519.
> > 
> > very slow vs rsa, but as we will use a generic framework we will just need to
> > add the algo
> > 
> > if you can break rsa4096, the chance you can break ECC are high too
> 
> If you want to open the box, today you would probably not break
> rsa2048/sha1 (unless you have huge calculation power) but look for
> implementation weaknesses, like bugs or side channel attacks.

I alredy see it done on rsa1024 few years ago, today rs2048 is supposedly
secured but as you hw may have to run for 10 years rs2048/sha1 is considered not
strong enough

Keep in on mind, for security you do need to choose the correct algo for how
long the data need to be secured.
> 
> >> In some cases, where the SoC's ROM code only supports RSA2048 with SHA1,
> >> using stronger settings in Barebox doesn't increase security. So there
> >> we want to use the same settings as the ROM code.
> > 
> > agreed but I refuse to allow it unless we have no choice
> > and emit a warning
> > 
> > and even I'll prefer to use stonger, yes this will increase the security.
> > As a secure boot is as strong as it's weak link
> > 
> > but this will not reduce it either
> 
> Adding unneeded complexity might not the best move here.
common it just change the sha and the number of bits of key

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 15:54           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 16:06             ` Marc Kleine-Budde
  2015-03-13 17:00               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Marc Kleine-Budde @ 2015-03-13 16:06 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox


[-- Attachment #1.1: Type: text/plain, Size: 953 bytes --]

On 03/13/2015 04:54 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>> if you can break rsa4096, the chance you can break ECC are high too
>>
>> If you want to open the box, today you would probably not break
>> rsa2048/sha1 (unless you have huge calculation power) but look for
>> implementation weaknesses, like bugs or side channel attacks.
> 
> I alredy see it done on rsa1024 few years ago, today rs2048 is supposedly
> secured but as you hw may have to run for 10 years rs2048/sha1 is considered not
> strong enough

Some thoughts on 2048 vs. 4096:
https://www.yubico.com/2015/02/big-debate-2048-4096-yubicos-stand/

While sha1 is considered broken.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 149 bytes --]

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 15:41             ` Jan Lübbe
@ 2015-03-13 16:08               ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 10:19                 ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 16:08 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 16:41 Fri 13 Mar     , Jan Lübbe wrote:
> On Fr, 2015-03-13 at 15:28 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > It's not the job of barebox to define security policies, it must fit
> > > well into the larger security design, which may require compromises.
> > 
> > I disagree, disable by default non secure feature is require to pass
> > secure boot certification
> 
> Is there a specific certification you are targeting?

yes but can not give details all under NDA, a book of more than 500 pages
for bootloader/linux/kernel & co
> 
> How do you intend to handle console access in verified boot mode?
> Allowing access to md/mw would break any security.

it's already mainline for month, check password support

as I put it in production more than 1 years ago

or simple disable input console all time, the code is here

the main problem is not console but env you need to drop RW env support
and use only RO one, except for keyring support where you will a RW env but
not executable and only accesable by crypto API

otherwise you need to use a secured digest such as HMAC/CMAC/OMAC support
to sign the env at runtime and ensure the symetric key is secured
or encrypt it via aes (did this in the past)

==
ww may have to get secured malloac with part where the md/mw and any other
API can not touch only the crypto API

but this will be for later
==
> 
> I was thinking about switching off access to the HW AES keys as soon as
> a prompt appears. At least on MX28/MX6 that's possible and important.

Password & defaultenv2

16 characters min password with sha256 min or best sha512 or pbkdf2

I'll send a patch to use the pbkdf2 for password

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 16:06             ` Marc Kleine-Budde
@ 2015-03-13 17:00               ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 10:04                 ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-13 17:00 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: barebox

On 17:06 Fri 13 Mar     , Marc Kleine-Budde wrote:
> On 03/13/2015 04:54 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> >>> if you can break rsa4096, the chance you can break ECC are high too
> >>
> >> If you want to open the box, today you would probably not break
> >> rsa2048/sha1 (unless you have huge calculation power) but look for
> >> implementation weaknesses, like bugs or side channel attacks.
> > 
> > I alredy see it done on rsa1024 few years ago, today rs2048 is supposedly
> > secured but as you hw may have to run for 10 years rs2048/sha1 is considered not
> > strong enough
> 
> Some thoughts on 2048 vs. 4096:
> https://www.yubico.com/2015/02/big-debate-2048-4096-yubicos-stand/

I known about it already read it and work with yubico stuff

I disagre on the fact that rsa2048 is good for 15 years, with more and more
low cost power efficent SoC build a super calculator will be cheaper and
cheaper. I'd give it a go for less than 10 years.

It's always the same question what the hardware control. what damage can
happend if the software is tampered with.

A hw that control security door and co => high rist life issue.
Medical stuf ditto.
> 
> While sha1 is considered broken.
it's broken and sha256 not yet but in 10 years strongly suspected
even in brut force

That's why FIPS work on SHA-2

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC] digest: Add enum
  2015-03-13 10:10       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-13 18:50         ` Robert Schwebel
  0 siblings, 0 replies; 59+ messages in thread
From: Robert Schwebel @ 2015-03-13 18:50 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fri, Mar 13, 2015 at 11:10:19AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 10:54 Fri 13 Mar     , Jan Lübbe wrote:
> > On Do, 2015-03-12 at 18:50 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > do as in the kernel use the string as we may want to add hw IP
> > 
> > You mean we should add a priority instead? The kernel also has separate
> > names for the algorithm and for the driver.
> 
> yes when we add hw ip we will have to do so too
> as we maybe enable the hw driver but the device as in multiple image build
> such as imx

Jean-Christophe, please take the time to write in full sentences, start
them with upper case characters and don't forget the dot at the end and
other punctuation marks. And re-read the text before sending.

It is of course no requirement here to write 100% proper English - most
of us are no native speakers. But your texts make it pretty difficult to
follow what you intend to say, so please make it easier for us to
understand your text.

Thanks.

Robert
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-13 15:49               ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 10:00                 ` Jan Lübbe
  2015-03-16 10:27                   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 10:00 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

Hi,

On Fr, 2015-03-13 at 16:49 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> you just need to have a unique ID on the HW and then use a x509 object
> to store it. then signed it with you CA. As only validated keys can be
> used, you can easly give a generated key for a specific HW.
> And this key will be valid only for this HW.

Yes, this sounds useful. So you'd have a board-specific way to check the
unique ID constraint in an intermediate cert against the HW ID?

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 17:00               ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 10:04                 ` Jan Lübbe
  2015-03-16 10:28                   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 10:04 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Fr, 2015-03-13 at 18:00 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > While sha1 is considered broken.
> it's broken and sha256 not yet but in 10 years strongly suspected
> even in brut force
> 
> That's why FIPS work on SHA-2

SHA256 is part of the SHA-2 family [1]. Keccak is the winner of the
SHA-3 competition.

Regards,
Jan

[1] http://en.wikipedia.org/wiki/SHA-2
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-13 16:08               ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 10:19                 ` Jan Lübbe
  2015-03-16 11:14                   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 10:19 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

Hi Jean-Christophe,

On Fr, 2015-03-13 at 17:08 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:41 Fri 13 Mar     , Jan Lübbe wrote:
> > On Fr, 2015-03-13 at 15:28 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > It's not the job of barebox to define security policies, it must fit
> > > > well into the larger security design, which may require compromises.
> > > 
> > > I disagree, disable by default non secure feature is require to pass
> > > secure boot certification
> > 
> > Is there a specific certification you are targeting?
> 
> yes but can not give details all under NDA, a book of more than 500 pages
> for bootloader/linux/kernel & co

OK, that's unfortunate. Still I'd like to have some documentation on the
overall design of Barebox's verified boot. That doesn't mean you have to
write it all by yourself. ;)

> > How do you intend to handle console access in verified boot mode?
> > Allowing access to md/mw would break any security.
> 
> it's already mainline for month, check password support
> 
> as I put it in production more than 1 years ago
> 
> or simple disable input console all time, the code is here

So currently we have:
1) use password
2) disable console

Later I'd like to have optional support to switch barebox into a
"non-secure" or "developer" mode at runtime, which would make hardware
secrets inaccessible. That could be triggered when a prompt appears or
when booting for a different source (such as USB fastboot).

> the main problem is not console but env you need to drop RW env support
> and use only RO one, except for keyring support where you will a RW env but
> not executable and only accesable by crypto API
> 
> otherwise you need to use a secured digest such as HMAC/CMAC/OMAC support
> to sign the env at runtime and ensure the symetric key is secured
> or encrypt it via aes (did this in the past)

For an upcoming project we'll add HMAC support to the state storage Marc
recently submitted.

> ww may have to get secured malloac with part where the md/mw and any other
> API can not touch only the crypto API
> 
> but this will be for later

Yes.

> I'll send a patch to use the pbkdf2 for password

Nice.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-16 10:00                 ` Jan Lübbe
@ 2015-03-16 10:27                   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 11:25                     ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 10:27 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:00 Mon 16 Mar     , Jan Lübbe wrote:
> Hi,
> 
> On Fr, 2015-03-13 at 16:49 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > you just need to have a unique ID on the HW and then use a x509 object
> > to store it. then signed it with you CA. As only validated keys can be
> > used, you can easly give a generated key for a specific HW.
> > And this key will be valid only for this HW.
> 
> Yes, this sounds useful. So you'd have a board-specific way to check the
> unique ID constraint in an intermediate cert against the HW ID?
yes more or less but but at the key itself as you will have to upload the
key to the board. And the key will only be accepted to be stored as it will
be valid and have the HW ID.

And for the record remember if you want to use module in secured boot mode
for the kernel you will have to use x509 certificate anyway.

So why not to use the same principal.

u-boot way is not what is doing today on the market for authentication
format. Today it's x509 or PGP.

So I do prefer to stay as standard as possible, this does not mean we can not
support the FTD stuff. But IMHO it's not the right way.

We may have to even support the Microsoft format. Specially if we want to be
able one day (my personnal target) a real replacement for grub2 too.

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 10:04                 ` Jan Lübbe
@ 2015-03-16 10:28                   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 10:28 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:04 Mon 16 Mar     , Jan Lübbe wrote:
> On Fr, 2015-03-13 at 18:00 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > While sha1 is considered broken.
> > it's broken and sha256 not yet but in 10 years strongly suspected
> > even in brut force
> > 
> > That's why FIPS work on SHA-2
> 
> SHA256 is part of the SHA-2 family [1]. Keccak is the winner of the
> SHA-3 competition.
Yeah tired when wrote that I was talking about Keccak.

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 10:19                 ` Jan Lübbe
@ 2015-03-16 11:14                   ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 12:08                     ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 11:14 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 11:19 Mon 16 Mar     , Jan Lübbe wrote:
> Hi Jean-Christophe,
> 
> On Fr, 2015-03-13 at 17:08 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 16:41 Fri 13 Mar     , Jan Lübbe wrote:
> > > On Fr, 2015-03-13 at 15:28 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > > It's not the job of barebox to define security policies, it must fit
> > > > > well into the larger security design, which may require compromises.
> > > > 
> > > > I disagree, disable by default non secure feature is require to pass
> > > > secure boot certification
> > > 
> > > Is there a specific certification you are targeting?
> > 
> > yes but can not give details all under NDA, a book of more than 500 pages
> > for bootloader/linux/kernel & co
> 
> OK, that's unfortunate. Still I'd like to have some documentation on the
> overall design of Barebox's verified boot. That doesn't mean you have to
> write it all by yourself. ;)

I'll already pass the certification but it's a nightmare.

I wish to have a mainline version that can pass it
> 
> > > How do you intend to handle console access in verified boot mode?
> > > Allowing access to md/mw would break any security.
> > 
> > it's already mainline for month, check password support
> > 
> > as I put it in production more than 1 years ago
> > 
> > or simple disable input console all time, the code is here
> 
> So currently we have:
> 1) use password
> 2) disable console
console enable
but require a password to unlock

I've on an other hw HMAC for envfs to ensure envfs is not tempenred with.
I've on an other HW where we encrypt in in AES CBC or AES-XTS (this one not
yet in production in qualification)
> 
> Later I'd like to have optional support to switch barebox into a
> "non-secure" or "developer" mode at runtime, which would make hardware
> secrets inaccessible. That could be triggered when a prompt appears or
> when booting for a different source (such as USB fastboot).

yeah, I like the idea but for this will have to put a lot of protection so you
can not read/write some part of the memory included barebox itself (in RAM)

As in the kernel we have no memmory protection from the shell.
> 
> > the main problem is not console but env you need to drop RW env support
> > and use only RO one, except for keyring support where you will a RW env but
> > not executable and only accesable by crypto API
> > 
> > otherwise you need to use a secured digest such as HMAC/CMAC/OMAC support
> > to sign the env at runtime and ensure the symetric key is secured
> > or encrypt it via aes (did this in the past)
> 
> For an upcoming project we'll add HMAC support to the state storage Marc
> recently submitted.
I've a patch too I need to send it

but I prefer to wait we have keystore support as this will store the key for
the HMAC otherwise we need to use HW HMAC that store the key in the soc

> 
> > ww may have to get secured malloac with part where the md/mw and any other
> > API can not touch only the crypto API
> > 
> > but this will be for later
> 
> Yes.
> 
> > I'll send a patch to use the pbkdf2 for password
> 
> Nice.

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-16 10:27                   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 11:25                     ` Jan Lübbe
  2015-03-16 11:33                       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 11:25 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Mo, 2015-03-16 at 11:27 +0100, Jean-Christophe PLAGNIOL-VILLARD
wrote:
> On 11:00 Mon 16 Mar     , Jan Lübbe wrote:
> > On Fr, 2015-03-13 at 16:49 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > you just need to have a unique ID on the HW and then use a x509 object
> > > to store it. then signed it with you CA. As only validated keys can be
> > > used, you can easly give a generated key for a specific HW.
> > > And this key will be valid only for this HW.
> > 
> > Yes, this sounds useful. So you'd have a board-specific way to check the
> > unique ID constraint in an intermediate cert against the HW ID?
> yes more or less but but at the key itself as you will have to upload the
> key to the board. And the key will only be accepted to be stored as it will
> be valid and have the HW ID.

OK. Sounds good to me.

> And for the record remember if you want to use module in secured boot mode
> for the kernel you will have to use x509 certificate anyway.
> 
> So why not to use the same principal.
> 
> u-boot way is not what is doing today on the market for authentication
> format. Today it's x509 or PGP.
> 
> So I do prefer to stay as standard as possible, this does not mean we can not
> support the FTD stuff. But IMHO it's not the right way.

x509 only defines the certificate format, not how it is used to sign
kernel, initramfs and device tree.

The kernel defines its own format based on ELF and store the signature
inside. That can't be reused directly for the kernel itself, initramfs
or DTB. UEFI has again its own format.

We don't want to sign kernel, initramfs and DTB individually, as this
would allow an attacker to mix-and-match these to trigger a
vulnerability. So we need to have some format which supports signing a
given configuration consisting of specific kernel, initramfs and DTB.

FIT handles this requirement. It also supports having multiple
configurations (each signed) referencing for example the same kernel
+initramfs but different DTBs for a set of similar boards.

What is the image format you intend to use with x509 certs?

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-16 11:25                     ` Jan Lübbe
@ 2015-03-16 11:33                       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 15:42                         ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 11:33 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 12:25 Mon 16 Mar     , Jan Lübbe wrote:
> On Mo, 2015-03-16 at 11:27 +0100, Jean-Christophe PLAGNIOL-VILLARD
> wrote:
> > On 11:00 Mon 16 Mar     , Jan Lübbe wrote:
> > > On Fr, 2015-03-13 at 16:49 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > you just need to have a unique ID on the HW and then use a x509 object
> > > > to store it. then signed it with you CA. As only validated keys can be
> > > > used, you can easly give a generated key for a specific HW.
> > > > And this key will be valid only for this HW.
> > > 
> > > Yes, this sounds useful. So you'd have a board-specific way to check the
> > > unique ID constraint in an intermediate cert against the HW ID?
> > yes more or less but but at the key itself as you will have to upload the
> > key to the board. And the key will only be accepted to be stored as it will
> > be valid and have the HW ID.
> 
> OK. Sounds good to me.
> 
> > And for the record remember if you want to use module in secured boot mode
> > for the kernel you will have to use x509 certificate anyway.
> > 
> > So why not to use the same principal.
> > 
> > u-boot way is not what is doing today on the market for authentication
> > format. Today it's x509 or PGP.
> > 
> > So I do prefer to stay as standard as possible, this does not mean we can not
> > support the FTD stuff. But IMHO it's not the right way.
> 
> x509 only defines the certificate format, not how it is used to sign
> kernel, initramfs and device tree.
> 
> The kernel defines its own format based on ELF and store the signature
> inside. That can't be reused directly for the kernel itself, initramfs
> or DTB. UEFI has again its own format.
> 
> We don't want to sign kernel, initramfs and DTB individually, as this
> would allow an attacker to mix-and-match these to trigger a
> vulnerability. So we need to have some format which supports signing a
> given configuration consisting of specific kernel, initramfs and DTB.
> 
> FIT handles this requirement. It also supports having multiple
> configurations (each signed) referencing for example the same kernel
> +initramfs but different DTBs for a set of similar boards.
> 
> What is the image format you intend to use with x509 certs?

I'm not talking about FIT format but the key FTD format

I do not like and do not want to use the FTD format to store the key
but x509.

Image format need to be 100% seperated from key format.

That's why I work on a framework so we do not care of both.

Multiple image format with multiple image of key format.

So internally we will store the key in our own format so we can do what we
want.

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 11:14                   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 12:08                     ` Jan Lübbe
  2015-03-16 12:19                       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 12:08 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Mo, 2015-03-16 at 12:14 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 11:19 Mon 16 Mar     , Jan Lübbe wrote:
> > Later I'd like to have optional support to switch barebox into a
> > "non-secure" or "developer" mode at runtime, which would make hardware
> > secrets inaccessible. That could be triggered when a prompt appears or
> > when booting for a different source (such as USB fastboot).
> 
> yeah, I like the idea but for this will have to put a lot of protection so you
> can not read/write some part of the memory included barebox itself (in RAM)
> 
> As in the kernel we have no memmory protection from the shell.

Not necessarily. For example on the MX6 you can trigger a security
violation in the CAAM from software. That will clear the OTPMK in its
Key-RAM. From that point on you can run any software but you will not be
able to decrypt any secret data which was encrypted with the OTPMK.

On hardware which supports something like this, debugging hardware
problems is easy and there is no danger of leaking any secret
information. If something is useful/possible in any specific project
obviously depends on the threat model and hardware capabilities.

> > > the main problem is not console but env you need to drop RW env support
> > > and use only RO one, except for keyring support where you will a RW env but
> > > not executable and only accesable by crypto API
> > > 
> > > otherwise you need to use a secured digest such as HMAC/CMAC/OMAC support
> > > to sign the env at runtime and ensure the symetric key is secured
> > > or encrypt it via aes (did this in the past)
> > 
> > For an upcoming project we'll add HMAC support to the state storage Marc
> > recently submitted.
> I've a patch too I need to send it

For environment or state storage?

> but I prefer to wait we have keystore support as this will store the key for
> the HMAC otherwise we need to use HW HMAC that store the key in the soc

Another possibility is to use the HW AES key and a compiled in value to
derive a per-device HMAC secret. The same approach can also be used in
Linux for deriving the IMA/EVM HMAC secret.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 12:08                     ` Jan Lübbe
@ 2015-03-16 12:19                       ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 13:28                         ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 12:19 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 13:08 Mon 16 Mar     , Jan Lübbe wrote:
> On Mo, 2015-03-16 at 12:14 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 11:19 Mon 16 Mar     , Jan Lübbe wrote:
> > > Later I'd like to have optional support to switch barebox into a
> > > "non-secure" or "developer" mode at runtime, which would make hardware
> > > secrets inaccessible. That could be triggered when a prompt appears or
> > > when booting for a different source (such as USB fastboot).
> > 
> > yeah, I like the idea but for this will have to put a lot of protection so you
> > can not read/write some part of the memory included barebox itself (in RAM)
> > 
> > As in the kernel we have no memmory protection from the shell.
> 
> Not necessarily. For example on the MX6 you can trigger a security
> violation in the CAAM from software. That will clear the OTPMK in its
> Key-RAM. From that point on you can run any software but you will not be
> able to decrypt any secret data which was encrypted with the OTPMK.
> 
> On hardware which supports something like this, debugging hardware
> problems is easy and there is no danger of leaking any secret
> information. If something is useful/possible in any specific project
> obviously depends on the threat model and hardware capabilities.

I knonw about the imx6 but that does not mean all the SoC
unfortunatly.

The other pb I see is this one where and do you plan to store the RO x509
the trusted one.

if you use on OTP this means this is enough to ensure secured boot as if you
can not modify the primary cert of key. No one can brake it. But as you load
it in ram you need to be sure no one modify it. Even in unlock mode to do only
allow to boot secure images by expected key.

So you may not have secured place to store the cert or key in ram but only
RAM. so we do need to forbidden this memory acces to everyone except the
crypto API. if we want ot allow dev mode.
> 
> > > > the main problem is not console but env you need to drop RW env support
> > > > and use only RO one, except for keyring support where you will a RW env but
> > > > not executable and only accesable by crypto API
> > > > 
> > > > otherwise you need to use a secured digest such as HMAC/CMAC/OMAC support
> > > > to sign the env at runtime and ensure the symetric key is secured
> > > > or encrypt it via aes (did this in the past)
> > > 
> > > For an upcoming project we'll add HMAC support to the state storage Marc
> > > recently submitted.
> > I've a patch too I need to send it
> 
> For environment or state storage?
envfs
> 
> > but I prefer to wait we have keystore support as this will store the key for
> > the HMAC otherwise we need to use HW HMAC that store the key in the soc
> 
> Another possibility is to use the HW AES key and a compiled in value to
> derive a per-device HMAC secret. The same approach can also be used in
> Linux for deriving the IMA/EVM HMAC secret.
this for me need to be integrated in the keystore to be transparent for the
rest of the API

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 12:19                       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 13:28                         ` Jan Lübbe
  2015-03-16 13:51                           ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 13:28 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Mo, 2015-03-16 at 13:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 13:08 Mon 16 Mar     , Jan Lübbe wrote:
> > On Mo, 2015-03-16 at 12:14 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > On 11:19 Mon 16 Mar     , Jan Lübbe wrote:
> > > > Later I'd like to have optional support to switch barebox into a
> > > > "non-secure" or "developer" mode at runtime, which would make hardware
> > > > secrets inaccessible. That could be triggered when a prompt appears or
> > > > when booting for a different source (such as USB fastboot).
> > > 
> > > yeah, I like the idea but for this will have to put a lot of protection so you
> > > can not read/write some part of the memory included barebox itself (in RAM)
> > > 
> > > As in the kernel we have no memmory protection from the shell.
> > 
> > Not necessarily. For example on the MX6 you can trigger a security
> > violation in the CAAM from software. That will clear the OTPMK in its
> > Key-RAM. From that point on you can run any software but you will not be
> > able to decrypt any secret data which was encrypted with the OTPMK.
> > 
> > On hardware which supports something like this, debugging hardware
> > problems is easy and there is no danger of leaking any secret
> > information. If something is useful/possible in any specific project
> > obviously depends on the threat model and hardware capabilities.
> 
> I knonw about the imx6 but that does not mean all the SoC
> unfortunatly.

Yes, every SoC is different. But we should be able to use HW features
when the are available, as sometimes the HW is selected specifically to
used these security features.

> The other pb I see is this one where and do you plan to store the RO x509
> the trusted one.

Sorry, I can't parse this.

> if you use on OTP this means this is enough to ensure secured boot as if you
> can not modify the primary cert of key. No one can brake it. But as you load
> it in ram you need to be sure no one modify it. Even in unlock mode to do only
> allow to boot secure images by expected key.

I should have been more clear: The use case here is to ensure that the
OTPMK-AES-HW-Key is only available when booting with a correct boot
chain. It's OK to boot something else (only the OTPMK needs to be
cleared).

This is a very different goal from making sure that only correctly
signed code is executed.

Both cases need mostly the same verified boot features, only the policy
(especially what to do on signature errors) is different.

> So you may not have secured place to store the cert or key in ram but only
> RAM. so we do need to forbidden this memory acces to everyone except the
> crypto API. if we want ot allow dev mode.

On MX6 this can be done by the HW. Doing this (without TrustZone) purely
in SW seems extremely difficult.

> > > > > the main problem is not console but env you need to drop RW env support
> > > > > and use only RO one, except for keyring support where you will a RW env but
> > > > > not executable and only accesable by crypto API
> > > > > 
> > > > > otherwise you need to use a secured digest such as HMAC/CMAC/OMAC support
> > > > > to sign the env at runtime and ensure the symetric key is secured
> > > > > or encrypt it via aes (did this in the past)
> > > > 
> > > > For an upcoming project we'll add HMAC support to the state storage Marc
> > > > recently submitted.
> > > I've a patch too I need to send it
> > 
> > For environment or state storage?
> envfs

Nice. :)

> > 
> > > but I prefer to wait we have keystore support as this will store the key for
> > > the HMAC otherwise we need to use HW HMAC that store the key in the soc
> > 
> > Another possibility is to use the HW AES key and a compiled in value to
> > derive a per-device HMAC secret. The same approach can also be used in
> > Linux for deriving the IMA/EVM HMAC secret.
> this for me need to be integrated in the keystore to be transparent for the
> rest of the API

That shouldn't be hard. We can look at this in detail after you've
posted that API.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 13:28                         ` Jan Lübbe
@ 2015-03-16 13:51                           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 14:31                             ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 13:51 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 14:28 Mon 16 Mar     , Jan Lübbe wrote:
> On Mo, 2015-03-16 at 13:19 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 13:08 Mon 16 Mar     , Jan Lübbe wrote:
> > > On Mo, 2015-03-16 at 12:14 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > On 11:19 Mon 16 Mar     , Jan Lübbe wrote:
> > > > > Later I'd like to have optional support to switch barebox into a
> > > > > "non-secure" or "developer" mode at runtime, which would make hardware
> > > > > secrets inaccessible. That could be triggered when a prompt appears or
> > > > > when booting for a different source (such as USB fastboot).
> > > > 
> > > > yeah, I like the idea but for this will have to put a lot of protection so you
> > > > can not read/write some part of the memory included barebox itself (in RAM)
> > > > 
> > > > As in the kernel we have no memmory protection from the shell.
> > > 
> > > Not necessarily. For example on the MX6 you can trigger a security
> > > violation in the CAAM from software. That will clear the OTPMK in its
> > > Key-RAM. From that point on you can run any software but you will not be
> > > able to decrypt any secret data which was encrypted with the OTPMK.
> > > 
> > > On hardware which supports something like this, debugging hardware
> > > problems is easy and there is no danger of leaking any secret
> > > information. If something is useful/possible in any specific project
> > > obviously depends on the threat model and hardware capabilities.
> > 
> > I knonw about the imx6 but that does not mean all the SoC
> > unfortunatly.
> 
> Yes, every SoC is different. But we should be able to use HW features
> when the are available, as sometimes the HW is selected specifically to
> used these security features.

I agree with you we just need to ensure that it work also when we can not
use such HW feature.
> 
> > The other pb I see is this one where and do you plan to store the RO x509
> > the trusted one.
> 
> Sorry, I can't parse this.
where do we store the trusted keys/cert need to be secured or inaccessible
except crypto API
> 
> > if you use on OTP this means this is enough to ensure secured boot as if you
> > can not modify the primary cert of key. No one can brake it. But as you load
> > it in ram you need to be sure no one modify it. Even in unlock mode to do only
> > allow to boot secure images by expected key.
> 
> I should have been more clear: The use case here is to ensure that the
> OTPMK-AES-HW-Key is only available when booting with a correct boot
> chain. It's OK to boot something else (only the OTPMK needs to be
> cleared).
> 
> This is a very different goal from making sure that only correctly
> signed code is executed.
> 
> Both cases need mostly the same verified boot features, only the policy
> (especially what to do on signature errors) is different.
secure boot means in 95% of the case only correctly signed file can be booted
> 
> > So you may not have secured place to store the cert or key in ram but only
> > RAM. so we do need to forbidden this memory acces to everyone except the
> > crypto API. if we want ot allow dev mode.
> 
> On MX6 this can be done by the HW. Doing this (without TrustZone) purely
> in SW seems extremely difficult.

if you do not allow console easy, if you do you need to make the memory where
you do store the trusted keys and barebox itself no accessible by any std API
or command

such as md/mw, etc...

yes this will be difficult

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 13:51                           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 14:31                             ` Jan Lübbe
  2015-03-16 14:40                               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 14:31 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Mo, 2015-03-16 at 14:51 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > The other pb I see is this one where and do you plan to store the RO x509
> > > the trusted one.
> > 
> > Sorry, I can't parse this.
> where do we store the trusted keys/cert need to be secured or inaccessible
> except crypto API

(The following depends on prohibiting any unauthenticated access to the
barebox console.)

If you just use a chain of signed code like with HAB on i.MX, every cert
is verified by the previous step (up to the SRK table hash), so there is
no need to additionally protect certs against modification. Any modified
cert would result in a verification error. In this setup there is no
secret information on the device at all.

When doing this without support from the SoC's ROM code, you could store
barebox (with compiled-in master public key(s)) in RO flash. Against an
attacker without physical access, this results in the same security
properties. You couldn't update the RO barebox, tough (only boot another
one second stage).

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 14:31                             ` Jan Lübbe
@ 2015-03-16 14:40                               ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-16 14:50                                 ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-16 14:40 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 15:31 Mon 16 Mar     , Jan Lübbe wrote:
> On Mo, 2015-03-16 at 14:51 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > The other pb I see is this one where and do you plan to store the RO x509
> > > > the trusted one.
> > > 
> > > Sorry, I can't parse this.
> > where do we store the trusted keys/cert need to be secured or inaccessible
> > except crypto API
> 
> (The following depends on prohibiting any unauthenticated access to the
> barebox console.)
> 
> If you just use a chain of signed code like with HAB on i.MX, every cert
> is verified by the previous step (up to the SRK table hash), so there is
> no need to additionally protect certs against modification. Any modified
> cert would result in a verification error. In this setup there is no
> secret information on the device at all.
> 
> When doing this without support from the SoC's ROM code, you could store
> barebox (with compiled-in master public key(s)) in RO flash. Against an
> attacker without physical access, this results in the same security
> properties. You couldn't update the RO barebox, tough (only boot another
> one second stage).

I agree with you I said the same

my key point is if we do allow console access we need be sure at 100% that
they can not tempered with the trusted key in RAM and barebox binary and
malloc space

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-16 14:40                               ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 14:50                                 ` Jan Lübbe
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 14:50 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Mo, 2015-03-16 at 15:40 +0100, Jean-Christophe PLAGNIOL-VILLARD
wrote:
> On 15:31 Mon 16 Mar     , Jan Lübbe wrote:
> > (The following depends on prohibiting any unauthenticated access to the
> > barebox console.)
> > 
> > If you just use a chain of signed code like with HAB on i.MX, every cert
> > is verified by the previous step (up to the SRK table hash), so there is
> > no need to additionally protect certs against modification. Any modified
> > cert would result in a verification error. In this setup there is no
> > secret information on the device at all.
> > 
> > When doing this without support from the SoC's ROM code, you could store
> > barebox (with compiled-in master public key(s)) in RO flash. Against an
> > attacker without physical access, this results in the same security
> > properties. You couldn't update the RO barebox, tough (only boot another
> > one second stage).
> 
> I agree with you I said the same
> 
> my key point is if we do allow console access we need be sure at 100% that
> they can not tempered with the trusted key in RAM and barebox binary and
> malloc space

Yes. We would also need to disallow access to devices and non-verifying
boot commands.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-16 11:33                       ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-16 15:42                         ` Jan Lübbe
  2015-03-17 10:48                           ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-16 15:42 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Mo, 2015-03-16 at 12:33 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> I do not like and do not want to use the FTD format to store the key
> but x509.

Yes, I think we are in agreement that we need to support both key
formats.

> Image format need to be 100% seperated from key format.

Of course.

> That's why I work on a framework so we do not care of both.
> 
> Multiple image format with multiple image of key format.

Could you explain your image format in a bit more detail? How your
intend to defend against a mix-and-match attack?

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-16 15:42                         ` Jan Lübbe
@ 2015-03-17 10:48                           ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-17 12:09                             ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-17 10:48 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 16:42 Mon 16 Mar     , Jan Lübbe wrote:
> On Mo, 2015-03-16 at 12:33 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > I do not like and do not want to use the FTD format to store the key
> > but x509.
> 
> Yes, I think we are in agreement that we need to support both key
> formats.
> 
> > Image format need to be 100% seperated from key format.
> 
> Of course.
> 
> > That's why I work on a framework so we do not care of both.
> > 
> > Multiple image format with multiple image of key format.
> 
> Could you explain your image format in a bit more detail? How your
> intend to defend against a mix-and-match attack?

One of the format we are using can only be one configure signed or/and encrypted
so no mix-and-match attack

Best Regards,
J.
> 
> Regards,
> Jan
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-17 10:48                           ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-17 12:09                             ` Jan Lübbe
  2015-03-17 12:39                               ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Lübbe @ 2015-03-17 12:09 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

Hi Jean-Christophe,

On Di, 2015-03-17 at 11:48 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > Could you explain your image format in a bit more detail? How your
> > intend to defend against a mix-and-match attack?
> 
> One of the format we are using can only be one configure signed or/and
> encrypted so no mix-and-match attack

Sorry, it's still not clear to me. Do you mean you would use FIT in that
case (it supports signed configurations)? Or do you mean that you are
using several formats, one of which uses signed/encrypted configurations
of kernel/initramfs/dt?

I want to understand how your image formats would be used in the larger
context of a BSP or distribution. Please describe which image formats
you want to support (in addition to FIT). How are they structured? How
are they generated? Are they already supported by other software? 

Thanks,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-17 12:09                             ` Jan Lübbe
@ 2015-03-17 12:39                               ` Jean-Christophe PLAGNIOL-VILLARD
  2015-03-17 12:57                                 ` Jan Lübbe
  0 siblings, 1 reply; 59+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-17 12:39 UTC (permalink / raw)
  To: Jan Lübbe; +Cc: barebox

On 13:09 Tue 17 Mar     , Jan Lübbe wrote:
> Hi Jean-Christophe,
> 
> On Di, 2015-03-17 at 11:48 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > Could you explain your image format in a bit more detail? How your
> > > intend to defend against a mix-and-match attack?
> > 
> > One of the format we are using can only be one configure signed or/and
> > encrypted so no mix-and-match attack
> 
> Sorry, it's still not clear to me. Do you mean you would use FIT in that
> case (it supports signed configurations)? Or do you mean that you are
> using several formats, one of which uses signed/encrypted configurations
> of kernel/initramfs/dt?
yes sevral format FIT is just one of them
> 
> I want to understand how your image formats would be used in the larger
> context of a BSP or distribution. Please describe which image formats
> you want to support (in addition to FIT). How are they structured? How
> are they generated? Are they already supported by other software? 
Today we use a bpk formoat

in bpk format you can store different data for each hw_id, each data have a
specific type.

we add a new type for the signature.

we do a sha512 of the other data of one hw_id and signed it with a rsa4096
we use 1 unique rsa key per HW_ID

as soon as one of the file of a specific hw_id is open we check the signature

The code is no public yet but this is handled at FS level

and we allow only to open data that have been verified or decrypted if we use
AES

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 2/4] Add rsa support
  2015-03-17 12:39                               ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-17 12:57                                 ` Jan Lübbe
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Lübbe @ 2015-03-17 12:57 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Di, 2015-03-17 at 13:39 +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > I want to understand how your image formats would be used in the larger
> > context of a BSP or distribution. Please describe which image formats
> > you want to support (in addition to FIT). How are they structured? How
> > are they generated? Are they already supported by other software? 
> Today we use a bpk formoat
> 
> in bpk format you can store different data for each hw_id, each data have a
> specific type.
> 
> we add a new type for the signature.
> 
> we do a sha512 of the other data of one hw_id and signed it with a rsa4096
> we use 1 unique rsa key per HW_ID
> 
> as soon as one of the file of a specific hw_id is open we check the signature
> 
> The code is no public yet but this is handled at FS level
> 
> and we allow only to open data that have been verified or decrypted if we use
> AES

Thanks for the explanation, it's clearer now.

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 0/4] FIT Support
  2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
                   ` (4 preceding siblings ...)
  2015-03-12 14:51 ` [RFC] digest: Add enum Jan Luebbe
@ 2015-11-11 11:39 ` Yegor Yefremov
  2015-11-13 11:35   ` Antony Pavlov
  2015-11-13 12:54   ` Sascha Hauer
  5 siblings, 2 replies; 59+ messages in thread
From: Yegor Yefremov @ 2015-11-11 11:39 UTC (permalink / raw)
  To: Jan Luebbe; +Cc: barebox

On Thu, Mar 12, 2015 at 3:39 PM, Jan Luebbe <jlu@pengutronix.de> wrote:
> Hi,
>
> this is the current work-in-progress state of my FIT support patches.
> The FIT loading code has basically been rewritten from scratch, as the
> original U-Boot code uses libfdt and barebox's DT support works on an
> in-memory tree.
>
> These patches apply on v2015.03.0.
> The two patches from Sascha are required for the basic RSA support.
> The third patch adds FIT support.
> The fourth patch contains some test data to use in the sandbox.
>
> $ ./barebox -i key.dtb -i sign-configs.itb
> add file key.dtb()
> add file sign-configs.itb()
>
> barebox 2015.03.0-00005-g574d35e191f7-dirty #81 Thu Mar 12 14:57:13 CET 2015
>
> Board: barebox sandbox
> ...
> Hit any key to stop autoboot:  3
> barebox@barebox sandbox:/ oftree -l /dev/fd0
> barebox@barebox sandbox:/ bootm /dev/fd1
>
> Loading open firmware Device Tree flattened Binary '/dev/fd1'
> FIT '/dev/fd1': 'Chrome OS kernel image with one or more FDT blobs'
> FIT configuration 'conf@1' (no description)
> sig OK
> FIT image 'kernel@1' (no description)
> hash OK
> FIT image 'fdt@1': 'snow'
> hash OK
>
> Jan Luebbe (2):
>   FIT: add FIT image support
>   FIT: add test config and data [do not merge]
>
> Sascha Hauer (2):
>   digest: Make filename arguments const
>   Add rsa support
>
>  arch/arm/lib/bootm.c                   |  74 +++++
>  arch/sandbox/configs/sandbox_defconfig |  33 +-
>  commands/Kconfig                       |   8 +
>  common/Kconfig                         |   7 +
>  common/Makefile                        |   1 +
>  common/digest.c                        |   8 +-
>  common/image-fit.c                     | 585 +++++++++++++++++++++++++++++++++
>  crypto/Kconfig                         |   3 +
>  crypto/Makefile                        |   1 +
>  crypto/rsa.c                           | 411 +++++++++++++++++++++++
>  include/asm-generic/errno.h            |   5 +
>  include/digest.h                       |   8 +-
>  include/image-fit.h                    |  42 +++
>  include/rsa.h                          |  54 +++
>  key.dtb                                | Bin 0 -> 1023 bytes
>  key.dts                                |  27 ++
>  sign-configs.itb                       | Bin 0 -> 2453 bytes
>  17 files changed, 1247 insertions(+), 20 deletions(-)
>  create mode 100644 common/image-fit.c
>  create mode 100644 crypto/rsa.c
>  create mode 100644 include/image-fit.h
>  create mode 100644 include/rsa.h
>  create mode 100644 key.dtb
>  create mode 100644 key.dts
>  create mode 100644 sign-configs.itb
>
> --
> 2.1.4

What the state of FIT support in Barebox?

Yegor

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 0/4] FIT Support
  2015-11-11 11:39 ` [RFC 0/4] FIT Support Yegor Yefremov
@ 2015-11-13 11:35   ` Antony Pavlov
  2015-11-13 12:54   ` Sascha Hauer
  1 sibling, 0 replies; 59+ messages in thread
From: Antony Pavlov @ 2015-11-13 11:35 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

On Wed, 11 Nov 2015 12:39:14 +0100
Yegor Yefremov <yegorslists@googlemail.com> wrote:

> On Thu, Mar 12, 2015 at 3:39 PM, Jan Luebbe <jlu@pengutronix.de> wrote:
> > Hi,
> >
> > this is the current work-in-progress state of my FIT support patches.
> > The FIT loading code has basically been rewritten from scratch, as the
> > original U-Boot code uses libfdt and barebox's DT support works on an
> > in-memory tree.
> >
> > These patches apply on v2015.03.0.
> > The two patches from Sascha are required for the basic RSA support.
> > The third patch adds FIT support.
> > The fourth patch contains some test data to use in the sandbox.
> >
> > $ ./barebox -i key.dtb -i sign-configs.itb
> > add file key.dtb()
> > add file sign-configs.itb()
> >
> > barebox 2015.03.0-00005-g574d35e191f7-dirty #81 Thu Mar 12 14:57:13 CET 2015
> >
> > Board: barebox sandbox
> > ...
> > Hit any key to stop autoboot:  3
> > barebox@barebox sandbox:/ oftree -l /dev/fd0
> > barebox@barebox sandbox:/ bootm /dev/fd1
> >
> > Loading open firmware Device Tree flattened Binary '/dev/fd1'
> > FIT '/dev/fd1': 'Chrome OS kernel image with one or more FDT blobs'
> > FIT configuration 'conf@1' (no description)
> > sig OK
> > FIT image 'kernel@1' (no description)
> > hash OK
> > FIT image 'fdt@1': 'snow'
> > hash OK
> >
> > Jan Luebbe (2):
> >   FIT: add FIT image support
> >   FIT: add test config and data [do not merge]
> >
> > Sascha Hauer (2):
> >   digest: Make filename arguments const
> >   Add rsa support
> >
> >  arch/arm/lib/bootm.c                   |  74 +++++
> >  arch/sandbox/configs/sandbox_defconfig |  33 +-
> >  commands/Kconfig                       |   8 +
> >  common/Kconfig                         |   7 +
> >  common/Makefile                        |   1 +
> >  common/digest.c                        |   8 +-
> >  common/image-fit.c                     | 585 +++++++++++++++++++++++++++++++++
> >  crypto/Kconfig                         |   3 +
> >  crypto/Makefile                        |   1 +
> >  crypto/rsa.c                           | 411 +++++++++++++++++++++++
> >  include/asm-generic/errno.h            |   5 +
> >  include/digest.h                       |   8 +-
> >  include/image-fit.h                    |  42 +++
> >  include/rsa.h                          |  54 +++
> >  key.dtb                                | Bin 0 -> 1023 bytes
> >  key.dts                                |  27 ++
> >  sign-configs.itb                       | Bin 0 -> 2453 bytes
> >  17 files changed, 1247 insertions(+), 20 deletions(-)
> >  create mode 100644 common/image-fit.c
> >  create mode 100644 crypto/rsa.c
> >  create mode 100644 include/image-fit.h
> >  create mode 100644 include/rsa.h
> >  create mode 100644 key.dtb
> >  create mode 100644 key.dts
> >  create mode 100644 sign-configs.itb
> >
> > --
> > 2.1.4
> 
> What the state of FIT support in Barebox?

Sascha!

Could you tell us, please,
is there any interest in FIT support in Barebox?

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 0/4] FIT Support
  2015-11-11 11:39 ` [RFC 0/4] FIT Support Yegor Yefremov
  2015-11-13 11:35   ` Antony Pavlov
@ 2015-11-13 12:54   ` Sascha Hauer
  2015-12-29  8:10     ` Yegor Yefremov
  2016-01-05  8:11     ` Marc Kleine-Budde
  1 sibling, 2 replies; 59+ messages in thread
From: Sascha Hauer @ 2015-11-13 12:54 UTC (permalink / raw)
  To: Yegor Yefremov; +Cc: barebox

On Wed, Nov 11, 2015 at 12:39:14PM +0100, Yegor Yefremov wrote:
> On Thu, Mar 12, 2015 at 3:39 PM, Jan Luebbe <jlu@pengutronix.de> wrote:
> > Hi,
> >
> > this is the current work-in-progress state of my FIT support patches.
> > The FIT loading code has basically been rewritten from scratch, as the
> > original U-Boot code uses libfdt and barebox's DT support works on an
> > in-memory tree.
> >
> > These patches apply on v2015.03.0.
> > The two patches from Sascha are required for the basic RSA support.
> > The third patch adds FIT support.
> > The fourth patch contains some test data to use in the sandbox.
> >
> > $ ./barebox -i key.dtb -i sign-configs.itb
> > add file key.dtb()
> > add file sign-configs.itb()
> >
> > barebox 2015.03.0-00005-g574d35e191f7-dirty #81 Thu Mar 12 14:57:13 CET 2015
> >
> > Board: barebox sandbox
> > ...
> > Hit any key to stop autoboot:  3
> > barebox@barebox sandbox:/ oftree -l /dev/fd0
> > barebox@barebox sandbox:/ bootm /dev/fd1
> >
> > Loading open firmware Device Tree flattened Binary '/dev/fd1'
> > FIT '/dev/fd1': 'Chrome OS kernel image with one or more FDT blobs'
> > FIT configuration 'conf@1' (no description)
> > sig OK
> > FIT image 'kernel@1' (no description)
> > hash OK
> > FIT image 'fdt@1': 'snow'
> > hash OK
> >
> > Jan Luebbe (2):
> >   FIT: add FIT image support
> >   FIT: add test config and data [do not merge]
> >
> > Sascha Hauer (2):
> >   digest: Make filename arguments const
> >   Add rsa support
> >
> >  arch/arm/lib/bootm.c                   |  74 +++++
> >  arch/sandbox/configs/sandbox_defconfig |  33 +-
> >  commands/Kconfig                       |   8 +
> >  common/Kconfig                         |   7 +
> >  common/Makefile                        |   1 +
> >  common/digest.c                        |   8 +-
> >  common/image-fit.c                     | 585 +++++++++++++++++++++++++++++++++
> >  crypto/Kconfig                         |   3 +
> >  crypto/Makefile                        |   1 +
> >  crypto/rsa.c                           | 411 +++++++++++++++++++++++
> >  include/asm-generic/errno.h            |   5 +
> >  include/digest.h                       |   8 +-
> >  include/image-fit.h                    |  42 +++
> >  include/rsa.h                          |  54 +++
> >  key.dtb                                | Bin 0 -> 1023 bytes
> >  key.dts                                |  27 ++
> >  sign-configs.itb                       | Bin 0 -> 2453 bytes
> >  17 files changed, 1247 insertions(+), 20 deletions(-)
> >  create mode 100644 common/image-fit.c
> >  create mode 100644 crypto/rsa.c
> >  create mode 100644 include/image-fit.h
> >  create mode 100644 include/rsa.h
> >  create mode 100644 key.dtb
> >  create mode 100644 key.dts
> >  create mode 100644 sign-configs.itb
> >
> > --
> > 2.1.4
> 
> What the state of FIT support in Barebox?

The state is: We have and use these patches, the newest version is based
on v2015.09. I don't know what's different in our current version
compared to this posted version.

I think we should mainline them quite soon, they are more helpful
in-tree.

Steffen, Marc, Markus? Any volunteers to resend them?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 0/4] FIT Support
  2015-11-13 12:54   ` Sascha Hauer
@ 2015-12-29  8:10     ` Yegor Yefremov
  2016-01-05  8:11     ` Marc Kleine-Budde
  1 sibling, 0 replies; 59+ messages in thread
From: Yegor Yefremov @ 2015-12-29  8:10 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

On Fri, Nov 13, 2015 at 1:54 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Wed, Nov 11, 2015 at 12:39:14PM +0100, Yegor Yefremov wrote:
>> On Thu, Mar 12, 2015 at 3:39 PM, Jan Luebbe <jlu@pengutronix.de> wrote:
>> > Hi,
>> >
>> > this is the current work-in-progress state of my FIT support patches.
>> > The FIT loading code has basically been rewritten from scratch, as the
>> > original U-Boot code uses libfdt and barebox's DT support works on an
>> > in-memory tree.
>> >
>> > These patches apply on v2015.03.0.
>> > The two patches from Sascha are required for the basic RSA support.
>> > The third patch adds FIT support.
>> > The fourth patch contains some test data to use in the sandbox.
>> >
>> > $ ./barebox -i key.dtb -i sign-configs.itb
>> > add file key.dtb()
>> > add file sign-configs.itb()
>> >
>> > barebox 2015.03.0-00005-g574d35e191f7-dirty #81 Thu Mar 12 14:57:13 CET 2015
>> >
>> > Board: barebox sandbox
>> > ...
>> > Hit any key to stop autoboot:  3
>> > barebox@barebox sandbox:/ oftree -l /dev/fd0
>> > barebox@barebox sandbox:/ bootm /dev/fd1
>> >
>> > Loading open firmware Device Tree flattened Binary '/dev/fd1'
>> > FIT '/dev/fd1': 'Chrome OS kernel image with one or more FDT blobs'
>> > FIT configuration 'conf@1' (no description)
>> > sig OK
>> > FIT image 'kernel@1' (no description)
>> > hash OK
>> > FIT image 'fdt@1': 'snow'
>> > hash OK
>> >
>> > Jan Luebbe (2):
>> >   FIT: add FIT image support
>> >   FIT: add test config and data [do not merge]
>> >
>> > Sascha Hauer (2):
>> >   digest: Make filename arguments const
>> >   Add rsa support
>> >
>> >  arch/arm/lib/bootm.c                   |  74 +++++
>> >  arch/sandbox/configs/sandbox_defconfig |  33 +-
>> >  commands/Kconfig                       |   8 +
>> >  common/Kconfig                         |   7 +
>> >  common/Makefile                        |   1 +
>> >  common/digest.c                        |   8 +-
>> >  common/image-fit.c                     | 585 +++++++++++++++++++++++++++++++++
>> >  crypto/Kconfig                         |   3 +
>> >  crypto/Makefile                        |   1 +
>> >  crypto/rsa.c                           | 411 +++++++++++++++++++++++
>> >  include/asm-generic/errno.h            |   5 +
>> >  include/digest.h                       |   8 +-
>> >  include/image-fit.h                    |  42 +++
>> >  include/rsa.h                          |  54 +++
>> >  key.dtb                                | Bin 0 -> 1023 bytes
>> >  key.dts                                |  27 ++
>> >  sign-configs.itb                       | Bin 0 -> 2453 bytes
>> >  17 files changed, 1247 insertions(+), 20 deletions(-)
>> >  create mode 100644 common/image-fit.c
>> >  create mode 100644 crypto/rsa.c
>> >  create mode 100644 include/image-fit.h
>> >  create mode 100644 include/rsa.h
>> >  create mode 100644 key.dtb
>> >  create mode 100644 key.dts
>> >  create mode 100644 sign-configs.itb
>> >
>> > --
>> > 2.1.4
>>
>> What the state of FIT support in Barebox?
>
> The state is: We have and use these patches, the newest version is based
> on v2015.09. I don't know what's different in our current version
> compared to this posted version.

I'm trying to apply/compile the patches from march and there are many
places, where the patches fail to apply or fail to compile as digest
structure has changed a lot. Do you have a newer version meanwhile?

> I think we should mainline them quite soon, they are more helpful
> in-tree.
>
> Steffen, Marc, Markus? Any volunteers to resend them?
>
> Sascha
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 3/4] FIT: add FIT image support
  2015-03-12 14:39 ` [RFC 3/4] FIT: add FIT image support Jan Luebbe
  2015-03-12 18:19   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2015-12-29 10:18   ` Yegor Yefremov
  1 sibling, 0 replies; 59+ messages in thread
From: Yegor Yefremov @ 2015-12-29 10:18 UTC (permalink / raw)
  To: Jan Luebbe; +Cc: barebox

On Thu, Mar 12, 2015 at 3:39 PM, Jan Luebbe <jlu@pengutronix.de> wrote:
> The FIT image format was defined for U-Boot and has been adopted by the
> depthcharge project as well. It is intended to be a replacement for the
> uimage format and has been extended to support signing of kernel,
> initramfs and devicetree images. This patch adds support for booting FIT
> images to barebox.
>
> To verify signed images, the RSA public key data must be available in
> the internal device tree. Currently only signature verification on
> configurations (which contains hashes of all referenced images) are
> implemented, as this is the most useful use case and reduces the
> complexity of the implementation.
>
> The host tool (mkimage) to sign images has not yet been imported from U-Boot.
>
> Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
> ---
>  arch/arm/lib/bootm.c |  74 +++++++
>  commands/Kconfig     |   8 +
>  common/Kconfig       |   7 +
>  common/Makefile      |   1 +
>  common/image-fit.c   | 585 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/image-fit.h  |  42 ++++
>  6 files changed, 717 insertions(+)
>  create mode 100644 common/image-fit.c
>  create mode 100644 include/image-fit.h
>
> diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
> index 8327c3f5603a..6d30c594bdc2 100644
> --- a/arch/arm/lib/bootm.c
> +++ b/arch/arm/lib/bootm.c
> @@ -552,6 +552,78 @@ BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs
>  BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage");
>  #endif
>
> +#include <image-fit.h>
> +
> +static int do_bootm_arm_fit(struct image_data *data)
> +{
> +       struct fit_handle *handle;
> +       int ret;
> +       unsigned long mem_free;
> +       unsigned long mem_start, mem_size;
> +
> +       handle = fit_open(data->os_file, data->os_num, data->verbose);
> +       if (!handle)
> +               return -EINVAL;
> +
> +       ret = sdram_start_and_size(&mem_start, &mem_size);
> +       if (ret)
> +               return ret;
> +
> +       /* no support for custom load address */
> +       data->os_address = mem_start + PAGE_ALIGN(handle->kernel_size * 4);
> +       data->os_res = request_sdram_region("fit-kernel", data->os_address, handle->kernel_size);
> +       if (!data->os_res) {
> +               pr_err("Cannot request region 0x%08lx - 0x%08lx\n",
> +                               data->os_address, handle->kernel_size);
> +               ret = -ENOMEM;
> +               goto err_out;
> +       }
> +       memcpy((void *)data->os_res->start, handle->kernel, handle->kernel_size);
> +
> +       /*
> +        * Put oftree/initrd close behind compressed kernel image to avoid
> +        * placing it outside of the kernels lowmem.
> +        */
> +       if (handle->initrd_size) {
> +               data->initrd_address = PAGE_ALIGN(data->os_res->end + SZ_1M);
> +               data->initrd_res = request_sdram_region("fit-initrd", data->initrd_address, handle->initrd_size);
> +               if (!data->initrd_res) {
> +                       ret = -ENOMEM;
> +                       goto err_out;
> +               }
> +               memcpy((void *)data->initrd_res->start, handle->initrd, handle->initrd_size);
> +       }
> +
> +       data->of_root_node = of_unflatten_dtb(handle->oftree);
> +       if (!data->of_root_node) {
> +               pr_err("unable to unflatten devicetree\n");
> +               ret = -EINVAL;
> +               goto err_out;
> +       }
> +
> +       /*
> +        * Put devicetree right after initrd if present or after the kernel
> +        * if not.
> +        */
> +       if (data->initrd_res)
> +               mem_free = PAGE_ALIGN(data->initrd_res->end);
> +       else
> +               mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M);
> +
> +       return __do_bootm_linux(data, mem_free, 0);
> +
> +err_out:
> +       if (handle)
> +               fit_close(handle);
> +       return ret;
> +}
> +
> +static struct image_handler arm_fit_handler = {
> +        .name = "FIT image",
> +        .bootm = do_bootm_arm_fit,
> +        .filetype = filetype_oftree,
> +};
> +
>  static struct binfmt_hook binfmt_aimage_hook = {
>         .type = filetype_aimage,
>         .exec = "bootm",
> @@ -577,6 +649,8 @@ static int armlinux_register_image_handler(void)
>                 register_image_handler(&aimage_handler);
>                 binfmt_register(&binfmt_aimage_hook);
>         }
> +       if (IS_BUILTIN(CONFIG_CMD_BOOTM_FITIMAGE))
> +               register_image_handler(&arm_fit_handler);
>         binfmt_register(&binfmt_arm_zimage_hook);
>         binfmt_register(&binfmt_barebox_hook);
>
> diff --git a/commands/Kconfig b/commands/Kconfig
> index e4f68e7bda31..8d8fd46c15ec 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -402,6 +402,14 @@ config CMD_BOOTM_AIMAGE
>         help
>           Support using Android Images.
>
> +config CMD_BOOTM_FITIMAGE
> +       bool
> +       prompt "FIT image support"
> +       select FITIMAGE
> +       depends on CMD_BOOTM && (ARM || SANDBOX)
> +       help
> +         Support using FIT Images.
> +
>  config CMD_BOOTU
>         tristate
>         default y
> diff --git a/common/Kconfig b/common/Kconfig
> index d4373431aae8..9dd0b65ef8ae 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -66,6 +66,13 @@ config UIMAGE
>         select CRC32
>         bool
>
> +config FITIMAGE
> +       bool
> +       select OFTREE
> +       select SHA1
> +       select SHA256
> +       select RSA
> +
>  config LOGBUF
>         bool
>
> diff --git a/common/Makefile b/common/Makefile
> index ee5dca70236e..a8008292f0d8 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_RESET_SOURCE)    += reset_source.o
>  obj-$(CONFIG_SHELL_HUSH)       += hush.o
>  obj-$(CONFIG_SHELL_SIMPLE)     += parser.o
>  obj-$(CONFIG_UIMAGE)           += image.o uimage.o
> +obj-$(CONFIG_FITIMAGE)         += image-fit.o
>  obj-$(CONFIG_MENUTREE)         += menutree.o
>  obj-$(CONFIG_EFI_GUID)         += efi-guid.o
>  obj-$(CONFIG_EFI_DEVICEPATH)   += efi-devicepath.o
> diff --git a/common/image-fit.c b/common/image-fit.c
> new file mode 100644
> index 000000000000..77df5e5f4205
> --- /dev/null
> +++ b/common/image-fit.c
> @@ -0,0 +1,585 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> + *
> + * Copyright (C) Jan Lübbe, 2014
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <boot.h>
> +#include <libfile.h>
> +#include <fdt.h>
> +#include <digest.h>
> +#include <of.h>
> +#include <fs.h>
> +#include <malloc.h>
> +#include <linux/ctype.h>
> +#include <asm/byteorder.h>
> +#include <errno.h>
> +#include <linux/err.h>
> +#include <stringlist.h>
> +#include <rsa.h>
> +#include <image-fit.h>
> +
> +#define FDT_MAX_DEPTH  32
> +#define FDT_MAX_PATH_LEN 200
> +
> +#define CHECK_LEVEL_NONE 0
> +#define CHECK_LEVEL_HASH 1
> +#define CHECK_LEVEL_SIG 2
> +#define CHECK_LEVEL_MAX 3
> +
> +static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int size)
> +{
> +       dt += size;
> +       dt = ALIGN(dt, 4);
> +
> +       if (dt > f->off_dt_struct + f->size_dt_struct)
> +               return 0;
> +
> +       return dt;
> +}
> +
> +static char *dt_string(struct fdt_header *f, char *strstart, uint32_t ofs)
> +{
> +       if (ofs > f->size_dt_strings)
> +               return NULL;
> +       else
> +               return strstart + ofs;
> +}
> +
> +static int of_read_string_list(struct device_node *np, const char *name, struct string_list *sl)
> +{
> +       struct property *prop;
> +       const char *s;
> +
> +       of_property_for_each_string(np, name, prop, s) {
> +               string_list_add(sl, s);
> +       }
> +
> +       return prop ? 0 : -EINVAL;
> +}
> +
> +static int fit_digest(void *fit, struct digest *digest,
> +               struct string_list *inc_nodes, struct string_list *exc_props,
> +               uint32_t hashed_strings_start, uint32_t hashed_strings_size)
> +{
> +       struct fdt_header *fdt = fit;
> +       uint32_t dt_struct;
> +       void *dt_strings;
> +       struct fdt_header f;
> +       int stack[FDT_MAX_DEPTH];
> +       char path[FDT_MAX_PATH_LEN];
> +       char *end;
> +       uint32_t tag;
> +       int start = -1;
> +       int depth = -1;
> +       int want = 0;
> +
> +       f.totalsize = fdt32_to_cpu(fdt->totalsize);
> +       f.off_dt_struct = fdt32_to_cpu(fdt->off_dt_struct);
> +       f.size_dt_struct = fdt32_to_cpu(fdt->size_dt_struct);
> +       f.off_dt_strings = fdt32_to_cpu(fdt->off_dt_strings);
> +       f.size_dt_strings = fdt32_to_cpu(fdt->size_dt_strings);
> +
> +       if (hashed_strings_start > f.size_dt_strings ||
> +           hashed_strings_size > f.size_dt_strings ||
> +           hashed_strings_start + hashed_strings_size > f.size_dt_strings) {
> +               pr_err("%s: hashed-strings too large\n", __func__);
> +               return -EINVAL;
> +       }
> +
> +       dt_struct = f.off_dt_struct;
> +       dt_strings = (void *)fdt + f.off_dt_strings;
> +
> +       end = path;
> +       *end = '\0';
> +
> +       do {
> +               const struct fdt_property *fdt_prop;
> +               const struct fdt_node_header *fnh;
> +               const char *name;
> +               int include = 0;
> +               int stop_at = 0;
> +               int offset = dt_struct;
> +               int maxlen, len;
> +
> +               tag = be32_to_cpu(*(uint32_t *)(fit + dt_struct));
> +
> +               switch (tag) {
> +               case FDT_BEGIN_NODE:
> +                       fnh = fit + dt_struct;
> +                       name = fnh->name;
> +                       maxlen = (unsigned long)fdt + f.off_dt_struct +
> +                               f.size_dt_struct - (unsigned long)name;
> +
> +                       len = strnlen(name, maxlen + 1);
> +                       if (len > maxlen)
> +                               return -ESPIPE;
> +
> +                       dt_struct = dt_struct_advance(&f, dt_struct,
> +                                       sizeof(struct fdt_node_header) + len + 1);
> +
> +                       depth++;
> +                       if (depth == FDT_MAX_DEPTH)
> +                               return -ESPIPE;
> +                       if (end - path + 2 + len >= FDT_MAX_PATH_LEN)
> +                               return -ESPIPE;
> +                       if (end != path + 1)
> +                               *end++ = '/';
> +                       strcpy(end, name);
> +                       end += len;
> +                       stack[depth] = want;
> +                       if (want == 1)
> +                               stop_at = offset;
> +                       if (string_list_contains(inc_nodes, path))
> +                               want = 2;
> +                       else if (want)
> +                               want--;
> +                       else
> +                               stop_at = offset;
> +                       include = want;
> +
> +                       break;
> +
> +               case FDT_END_NODE:
> +                       dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
> +
> +                       include = want;
> +                       want = stack[depth--];
> +                       while (end > path && *--end != '/')
> +                               ;
> +                       *end = '\0';
> +
> +                       break;
> +
> +               case FDT_PROP:
> +                       fdt_prop = fit + dt_struct;
> +                       len = fdt32_to_cpu(fdt_prop->len);
> +
> +                       name = dt_string(&f, dt_strings, fdt32_to_cpu(fdt_prop->nameoff));
> +                       if (!name)
> +                               return -ESPIPE;
> +
> +                       dt_struct = dt_struct_advance(&f, dt_struct,
> +                                       sizeof(struct fdt_property) + len);
> +
> +                       include = want >= 2;
> +                       stop_at = offset;
> +                       if (string_list_contains(exc_props, name))
> +                               include = 0;
> +
> +                       break;
> +
> +               case FDT_NOP:
> +                       dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
> +
> +                       include = want >= 2;
> +                       stop_at = offset;
> +
> +                       break;
> +
> +               case FDT_END:
> +                       dt_struct = dt_struct_advance(&f, dt_struct, FDT_TAGSIZE);
> +
> +                       include = 1;
> +
> +                       break;
> +
> +               default:
> +                       pr_err("%s: Unknown tag 0x%08X\n", __func__, tag);
> +                       return -EINVAL;
> +               }
> +
> +               if (!dt_struct)
> +                       return -ESPIPE;
> +
> +               pr_debug("%s: include %d, want %d, offset 0x%x, len 0x%x\n",
> +                       path, include, want, offset, dt_struct-offset);
> +
> +               if (include && start == -1)
> +                       start = offset;
> +
> +               if (!include && start != -1) {
> +                       pr_debug("region: 0x%p+0x%x\n", fit+start, offset-start);
> +                       digest->update(digest, fit+start, offset-start);
> +                       start = -1;
> +               }
> +       } while (tag != FDT_END);
> +
> +       pr_debug("region: 0x%p+0x%x\n", fit+start, dt_struct-start);
> +       digest->update(digest, fit+start, dt_struct-start);
> +
> +       pr_debug("strings: 0x%p+0x%x\n", dt_strings+hashed_strings_start, hashed_strings_size);
> +       digest->update(digest, dt_strings+hashed_strings_start, hashed_strings_size);
> +
> +       return 0;
> +}
> +
> +/*
> + * The consistency of the FTD structure was already checked by of_unflatten_dtb()
> + */
> +static int fit_verify_signature(struct device_node *sig_node, void *fit)
> +{
> +       uint32_t hashed_strings_start, hashed_strings_size;
> +       struct string_list inc_nodes, exc_props;
> +       struct rsa_public_key key = {};
> +       struct digest *digest;
> +       int sig_len;
> +       const char *algo_name, *key_name, *sig_value;
> +       char *key_path;
> +       struct device_node *key_node;
> +       enum hash_algo algo;
> +       void *hash;
> +       int ret;
> +
> +       if (of_property_read_string(sig_node, "algo", &algo_name)) {
> +               pr_err("algo not found\n");
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +       if (strcmp(algo_name, "sha1,rsa2048") == 0) {
> +               algo = HASH_ALGO_SHA1;
> +       } else {
> +               pr_err("unknown algo %s\n", algo_name);
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +       digest = digest_get(algo);
> +       if (!digest) {
> +               pr_err("unsupported algo %s\n", algo_name);
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +
> +       sig_value = of_get_property(sig_node, "value", &sig_len);
> +       if (!sig_value) {
> +               pr_err("signature value not found\n");
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +
> +       if (of_property_read_string(sig_node, "key-name-hint", &key_name)) {
> +               pr_err("key name not found\n");
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +       key_path = asprintf("/signature/key-%s", key_name);
> +       if (!key_name) {
> +               ret = -ENOMEM;
> +               goto out;
> +       }
> +       key_node = of_find_node_by_path(key_path);
> +       free(key_path);
> +       if (!key_node) {
> +               pr_info("failed to find key node\n");
> +               ret = -ENOENT;
> +               goto out;
> +       }
> +
> +       ret = rsa_of_read_key(key_node, &key);
> +       if (ret) {
> +               pr_info("failed to read key\n");
> +               ret = -ENOENT;
> +               goto out;
> +       }
> +
> +       if (of_property_read_u32_index(sig_node, "hashed-strings", 0, &hashed_strings_start)) {
> +               pr_err("%s: hashed-strings start not found\n", __func__);
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +       if (of_property_read_u32_index(sig_node, "hashed-strings", 1, &hashed_strings_size)) {
> +               pr_err("%s: hashed-strings size not found\n", __func__);
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +
> +       string_list_init(&inc_nodes);
> +       string_list_init(&exc_props);
> +
> +       if (of_read_string_list(sig_node, "hashed-nodes", &inc_nodes))
> +       {
> +               pr_err("%s: hashed-nodes invalid\n", __func__);
> +               ret = -EINVAL;
> +               goto out_sl;
> +       }
> +
> +       string_list_add(&exc_props, "data");
> +
> +       digest->init(digest);
> +       ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start, hashed_strings_size);
> +       hash = xzalloc(digest->length);
> +       digest->final(digest, hash);
> +
> +       ret = rsa_verify(&key, sig_value, sig_len, hash, algo);
> +       if (ret) {
> +               pr_info("sig BAD\n");
> +               ret = CHECK_LEVEL_NONE;
> +       } else {
> +               pr_info("sig OK\n");
> +               ret = CHECK_LEVEL_SIG;
> +       }
> +
> +       free(hash);
> +out_sl:
> +       string_list_free(&inc_nodes);
> +       string_list_free(&exc_props);
> +out:
> +       return ret;
> +}
> +
> +static int fit_verify_hash(struct device_node *hash, const void *data, int data_len)
> +{
> +       struct digest *d;
> +       const char *algo;
> +       const char *value_read;
> +       char *value_calc;
> +       int hash_len;
> +
> +       value_read = of_get_property(hash, "value", &hash_len);
> +       if (!value_read) {
> +               pr_err("value not found\n");
> +               return CHECK_LEVEL_NONE;
> +       }
> +
> +       if (of_property_read_string(hash, "algo", &algo)) {
> +               pr_err("algo not found\n");
> +               return -EINVAL;
> +       }
> +
> +       d = digest_get_by_name(algo);
> +       if (!d) {
> +               pr_err("unsupported algo %s\n", algo);
> +               return -EINVAL;
> +       }
> +
> +       if (hash_len != d->length) {
> +               pr_err("invalid hash length %d\n", hash_len);
> +               return -EINVAL;
> +       }
> +
> +       value_calc = xmalloc(hash_len);
> +
> +       d->init(d);
> +       d->update(d, data, data_len);
> +       d->final(d, value_calc);
> +
> +       if (memcmp(value_read, value_calc, hash_len)) {
> +               pr_info("hash BAD\n");
> +               return CHECK_LEVEL_NONE;
> +       } else {
> +               pr_info("hash OK\n");
> +               return CHECK_LEVEL_HASH;
> +       }
> +}
> +
> +static int fit_open_image(struct fit_handle *handle, const char* unit)
> +{
> +       struct device_node *image = NULL, *hash;
> +       const char *type = NULL, *desc;
> +       const void *data;
> +       int data_len;
> +       int ret, level;
> +
> +       image = of_get_child_by_name(handle->root, "images");
> +       if (!image)
> +               return -ENOENT;
> +
> +       image = of_get_child_by_name(image, unit);
> +       if (!image)
> +               return -ENOENT;
> +
> +       if (of_property_read_string(image, "description", &desc)) {
> +               pr_info("FIT image '%s' (no description)\n", unit);
> +       } else {
> +               pr_info("FIT image '%s': '%s'\n", unit, desc);
> +       }
> +
> +       of_property_read_string(image, "type", &type);
> +       if (!type)
> +               return -EINVAL;
> +
> +       data = of_get_property(image, "data", &data_len);
> +       if (!data) {
> +               pr_err("data not found\n");
> +               return -EINVAL;
> +       }
> +
> +       level = CHECK_LEVEL_MAX;
> +       for_each_child_of_node(image, hash) {
> +               if (handle->verbose)
> +                       of_print_nodes(hash, 0);
> +               ret = fit_verify_hash(hash, data, data_len);
> +               if (ret < 0)
> +                       return ret;
> +               level = min(level, ret);
> +       }
> +       if (level == CHECK_LEVEL_MAX) {
> +               return -EINVAL;
> +       }
> +
> +       if (level == CHECK_LEVEL_HASH) {
> +               if (strcmp(type, "kernel") == 0 ||
> +                       strcmp(type, "kernel_noload") == 0) {
> +                       handle->kernel = data;
> +                       handle->kernel_size = data_len;
> +               } else if (strcmp(type, "flat_dt") == 0) {
> +                       handle->oftree = data;
> +                       handle->oftree_size = data_len;
> +               } else if (strcmp(type, "ramdisk") == 0) {
> +                       handle->initrd = data;
> +                       handle->initrd_size = data_len;
> +               } else {
> +                       pr_info("unknown image type %s, ignoring\n", type);
> +               }
> +       }
> +
> +       return level;
> +}
> +
> +static int fit_open_configuration(struct fit_handle *handle, int num)
> +{
> +       struct device_node *conf_node = NULL, *sig_node;
> +       char unit_name[10];
> +       const char *unit, *desc;
> +       int ret, level;
> +
> +       conf_node = of_get_child_by_name(handle->root, "configurations");
> +       if (!conf_node)
> +               return -ENOENT;
> +
> +       if (num) {
> +               snprintf(unit_name, sizeof(unit_name), "conf@%d", num);

works for me with this change:

               snprintf(unit_name, sizeof(unit_name), "conf%d@1", num);

> +               unit = unit_name;
> +       } else if (of_property_read_string(conf_node, "default", &unit)) {
> +               unit = "conf@1";
> +       }
> +
> +       conf_node = of_get_child_by_name(conf_node, unit);
> +       if (!conf_node) {
> +               pr_err("FIT configuration '%s' not found\n", unit);
> +               return -ENOENT;
> +       }
> +
> +       if (of_property_read_string(conf_node, "description", &desc)) {
> +               pr_info("FIT configuration '%s' (no description)\n", unit);
> +       } else {
> +               pr_info("FIT configuration '%s': '%s'\n", unit, desc);
> +       }
> +
> +       level = CHECK_LEVEL_MAX;
> +       for_each_child_of_node(conf_node, sig_node) {
> +               if (handle->verbose)
> +                       of_print_nodes(sig_node, 0);
> +               ret = fit_verify_signature(sig_node, handle->fit);
> +               if (ret < 0)
> +                       return ret;
> +               level = min(level, ret);
> +       }
> +       if (level == CHECK_LEVEL_MAX)
> +               return -EINVAL;
> +
> +       if (level != CHECK_LEVEL_SIG)
> +               return -EINVAL;
> +
> +       if (of_property_read_string(conf_node, "kernel", &unit) == 0)
> +               level = min(level, fit_open_image(handle, unit));
> +       else
> +               return -ENOENT;
> +
> +       if (of_property_read_string(conf_node, "fdt", &unit) == 0)
> +               level = min(level, fit_open_image(handle, unit));
> +
> +       if (of_property_read_string(conf_node, "ramdisk", &unit) == 0)
> +               level = min(level, fit_open_image(handle, unit));
> +
> +       if (level != CHECK_LEVEL_HASH)
> +               return -EINVAL;
> +
> +       return 0;
> +}
> +
> +struct fit_handle *fit_open(const char *filename, int num, bool verbose)
> +{
> +       struct fit_handle *handle = NULL;
> +       const char *desc;
> +
> +       handle = xzalloc(sizeof(struct fit_handle));
> +
> +       handle->verbose = verbose;
> +
> +       handle->fit = read_file(filename, &handle->size);
> +       if (!handle->fit) {
> +               pr_err("unable to read %s: %s\n", filename, strerror(errno));
> +               goto err;
> +       }
> +
> +       handle->root = of_unflatten_dtb(handle->fit);
> +       if (IS_ERR(handle->root)) {
> +               goto err;
> +       }
> +
> +       if (of_property_read_string(handle->root, "description", &desc)) {
> +               pr_info("FIT '%s' (no description)\n", filename);
> +       } else {
> +               pr_info("FIT '%s': '%s'\n", filename, desc);
> +       }
> +
> +       if (fit_open_configuration(handle, num))
> +               goto err;
> +
> +       return handle;
> +err:
> +       if (handle->root)
> +               of_delete_node(handle->root);
> +       if (handle->fit)
> +               free(handle->fit);
> +       free(handle);
> +
> +       return NULL;
> +}
> +
> +void fit_close(struct fit_handle *handle)
> +{
> +       if (handle->root)
> +               of_delete_node(handle->root);
> +       if (handle->fit)
> +               free(handle->fit);
> +       free(handle);
> +}
> +
> +#ifdef CONFIG_SANDBOX
> +static int do_bootm_sandbox_fit(struct image_data *data)
> +{
> +       struct fit_handle *handle;
> +       handle = fit_open(data->os_file, data->os_num, data->verbose);
> +       if (handle)
> +               fit_close(handle);
> +       return 0;
> +}
> +
> +static struct image_handler sandbox_fit_handler = {
> +       .name = "FIT image",
> +       .bootm = do_bootm_sandbox_fit,
> +       .filetype = filetype_oftree,
> +};
> +
> +static int sandbox_fit_register(void)
> +{
> +       return register_image_handler(&sandbox_fit_handler);
> +}
> +late_initcall(sandbox_fit_register);
> +#endif
> +
> diff --git a/include/image-fit.h b/include/image-fit.h
> new file mode 100644
> index 000000000000..bcbc859ead37
> --- /dev/null
> +++ b/include/image-fit.h
> @@ -0,0 +1,42 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> + *
> + * Copyright (C) Jan Lübbe, 2014
> + */
> +
> +#ifndef __IMAGE_FIT_H__
> +#define __IMAGE_FIT_H__
> +
> +#include <linux/types.h>
> +
> +struct fit_handle {
> +       void *fit;
> +       size_t size;
> +
> +       bool verbose;
> +
> +       struct device_node *root;
> +
> +       const void *kernel;
> +       unsigned long kernel_size;
> +       const void *oftree;
> +       unsigned long oftree_size;
> +       const void *initrd;
> +       unsigned long initrd_size;
> +};
> +
> +struct fit_handle *fit_open(const char *filename, int num, bool verbose);
> +void fit_close(struct fit_handle *handle);
> +
> +#endif /* __IMAGE_FIT_H__ */
> --
> 2.1.4
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [RFC 0/4] FIT Support
  2015-11-13 12:54   ` Sascha Hauer
  2015-12-29  8:10     ` Yegor Yefremov
@ 2016-01-05  8:11     ` Marc Kleine-Budde
  1 sibling, 0 replies; 59+ messages in thread
From: Marc Kleine-Budde @ 2016-01-05  8:11 UTC (permalink / raw)
  To: Sascha Hauer, Yegor Yefremov; +Cc: barebox


[-- Attachment #1.1: Type: text/plain, Size: 481 bytes --]

On 11/13/2015 01:54 PM, Sascha Hauer wrote:
> I think we should mainline them quite soon, they are more helpful
> in-tree.
> 
> Steffen, Marc, Markus? Any volunteers to resend them?

Done.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

[-- Attachment #2: Type: text/plain, Size: 149 bytes --]

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2016-01-05  8:12 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-12 14:39 [RFC 0/4] FIT Support Jan Luebbe
2015-03-12 14:39 ` [RFC 1/4] digest: Make filename arguments const Jan Luebbe
2015-03-13  7:40   ` Sascha Hauer
2015-03-12 14:39 ` [RFC 2/4] Add rsa support Jan Luebbe
2015-03-12 17:47   ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13  9:35     ` Jan Lübbe
2015-03-13  9:56       ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 10:06         ` Sascha Hauer
2015-03-13 10:12           ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 10:22             ` Jan Lübbe
2015-03-13 10:26               ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 10:10         ` Jan Lübbe
2015-03-13 10:25           ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 10:43             ` Jan Lübbe
2015-03-13 15:49               ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 10:00                 ` Jan Lübbe
2015-03-16 10:27                   ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 11:25                     ` Jan Lübbe
2015-03-16 11:33                       ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 15:42                         ` Jan Lübbe
2015-03-17 10:48                           ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-17 12:09                             ` Jan Lübbe
2015-03-17 12:39                               ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-17 12:57                                 ` Jan Lübbe
2015-03-12 14:39 ` [RFC 3/4] FIT: add FIT image support Jan Luebbe
2015-03-12 18:19   ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13  9:28     ` Jan Lübbe
2015-03-13 10:05       ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 10:21         ` Jan Lübbe
2015-03-13 14:28           ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 15:41             ` Jan Lübbe
2015-03-13 16:08               ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 10:19                 ` Jan Lübbe
2015-03-16 11:14                   ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 12:08                     ` Jan Lübbe
2015-03-16 12:19                       ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 13:28                         ` Jan Lübbe
2015-03-16 13:51                           ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 14:31                             ` Jan Lübbe
2015-03-16 14:40                               ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 14:50                                 ` Jan Lübbe
2015-03-13 11:33         ` Marc Kleine-Budde
2015-03-13 15:54           ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 16:06             ` Marc Kleine-Budde
2015-03-13 17:00               ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-16 10:04                 ` Jan Lübbe
2015-03-16 10:28                   ` Jean-Christophe PLAGNIOL-VILLARD
2015-12-29 10:18   ` Yegor Yefremov
2015-03-12 14:39 ` [RFC 4/4] FIT: add test config and data [do not merge] Jan Luebbe
2015-03-12 14:51 ` [RFC] digest: Add enum Jan Luebbe
2015-03-12 17:50   ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13  9:54     ` Jan Lübbe
2015-03-13 10:10       ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-13 18:50         ` Robert Schwebel
2015-11-11 11:39 ` [RFC 0/4] FIT Support Yegor Yefremov
2015-11-13 11:35   ` Antony Pavlov
2015-11-13 12:54   ` Sascha Hauer
2015-12-29  8:10     ` Yegor Yefremov
2016-01-05  8:11     ` Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox