All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation
@ 2014-12-30  9:30 Ruchika Gupta
  2014-12-30  9:30 ` [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig Ruchika Gupta
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

Public exponentiation which is required in rsa verify functionality is
tightly integrated with verification code in rsa_verify.c. The patch
splits the file into twp separating the modular exponentiation.

1. rsa-verify.c
- The file parses device tree keys node to fill a keyprop structure.
The keyprop structure can then be converted to implementation specific
format.
(struct rsa_pub_key for sw implementation)
- The parsed device tree node is then passed to a generic rsa_mod_exp
function.

2. rsa-mod-exp.c
Move the software specific functions related to modular exponentiation
from rsa-verify.c to this file.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Modified rsa_mod_exp_sw function to add pointer to output length

Changes in v3:
Kconfig moved to separate patch. This patch just splits the file now

Changes in v2:
Addressed few of Simon Glass's comments:
- Kconfig option added for RSA
- Comments added for new keyprop struct

 include/u-boot/rsa-mod-exp.h |  49 +++++++
 lib/rsa/Makefile             |   2 +-
 lib/rsa/rsa-mod-exp.c        | 309 ++++++++++++++++++++++++++++++++++++++
 lib/rsa/rsa-verify.c         | 343 +++++++++----------------------------------
 tools/Makefile               |   3 +-
 5 files changed, 429 insertions(+), 277 deletions(-)
 create mode 100644 include/u-boot/rsa-mod-exp.h
 create mode 100644 lib/rsa/rsa-mod-exp.c

diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
new file mode 100644
index 0000000..7b74f3c
--- /dev/null
+++ b/include/u-boot/rsa-mod-exp.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Ruchika Gupta.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+*/
+
+#ifndef _RSA_MOD_EXP_H
+#define _RSA_MOD_EXP_H
+
+#include <errno.h>
+#include <image.h>
+
+/**
+ * struct key_prop - holder for a public key properties
+ *
+ * The struct has pointers to modulus (Typically called N),
+ * The inverse, R^2, exponent. These can be typecasted and
+ * used as byte arrays or converted to the required format
+ * as per requirement of RSA implementation.
+ */
+struct key_prop {
+	const void *rr;		/* R^2 can be treated as byte array */
+	const void *modulus;	/* modulus as byte array */
+	const void *public_exponent; /* public exponent as byte array */
+	uint32_t n0inv;		/* -1 / modulus[0] mod 2^32 */
+	int num_bits;		/* Key length in bits */
+	uint32_t exp_len;	/* Exponent length in number of uint8_t */
+};
+
+/**
+ * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
+ *
+ * Operation: result[] = sig ^ exponent % modulus
+ *
+ * @sig:	RSA PKCS1.5 signature
+ * @sig_len:	Length of signature in number of bytes
+ * @node:	Node with RSA key elements like modulus, exponent, R^2, n0inv
+ * @outp:	Set to an allocated buffer holding the output hash
+ * @out_len:	Set to length of hash(outp) calculated after exponentiation
+ *
+ * This computes exponentiation over the signature. Resulting hash value is
+ * placed in an allocated buffer, the pointer is returned as *outp. The
+ * length of calulated hash is returned via the out_len pointer argument. The
+ * caller should free *outp
+ */
+int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
+		struct key_prop *node, uint8_t **outp, uint32_t *out_len);
+
+#endif
diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
index a5a96cb6..cc25b3c 100644
--- a/lib/rsa/Makefile
+++ b/lib/rsa/Makefile
@@ -7,4 +7,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
+obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o rsa-mod-exp.o
diff --git a/lib/rsa/rsa-mod-exp.c b/lib/rsa/rsa-mod-exp.c
new file mode 100644
index 0000000..af01b74
--- /dev/null
+++ b/lib/rsa/rsa-mod-exp.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <asm/errno.h>
+#include <asm/types.h>
+#include <asm/unaligned.h>
+#else
+#include "fdt_host.h"
+#include "mkimage.h"
+#include <fdt_support.h>
+#endif
+#include <malloc.h>
+#include <u-boot/rsa.h>
+#include <u-boot/rsa-mod-exp.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
+
+/**
+ * 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, uint32_t *inout)
+{
+	uint32_t *result, *ptr;
+	uint i;
+	int j, k;
+
+	/* 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;
+	}
+
+	uint32_t val[key->len], acc[key->len], tmp[key->len];
+	uint32_t a_scaled[key->len];
+	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@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@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;
+}
+
+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_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
+		struct key_prop *prop, uint8_t **out, uint32_t *len)
+{
+	struct rsa_public_key key;
+	int ret;
+
+	if (!prop) {
+		debug("%s: Skipping invalid prop", __func__);
+		return -EBADF;
+	}
+	if (!prop->n0inv) {
+		debug("%s: Missing rsa,n0-inverse", __func__);
+		return -EFAULT;
+	}
+	key.n0inv = prop->n0inv;
+	key.len = prop->num_bits;
+
+	if (!prop->public_exponent)
+		key.exponent = RSA_DEFAULT_PUBEXP;
+	else
+		key.exponent =
+			fdt64_to_cpu(*((uint64_t *)(prop->public_exponent)));
+
+	if (!key.len || !prop->modulus || !prop->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;
+	uint32_t key1[key.len], key2[key.len];
+
+	key.modulus = key1;
+	key.rr = key2;
+	rsa_convert_big_endian(key.modulus, (uint32_t *)prop->modulus, key.len);
+	rsa_convert_big_endian(key.rr, (uint32_t *)prop->rr, key.len);
+	if (!key.modulus || !key.rr) {
+		debug("%s: Out of memory", __func__);
+		return -ENOMEM;
+	}
+
+	uint32_t *buf = malloc(sig_len);
+
+	memcpy(buf, sig, sig_len);
+
+	ret = pow_mod(&key, buf);
+	if (ret)
+		return ret;
+
+	*out = (uint8_t *)buf;
+	*len = sig_len;
+
+	return 0;
+}
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 4ef19b6..1d2e707 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -17,230 +17,27 @@
 #include "mkimage.h"
 #include <fdt_support.h>
 #endif
+#include <malloc.h>
+#include <u-boot/rsa-mod-exp.h>
 #include <u-boot/rsa.h>
-#include <u-boot/sha1.h>
-#include <u-boot/sha256.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
 
 /**
- * subtract_modulus() - subtract modulus from the given value
+ * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
- * @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
+ * Verify a RSA PKCS1.5 signature against an expected hash using
+ * the RSA Key properties in prop structure.
  *
- * @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
+ * @prop:	Specifies key
+ * @sig:	Signature
+ * @sig_len:	Number of bytes in signature
+ * @hash:	Pointer to the expected hash
+ * @algo:	Checksum algo structure having information on RSA padding etc.
+ * @return 0 if verified, -ve on error
  */
-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, uint32_t *inout)
-{
-	uint32_t *result, *ptr;
-	uint i;
-	int j, k;
-
-	/* 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;
-	}
-
-	uint32_t val[key->len], acc[key->len], tmp[key->len];
-	uint32_t a_scaled[key->len];
-	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@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@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;
-}
-
-static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
+static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
 			  const uint32_t sig_len, const uint8_t *hash,
 			  struct checksum_algo *algo)
 {
@@ -248,10 +45,10 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
 	int pad_len;
 	int ret;
 
-	if (!key || !sig || !hash || !algo)
+	if (!prop || !sig || !hash || !algo)
 		return -EIO;
 
-	if (sig_len != (key->len * sizeof(uint32_t))) {
+	if (sig_len != (prop->num_bits / 8)) {
 		debug("Signature is of incorrect length %d\n", sig_len);
 		return -EINVAL;
 	}
@@ -265,13 +62,20 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
 		return -EINVAL;
 	}
 
-	uint32_t buf[sig_len / sizeof(uint32_t)];
+	uint8_t *buf;
+	uint32_t buf_len;
 
-	memcpy(buf, sig, sig_len);
-
-	ret = pow_mod(key, buf);
-	if (ret)
+	ret = rsa_mod_exp_sw(sig, sig_len, prop, &buf, &buf_len);
+	if (ret) {
+		debug("Error in Modular exponentation\n");
 		return ret;
+	}
+
+	if (buf_len != sig_len) {
+		debug("In RSAVerify(): hash length not same as sig len\n");
+		free(buf);
+		return -EINVAL;
+	}
 
 	padding = algo->rsa_padding;
 	pad_len = algo->pad_len - algo->checksum_len;
@@ -279,84 +83,73 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
 	/* Check pkcs1.5 padding bytes. */
 	if (memcmp(buf, padding, pad_len)) {
 		debug("In RSAVerify(): Padding check failed!\n");
+		free(buf);
 		return -EINVAL;
 	}
 
 	/* Check hash. */
-	if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) {
+	if (memcmp(buf + pad_len, hash, sig_len - pad_len)) {
 		debug("In RSAVerify(): Hash check failed!\n");
+		free(buf);
 		return -EACCES;
 	}
 
-	return 0;
-}
-
-static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
-{
-	int i;
+	free(buf);
 
-	for (i = 0; i < len; i++)
-		dst[i] = fdt32_to_cpu(src[len - 1 - i]);
+	return 0;
 }
 
+/**
+ * rsa_verify_with_keynode() - Verify a signature against some data using
+ * information in node with prperties of RSA Key like modulus, exponent etc.
+ *
+ * Parse sign-node and fill a key_prop structure with properties of the
+ * key.  Verify a RSA PKCS1.5 signature against an expected hash using
+ * the properties parsed
+ *
+ * @info:	Specifies key and FIT information
+ * @hash:	Pointer to the expected hash
+ * @sig:	Signature
+ * @sig_len:	Number of bytes in signature
+ * @node:	Node having the RSA Key properties
+ * @return 0 if verified, -ve on error
+ */
 static int rsa_verify_with_keynode(struct image_sign_info *info,
-		const void *hash, uint8_t *sig, uint sig_len, int node)
+				   const void *hash, uint8_t *sig,
+				   uint sig_len, int node)
 {
 	const void *blob = info->fdt_blob;
-	struct rsa_public_key key;
-	const void *modulus, *rr;
-	const uint64_t *public_exponent;
+	struct key_prop prop;
 	int length;
-	int ret;
+	int ret = 0;
 
 	if (node < 0) {
 		debug("%s: Skipping invalid node", __func__);
 		return -EBADF;
 	}
-	if (!fdt_getprop(blob, node, "rsa,n0-inverse", NULL)) {
-		debug("%s: Missing rsa,n0-inverse", __func__);
-		return -EFAULT;
-	}
-	key.len = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
-	key.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
-	public_exponent = fdt_getprop(blob, 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 = fdt_getprop(blob, node, "rsa,modulus", NULL);
-	rr = fdt_getprop(blob, 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);
+	prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
+
+	prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
+
+	prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
+	if (!prop.public_exponent || length < sizeof(uint64_t))
+		prop.public_exponent = NULL;
+
+	prop.exp_len = sizeof(uint64_t);
+
+	prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
+
+	prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
+
+	if (!prop.num_bits || !prop.modulus) {
+		debug("%s: Missing RSA key info", __func__);
 		return -EFAULT;
 	}
-	key.len /= sizeof(uint32_t) * 8;
-	uint32_t key1[key.len], key2[key.len];
-
-	key.modulus = key1;
-	key.rr = key2;
-	rsa_convert_big_endian(key.modulus, modulus, key.len);
-	rsa_convert_big_endian(key.rr, rr, key.len);
-	if (!key.modulus || !key.rr) {
-		debug("%s: Out of memory", __func__);
-		return -ENOMEM;
-	}
 
-	debug("key length %d\n", key.len);
-	ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
-	if (ret) {
-		printf("%s: RSA failed to verify: %d\n", __func__, ret);
-		return ret;
-	}
+	ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum);
 
-	return 0;
+	return ret;
 }
 
 int rsa_verify(struct image_sign_info *info,
diff --git a/tools/Makefile b/tools/Makefile
index a4216a1..0b981da 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -60,7 +60,8 @@ FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
 LIBFDT_OBJS := $(addprefix lib/libfdt/, \
 			fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
 RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
-					rsa-sign.o rsa-verify.o rsa-checksum.o)
+					rsa-sign.o rsa-verify.o rsa-checksum.o \
+					rsa-mod-exp.o)
 
 # common objs for dumpimage and mkimage
 dumpimage-mkimage-objs := aisimage.o \
-- 
1.8.1.4

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

* [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2015-01-02 21:38   ` Simon Glass
  2014-12-30  9:30 ` [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver Ruchika Gupta
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

For FIT signature based approach to work, RSA library needs to be selected. The FIT_SIGNATURE option in Kconfig is modified to automatically select RSA.
Selecting RSA compiles the RSA library required for image verification.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Expanded CONFIG_RSA with documentation link

Changes in v3:
New patch created for adding Kconfig option for FIT signature

 Kconfig     | 3 ++-
 lib/Kconfig | 7 +++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/Kconfig b/Kconfig
index 153ee2b..c2d7cb9 100644
--- a/Kconfig
+++ b/Kconfig
@@ -116,8 +116,9 @@ config FIT_VERBOSE
 	depends on FIT
 
 config FIT_SIGNATURE
-	bool "Enabel signature verification of FIT uImages"
+	bool "Enable signature verification of FIT uImages"
 	depends on FIT
+	select RSA
 	help
 	  This option enables signature verification of FIT uImages,
 	  using a hash signed and verified using RSA.
diff --git a/lib/Kconfig b/lib/Kconfig
index 8460439..2455f7a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -27,4 +27,11 @@ config SYS_HZ
 	  get_timer() must operate in milliseconds and this option must be
 	  set to 1000.
 
+config RSA
+	bool "Use RSA Library"
+	help
+	  RSA support.This enables the RSA algorithm used for FIT image
+	  verification in U-Boot.
+	  See doc/uImage.FIT/signature.txt for more details.
+
 endmenu
-- 
1.8.1.4

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

* [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
  2014-12-30  9:30 ` [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2015-01-02 22:24   ` Simon Glass
  2014-12-30  9:30 ` [U-Boot] [PATCH 4/9] [v4] configs: Move CONFIG_FIT_SIGNATURE to defconfig Ruchika Gupta
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

Add a new rsa uclass for performing modular exponentiation and implement
the software driver basing on this uclass.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Removed Kconfig option for DM_RSA
Corrected driver name for sw rsa driver
Updated the rsa_mod_exp operation to have output length

Changes in v3:
New patch with driver model for RSA UCLASS

 drivers/crypto/Makefile         |  1 +
 drivers/crypto/rsa/Makefile     |  7 +++++++
 drivers/crypto/rsa/rsa_sw.c     | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/crypto/rsa/rsa_uclass.c | 31 +++++++++++++++++++++++++++++++
 include/dm/uclass-id.h          |  1 +
 include/u-boot/rsa-mod-exp.h    | 37 +++++++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+)
 create mode 100644 drivers/crypto/rsa/Makefile
 create mode 100644 drivers/crypto/rsa/rsa_sw.c
 create mode 100644 drivers/crypto/rsa/rsa_uclass.c

diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7b79237..a2f30fc 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -6,4 +6,5 @@
 #
 
 obj-$(CONFIG_EXYNOS_ACE_SHA)	+= ace_sha.o
+obj-y += rsa/
 obj-y += fsl/
diff --git a/drivers/crypto/rsa/Makefile b/drivers/crypto/rsa/Makefile
new file mode 100644
index 0000000..927c5bd
--- /dev/null
+++ b/drivers/crypto/rsa/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2014 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_RSA) += rsa_uclass.o rsa_sw.o
diff --git a/drivers/crypto/rsa/rsa_sw.c b/drivers/crypto/rsa/rsa_sw.c
new file mode 100644
index 0000000..3dcd512
--- /dev/null
+++ b/drivers/crypto/rsa/rsa_sw.c
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc.
+ * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <u-boot/rsa-mod-exp.h>
+
+int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+		struct key_prop *prop, uint8_t **outp, uint32_t *out_len)
+{
+	int ret = 0;
+
+	ret = rsa_mod_exp_sw(sig, sig_len, prop, outp, out_len);
+	if (ret) {
+		debug("%s: RSA failed to verify: %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct rsa_ops rsa_ops_sw = {
+	.mod_exp	= mod_exp_sw,
+};
+
+U_BOOT_DRIVER(rsa_sw) = {
+	.name	= "rsa_sw",
+	.id	= UCLASS_RSA,
+	.ops	= &rsa_ops_sw,
+};
+
+U_BOOT_DEVICE(rsa_sw) = {
+	.name = "rsa_sw",
+};
diff --git a/drivers/crypto/rsa/rsa_uclass.c b/drivers/crypto/rsa/rsa_uclass.c
new file mode 100644
index 0000000..4d52dcc
--- /dev/null
+++ b/drivers/crypto/rsa/rsa_uclass.c
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc
+ * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <u-boot/rsa-mod-exp.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+		struct key_prop *node, uint8_t **out, uint32_t *out_len)
+{
+	const struct rsa_ops *ops = device_get_ops(dev);
+
+	if (!ops->mod_exp)
+		return -ENOSYS;
+
+	return ops->mod_exp(dev, sig, sig_len, node, out, out_len);
+}
+
+UCLASS_DRIVER(rsa) = {
+	.id		= UCLASS_RSA,
+	.name		= "rsa",
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index f17c3c2..823e43c 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -33,6 +33,7 @@ enum uclass_id {
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
+	UCLASS_RSA,		/* RSA Mod Exp device */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
index 7b74f3c..417e468 100644
--- a/include/u-boot/rsa-mod-exp.h
+++ b/include/u-boot/rsa-mod-exp.h
@@ -46,4 +46,41 @@ struct key_prop {
 int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
 		struct key_prop *node, uint8_t **outp, uint32_t *out_len);
 
+int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+		struct key_prop *node, uint8_t **outp, uint32_t *out_len);
+
+/**
+ * struct struct rsa_ops - Driver model for RSA operations
+ *
+ * The uclass interface is implemented by all crypto devices which use
+ * driver model.
+ */
+struct rsa_ops {
+	/**
+	 * Perform Modular Exponentiation
+	 *
+	 * Operation: out[] = sig ^ exponent % modulus
+	 *
+	 * @dev:	RSA Device
+	 * @sig:	RSA PKCS1.5 signature
+	 * @sig_len:	Length of signature in number of bytes
+	 * @node:	Node with RSA key elements like modulus, exponent,
+	 *		R^2, n0inv
+	 * @outp:	Set to an allocated buffer holding the output hash
+	 * @out_len:	Set to length of hash(outp) calculated after
+	 *		exponentiation.
+	 *
+	 * This computes exponentiation over the signature. Resulting
+	 * hash value is placed in an allocated buffer, the pointer is
+	 * returned as *outp. The length of calulated hash is returned via
+	 * the out_len pointer argument. The caller should free *outp
+	 *
+	 * Returns: 0 if exponentiation is successful, or a negative value
+	 * if it wasn't.
+	 */
+	int (*mod_exp)(struct udevice *dev, const uint8_t *sig,
+			   uint32_t sig_len, struct key_prop *node,
+			   uint8_t **outp, uint32_t *len);
+};
+
 #endif
-- 
1.8.1.4

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

* [U-Boot] [PATCH 4/9] [v4] configs: Move CONFIG_FIT_SIGNATURE to defconfig
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
  2014-12-30  9:30 ` [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig Ruchika Gupta
  2014-12-30  9:30 ` [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2014-12-30  9:30 ` [U-Boot] [PATCH 5/9] [v4] lib/rsa: Modify rsa to use DM driver Ruchika Gupta
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

For the platforms which use,CONFIG_FIT_SIGNATURE, the required configs are
moved to the platform's defconfig file. Selecting CONFIG_FIT_SIGNATURE using
defconfig automatically resolves the dependencies for signature verification.
The RSA library gets automatically selected and user does not have to define
CONFIG_RSA manually.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
Acked-by: Simon Glass <sjg@chromium.org>

---
Changes in v4:
No changes

Changes in v3:
New patch 

 configs/ids8313_defconfig          | 2 ++
 configs/sandbox_defconfig          | 3 +++
 configs/zynq_microzed_defconfig    | 3 +++
 configs/zynq_zc70x_defconfig       | 3 +++
 configs/zynq_zc770_xm010_defconfig | 3 +++
 configs/zynq_zc770_xm012_defconfig | 3 +++
 configs/zynq_zc770_xm013_defconfig | 3 +++
 configs/zynq_zed_defconfig         | 3 +++
 configs/zynq_zybo_defconfig        | 3 +++
 include/configs/am335x_evm.h       | 4 ++--
 include/configs/ids8313.h          | 3 ---
 include/configs/sandbox.h          | 3 ---
 include/configs/zynq-common.h      | 6 ------
 13 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
index 1c665aa..8479cd4 100644
--- a/configs/ids8313_defconfig
+++ b/configs/ids8313_defconfig
@@ -1,4 +1,6 @@
 CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xFFF00000"
 CONFIG_PPC=y
 CONFIG_MPC83xx=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
 CONFIG_TARGET_IDS8313=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 47d8400..0111f25 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -1,3 +1,6 @@
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 9588849..b9a6fe5 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -3,4 +3,7 @@ CONFIG_SPL=y
 +S:CONFIG_ZYNQ=y
 +S:CONFIG_TARGET_ZYNQ_MICROZED=y
 CONFIG_OF_CONTROL=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
index cf50730..dc8aa84 100644
--- a/configs/zynq_zc70x_defconfig
+++ b/configs/zynq_zc70x_defconfig
@@ -4,3 +4,6 @@ CONFIG_SPL=y
 +S:CONFIG_TARGET_ZYNQ_ZC70X=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 8bb405d..2f5fa8c 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -5,3 +5,6 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
 +S:CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 0ba5da5..a92d495 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -5,3 +5,6 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
 +S:CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 13f8112..3a02f75 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -5,3 +5,6 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
 +S:CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index eb057fa..1d816f6 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -4,3 +4,6 @@ CONFIG_SPL=y
 +S:CONFIG_TARGET_ZYNQ_ZED=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 12311cd..9183629 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -4,3 +4,6 @@ CONFIG_SPL=y
 +S:CONFIG_TARGET_ZYNQ_ZYBO=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 560e3bf..cc36985 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -23,8 +23,8 @@
 # define CONFIG_TIMESTAMP
 # define CONFIG_LZO
 # ifdef CONFIG_ENABLE_VBOOT
-#  define CONFIG_FIT_SIGNATURE
-#  define CONFIG_RSA
+# define CONFIG_FIT_SIGNATURE
+# define CONFIG_RSA
 # endif
 #endif
 
diff --git a/include/configs/ids8313.h b/include/configs/ids8313.h
index f084834..2384864 100644
--- a/include/configs/ids8313.h
+++ b/include/configs/ids8313.h
@@ -575,12 +575,9 @@
 
 #define CONFIG_VERSION_VARIABLE
 
-#define CONFIG_FIT
-#define CONFIG_FIT_SIGNATURE
 #define CONFIG_IMAGE_FORMAT_LEGACY
 #define CONFIG_CMD_FDT
 #define CONFIG_CMD_HASH
-#define CONFIG_RSA
 #define CONFIG_SHA1
 #define CONFIG_SHA256
 
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 657f751..6fd29b9 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -41,9 +41,6 @@
 
 #define CONFIG_OF_LIBFDT
 #define CONFIG_LMB
-#define CONFIG_FIT
-#define CONFIG_FIT_SIGNATURE
-#define CONFIG_RSA
 #define CONFIG_CMD_FDT
 #define CONFIG_ANDROID_BOOT_IMAGE
 
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 87b4fff..3894517 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -219,17 +219,11 @@
 #define CONFIG_OF_LIBFDT
 
 /* FIT support */
-#define CONFIG_FIT
-#define CONFIG_FIT_VERBOSE	1 /* enable fit_format_{error,warning}() */
 #define CONFIG_IMAGE_FORMAT_LEGACY /* enable also legacy image format */
 
 /* FDT support */
 #define CONFIG_DISPLAY_BOARDINFO_LATE
 
-/* RSA support */
-#define CONFIG_FIT_SIGNATURE
-#define CONFIG_RSA
-
 /* Extend size of kernel image for uncompression */
 #define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
 
-- 
1.8.1.4

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

* [U-Boot] [PATCH 5/9] [v4] lib/rsa: Modify rsa to use DM driver
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
                   ` (2 preceding siblings ...)
  2014-12-30  9:30 ` [U-Boot] [PATCH 4/9] [v4] configs: Move CONFIG_FIT_SIGNATURE to defconfig Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2015-01-02 22:24   ` Simon Glass
  2014-12-30  9:30 ` [U-Boot] [PATCH 6/9] [v4] DM: crypto/fsl - Add Freescale rsa " Ruchika Gupta
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

Modify rsa_verify to use the rsa driver of DM library .The tools
will continue to use the same RSA sw library.

CONFIG_RSA is now dependent on CONFIG_DM. All configurations which
enable FIT based signatures have been modified to enable CONFIG_DM
by default.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Make CONFIG_RSA always depenedent on Driver Model. 
Add CONFIG_DM in defconfigs of the platforms which enable CONFIG_FIT_SIGNATURE

Changes in v3:
New patch

 README                             |  7 ++++++-
 configs/ids8313_defconfig          |  1 +
 configs/sandbox_defconfig          |  1 +
 configs/zynq_microzed_defconfig    |  1 +
 configs/zynq_zc70x_defconfig       |  1 +
 configs/zynq_zc770_xm010_defconfig |  1 +
 configs/zynq_zc770_xm012_defconfig |  1 +
 configs/zynq_zc770_xm013_defconfig |  1 +
 configs/zynq_zed_defconfig         |  1 +
 configs/zynq_zybo_defconfig        |  1 +
 include/configs/am335x_evm.h       |  3 +++
 include/configs/sandbox.h          |  1 -
 lib/Kconfig                        |  5 ++++-
 lib/rsa/rsa-verify.c               | 19 +++++++++++++++++++
 14 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/README b/README
index 4ca04d0..1d7978f 100644
--- a/README
+++ b/README
@@ -3173,8 +3173,13 @@ CBFS (Coreboot Filesystem) support
 		This enables the RSA algorithm used for FIT image verification
 		in U-Boot. See doc/uImage.FIT/signature.txt for more information.
 
+		The Modular Exponentiation algorithm in RSA is implemented using
+		driver model. So CONFIG_DM needs to be enabled by default for this
+		library to function.
+
 		The signing part is build into mkimage regardless of this
-		option.
+		option. The software based modular exponentiation is built into
+		mkimage irrespective of this option.
 
 - bootcount support:
 		CONFIG_BOOTCOUNT_LIMIT
diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
index 8479cd4..0950ec8 100644
--- a/configs/ids8313_defconfig
+++ b/configs/ids8313_defconfig
@@ -4,3 +4,4 @@ CONFIG_MPC83xx=y
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_TARGET_IDS8313=y
+CONFIG_DM=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 0111f25..660063e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -3,4 +3,5 @@ CONFIG_OF_HOSTFILE=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index b9a6fe5..8b985fe 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -6,4 +6,5 @@ CONFIG_OF_CONTROL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
index dc8aa84..cceb321 100644
--- a/configs/zynq_zc70x_defconfig
+++ b/configs/zynq_zc70x_defconfig
@@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 2f5fa8c..2935c0d 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index a92d495..0401739 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 3a02f75..a95970a 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index 1d816f6..0fbc41a 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 9183629..4e66760 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index cc36985..1eb0ce7 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -24,6 +24,9 @@
 # define CONFIG_LZO
 # ifdef CONFIG_ENABLE_VBOOT
 # define CONFIG_FIT_SIGNATURE
+#ifndef CONFIG_DM
+#define CONFIG_DM
+#endif
 # define CONFIG_RSA
 # endif
 #endif
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 6fd29b9..e9d3f32 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -23,7 +23,6 @@
 
 #define CONFIG_BOOTSTAGE
 #define CONFIG_BOOTSTAGE_REPORT
-#define CONFIG_DM
 #define CONFIG_CMD_DEMO
 #define CONFIG_CMD_DM
 #define CONFIG_DM_DEMO
diff --git a/lib/Kconfig b/lib/Kconfig
index 2455f7a..f317f81 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -29,9 +29,12 @@ config SYS_HZ
 
 config RSA
 	bool "Use RSA Library"
+	depends on DM
 	help
 	  RSA support.This enables the RSA algorithm used for FIT image
-	  verification in U-Boot.
+	  verification in U-Boot. RSA support for Modular exponentiation
+	  is implemented as a driver model. Driver Model should be enabled
+	  to select this option.
 	  See doc/uImage.FIT/signature.txt for more details.
 
 endmenu
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 1d2e707..af915d3 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -12,6 +12,7 @@
 #include <asm/errno.h>
 #include <asm/types.h>
 #include <asm/unaligned.h>
+#include <dm.h>
 #else
 #include "fdt_host.h"
 #include "mkimage.h"
@@ -44,6 +45,9 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
 	const uint8_t *padding;
 	int pad_len;
 	int ret;
+#if !defined(USE_HOSTCC)
+	struct udevice *rsa_dev;
+#endif
 
 	if (!prop || !sig || !hash || !algo)
 		return -EIO;
@@ -65,11 +69,26 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
 	uint8_t *buf;
 	uint32_t buf_len;
 
+#if !defined(USE_HOSTCC)
+	ret = uclass_get_device(UCLASS_RSA, 0, &rsa_dev);
+	if (!ret) {
+		ret = rsa_mod_exp(rsa_dev, sig, sig_len, prop, &buf,
+				  &buf_len);
+		if (ret) {
+			debug("Error in Modular exponentation\n");
+			return ret;
+		}
+	} else {
+		printf("RSA: Can't find Mod Exp implemnetation\n");
+		return -EINVAL;
+	}
+#else
 	ret = rsa_mod_exp_sw(sig, sig_len, prop, &buf, &buf_len);
 	if (ret) {
 		debug("Error in Modular exponentation\n");
 		return ret;
 	}
+#endif
 
 	if (buf_len != sig_len) {
 		debug("In RSAVerify(): hash length not same as sig len\n");
-- 
1.8.1.4

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

* [U-Boot] [PATCH 6/9] [v4] DM: crypto/fsl - Add Freescale rsa DM driver
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
                   ` (3 preceding siblings ...)
  2014-12-30  9:30 ` [U-Boot] [PATCH 5/9] [v4] lib/rsa: Modify rsa to use DM driver Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2014-12-30  9:30 ` [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation Ruchika Gupta
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

Driver added for RSA Modular Exponentiation using Freescale Hardware
Accelerator CAAM. The driver used uclass rsa.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Modified for the changes in op function of rsa class mod_exp

Changes in v3:
Moved to integrate with RSA UCLASS

 drivers/crypto/Kconfig        |  1 +
 drivers/crypto/fsl/Kconfig    |  6 ++++
 drivers/crypto/fsl/Makefile   |  1 +
 drivers/crypto/fsl/fsl_rsa.c  | 69 +++++++++++++++++++++++++++++++++++++++++++
 drivers/crypto/fsl/jobdesc.c  | 28 ++++++++++++++++++
 drivers/crypto/fsl/jobdesc.h  |  5 ++++
 drivers/crypto/fsl/rsa_caam.h | 28 ++++++++++++++++++
 7 files changed, 138 insertions(+)
 create mode 100644 drivers/crypto/fsl/Kconfig
 create mode 100644 drivers/crypto/fsl/fsl_rsa.c
 create mode 100644 drivers/crypto/fsl/rsa_caam.h

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index e69de29..bd26a2b 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -0,0 +1 @@
+source drivers/crypto/fsl/Kconfig
diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
new file mode 100644
index 0000000..86b2f2f
--- /dev/null
+++ b/drivers/crypto/fsl/Kconfig
@@ -0,0 +1,6 @@
+config FSL_CAAM
+	bool "Freescale Crypto Driver Support"
+	help
+	  Enables the Freescale's Cryptographic Accelerator and Assurance
+	  Module (CAAM), also known as the SEC version 4 (SEC4). The driver uses
+	  Job Ring as interface to communicate with CAAM.
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index cb13d2e..db3c010 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -8,3 +8,4 @@
 
 obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
 obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
+obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
diff --git a/drivers/crypto/fsl/fsl_rsa.c b/drivers/crypto/fsl/fsl_rsa.c
new file mode 100644
index 0000000..21156b2
--- /dev/null
+++ b/drivers/crypto/fsl/fsl_rsa.c
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc.
+ * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <asm/types.h>
+#include <malloc.h>
+#include "jobdesc.h"
+#include "desc.h"
+#include "jr.h"
+#include "rsa_caam.h"
+#include <u-boot/rsa-mod-exp.h>
+
+int fsl_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+		struct key_prop *prop, uint8_t **outp, uint32_t *out_len)
+{
+	uint32_t keylen;
+	struct pk_in_params pkin;
+	uint32_t desc[MAX_CAAM_DESCSIZE];
+	int ret;
+
+	/* Length in bytes */
+	keylen = prop->num_bits / 8;
+
+	*outp = malloc(sig_len);
+	if (!*outp) {
+		debug("%s: Out of malloc space\n", __func__);
+		return -EFAULT;
+	}
+
+	printf("HW\n");
+	pkin.a = sig;
+	pkin.a_siz = sig_len;
+	pkin.n = prop->modulus;
+	pkin.n_siz = keylen;
+	pkin.e = prop->public_exponent;
+	pkin.e_siz = prop->exp_len;
+
+	inline_cnstr_jobdesc_pkha_rsaexp(desc, &pkin, *outp, sig_len);
+
+	ret = run_descriptor_jr(desc);
+	if (ret) {
+		debug("%s: RSA failed to verify: %d\n", __func__, ret);
+		return -EFAULT;
+	}
+
+	*out_len = sig_len;
+
+	return 0;
+}
+
+static const struct rsa_ops fsl_rsa_ops = {
+	.mod_exp	= fsl_mod_exp,
+};
+
+U_BOOT_DRIVER(fsl_rsa) = {
+	.name	= "fsl_rsa",
+	.id	= UCLASS_RSA,
+	.ops	= &fsl_rsa_ops,
+};
+
+U_BOOT_DEVICE(fsl_rsa) = {
+	.name = "fsl_rsa",
+};
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 1386bae..cc0dced 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -11,6 +11,7 @@
 #include <common.h>
 #include "desc_constr.h"
 #include "jobdesc.h"
+#include "rsa_caam.h"
 
 #define KEY_BLOB_SIZE			32
 #define MAC_SIZE			16
@@ -123,3 +124,30 @@ void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc)
 	append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
 			 OP_ALG_RNG4_SK);
 }
+
+/* Change key size to bytes form bits in calling function*/
+void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
+				      struct pk_in_params *pkin, uint8_t *out,
+				      uint32_t out_siz)
+{
+	dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
+
+	dma_addr_e = virt_to_phys((void *)pkin->e);
+	dma_addr_a = virt_to_phys((void *)pkin->a);
+	dma_addr_n = virt_to_phys((void *)pkin->n);
+	dma_addr_out = virt_to_phys((void *)out);
+
+	init_job_desc(desc, 0);
+	append_key(desc, dma_addr_e, pkin->e_siz, KEY_DEST_PKHA_E | CLASS_1);
+
+	append_fifo_load(desc, dma_addr_a,
+			 pkin->a_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_A);
+
+	append_fifo_load(desc, dma_addr_n,
+			 pkin->n_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_N);
+
+	append_operation(desc, OP_TYPE_PK | OP_ALG_PK | OP_ALG_PKMODE_MOD_EXPO);
+
+	append_fifo_store(desc, dma_addr_out, out_siz,
+			  LDST_CLASS_1_CCB | FIFOST_TYPE_PKHA_B);
+}
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
index 3cf7226..84b3edd 100644
--- a/drivers/crypto/fsl/jobdesc.h
+++ b/drivers/crypto/fsl/jobdesc.h
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include "rsa_caam.h"
 
 #define KEY_IDNFR_SZ_BYTES		16
 
@@ -26,4 +27,8 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
 				     uint32_t out_sz);
 
 void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc);
+
+void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
+				      struct pk_in_params *pkin, uint8_t *out,
+				      uint32_t out_siz);
 #endif
diff --git a/drivers/crypto/fsl/rsa_caam.h b/drivers/crypto/fsl/rsa_caam.h
new file mode 100644
index 0000000..4ff87ef
--- /dev/null
+++ b/drivers/crypto/fsl/rsa_caam.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __RSA_CAAM_H
+#define __RSA_CAAM_H
+
+#include <common.h>
+
+/**
+ * struct pk_in_params - holder for input to PKHA block in CAAM
+ * These parameters are required to perform Modular Exponentiation
+ * using PKHA Block in CAAM
+ */
+struct pk_in_params {
+	const uint8_t *e;	/* public exponent as byte array */
+	uint32_t e_siz;		/* size of e[] in number of bytes */
+	const uint8_t *n;	/* modulus as byte array */
+	uint32_t n_siz;		/* size of n[] in number of bytes */
+	const uint8_t *a;		/* Signature as byte array */
+	uint32_t a_siz;		/* size of a[] in number of bytes */
+	uint8_t *b;		/* Result exp. modulus in number of bytes */
+	uint32_t b_siz;		/* size of b[] in number of bytes */
+};
+
+#endif
-- 
1.8.1.4

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

* [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
                   ` (4 preceding siblings ...)
  2014-12-30  9:30 ` [U-Boot] [PATCH 6/9] [v4] DM: crypto/fsl - Add Freescale rsa " Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2015-01-02 22:24   ` Simon Glass
  2014-12-30  9:30 ` [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash Ruchika Gupta
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

Kconfig option added for devices which support RSA Verification.
1. RSA_SOFTWARE_EXP
Enables driver for supporting RSA Modular Exponentiation in Software
2. RSA_FREESCALE_EXP
Enables driver for supporting RSA Modular Exponentiation using Freescale specific
driver

The above drivers use RSA uclass

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Introduced 2 options when CONFIG_RSA is selected:
RSA_SOFTWARE_EXP
RSA_FREESCALE_EXP

Removed RSA_HW. Changes the name pf RSA_SW to RSA_SOFTWARE_EXP

Changes in v3:
New patch

 lib/Kconfig     | 10 +---------
 lib/rsa/Kconfig | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 9 deletions(-)
 create mode 100644 lib/rsa/Kconfig

diff --git a/lib/Kconfig b/lib/Kconfig
index f317f81..a1f30a2 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -27,14 +27,6 @@ config SYS_HZ
 	  get_timer() must operate in milliseconds and this option must be
 	  set to 1000.
 
-config RSA
-	bool "Use RSA Library"
-	depends on DM
-	help
-	  RSA support.This enables the RSA algorithm used for FIT image
-	  verification in U-Boot. RSA support for Modular exponentiation
-	  is implemented as a driver model. Driver Model should be enabled
-	  to select this option.
-	  See doc/uImage.FIT/signature.txt for more details.
+source lib/rsa/Kconfig
 
 endmenu
diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
new file mode 100644
index 0000000..14155b9
--- /dev/null
+++ b/lib/rsa/Kconfig
@@ -0,0 +1,30 @@
+config RSA
+	bool "Use RSA Library"
+	depends on DM
+	select RSA_FREESCALE_EXP if FSL_CAAM
+	select RSA_SOFTWARE_EXP if !RSA_FREESCALE_EXP
+	help
+	  RSA support.This enables the RSA algorithm used for FIT image
+	  verification in U-Boot. RSA support for Modular exponentiation
+	  is implemented as a driver model. Driver Model should be enabled
+	  to select this option.
+	  See doc/uImage.FIT/signature.txt for more details.
+
+if RSA
+config RSA_SOFTWARE_EXP
+	bool "Enable driver for RSA Modular Exponentiation in software"
+	depends on DM && RSA
+	help
+	  Enables driver for modular exponentiation in software. This is a RSA
+	  algorithm used in FIT image verification. It required RSA Key as
+	  input.
+	  See doc/uImage.FIT/signature.txt for more details.
+
+config RSA_FREESCALE_EXP
+	bool "Enable RSA Modular Exponentiation with FSL crypto accelerator"
+	depends on DM && RSA && FSL_CAAM
+	help
+	Enables driver for RSA modular exponentiation using Freescale cryptographic
+	accelerator - CAAM.
+
+endif
-- 
1.8.1.4

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

* [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
                   ` (5 preceding siblings ...)
  2014-12-30  9:30 ` [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2015-01-02 22:24   ` Simon Glass
  2014-12-30  9:30 ` [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo Ruchika Gupta
  2015-01-02 22:24 ` [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Simon Glass
  8 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

The hash_algo structure has some implementations in which progressive hash
API's are not defined. These are basically the hardware based implementations
of SHA. An API is added to find the algo which has progressive hash API's
defined. This can then be integrated with RSA checksum library which uses
Progressive Hash API's.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
Few cosmetic changes. Currently I have not replaced CONFIG_SHA1  with CONFIG_CMD_SHA1SUM.
Waiting for reply from Simon and Denx for the same.

Changes in v3 :
Corrected ifdef for SHA1

Changes in v2 :
Added commit message

 common/hash.c  | 33 ++++++++++++++++++++++++---------
 include/hash.h | 14 ++++++++++++++
 2 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/common/hash.c b/common/hash.c
index 12d6759..ea1ec60 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -20,7 +20,7 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 
-#ifdef CONFIG_CMD_SHA1SUM
+#ifdef CONFIG_SHA1
 static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
 {
 	sha1_context *ctx = malloc(sizeof(sha1_context));
@@ -125,12 +125,7 @@ static struct hash_algo hash_algo[] = {
 		CHUNKSZ_SHA256,
 	},
 #endif
-	/*
-	 * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
-	 * it bloats the code for boards which use SHA1 but not the 'hash'
-	 * or 'sha1sum' commands.
-	 */
-#ifdef CONFIG_CMD_SHA1SUM
+#ifdef CONFIG_SHA1
 	{
 		"sha1",
 		SHA1_SUM_LEN,
@@ -140,7 +135,6 @@ static struct hash_algo hash_algo[] = {
 		hash_update_sha1,
 		hash_finish_sha1,
 	},
-#define MULTI_HASH
 #endif
 #ifdef CONFIG_SHA256
 	{
@@ -152,7 +146,6 @@ static struct hash_algo hash_algo[] = {
 		hash_update_sha256,
 		hash_finish_sha256,
 	},
-#define MULTI_HASH
 #endif
 	{
 		"crc32",
@@ -165,6 +158,10 @@ static struct hash_algo hash_algo[] = {
 	},
 };
 
+#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM)
+#define MULTI_HASH
+#endif
+
 #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
 #define MULTI_HASH
 #endif
@@ -311,6 +308,24 @@ int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
 	return -EPROTONOSUPPORT;
 }
 
+int hash_progressive_lookup_algo(const char *algo_name,
+				 struct hash_algo **algop)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
+		if (!strcmp(algo_name, hash_algo[i].name)) {
+			if (hash_algo[i].hash_init) {
+				*algop = &hash_algo[i];
+				return 0;
+			}
+		}
+	}
+
+	debug("Unknown hash algorithm '%s'\n", algo_name);
+	return -EPROTONOSUPPORT;
+}
+
 void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output)
 {
 	int i;
diff --git a/include/hash.h b/include/hash.h
index d8ec4f0..c0a7ebc 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -128,6 +128,20 @@ int hash_block(const char *algo_name, const void *data, unsigned int len,
 int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
 
 /**
+ * hash_progressive_lookup_algo() - Look up hash_algo for prog. hash support
+ *
+ * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
+ * algorithm is not available with progressive hash support.
+ *
+ * @algo_name: Hash algorithm to look up
+ * @algop: Pointer to the hash_algo struct if found
+ *
+ * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
+ */
+int hash_progressive_lookup_algo(const char *algo_name,
+				 struct hash_algo **algop);
+
+/**
  * hash_show() - Print out a hash algorithm and value
  *
  * You will get a message like this (without a newline@the end):
-- 
1.8.1.4

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

* [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
                   ` (6 preceding siblings ...)
  2014-12-30  9:30 ` [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash Ruchika Gupta
@ 2014-12-30  9:30 ` Ruchika Gupta
  2015-01-02 22:24   ` Simon Glass
  2015-01-02 22:24 ` [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Simon Glass
  8 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2014-12-30  9:30 UTC (permalink / raw)
  To: u-boot

Currently the hash functions used in RSA are called directly from the sha1
and sha256 libraries. Change the RSA checksum library to use the progressive
hash API's registered with struct hash_algo. This will allow the checksum
library to use the hardware accelerated progressive hash API's once available.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v4:
No changes in this patch. Still under discussion

Changes in v3:
Modified rsa-verify to check for return from checksum function

Changes in v2:
Added generic function hash_calculate. Pass an additional
argument as name of algorithm. 

 common/image-sig.c            |  6 ++---
 include/image.h               |  5 ++--
 include/u-boot/rsa-checksum.h | 17 ++++++++++----
 lib/rsa/rsa-checksum.c        | 53 +++++++++++++++++++++++++++++++++++++++----
 lib/rsa/rsa-verify.c          |  7 +++++-
 5 files changed, 74 insertions(+), 14 deletions(-)

diff --git a/common/image-sig.c b/common/image-sig.c
index 8601eda..2c9f0cd 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -38,7 +38,7 @@ struct checksum_algo checksum_algos[] = {
 #if IMAGE_ENABLE_SIGN
 		EVP_sha1,
 #endif
-		sha1_calculate,
+		hash_calculate,
 		padding_sha1_rsa2048,
 	},
 	{
@@ -48,7 +48,7 @@ struct checksum_algo checksum_algos[] = {
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
 #endif
-		sha256_calculate,
+		hash_calculate,
 		padding_sha256_rsa2048,
 	},
 	{
@@ -58,7 +58,7 @@ struct checksum_algo checksum_algos[] = {
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
 #endif
-		sha256_calculate,
+		hash_calculate,
 		padding_sha256_rsa4096,
 	}
 
diff --git a/include/image.h b/include/image.h
index af30d60..ec55f23 100644
--- a/include/image.h
+++ b/include/image.h
@@ -926,8 +926,9 @@ struct checksum_algo {
 #if IMAGE_ENABLE_SIGN
 	const EVP_MD *(*calculate_sign)(void);
 #endif
-	void (*calculate)(const struct image_region region[],
-			  int region_count, uint8_t *checksum);
+	int (*calculate)(const char *name,
+			 const struct image_region region[],
+			 int region_count, uint8_t *checksum);
 	const uint8_t *rsa_padding;
 };
 
diff --git a/include/u-boot/rsa-checksum.h b/include/u-boot/rsa-checksum.h
index c996fb3..3c69d85 100644
--- a/include/u-boot/rsa-checksum.h
+++ b/include/u-boot/rsa-checksum.h
@@ -16,9 +16,18 @@ extern const uint8_t padding_sha256_rsa4096[];
 extern const uint8_t padding_sha256_rsa2048[];
 extern const uint8_t padding_sha1_rsa2048[];
 
-void sha256_calculate(const struct image_region region[], int region_count,
-		      uint8_t *checksum);
-void sha1_calculate(const struct image_region region[], int region_count,
-		    uint8_t *checksum);
+/**
+ * hash_calculate() - Calculate hash over the data
+ *
+ * @name:  Name of algorithm to be used for hash calculation
+ * @region: Array having info of regions over which hash needs to be calculated
+ * @region_count: Number of regions in the region array
+ * @checksum: Buffer contanining the output hash
+ *
+ * @return 0 if OK, < 0 if error
+ */
+int hash_calculate(const char *name,
+		   const struct image_region region[], int region_count,
+		   uint8_t *checksum);
 
 #endif
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
index 8d8b59f..7f1909a 100644
--- a/lib/rsa/rsa-checksum.c
+++ b/lib/rsa/rsa-checksum.c
@@ -10,12 +10,13 @@
 #include <asm/byteorder.h>
 #include <asm/errno.h>
 #include <asm/unaligned.h>
+#include <hash.h>
 #else
 #include "fdt_host.h"
-#endif
-#include <u-boot/rsa.h>
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
+#endif
+#include <u-boot/rsa.h>
 
 /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
 
@@ -136,7 +137,33 @@ const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = {
 	0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
 };
 
-void sha1_calculate(const struct image_region region[], int region_count,
+#ifndef USE_HOSTCC
+int hash_calculate(const char *name,
+		    const struct image_region region[],
+		    int region_count, uint8_t *checksum)
+{
+	struct hash_algo *algo;
+	int ret = 0;
+	void *ctx;
+	uint32_t i;
+	i = 0;
+
+	ret = hash_progressive_lookup_algo(name, &algo);
+	if (ret)
+		return ret;
+
+	algo->hash_init(algo, &ctx);
+	for (i = 0; i < region_count - 1; i++)
+		algo->hash_update(algo, ctx, region[i].data, region[i].size, 0);
+
+	algo->hash_update(algo, ctx, region[i].data, region[i].size, 1);
+	algo->hash_finish(algo, ctx, checksum, algo->digest_size);
+
+	return 0;
+}
+
+#else
+int sha1_calculate(const struct image_region region[], int region_count,
 		    uint8_t *checksum)
 {
 	sha1_context ctx;
@@ -147,9 +174,11 @@ void sha1_calculate(const struct image_region region[], int region_count,
 	for (i = 0; i < region_count; i++)
 		sha1_update(&ctx, region[i].data, region[i].size);
 	sha1_finish(&ctx, checksum);
+
+	return 0;
 }
 
-void sha256_calculate(const struct image_region region[], int region_count,
+int sha256_calculate(const struct image_region region[], int region_count,
 		      uint8_t *checksum)
 {
 	sha256_context ctx;
@@ -160,4 +189,20 @@ void sha256_calculate(const struct image_region region[], int region_count,
 	for (i = 0; i < region_count; i++)
 		sha256_update(&ctx, region[i].data, region[i].size);
 	sha256_finish(&ctx, checksum);
+
+	return 0;
 }
+
+int hash_calculate(const char *name,
+		   const struct image_region region[], int region_count,
+		   uint8_t *checksum)
+{
+	if (!strcmp(name, "sha1"))
+		sha1_calculate(region, region_count, checksum);
+
+	if (!strcmp(name, "sha256"))
+		sha256_calculate(region, region_count, checksum);
+
+	return 0;
+}
+#endif
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index af915d3..cf5acdf 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -201,7 +201,12 @@ int rsa_verify(struct image_sign_info *info,
 	}
 
 	/* Calculate checksum with checksum-algorithm */
-	info->algo->checksum->calculate(region, region_count, hash);
+	ret = info->algo->checksum->calculate(info->algo->checksum->name,
+					region, region_count, hash);
+	if (ret < 0) {
+		debug("%s: Error in checksum calculation\n", __func__);
+		return -EINVAL;
+	}
 
 	/* See if we must use a particular key */
 	if (info->required_keynode != -1) {
-- 
1.8.1.4

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

* [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig
  2014-12-30  9:30 ` [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig Ruchika Gupta
@ 2015-01-02 21:38   ` Simon Glass
  0 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2015-01-02 21:38 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> For FIT signature based approach to work, RSA library needs to be selected. The FIT_SIGNATURE option in Kconfig is modified to automatically select RSA.
> Selecting RSA compiles the RSA library required for image verification.

Please word-wrap this.

Assuming you fix the two nits:

Acked-by: Simon Glass <sjg@chromium.org>

>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> Expanded CONFIG_RSA with documentation link
>
> Changes in v3:
> New patch created for adding Kconfig option for FIT signature
>
>  Kconfig     | 3 ++-
>  lib/Kconfig | 7 +++++++
>  2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/Kconfig b/Kconfig
> index 153ee2b..c2d7cb9 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -116,8 +116,9 @@ config FIT_VERBOSE
>         depends on FIT
>
>  config FIT_SIGNATURE
> -       bool "Enabel signature verification of FIT uImages"
> +       bool "Enable signature verification of FIT uImages"
>         depends on FIT
> +       select RSA
>         help
>           This option enables signature verification of FIT uImages,
>           using a hash signed and verified using RSA.
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 8460439..2455f7a 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -27,4 +27,11 @@ config SYS_HZ
>           get_timer() must operate in milliseconds and this option must be
>           set to 1000.
>
> +config RSA
> +       bool "Use RSA Library"
> +       help
> +         RSA support.This enables the RSA algorithm used for FIT image

Space after '.'

> +         verification in U-Boot.
> +         See doc/uImage.FIT/signature.txt for more details.
> +
>  endmenu
> --
> 1.8.1.4
>

Regards,
Simon

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

* [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation
  2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
                   ` (7 preceding siblings ...)
  2014-12-30  9:30 ` [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo Ruchika Gupta
@ 2015-01-02 22:24 ` Simon Glass
  8 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2015-01-02 22:24 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> Public exponentiation which is required in rsa verify functionality is
> tightly integrated with verification code in rsa_verify.c. The patch
> splits the file into twp separating the modular exponentiation.
>
> 1. rsa-verify.c
> - The file parses device tree keys node to fill a keyprop structure.
> The keyprop structure can then be converted to implementation specific
> format.
> (struct rsa_pub_key for sw implementation)
> - The parsed device tree node is then passed to a generic rsa_mod_exp
> function.
>
> 2. rsa-mod-exp.c
> Move the software specific functions related to modular exponentiation
> from rsa-verify.c to this file.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> Modified rsa_mod_exp_sw function to add pointer to output length
>
> Changes in v3:
> Kconfig moved to separate patch. This patch just splits the file now
>
> Changes in v2:
> Addressed few of Simon Glass's comments:
> - Kconfig option added for RSA
> - Comments added for new keyprop struct
>
>  include/u-boot/rsa-mod-exp.h |  49 +++++++
>  lib/rsa/Makefile             |   2 +-
>  lib/rsa/rsa-mod-exp.c        | 309 ++++++++++++++++++++++++++++++++++++++
>  lib/rsa/rsa-verify.c         | 343 +++++++++----------------------------------
>  tools/Makefile               |   3 +-
>  5 files changed, 429 insertions(+), 277 deletions(-)
>  create mode 100644 include/u-boot/rsa-mod-exp.h
>  create mode 100644 lib/rsa/rsa-mod-exp.c
>
> diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
> new file mode 100644
> index 0000000..7b74f3c
> --- /dev/null
> +++ b/include/u-boot/rsa-mod-exp.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2014, Ruchika Gupta.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> +*/
> +
> +#ifndef _RSA_MOD_EXP_H
> +#define _RSA_MOD_EXP_H
> +
> +#include <errno.h>
> +#include <image.h>
> +
> +/**
> + * struct key_prop - holder for a public key properties
> + *
> + * The struct has pointers to modulus (Typically called N),
> + * The inverse, R^2, exponent. These can be typecasted and
> + * used as byte arrays or converted to the required format
> + * as per requirement of RSA implementation.
> + */
> +struct key_prop {
> +       const void *rr;         /* R^2 can be treated as byte array */
> +       const void *modulus;    /* modulus as byte array */
> +       const void *public_exponent; /* public exponent as byte array */
> +       uint32_t n0inv;         /* -1 / modulus[0] mod 2^32 */
> +       int num_bits;           /* Key length in bits */
> +       uint32_t exp_len;       /* Exponent length in number of uint8_t */
> +};
> +
> +/**
> + * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
> + *
> + * Operation: result[] = sig ^ exponent % modulus
> + *
> + * @sig:       RSA PKCS1.5 signature
> + * @sig_len:   Length of signature in number of bytes
> + * @node:      Node with RSA key elements like modulus, exponent, R^2, n0inv
> + * @outp:      Set to an allocated buffer holding the output hash
> + * @out_len:   Set to length of hash(outp) calculated after exponentiation
> + *
> + * This computes exponentiation over the signature. Resulting hash value is
> + * placed in an allocated buffer, the pointer is returned as *outp. The
> + * length of calulated hash is returned via the out_len pointer argument. The
> + * caller should free *outp
> + */
> +int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
> +               struct key_prop *node, uint8_t **outp, uint32_t *out_len);
> +
> +#endif
> diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
> index a5a96cb6..cc25b3c 100644
> --- a/lib/rsa/Makefile
> +++ b/lib/rsa/Makefile
> @@ -7,4 +7,4 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> -obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
> +obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o rsa-mod-exp.o
> diff --git a/lib/rsa/rsa-mod-exp.c b/lib/rsa/rsa-mod-exp.c
> new file mode 100644
> index 0000000..af01b74
> --- /dev/null
> +++ b/lib/rsa/rsa-mod-exp.c
> @@ -0,0 +1,309 @@
> +/*
> + * Copyright (c) 2013, Google Inc.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef USE_HOSTCC
> +#include <common.h>
> +#include <fdtdec.h>
> +#include <asm/types.h>
> +#include <asm/byteorder.h>
> +#include <asm/errno.h>
> +#include <asm/types.h>
> +#include <asm/unaligned.h>
> +#else
> +#include "fdt_host.h"
> +#include "mkimage.h"
> +#include <fdt_support.h>
> +#endif
> +#include <malloc.h>
> +#include <u-boot/rsa.h>
> +#include <u-boot/rsa-mod-exp.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
> +
> +/**
> + * 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, uint32_t *inout)
> +{
> +       uint32_t *result, *ptr;
> +       uint i;
> +       int j, k;
> +
> +       /* 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;
> +       }
> +
> +       uint32_t val[key->len], acc[key->len], tmp[key->len];
> +       uint32_t a_scaled[key->len];
> +       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@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;
> +}
> +
> +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_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
> +               struct key_prop *prop, uint8_t **out, uint32_t *len)
> +{
> +       struct rsa_public_key key;
> +       int ret;
> +
> +       if (!prop) {
> +               debug("%s: Skipping invalid prop", __func__);
> +               return -EBADF;
> +       }
> +       if (!prop->n0inv) {

Sorry I did not notice this in v3, but you should remove this check.
This is a value, not a pointer.

> +               debug("%s: Missing rsa,n0-inverse", __func__);
> +               return -EFAULT;
> +       }
> +       key.n0inv = prop->n0inv;
> +       key.len = prop->num_bits;
> +
> +       if (!prop->public_exponent)
> +               key.exponent = RSA_DEFAULT_PUBEXP;
> +       else
> +               key.exponent =
> +                       fdt64_to_cpu(*((uint64_t *)(prop->public_exponent)));
> +
> +       if (!key.len || !prop->modulus || !prop->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;
> +       uint32_t key1[key.len], key2[key.len];
> +
> +       key.modulus = key1;
> +       key.rr = key2;
> +       rsa_convert_big_endian(key.modulus, (uint32_t *)prop->modulus, key.len);
> +       rsa_convert_big_endian(key.rr, (uint32_t *)prop->rr, key.len);
> +       if (!key.modulus || !key.rr) {
> +               debug("%s: Out of memory", __func__);
> +               return -ENOMEM;
> +       }
> +
> +       uint32_t *buf = malloc(sig_len);

Can you declare buf at the top of the function?

Also you need

if (!buf)
   return -ENOMEM;

> +
> +       memcpy(buf, sig, sig_len);
> +
> +       ret = pow_mod(&key, buf);
> +       if (ret)
> +               return ret;
> +
> +       *out = (uint8_t *)buf;
> +       *len = sig_len;

If len is the same as sig_len, why do you need this extra parameter? I
wonder if I put you wrong somewhere? If sig_len is passed in, there is
no need for rsa_mod_exp_sw() to malloc() space - the caller may as
well just supply the buffer as now.

> +
> +       return 0;
> +}
> diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
> index 4ef19b6..1d2e707 100644
> --- a/lib/rsa/rsa-verify.c
> +++ b/lib/rsa/rsa-verify.c
> @@ -17,230 +17,27 @@
>  #include "mkimage.h"
>  #include <fdt_support.h>
>  #endif
> +#include <malloc.h>
> +#include <u-boot/rsa-mod-exp.h>
>  #include <u-boot/rsa.h>
> -#include <u-boot/sha1.h>
> -#include <u-boot/sha256.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
>
>  /**
> - * subtract_modulus() - subtract modulus from the given value
> + * rsa_verify_key() - Verify a signature against some data using RSA Key
>   *
> - * @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
> + * Verify a RSA PKCS1.5 signature against an expected hash using
> + * the RSA Key properties in prop structure.
>   *
> - * @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
> + * @prop:      Specifies key
> + * @sig:       Signature
> + * @sig_len:   Number of bytes in signature
> + * @hash:      Pointer to the expected hash
> + * @algo:      Checksum algo structure having information on RSA padding etc.
> + * @return 0 if verified, -ve on error
>   */
> -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, uint32_t *inout)
> -{
> -       uint32_t *result, *ptr;
> -       uint i;
> -       int j, k;
> -
> -       /* 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;
> -       }
> -
> -       uint32_t val[key->len], acc[key->len], tmp[key->len];
> -       uint32_t a_scaled[key->len];
> -       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@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;
> -}
> -
> -static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
> +static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
>                           const uint32_t sig_len, const uint8_t *hash,
>                           struct checksum_algo *algo)
>  {
> @@ -248,10 +45,10 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
>         int pad_len;
>         int ret;
>
> -       if (!key || !sig || !hash || !algo)
> +       if (!prop || !sig || !hash || !algo)
>                 return -EIO;
>
> -       if (sig_len != (key->len * sizeof(uint32_t))) {
> +       if (sig_len != (prop->num_bits / 8)) {
>                 debug("Signature is of incorrect length %d\n", sig_len);
>                 return -EINVAL;
>         }
> @@ -265,13 +62,20 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
>                 return -EINVAL;
>         }
>
> -       uint32_t buf[sig_len / sizeof(uint32_t)];
> +       uint8_t *buf;
> +       uint32_t buf_len;

Again please put declarations at the top. As per above comment perhaps
you can revert this chunk anyway. (and the next two)

>
> -       memcpy(buf, sig, sig_len);
> -
> -       ret = pow_mod(key, buf);
> -       if (ret)
> +       ret = rsa_mod_exp_sw(sig, sig_len, prop, &buf, &buf_len);
> +       if (ret) {
> +               debug("Error in Modular exponentation\n");
>                 return ret;
> +       }
> +
> +       if (buf_len != sig_len) {
> +               debug("In RSAVerify(): hash length not same as sig len\n");
> +               free(buf);
> +               return -EINVAL;
> +       }

This check doesn't achieve anything really. If ret == 0, then buf_len
== sig_len.

>
>         padding = algo->rsa_padding;
>         pad_len = algo->pad_len - algo->checksum_len;
> @@ -279,84 +83,73 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
>         /* Check pkcs1.5 padding bytes. */
>         if (memcmp(buf, padding, pad_len)) {
>                 debug("In RSAVerify(): Padding check failed!\n");
> +               free(buf);
>                 return -EINVAL;
>         }
>
>         /* Check hash. */
> -       if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) {
> +       if (memcmp(buf + pad_len, hash, sig_len - pad_len)) {
>                 debug("In RSAVerify(): Hash check failed!\n");
> +               free(buf);
>                 return -EACCES;
>         }
>
> -       return 0;
> -}
> -
> -static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
> -{
> -       int i;
> +       free(buf);
>
> -       for (i = 0; i < len; i++)
> -               dst[i] = fdt32_to_cpu(src[len - 1 - i]);
> +       return 0;
>  }
>
> +/**
> + * rsa_verify_with_keynode() - Verify a signature against some data using
> + * information in node with prperties of RSA Key like modulus, exponent etc.
> + *
> + * Parse sign-node and fill a key_prop structure with properties of the
> + * key.  Verify a RSA PKCS1.5 signature against an expected hash using
> + * the properties parsed
> + *
> + * @info:      Specifies key and FIT information
> + * @hash:      Pointer to the expected hash
> + * @sig:       Signature
> + * @sig_len:   Number of bytes in signature
> + * @node:      Node having the RSA Key properties
> + * @return 0 if verified, -ve on error
> + */
>  static int rsa_verify_with_keynode(struct image_sign_info *info,
> -               const void *hash, uint8_t *sig, uint sig_len, int node)
> +                                  const void *hash, uint8_t *sig,
> +                                  uint sig_len, int node)
>  {
>         const void *blob = info->fdt_blob;
> -       struct rsa_public_key key;
> -       const void *modulus, *rr;
> -       const uint64_t *public_exponent;
> +       struct key_prop prop;
>         int length;
> -       int ret;
> +       int ret = 0;
>
>         if (node < 0) {
>                 debug("%s: Skipping invalid node", __func__);
>                 return -EBADF;
>         }
> -       if (!fdt_getprop(blob, node, "rsa,n0-inverse", NULL)) {
> -               debug("%s: Missing rsa,n0-inverse", __func__);
> -               return -EFAULT;
> -       }
> -       key.len = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
> -       key.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
> -       public_exponent = fdt_getprop(blob, 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 = fdt_getprop(blob, node, "rsa,modulus", NULL);
> -       rr = fdt_getprop(blob, 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);
> +       prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
> +
> +       prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
> +
> +       prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
> +       if (!prop.public_exponent || length < sizeof(uint64_t))
> +               prop.public_exponent = NULL;
> +
> +       prop.exp_len = sizeof(uint64_t);
> +
> +       prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
> +
> +       prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
> +
> +       if (!prop.num_bits || !prop.modulus) {
> +               debug("%s: Missing RSA key info", __func__);
>                 return -EFAULT;
>         }
> -       key.len /= sizeof(uint32_t) * 8;
> -       uint32_t key1[key.len], key2[key.len];
> -
> -       key.modulus = key1;
> -       key.rr = key2;
> -       rsa_convert_big_endian(key.modulus, modulus, key.len);
> -       rsa_convert_big_endian(key.rr, rr, key.len);
> -       if (!key.modulus || !key.rr) {
> -               debug("%s: Out of memory", __func__);
> -               return -ENOMEM;
> -       }
>
> -       debug("key length %d\n", key.len);
> -       ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
> -       if (ret) {
> -               printf("%s: RSA failed to verify: %d\n", __func__, ret);
> -               return ret;
> -       }
> +       ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum);
>
> -       return 0;
> +       return ret;
>  }
>
>  int rsa_verify(struct image_sign_info *info,
> diff --git a/tools/Makefile b/tools/Makefile
> index a4216a1..0b981da 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -60,7 +60,8 @@ FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
>  LIBFDT_OBJS := $(addprefix lib/libfdt/, \
>                         fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
>  RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
> -                                       rsa-sign.o rsa-verify.o rsa-checksum.o)
> +                                       rsa-sign.o rsa-verify.o rsa-checksum.o \
> +                                       rsa-mod-exp.o)
>
>  # common objs for dumpimage and mkimage
>  dumpimage-mkimage-objs := aisimage.o \
> --
> 1.8.1.4
>

Regards,
Simon

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

* [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver
  2014-12-30  9:30 ` [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver Ruchika Gupta
@ 2015-01-02 22:24   ` Simon Glass
       [not found]     ` <1420537067401.77619@freescale.com>
  0 siblings, 1 reply; 21+ messages in thread
From: Simon Glass @ 2015-01-02 22:24 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> Add a new rsa uclass for performing modular exponentiation and implement
> the software driver basing on this uclass.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> Removed Kconfig option for DM_RSA
> Corrected driver name for sw rsa driver
> Updated the rsa_mod_exp operation to have output length
>
> Changes in v3:
> New patch with driver model for RSA UCLASS
>
>  drivers/crypto/Makefile         |  1 +
>  drivers/crypto/rsa/Makefile     |  7 +++++++
>  drivers/crypto/rsa/rsa_sw.c     | 39 +++++++++++++++++++++++++++++++++++++++
>  drivers/crypto/rsa/rsa_uclass.c | 31 +++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h          |  1 +
>  include/u-boot/rsa-mod-exp.h    | 37 +++++++++++++++++++++++++++++++++++++
>  6 files changed, 116 insertions(+)
>  create mode 100644 drivers/crypto/rsa/Makefile
>  create mode 100644 drivers/crypto/rsa/rsa_sw.c
>  create mode 100644 drivers/crypto/rsa/rsa_uclass.c

Again I'm a bit worried we are going off into the weeds.

Is this an RSA driver or a modular exponentiation driver? It seems
like the latter to me. If so, the uclass should be UCLASS_MOD_EXP, not
UCLASS_RSA, and the files and directories should be renames also. Some
hardware will implement the entire RSA algorithm, which would be a
true RSA uclass. Here I think you are only doing part of it.

Other than that rename the code looks fine.

Minor point: again I don't see the value of returning the same value
as sig_len, so you may as well drop those last two args to mod_exp() -
unless I am missing something.

>
> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> index 7b79237..a2f30fc 100644
> --- a/drivers/crypto/Makefile
> +++ b/drivers/crypto/Makefile
> @@ -6,4 +6,5 @@
>  #
>
>  obj-$(CONFIG_EXYNOS_ACE_SHA)   += ace_sha.o
> +obj-y += rsa/
>  obj-y += fsl/
> diff --git a/drivers/crypto/rsa/Makefile b/drivers/crypto/rsa/Makefile
> new file mode 100644
> index 0000000..927c5bd
> --- /dev/null
> +++ b/drivers/crypto/rsa/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# (C) Copyright 2014 Freescale Semiconductor, Inc.
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-$(CONFIG_RSA) += rsa_uclass.o rsa_sw.o
> diff --git a/drivers/crypto/rsa/rsa_sw.c b/drivers/crypto/rsa/rsa_sw.c
> new file mode 100644
> index 0000000..3dcd512
> --- /dev/null
> +++ b/drivers/crypto/rsa/rsa_sw.c
> @@ -0,0 +1,39 @@
> +/*
> + * (C) Copyright 2014 Freescale Semiconductor, Inc.
> + * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <u-boot/rsa-mod-exp.h>
> +
> +int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
> +               struct key_prop *prop, uint8_t **outp, uint32_t *out_len)
> +{
> +       int ret = 0;
> +
> +       ret = rsa_mod_exp_sw(sig, sig_len, prop, outp, out_len);
> +       if (ret) {
> +               debug("%s: RSA failed to verify: %d\n", __func__, ret);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct rsa_ops rsa_ops_sw = {
> +       .mod_exp        = mod_exp_sw,
> +};
> +
> +U_BOOT_DRIVER(rsa_sw) = {
> +       .name   = "rsa_sw",
> +       .id     = UCLASS_RSA,
> +       .ops    = &rsa_ops_sw,
> +};
> +
> +U_BOOT_DEVICE(rsa_sw) = {
> +       .name = "rsa_sw",
> +};
> diff --git a/drivers/crypto/rsa/rsa_uclass.c b/drivers/crypto/rsa/rsa_uclass.c
> new file mode 100644
> index 0000000..4d52dcc
> --- /dev/null
> +++ b/drivers/crypto/rsa/rsa_uclass.c
> @@ -0,0 +1,31 @@
> +/*
> + * (C) Copyright 2014 Freescale Semiconductor, Inc
> + * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <u-boot/rsa-mod-exp.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <malloc.h>
> +#include <asm/io.h>
> +#include <linux/list.h>
> +
> +int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
> +               struct key_prop *node, uint8_t **out, uint32_t *out_len)
> +{
> +       const struct rsa_ops *ops = device_get_ops(dev);
> +
> +       if (!ops->mod_exp)
> +               return -ENOSYS;
> +
> +       return ops->mod_exp(dev, sig, sig_len, node, out, out_len);
> +}
> +
> +UCLASS_DRIVER(rsa) = {
> +       .id             = UCLASS_RSA,
> +       .name           = "rsa",
> +};
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index f17c3c2..823e43c 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -33,6 +33,7 @@ enum uclass_id {
>         UCLASS_I2C,             /* I2C bus */
>         UCLASS_I2C_GENERIC,     /* Generic I2C device */
>         UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
> +       UCLASS_RSA,             /* RSA Mod Exp device */
>
>         UCLASS_COUNT,
>         UCLASS_INVALID = -1,
> diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
> index 7b74f3c..417e468 100644
> --- a/include/u-boot/rsa-mod-exp.h
> +++ b/include/u-boot/rsa-mod-exp.h
> @@ -46,4 +46,41 @@ struct key_prop {
>  int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
>                 struct key_prop *node, uint8_t **outp, uint32_t *out_len);
>
> +int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
> +               struct key_prop *node, uint8_t **outp, uint32_t *out_len);
> +
> +/**
> + * struct struct rsa_ops - Driver model for RSA operations
> + *
> + * The uclass interface is implemented by all crypto devices which use
> + * driver model.
> + */
> +struct rsa_ops {
> +       /**
> +        * Perform Modular Exponentiation
> +        *
> +        * Operation: out[] = sig ^ exponent % modulus
> +        *
> +        * @dev:        RSA Device
> +        * @sig:        RSA PKCS1.5 signature
> +        * @sig_len:    Length of signature in number of bytes
> +        * @node:       Node with RSA key elements like modulus, exponent,
> +        *              R^2, n0inv
> +        * @outp:       Set to an allocated buffer holding the output hash
> +        * @out_len:    Set to length of hash(outp) calculated after
> +        *              exponentiation.
> +        *
> +        * This computes exponentiation over the signature. Resulting
> +        * hash value is placed in an allocated buffer, the pointer is
> +        * returned as *outp. The length of calulated hash is returned via
> +        * the out_len pointer argument. The caller should free *outp
> +        *
> +        * Returns: 0 if exponentiation is successful, or a negative value
> +        * if it wasn't.
> +        */
> +       int (*mod_exp)(struct udevice *dev, const uint8_t *sig,
> +                          uint32_t sig_len, struct key_prop *node,
> +                          uint8_t **outp, uint32_t *len);
> +};
> +
>  #endif
> --
> 1.8.1.4
>

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

* [U-Boot] [PATCH 5/9] [v4] lib/rsa: Modify rsa to use DM driver
  2014-12-30  9:30 ` [U-Boot] [PATCH 5/9] [v4] lib/rsa: Modify rsa to use DM driver Ruchika Gupta
@ 2015-01-02 22:24   ` Simon Glass
  0 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2015-01-02 22:24 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> Modify rsa_verify to use the rsa driver of DM library .The tools
> will continue to use the same RSA sw library.
>
> CONFIG_RSA is now dependent on CONFIG_DM. All configurations which
> enable FIT based signatures have been modified to enable CONFIG_DM
> by default.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> Make CONFIG_RSA always depenedent on Driver Model.
> Add CONFIG_DM in defconfigs of the platforms which enable CONFIG_FIT_SIGNATURE
>
> Changes in v3:
> New patch
>
>  README                             |  7 ++++++-
>  configs/ids8313_defconfig          |  1 +
>  configs/sandbox_defconfig          |  1 +
>  configs/zynq_microzed_defconfig    |  1 +
>  configs/zynq_zc70x_defconfig       |  1 +
>  configs/zynq_zc770_xm010_defconfig |  1 +
>  configs/zynq_zc770_xm012_defconfig |  1 +
>  configs/zynq_zc770_xm013_defconfig |  1 +
>  configs/zynq_zed_defconfig         |  1 +
>  configs/zynq_zybo_defconfig        |  1 +
>  include/configs/am335x_evm.h       |  3 +++
>  include/configs/sandbox.h          |  1 -
>  lib/Kconfig                        |  5 ++++-
>  lib/rsa/rsa-verify.c               | 19 +++++++++++++++++++
>  14 files changed, 41 insertions(+), 3 deletions(-)
>
> diff --git a/README b/README
> index 4ca04d0..1d7978f 100644
> --- a/README
> +++ b/README
> @@ -3173,8 +3173,13 @@ CBFS (Coreboot Filesystem) support
>                 This enables the RSA algorithm used for FIT image verification
>                 in U-Boot. See doc/uImage.FIT/signature.txt for more information.
>
> +               The Modular Exponentiation algorithm in RSA is implemented using
> +               driver model. So CONFIG_DM needs to be enabled by default for this
> +               library to function.
> +
>                 The signing part is build into mkimage regardless of this
> -               option.
> +               option. The software based modular exponentiation is built into
> +               mkimage irrespective of this option.

Just to avoid confusion, I think your addition here to the README is good.

>
>  - bootcount support:
>                 CONFIG_BOOTCOUNT_LIMIT
> diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
> index 8479cd4..0950ec8 100644
> --- a/configs/ids8313_defconfig
> +++ b/configs/ids8313_defconfig
> @@ -4,3 +4,4 @@ CONFIG_MPC83xx=y
>  CONFIG_FIT=y
>  CONFIG_FIT_SIGNATURE=y
>  CONFIG_TARGET_IDS8313=y
> +CONFIG_DM=y

Eek I suspect this might cause a problem, but by the time this merges,
DM support for PPC should be merged, so OK.

> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index 0111f25..660063e 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -3,4 +3,5 @@ CONFIG_OF_HOSTFILE=y
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
>  CONFIG_DEFAULT_DEVICE_TREE="sandbox"
> diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
> index b9a6fe5..8b985fe 100644
> --- a/configs/zynq_microzed_defconfig
> +++ b/configs/zynq_microzed_defconfig
> @@ -6,4 +6,5 @@ CONFIG_OF_CONTROL=y
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
>  CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
> diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
> index dc8aa84..cceb321 100644
> --- a/configs/zynq_zc70x_defconfig
> +++ b/configs/zynq_zc70x_defconfig
> @@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
> diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
> index 2f5fa8c..2935c0d 100644
> --- a/configs/zynq_zc770_xm010_defconfig
> +++ b/configs/zynq_zc770_xm010_defconfig
> @@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
> diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
> index a92d495..0401739 100644
> --- a/configs/zynq_zc770_xm012_defconfig
> +++ b/configs/zynq_zc770_xm012_defconfig
> @@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
> diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
> index 3a02f75..a95970a 100644
> --- a/configs/zynq_zc770_xm013_defconfig
> +++ b/configs/zynq_zc770_xm013_defconfig
> @@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
> diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
> index 1d816f6..0fbc41a 100644
> --- a/configs/zynq_zed_defconfig
> +++ b/configs/zynq_zed_defconfig
> @@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
> diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
> index 9183629..4e66760 100644
> --- a/configs/zynq_zybo_defconfig
> +++ b/configs/zynq_zybo_defconfig
> @@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_FIT_SIGNATURE=y
> +CONFIG_DM=y
> diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
> index cc36985..1eb0ce7 100644
> --- a/include/configs/am335x_evm.h
> +++ b/include/configs/am335x_evm.h
> @@ -24,6 +24,9 @@
>  # define CONFIG_LZO
>  # ifdef CONFIG_ENABLE_VBOOT
>  # define CONFIG_FIT_SIGNATURE
> +#ifndef CONFIG_DM
> +#define CONFIG_DM
> +#endif
>  # define CONFIG_RSA
>  # endif

Since you have moved CONFIG_FIT_SIGNATURE to Kconfig you can remove
all of this and just add your options to
configs/am335x_boneblack_vboot_defconfig instead. That is the only
config which enables vboot.

>  #endif
> diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
> index 6fd29b9..e9d3f32 100644
> --- a/include/configs/sandbox.h
> +++ b/include/configs/sandbox.h
> @@ -23,7 +23,6 @@
>
>  #define CONFIG_BOOTSTAGE
>  #define CONFIG_BOOTSTAGE_REPORT
> -#define CONFIG_DM
>  #define CONFIG_CMD_DEMO
>  #define CONFIG_CMD_DM
>  #define CONFIG_DM_DEMO
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 2455f7a..f317f81 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -29,9 +29,12 @@ config SYS_HZ
>
>  config RSA
>         bool "Use RSA Library"
> +       depends on DM
>         help
>           RSA support.This enables the RSA algorithm used for FIT image
> -         verification in U-Boot.
> +         verification in U-Boot. RSA support for Modular exponentiation
> +         is implemented as a driver model. Driver Model should be enabled
> +         to select this option.

I think you should drop this change. The fact that it depends on DM
will be obvious from the depends line, and you won't see the option
unless DM is enabled anyway.

>           See doc/uImage.FIT/signature.txt for more details.
>
>  endmenu
> diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
> index 1d2e707..af915d3 100644
> --- a/lib/rsa/rsa-verify.c
> +++ b/lib/rsa/rsa-verify.c
> @@ -12,6 +12,7 @@
>  #include <asm/errno.h>
>  #include <asm/types.h>
>  #include <asm/unaligned.h>
> +#include <dm.h>
>  #else
>  #include "fdt_host.h"
>  #include "mkimage.h"
> @@ -44,6 +45,9 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
>         const uint8_t *padding;
>         int pad_len;
>         int ret;
> +#if !defined(USE_HOSTCC)
> +       struct udevice *rsa_dev;
> +#endif
>
>         if (!prop || !sig || !hash || !algo)
>                 return -EIO;
> @@ -65,11 +69,26 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
>         uint8_t *buf;
>         uint32_t buf_len;
>
> +#if !defined(USE_HOSTCC)
> +       ret = uclass_get_device(UCLASS_RSA, 0, &rsa_dev);
> +       if (!ret) {
> +               ret = rsa_mod_exp(rsa_dev, sig, sig_len, prop, &buf,
> +                                 &buf_len);
> +               if (ret) {
> +                       debug("Error in Modular exponentation\n");
> +                       return ret;
> +               }
> +       } else {
> +               printf("RSA: Can't find Mod Exp implemnetation\n");
> +               return -EINVAL;
> +       }
> +#else
>         ret = rsa_mod_exp_sw(sig, sig_len, prop, &buf, &buf_len);
>         if (ret) {
>                 debug("Error in Modular exponentation\n");
>                 return ret;
>         }
> +#endif

Please can you refactor to reduce duplication? Something like this
(excuse formatting):

> +#if !defined(USE_HOSTCC)
> +       ret = uclass_get_device(UCLASS_RSA, 0, &rsa_dev);
> +       if (ret)
> +               printf("RSA: Can't find Mod Exp implemnetation\n");          - fix typo here!
> +               return -EINVAL;
> +       }
   +       ret = rsa_mod_exp(rsa_dev, sig, sig_len, prop, &buf,
> +                                 &buf_len);
> +#else
>         ret = rsa_mod_exp_sw(sig, sig_len, prop, &buf, &buf_len);
#endif
>         if (ret) {
>                 debug("Error in Modular exponentation\n");
>                 return ret;
>         }


>
>         if (buf_len != sig_len) {
>                 debug("In RSAVerify(): hash length not same as sig len\n");
> --
> 1.8.1.4
>

Regards,
Simon

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

* [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation
  2014-12-30  9:30 ` [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation Ruchika Gupta
@ 2015-01-02 22:24   ` Simon Glass
  2015-01-06  9:38     ` Ruchika Gupta
  0 siblings, 1 reply; 21+ messages in thread
From: Simon Glass @ 2015-01-02 22:24 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> Kconfig option added for devices which support RSA Verification.
> 1. RSA_SOFTWARE_EXP
> Enables driver for supporting RSA Modular Exponentiation in Software
> 2. RSA_FREESCALE_EXP
> Enables driver for supporting RSA Modular Exponentiation using Freescale specific
> driver
>
> The above drivers use RSA uclass
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> Introduced 2 options when CONFIG_RSA is selected:
> RSA_SOFTWARE_EXP
> RSA_FREESCALE_EXP
>
> Removed RSA_HW. Changes the name pf RSA_SW to RSA_SOFTWARE_EXP
>
> Changes in v3:
> New patch
>
>  lib/Kconfig     | 10 +---------
>  lib/rsa/Kconfig | 30 ++++++++++++++++++++++++++++++
>  2 files changed, 31 insertions(+), 9 deletions(-)
>  create mode 100644 lib/rsa/Kconfig
>
> diff --git a/lib/Kconfig b/lib/Kconfig
> index f317f81..a1f30a2 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -27,14 +27,6 @@ config SYS_HZ
>           get_timer() must operate in milliseconds and this option must be
>           set to 1000.
>
> -config RSA
> -       bool "Use RSA Library"
> -       depends on DM
> -       help
> -         RSA support.This enables the RSA algorithm used for FIT image
> -         verification in U-Boot. RSA support for Modular exponentiation
> -         is implemented as a driver model. Driver Model should be enabled
> -         to select this option.
> -         See doc/uImage.FIT/signature.txt for more details.
> +source lib/rsa/Kconfig
>
>  endmenu
> diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
> new file mode 100644
> index 0000000..14155b9
> --- /dev/null
> +++ b/lib/rsa/Kconfig
> @@ -0,0 +1,30 @@
> +config RSA
> +       bool "Use RSA Library"
> +       depends on DM
> +       select RSA_FREESCALE_EXP if FSL_CAAM
> +       select RSA_SOFTWARE_EXP if !RSA_FREESCALE_EXP
> +       help
> +         RSA support.This enables the RSA algorithm used for FIT image
> +         verification in U-Boot. RSA support for Modular exponentiation
> +         is implemented as a driver model. Driver Model should be enabled
> +         to select this option.
> +         See doc/uImage.FIT/signature.txt for more details.
> +
> +if RSA
> +config RSA_SOFTWARE_EXP
> +       bool "Enable driver for RSA Modular Exponentiation in software"
> +       depends on DM && RSA
> +       help
> +         Enables driver for modular exponentiation in software. This is a RSA
> +         algorithm used in FIT image verification. It required RSA Key as
> +         input.
> +         See doc/uImage.FIT/signature.txt for more details.
> +
> +config RSA_FREESCALE_EXP

Just for clarify, I think these names are fine, it's the naming of the
uclass that I think should change. Perhaps UCLASS_MOD_EXP or
UCLASS_RSA_MOD_EXP?


> +       bool "Enable RSA Modular Exponentiation with FSL crypto accelerator"
> +       depends on DM && RSA && FSL_CAAM
> +       help
> +       Enables driver for RSA modular exponentiation using Freescale cryptographic
> +       accelerator - CAAM.
> +
> +endif
> --
> 1.8.1.4
>

Regards,
Simon

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

* [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash
  2014-12-30  9:30 ` [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash Ruchika Gupta
@ 2015-01-02 22:24   ` Simon Glass
  2015-01-06  9:38     ` Ruchika Gupta
  0 siblings, 1 reply; 21+ messages in thread
From: Simon Glass @ 2015-01-02 22:24 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> The hash_algo structure has some implementations in which progressive hash
> API's are not defined. These are basically the hardware based implementations
> of SHA. An API is added to find the algo which has progressive hash API's
> defined. This can then be integrated with RSA checksum library which uses
> Progressive Hash API's.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> Few cosmetic changes. Currently I have not replaced CONFIG_SHA1  with CONFIG_CMD_SHA1SUM.
> Waiting for reply from Simon and Denx for the same.

./tools/buildman/buildman -b try-rsa MPC8308RDB
boards.cfg is up to date. Nothing to do.
Building 10 commits for 1 boards (1 thread, 32 jobs per thread)
   10    0    0 /10     MPC8308RDB
(try-rsa=458103: asc) u> ./tools/buildman/buildman -b try-rsa MPC8308RDB -sS
boards.cfg is up to date. Nothing to do.
Summary of 10 commits for 1 boards (1 thread, 32 jobs per thread)
01: Merge branch 'master' of git://git.denx.de/u-boot-usb
02: rsa: Split the rsa-verify to separate the modular exponentiation
03: FIT: Modify option FIT_SIGNATURE in Kconfig
04: DM: crypto/rsa: Add rsa Modular Exponentiation DM driver
05: configs: Move CONFIG_FIT_SIGNATURE to defconfig
06: lib/rsa: Modify rsa to use DM driver
07: DM: crypto/fsl - Add Freescale rsa DM driver
08: lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation
09: hash: Add function to find hash_algo struct with progressive hash
   powerpc: (for 1/1 boards)  all +208.0  data +28.0  text +180.0
10: rsa: Use checksum algorithms from struct hash_algo
(no errors to report)
(try-rsa=458103: asc) u>

So this adds 180 bytes of code space. I really don't think that is a
big problem, so I think this patch is fine. I'll Wolfgang chime in if
he disagrees.

>
> Changes in v3 :
> Corrected ifdef for SHA1
>
> Changes in v2 :
> Added commit message
>
>  common/hash.c  | 33 ++++++++++++++++++++++++---------
>  include/hash.h | 14 ++++++++++++++
>  2 files changed, 38 insertions(+), 9 deletions(-)
>
> diff --git a/common/hash.c b/common/hash.c
> index 12d6759..ea1ec60 100644
> --- a/common/hash.c
> +++ b/common/hash.c
> @@ -20,7 +20,7 @@
>  #include <asm/io.h>
>  #include <asm/errno.h>
>
> -#ifdef CONFIG_CMD_SHA1SUM
> +#ifdef CONFIG_SHA1
>  static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
>  {
>         sha1_context *ctx = malloc(sizeof(sha1_context));
> @@ -125,12 +125,7 @@ static struct hash_algo hash_algo[] = {
>                 CHUNKSZ_SHA256,
>         },
>  #endif
> -       /*
> -        * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
> -        * it bloats the code for boards which use SHA1 but not the 'hash'
> -        * or 'sha1sum' commands.
> -        */
> -#ifdef CONFIG_CMD_SHA1SUM
> +#ifdef CONFIG_SHA1
>         {
>                 "sha1",
>                 SHA1_SUM_LEN,
> @@ -140,7 +135,6 @@ static struct hash_algo hash_algo[] = {
>                 hash_update_sha1,
>                 hash_finish_sha1,
>         },
> -#define MULTI_HASH
>  #endif
>  #ifdef CONFIG_SHA256
>         {
> @@ -152,7 +146,6 @@ static struct hash_algo hash_algo[] = {
>                 hash_update_sha256,
>                 hash_finish_sha256,
>         },
> -#define MULTI_HASH
>  #endif
>         {
>                 "crc32",
> @@ -165,6 +158,10 @@ static struct hash_algo hash_algo[] = {
>         },
>  };
>
> +#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM)
> +#define MULTI_HASH
> +#endif
> +
>  #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
>  #define MULTI_HASH
>  #endif
> @@ -311,6 +308,24 @@ int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
>         return -EPROTONOSUPPORT;
>  }
>
> +int hash_progressive_lookup_algo(const char *algo_name,
> +                                struct hash_algo **algop)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
> +               if (!strcmp(algo_name, hash_algo[i].name)) {
> +                       if (hash_algo[i].hash_init) {
> +                               *algop = &hash_algo[i];
> +                               return 0;
> +                       }
> +               }
> +       }

Can't you just call hash_lookup_algo() and then check for hash_init?

> +
> +       debug("Unknown hash algorithm '%s'\n", algo_name);
> +       return -EPROTONOSUPPORT;
> +}
> +
>  void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output)
>  {
>         int i;
> diff --git a/include/hash.h b/include/hash.h
> index d8ec4f0..c0a7ebc 100644
> --- a/include/hash.h
> +++ b/include/hash.h
> @@ -128,6 +128,20 @@ int hash_block(const char *algo_name, const void *data, unsigned int len,
>  int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
>
>  /**
> + * hash_progressive_lookup_algo() - Look up hash_algo for prog. hash support
> + *
> + * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
> + * algorithm is not available with progressive hash support.
> + *
> + * @algo_name: Hash algorithm to look up
> + * @algop: Pointer to the hash_algo struct if found
> + *
> + * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
> + */
> +int hash_progressive_lookup_algo(const char *algo_name,
> +                                struct hash_algo **algop);
> +
> +/**
>   * hash_show() - Print out a hash algorithm and value
>   *
>   * You will get a message like this (without a newline at the end):
> --
> 1.8.1.4
>

Regards,
Simon

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

* [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo
  2014-12-30  9:30 ` [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo Ruchika Gupta
@ 2015-01-02 22:24   ` Simon Glass
  2015-01-06  9:38     ` Ruchika Gupta
  0 siblings, 1 reply; 21+ messages in thread
From: Simon Glass @ 2015-01-02 22:24 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> Currently the hash functions used in RSA are called directly from the sha1
> and sha256 libraries. Change the RSA checksum library to use the progressive
> hash API's registered with struct hash_algo. This will allow the checksum
> library to use the hardware accelerated progressive hash API's once available.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
> Changes in v4:
> No changes in this patch. Still under discussion
>
> Changes in v3:
> Modified rsa-verify to check for return from checksum function
>
> Changes in v2:
> Added generic function hash_calculate. Pass an additional
> argument as name of algorithm.
>
>  common/image-sig.c            |  6 ++---
>  include/image.h               |  5 ++--
>  include/u-boot/rsa-checksum.h | 17 ++++++++++----
>  lib/rsa/rsa-checksum.c        | 53 +++++++++++++++++++++++++++++++++++++++----
>  lib/rsa/rsa-verify.c          |  7 +++++-
>  5 files changed, 74 insertions(+), 14 deletions(-)
>
> diff --git a/common/image-sig.c b/common/image-sig.c
> index 8601eda..2c9f0cd 100644
> --- a/common/image-sig.c
> +++ b/common/image-sig.c
> @@ -38,7 +38,7 @@ struct checksum_algo checksum_algos[] = {
>  #if IMAGE_ENABLE_SIGN
>                 EVP_sha1,
>  #endif
> -               sha1_calculate,
> +               hash_calculate,
>                 padding_sha1_rsa2048,
>         },
>         {
> @@ -48,7 +48,7 @@ struct checksum_algo checksum_algos[] = {
>  #if IMAGE_ENABLE_SIGN
>                 EVP_sha256,
>  #endif
> -               sha256_calculate,
> +               hash_calculate,
>                 padding_sha256_rsa2048,
>         },
>         {
> @@ -58,7 +58,7 @@ struct checksum_algo checksum_algos[] = {
>  #if IMAGE_ENABLE_SIGN
>                 EVP_sha256,
>  #endif
> -               sha256_calculate,
> +               hash_calculate,
>                 padding_sha256_rsa4096,
>         }
>
> diff --git a/include/image.h b/include/image.h
> index af30d60..ec55f23 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -926,8 +926,9 @@ struct checksum_algo {
>  #if IMAGE_ENABLE_SIGN
>         const EVP_MD *(*calculate_sign)(void);
>  #endif
> -       void (*calculate)(const struct image_region region[],
> -                         int region_count, uint8_t *checksum);
> +       int (*calculate)(const char *name,
> +                        const struct image_region region[],
> +                        int region_count, uint8_t *checksum);
>         const uint8_t *rsa_padding;
>  };
>
> diff --git a/include/u-boot/rsa-checksum.h b/include/u-boot/rsa-checksum.h
> index c996fb3..3c69d85 100644
> --- a/include/u-boot/rsa-checksum.h
> +++ b/include/u-boot/rsa-checksum.h
> @@ -16,9 +16,18 @@ extern const uint8_t padding_sha256_rsa4096[];
>  extern const uint8_t padding_sha256_rsa2048[];
>  extern const uint8_t padding_sha1_rsa2048[];
>
> -void sha256_calculate(const struct image_region region[], int region_count,
> -                     uint8_t *checksum);
> -void sha1_calculate(const struct image_region region[], int region_count,
> -                   uint8_t *checksum);
> +/**
> + * hash_calculate() - Calculate hash over the data
> + *
> + * @name:  Name of algorithm to be used for hash calculation
> + * @region: Array having info of regions over which hash needs to be calculated
> + * @region_count: Number of regions in the region array
> + * @checksum: Buffer contanining the output hash
> + *
> + * @return 0 if OK, < 0 if error
> + */
> +int hash_calculate(const char *name,
> +                  const struct image_region region[], int region_count,
> +                  uint8_t *checksum);
>
>  #endif
> diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
> index 8d8b59f..7f1909a 100644
> --- a/lib/rsa/rsa-checksum.c
> +++ b/lib/rsa/rsa-checksum.c
> @@ -10,12 +10,13 @@
>  #include <asm/byteorder.h>
>  #include <asm/errno.h>
>  #include <asm/unaligned.h>
> +#include <hash.h>
>  #else
>  #include "fdt_host.h"
> -#endif
> -#include <u-boot/rsa.h>
>  #include <u-boot/sha1.h>
>  #include <u-boot/sha256.h>
> +#endif
> +#include <u-boot/rsa.h>
>
>  /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
>
> @@ -136,7 +137,33 @@ const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = {
>         0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
>  };
>
> -void sha1_calculate(const struct image_region region[], int region_count,
> +#ifndef USE_HOSTCC
> +int hash_calculate(const char *name,
> +                   const struct image_region region[],
> +                   int region_count, uint8_t *checksum)
> +{
> +       struct hash_algo *algo;
> +       int ret = 0;
> +       void *ctx;
> +       uint32_t i;
> +       i = 0;
> +
> +       ret = hash_progressive_lookup_algo(name, &algo);
> +       if (ret)
> +               return ret;
> +
> +       algo->hash_init(algo, &ctx);
> +       for (i = 0; i < region_count - 1; i++)
> +               algo->hash_update(algo, ctx, region[i].data, region[i].size, 0);
> +
> +       algo->hash_update(algo, ctx, region[i].data, region[i].size, 1);
> +       algo->hash_finish(algo, ctx, checksum, algo->digest_size);

Shouldn't you have error checking on these calls?

> +
> +       return 0;
> +}
> +
> +#else

It seems odd to duplicate this code. I'll email you a WIP patch to
correct this. Perhaps you could tidy it up and attach it to your
series? Then I think you can remove this #else part.

> +int sha1_calculate(const struct image_region region[], int region_count,
>                     uint8_t *checksum)
>  {
>         sha1_context ctx;
> @@ -147,9 +174,11 @@ void sha1_calculate(const struct image_region region[], int region_count,
>         for (i = 0; i < region_count; i++)
>                 sha1_update(&ctx, region[i].data, region[i].size);
>         sha1_finish(&ctx, checksum);
> +
> +       return 0;
>  }
>
> -void sha256_calculate(const struct image_region region[], int region_count,
> +int sha256_calculate(const struct image_region region[], int region_count,
>                       uint8_t *checksum)
>  {
>         sha256_context ctx;
> @@ -160,4 +189,20 @@ void sha256_calculate(const struct image_region region[], int region_count,
>         for (i = 0; i < region_count; i++)
>                 sha256_update(&ctx, region[i].data, region[i].size);
>         sha256_finish(&ctx, checksum);
> +
> +       return 0;
>  }
> +
> +int hash_calculate(const char *name,
> +                  const struct image_region region[], int region_count,
> +                  uint8_t *checksum)
> +{
> +       if (!strcmp(name, "sha1"))
> +               sha1_calculate(region, region_count, checksum);
> +
> +       if (!strcmp(name, "sha256"))
> +               sha256_calculate(region, region_count, checksum);
> +
> +       return 0;
> +}
> +#endif
> diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
> index af915d3..cf5acdf 100644
> --- a/lib/rsa/rsa-verify.c
> +++ b/lib/rsa/rsa-verify.c
> @@ -201,7 +201,12 @@ int rsa_verify(struct image_sign_info *info,
>         }
>
>         /* Calculate checksum with checksum-algorithm */
> -       info->algo->checksum->calculate(region, region_count, hash);
> +       ret = info->algo->checksum->calculate(info->algo->checksum->name,
> +                                       region, region_count, hash);
> +       if (ret < 0) {
> +               debug("%s: Error in checksum calculation\n", __func__);
> +               return -EINVAL;
> +       }
>
>         /* See if we must use a particular key */
>         if (info->required_keynode != -1) {
> --
> 1.8.1.4
>

Regards,
Simon

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

* [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation
  2015-01-02 22:24   ` Simon Glass
@ 2015-01-06  9:38     ` Ruchika Gupta
  0 siblings, 0 replies; 21+ messages in thread
From: Ruchika Gupta @ 2015-01-06  9:38 UTC (permalink / raw)
  To: u-boot

Hi Simon,

> -----Original Message-----
> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
> Sent: Saturday, January 03, 2015 3:54 AM
> To: Gupta Ruchika-R66431
> Cc: U-Boot Mailing List; Sun York-R58495
> Subject: Re: [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA
> Modular Exponentiation
> 
> Hi Ruchika,
> 
> On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com>
> wrote:
> > Kconfig option added for devices which support RSA Verification.
> > 1. RSA_SOFTWARE_EXP
> > Enables driver for supporting RSA Modular Exponentiation in Software
> > 2. RSA_FREESCALE_EXP Enables driver for supporting RSA Modular
> > Exponentiation using Freescale specific driver
> >
> > The above drivers use RSA uclass
> >
> > Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> > CC: Simon Glass <sjg@chromium.org>
> > ---
> > Changes in v4:
> > Introduced 2 options when CONFIG_RSA is selected:
> > RSA_SOFTWARE_EXP
> > RSA_FREESCALE_EXP
> >
> > Removed RSA_HW. Changes the name pf RSA_SW to RSA_SOFTWARE_EXP
> >
> > Changes in v3:
> > New patch
> >
> >  lib/Kconfig     | 10 +---------
> >  lib/rsa/Kconfig | 30 ++++++++++++++++++++++++++++++
> >  2 files changed, 31 insertions(+), 9 deletions(-)  create mode 100644
> > lib/rsa/Kconfig
> >
> > diff --git a/lib/Kconfig b/lib/Kconfig index f317f81..a1f30a2 100644
> > --- a/lib/Kconfig
> > +++ b/lib/Kconfig
> > @@ -27,14 +27,6 @@ config SYS_HZ
> >           get_timer() must operate in milliseconds and this option must be
> >           set to 1000.
> >
> > -config RSA
> > -       bool "Use RSA Library"
> > -       depends on DM
> > -       help
> > -         RSA support.This enables the RSA algorithm used for FIT image
> > -         verification in U-Boot. RSA support for Modular exponentiation
> > -         is implemented as a driver model. Driver Model should be enabled
> > -         to select this option.
> > -         See doc/uImage.FIT/signature.txt for more details.
> > +source lib/rsa/Kconfig
> >
> >  endmenu
> > diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig new file mode 100644
> > index 0000000..14155b9
> > --- /dev/null
> > +++ b/lib/rsa/Kconfig
> > @@ -0,0 +1,30 @@
> > +config RSA
> > +       bool "Use RSA Library"
> > +       depends on DM
> > +       select RSA_FREESCALE_EXP if FSL_CAAM
> > +       select RSA_SOFTWARE_EXP if !RSA_FREESCALE_EXP
> > +       help
> > +         RSA support.This enables the RSA algorithm used for FIT image
> > +         verification in U-Boot. RSA support for Modular exponentiation
> > +         is implemented as a driver model. Driver Model should be enabled
> > +         to select this option.
> > +         See doc/uImage.FIT/signature.txt for more details.
> > +
> > +if RSA
> > +config RSA_SOFTWARE_EXP
> > +       bool "Enable driver for RSA Modular Exponentiation in software"
> > +       depends on DM && RSA
> > +       help
> > +         Enables driver for modular exponentiation in software. This is a
> RSA
> > +         algorithm used in FIT image verification. It required RSA Key as
> > +         input.
> > +         See doc/uImage.FIT/signature.txt for more details.
> > +
> > +config RSA_FREESCALE_EXP
> 
> Just for clarify, I think these names are fine, it's the naming of the uclass
> that I think should change. Perhaps UCLASS_MOD_EXP or UCLASS_RSA_MOD_EXP?
I will change it in next version of patches.
> 
> 
> > +       bool "Enable RSA Modular Exponentiation with FSL crypto
> accelerator"
> > +       depends on DM && RSA && FSL_CAAM
> > +       help
> > +       Enables driver for RSA modular exponentiation using Freescale
> cryptographic
> > +       accelerator - CAAM.
> > +
> > +endif
> > --
> > 1.8.1.4
> >
> 
> Regards,
> Simon
Regards,
Ruchika

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

* [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash
  2015-01-02 22:24   ` Simon Glass
@ 2015-01-06  9:38     ` Ruchika Gupta
  2015-01-06 15:42       ` Simon Glass
  0 siblings, 1 reply; 21+ messages in thread
From: Ruchika Gupta @ 2015-01-06  9:38 UTC (permalink / raw)
  To: u-boot

Hi Simon,

> -----Original Message-----
> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
> Sent: Saturday, January 03, 2015 3:54 AM
> To: Gupta Ruchika-R66431
> Cc: U-Boot Mailing List; Sun York-R58495; Wolfgang Denk
> Subject: Re: [PATCH 8/9] [v4] hash: Add function to find hash_algo struct
> with progressive hash
> 
> Hi Ruchika,
> 
> On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com>
> wrote:
> > The hash_algo structure has some implementations in which progressive
> > hash API's are not defined. These are basically the hardware based
> > implementations of SHA. An API is added to find the algo which has
> > progressive hash API's defined. This can then be integrated with RSA
> > checksum library which uses Progressive Hash API's.
> >
> > Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> > CC: Simon Glass <sjg@chromium.org>
> > ---
> > Changes in v4:
> > Few cosmetic changes. Currently I have not replaced CONFIG_SHA1  with
> CONFIG_CMD_SHA1SUM.
> > Waiting for reply from Simon and Denx for the same.
> 
> ./tools/buildman/buildman -b try-rsa MPC8308RDB boards.cfg is up to date.
> Nothing to do.
> Building 10 commits for 1 boards (1 thread, 32 jobs per thread)
>    10    0    0 /10     MPC8308RDB
> (try-rsa=458103: asc) u> ./tools/buildman/buildman -b try-rsa MPC8308RDB -sS
> boards.cfg is up to date. Nothing to do.
> Summary of 10 commits for 1 boards (1 thread, 32 jobs per thread)
> 01: Merge branch 'master' of git://git.denx.de/u-boot-usb
> 02: rsa: Split the rsa-verify to separate the modular exponentiation
> 03: FIT: Modify option FIT_SIGNATURE in Kconfig
> 04: DM: crypto/rsa: Add rsa Modular Exponentiation DM driver
> 05: configs: Move CONFIG_FIT_SIGNATURE to defconfig
> 06: lib/rsa: Modify rsa to use DM driver
> 07: DM: crypto/fsl - Add Freescale rsa DM driver
> 08: lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation
> 09: hash: Add function to find hash_algo struct with progressive hash
>    powerpc: (for 1/1 boards)  all +208.0  data +28.0  text +180.0
> 10: rsa: Use checksum algorithms from struct hash_algo (no errors to report)
> (try-rsa=458103: asc) u>
> 
> So this adds 180 bytes of code space. I really don't think that is a big
> problem, so I think this patch is fine. I'll Wolfgang chime in if he
> disagrees.
> 
> >
> > Changes in v3 :
> > Corrected ifdef for SHA1
> >
> > Changes in v2 :
> > Added commit message
> >
> >  common/hash.c  | 33 ++++++++++++++++++++++++---------  include/hash.h
> > | 14 ++++++++++++++
> >  2 files changed, 38 insertions(+), 9 deletions(-)
> >
> > diff --git a/common/hash.c b/common/hash.c index 12d6759..ea1ec60
> > 100644
> > --- a/common/hash.c
> > +++ b/common/hash.c
> > @@ -20,7 +20,7 @@
> >  #include <asm/io.h>
> >  #include <asm/errno.h>
> >
> > -#ifdef CONFIG_CMD_SHA1SUM
> > +#ifdef CONFIG_SHA1
> >  static int hash_init_sha1(struct hash_algo *algo, void **ctxp)  {
> >         sha1_context *ctx = malloc(sizeof(sha1_context)); @@ -125,12
> > +125,7 @@ static struct hash_algo hash_algo[] = {
> >                 CHUNKSZ_SHA256,
> >         },
> >  #endif
> > -       /*
> > -        * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since
> otherwise
> > -        * it bloats the code for boards which use SHA1 but not the 'hash'
> > -        * or 'sha1sum' commands.
> > -        */
> > -#ifdef CONFIG_CMD_SHA1SUM
> > +#ifdef CONFIG_SHA1
> >         {
> >                 "sha1",
> >                 SHA1_SUM_LEN,
> > @@ -140,7 +135,6 @@ static struct hash_algo hash_algo[] = {
> >                 hash_update_sha1,
> >                 hash_finish_sha1,
> >         },
> > -#define MULTI_HASH
> >  #endif
> >  #ifdef CONFIG_SHA256
> >         {
> > @@ -152,7 +146,6 @@ static struct hash_algo hash_algo[] = {
> >                 hash_update_sha256,
> >                 hash_finish_sha256,
> >         },
> > -#define MULTI_HASH
> >  #endif
> >         {
> >                 "crc32",
> > @@ -165,6 +158,10 @@ static struct hash_algo hash_algo[] = {
> >         },
> >  };
> >
> > +#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM) #define
> > +MULTI_HASH #endif
> > +
> >  #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)  #define
> > MULTI_HASH  #endif @@ -311,6 +308,24 @@ int hash_lookup_algo(const
> > char *algo_name, struct hash_algo **algop)
> >         return -EPROTONOSUPPORT;
> >  }
> >
> > +int hash_progressive_lookup_algo(const char *algo_name,
> > +                                struct hash_algo **algop) {
> > +       int i;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
> > +               if (!strcmp(algo_name, hash_algo[i].name)) {
> > +                       if (hash_algo[i].hash_init) {
> > +                               *algop = &hash_algo[i];
> > +                               return 0;
> > +                       }
> > +               }
> > +       }
> 
> Can't you just call hash_lookup_algo() and then check for hash_init?
Hash_lookup_algo always searches from the start of hash_algo[]. So what you have suggested above wouldn't work.

> 
> > +
> > +       debug("Unknown hash algorithm '%s'\n", algo_name);
> > +       return -EPROTONOSUPPORT;
> > +}
> > +
> >  void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t
> > *output)  {
> >         int i;
> > diff --git a/include/hash.h b/include/hash.h index d8ec4f0..c0a7ebc
> > 100644
> > --- a/include/hash.h
> > +++ b/include/hash.h
> > @@ -128,6 +128,20 @@ int hash_block(const char *algo_name, const void
> > *data, unsigned int len,  int hash_lookup_algo(const char *algo_name,
> > struct hash_algo **algop);
> >
> >  /**
> > + * hash_progressive_lookup_algo() - Look up hash_algo for prog. hash
> > +support
> > + *
> > + * The function returns the pointer to the struct or -EPROTONOSUPPORT
> > +if the
> > + * algorithm is not available with progressive hash support.
> > + *
> > + * @algo_name: Hash algorithm to look up
> > + * @algop: Pointer to the hash_algo struct if found
> > + *
> > + * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
> > + */
> > +int hash_progressive_lookup_algo(const char *algo_name,
> > +                                struct hash_algo **algop);
> > +
> > +/**
> >   * hash_show() - Print out a hash algorithm and value
> >   *
> >   * You will get a message like this (without a newline at the end):
> > --
> > 1.8.1.4
> >
> 
> Regards,
> Simon

Regards,
Ruchika

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

* [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo
  2015-01-02 22:24   ` Simon Glass
@ 2015-01-06  9:38     ` Ruchika Gupta
  0 siblings, 0 replies; 21+ messages in thread
From: Ruchika Gupta @ 2015-01-06  9:38 UTC (permalink / raw)
  To: u-boot

Hi Simon,

> -----Original Message-----
> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
> Sent: Saturday, January 03, 2015 3:55 AM
> To: Gupta Ruchika-R66431
> Cc: U-Boot Mailing List; Sun York-R58495
> Subject: Re: [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct
> hash_algo
> 
> Hi Ruchika,
> 
> On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com>
> wrote:
> > Currently the hash functions used in RSA are called directly from the
> > sha1 and sha256 libraries. Change the RSA checksum library to use the
> > progressive hash API's registered with struct hash_algo. This will
> > allow the checksum library to use the hardware accelerated progressive hash
> API's once available.
> >
> > Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> > CC: Simon Glass <sjg@chromium.org>
> > ---
> > Changes in v4:
> > No changes in this patch. Still under discussion
> >
> > Changes in v3:
> > Modified rsa-verify to check for return from checksum function
> >
> > Changes in v2:
> > Added generic function hash_calculate. Pass an additional argument as
> > name of algorithm.
> >
> >  common/image-sig.c            |  6 ++---
> >  include/image.h               |  5 ++--
> >  include/u-boot/rsa-checksum.h | 17 ++++++++++----
> >  lib/rsa/rsa-checksum.c        | 53
> +++++++++++++++++++++++++++++++++++++++----
> >  lib/rsa/rsa-verify.c          |  7 +++++-
> >  5 files changed, 74 insertions(+), 14 deletions(-)
> >
> > diff --git a/common/image-sig.c b/common/image-sig.c index
> > 8601eda..2c9f0cd 100644
> > --- a/common/image-sig.c
> > +++ b/common/image-sig.c
> > @@ -38,7 +38,7 @@ struct checksum_algo checksum_algos[] = {  #if
> > IMAGE_ENABLE_SIGN
> >                 EVP_sha1,
> >  #endif
> > -               sha1_calculate,
> > +               hash_calculate,
> >                 padding_sha1_rsa2048,
> >         },
> >         {
> > @@ -48,7 +48,7 @@ struct checksum_algo checksum_algos[] = {  #if
> > IMAGE_ENABLE_SIGN
> >                 EVP_sha256,
> >  #endif
> > -               sha256_calculate,
> > +               hash_calculate,
> >                 padding_sha256_rsa2048,
> >         },
> >         {
> > @@ -58,7 +58,7 @@ struct checksum_algo checksum_algos[] = {  #if
> > IMAGE_ENABLE_SIGN
> >                 EVP_sha256,
> >  #endif
> > -               sha256_calculate,
> > +               hash_calculate,
> >                 padding_sha256_rsa4096,
> >         }
> >
> > diff --git a/include/image.h b/include/image.h index af30d60..ec55f23
> > 100644
> > --- a/include/image.h
> > +++ b/include/image.h
> > @@ -926,8 +926,9 @@ struct checksum_algo {  #if IMAGE_ENABLE_SIGN
> >         const EVP_MD *(*calculate_sign)(void);  #endif
> > -       void (*calculate)(const struct image_region region[],
> > -                         int region_count, uint8_t *checksum);
> > +       int (*calculate)(const char *name,
> > +                        const struct image_region region[],
> > +                        int region_count, uint8_t *checksum);
> >         const uint8_t *rsa_padding;
> >  };
> >
> > diff --git a/include/u-boot/rsa-checksum.h
> > b/include/u-boot/rsa-checksum.h index c996fb3..3c69d85 100644
> > --- a/include/u-boot/rsa-checksum.h
> > +++ b/include/u-boot/rsa-checksum.h
> > @@ -16,9 +16,18 @@ extern const uint8_t padding_sha256_rsa4096[];
> > extern const uint8_t padding_sha256_rsa2048[];  extern const uint8_t
> > padding_sha1_rsa2048[];
> >
> > -void sha256_calculate(const struct image_region region[], int
> region_count,
> > -                     uint8_t *checksum);
> > -void sha1_calculate(const struct image_region region[], int region_count,
> > -                   uint8_t *checksum);
> > +/**
> > + * hash_calculate() - Calculate hash over the data
> > + *
> > + * @name:  Name of algorithm to be used for hash calculation
> > + * @region: Array having info of regions over which hash needs to be
> > +calculated
> > + * @region_count: Number of regions in the region array
> > + * @checksum: Buffer contanining the output hash
> > + *
> > + * @return 0 if OK, < 0 if error
> > + */
> > +int hash_calculate(const char *name,
> > +                  const struct image_region region[], int region_count,
> > +                  uint8_t *checksum);
> >
> >  #endif
> > diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c index
> > 8d8b59f..7f1909a 100644
> > --- a/lib/rsa/rsa-checksum.c
> > +++ b/lib/rsa/rsa-checksum.c
> > @@ -10,12 +10,13 @@
> >  #include <asm/byteorder.h>
> >  #include <asm/errno.h>
> >  #include <asm/unaligned.h>
> > +#include <hash.h>
> >  #else
> >  #include "fdt_host.h"
> > -#endif
> > -#include <u-boot/rsa.h>
> >  #include <u-boot/sha1.h>
> >  #include <u-boot/sha256.h>
> > +#endif
> > +#include <u-boot/rsa.h>
> >
> >  /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
> >
> > @@ -136,7 +137,33 @@ const uint8_t padding_sha256_rsa4096[RSA4096_BYTES -
> SHA256_SUM_LEN] = {
> >         0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20  };
> >
> > -void sha1_calculate(const struct image_region region[], int
> > region_count,
> > +#ifndef USE_HOSTCC
> > +int hash_calculate(const char *name,
> > +                   const struct image_region region[],
> > +                   int region_count, uint8_t *checksum) {
> > +       struct hash_algo *algo;
> > +       int ret = 0;
> > +       void *ctx;
> > +       uint32_t i;
> > +       i = 0;
> > +
> > +       ret = hash_progressive_lookup_algo(name, &algo);
> > +       if (ret)
> > +               return ret;
> > +
> > +       algo->hash_init(algo, &ctx);
> > +       for (i = 0; i < region_count - 1; i++)
> > +               algo->hash_update(algo, ctx, region[i].data,
> > + region[i].size, 0);
> > +
> > +       algo->hash_update(algo, ctx, region[i].data, region[i].size, 1);
> > +       algo->hash_finish(algo, ctx, checksum, algo->digest_size);
> 
> Shouldn't you have error checking on these calls?
I will add the checks
> 
> > +
> > +       return 0;
> > +}
> > +
> > +#else
> 
> It seems odd to duplicate this code. I'll email you a WIP patch to correct
> this. Perhaps you could tidy it up and attach it to your series? Then I think
> you can remove this #else part.
I will try the WIP patch to see I this can be corrected.
> 
> > +int sha1_calculate(const struct image_region region[], int
> > +region_count,
> >                     uint8_t *checksum)  {
> >         sha1_context ctx;
> > @@ -147,9 +174,11 @@ void sha1_calculate(const struct image_region
> region[], int region_count,
> >         for (i = 0; i < region_count; i++)
> >                 sha1_update(&ctx, region[i].data, region[i].size);
> >         sha1_finish(&ctx, checksum);
> > +
> > +       return 0;
> >  }
> >
> > -void sha256_calculate(const struct image_region region[], int
> > region_count,
> > +int sha256_calculate(const struct image_region region[], int
> > +region_count,
> >                       uint8_t *checksum)  {
> >         sha256_context ctx;
> > @@ -160,4 +189,20 @@ void sha256_calculate(const struct image_region
> region[], int region_count,
> >         for (i = 0; i < region_count; i++)
> >                 sha256_update(&ctx, region[i].data, region[i].size);
> >         sha256_finish(&ctx, checksum);
> > +
> > +       return 0;
> >  }
> > +
> > +int hash_calculate(const char *name,
> > +                  const struct image_region region[], int region_count,
> > +                  uint8_t *checksum)
> > +{
> > +       if (!strcmp(name, "sha1"))
> > +               sha1_calculate(region, region_count, checksum);
> > +
> > +       if (!strcmp(name, "sha256"))
> > +               sha256_calculate(region, region_count, checksum);
> > +
> > +       return 0;
> > +}
> > +#endif
> > diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index
> > af915d3..cf5acdf 100644
> > --- a/lib/rsa/rsa-verify.c
> > +++ b/lib/rsa/rsa-verify.c
> > @@ -201,7 +201,12 @@ int rsa_verify(struct image_sign_info *info,
> >         }
> >
> >         /* Calculate checksum with checksum-algorithm */
> > -       info->algo->checksum->calculate(region, region_count, hash);
> > +       ret = info->algo->checksum->calculate(info->algo->checksum->name,
> > +                                       region, region_count, hash);
> > +       if (ret < 0) {
> > +               debug("%s: Error in checksum calculation\n", __func__);
> > +               return -EINVAL;
> > +       }
> >
> >         /* See if we must use a particular key */
> >         if (info->required_keynode != -1) {
> > --
> > 1.8.1.4
> >
> 
> Regards,
> Simon
Regards,
Ruchika

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

* [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash
  2015-01-06  9:38     ` Ruchika Gupta
@ 2015-01-06 15:42       ` Simon Glass
  0 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2015-01-06 15:42 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 6 January 2015 at 02:38, Ruchika Gupta <ruchika.gupta@freescale.com> wrote:
> Hi Simon,
>
>> -----Original Message-----
>> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
>> Sent: Saturday, January 03, 2015 3:54 AM
>> To: Gupta Ruchika-R66431
>> Cc: U-Boot Mailing List; Sun York-R58495; Wolfgang Denk
>> Subject: Re: [PATCH 8/9] [v4] hash: Add function to find hash_algo struct
>> with progressive hash
>>
>> Hi Ruchika,
>>
>> On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com>
>> wrote:
>> > The hash_algo structure has some implementations in which progressive
>> > hash API's are not defined. These are basically the hardware based
>> > implementations of SHA. An API is added to find the algo which has
>> > progressive hash API's defined. This can then be integrated with RSA
>> > checksum library which uses Progressive Hash API's.
>> >
>> > Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
>> > CC: Simon Glass <sjg@chromium.org>
>> > ---
>> > Changes in v4:
>> > Few cosmetic changes. Currently I have not replaced CONFIG_SHA1  with
>> CONFIG_CMD_SHA1SUM.
>> > Waiting for reply from Simon and Denx for the same.
>>
>> ./tools/buildman/buildman -b try-rsa MPC8308RDB boards.cfg is up to date.
>> Nothing to do.
>> Building 10 commits for 1 boards (1 thread, 32 jobs per thread)
>>    10    0    0 /10     MPC8308RDB
>> (try-rsa=458103: asc) u> ./tools/buildman/buildman -b try-rsa MPC8308RDB -sS
>> boards.cfg is up to date. Nothing to do.
>> Summary of 10 commits for 1 boards (1 thread, 32 jobs per thread)
>> 01: Merge branch 'master' of git://git.denx.de/u-boot-usb
>> 02: rsa: Split the rsa-verify to separate the modular exponentiation
>> 03: FIT: Modify option FIT_SIGNATURE in Kconfig
>> 04: DM: crypto/rsa: Add rsa Modular Exponentiation DM driver
>> 05: configs: Move CONFIG_FIT_SIGNATURE to defconfig
>> 06: lib/rsa: Modify rsa to use DM driver
>> 07: DM: crypto/fsl - Add Freescale rsa DM driver
>> 08: lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation
>> 09: hash: Add function to find hash_algo struct with progressive hash
>>    powerpc: (for 1/1 boards)  all +208.0  data +28.0  text +180.0
>> 10: rsa: Use checksum algorithms from struct hash_algo (no errors to report)
>> (try-rsa=458103: asc) u>
>>
>> So this adds 180 bytes of code space. I really don't think that is a big
>> problem, so I think this patch is fine. I'll Wolfgang chime in if he
>> disagrees.
>>
>> >
>> > Changes in v3 :
>> > Corrected ifdef for SHA1
>> >
>> > Changes in v2 :
>> > Added commit message
>> >
>> >  common/hash.c  | 33 ++++++++++++++++++++++++---------  include/hash.h
>> > | 14 ++++++++++++++
>> >  2 files changed, 38 insertions(+), 9 deletions(-)
>> >
>> > diff --git a/common/hash.c b/common/hash.c index 12d6759..ea1ec60
>> > 100644
>> > --- a/common/hash.c
>> > +++ b/common/hash.c
>> > @@ -20,7 +20,7 @@
>> >  #include <asm/io.h>
>> >  #include <asm/errno.h>
>> >
>> > -#ifdef CONFIG_CMD_SHA1SUM
>> > +#ifdef CONFIG_SHA1
>> >  static int hash_init_sha1(struct hash_algo *algo, void **ctxp)  {
>> >         sha1_context *ctx = malloc(sizeof(sha1_context)); @@ -125,12
>> > +125,7 @@ static struct hash_algo hash_algo[] = {
>> >                 CHUNKSZ_SHA256,
>> >         },
>> >  #endif
>> > -       /*
>> > -        * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since
>> otherwise
>> > -        * it bloats the code for boards which use SHA1 but not the 'hash'
>> > -        * or 'sha1sum' commands.
>> > -        */
>> > -#ifdef CONFIG_CMD_SHA1SUM
>> > +#ifdef CONFIG_SHA1
>> >         {
>> >                 "sha1",
>> >                 SHA1_SUM_LEN,
>> > @@ -140,7 +135,6 @@ static struct hash_algo hash_algo[] = {
>> >                 hash_update_sha1,
>> >                 hash_finish_sha1,
>> >         },
>> > -#define MULTI_HASH
>> >  #endif
>> >  #ifdef CONFIG_SHA256
>> >         {
>> > @@ -152,7 +146,6 @@ static struct hash_algo hash_algo[] = {
>> >                 hash_update_sha256,
>> >                 hash_finish_sha256,
>> >         },
>> > -#define MULTI_HASH
>> >  #endif
>> >         {
>> >                 "crc32",
>> > @@ -165,6 +158,10 @@ static struct hash_algo hash_algo[] = {
>> >         },
>> >  };
>> >
>> > +#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM) #define
>> > +MULTI_HASH #endif
>> > +
>> >  #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)  #define
>> > MULTI_HASH  #endif @@ -311,6 +308,24 @@ int hash_lookup_algo(const
>> > char *algo_name, struct hash_algo **algop)
>> >         return -EPROTONOSUPPORT;
>> >  }
>> >
>> > +int hash_progressive_lookup_algo(const char *algo_name,
>> > +                                struct hash_algo **algop) {
>> > +       int i;
>> > +
>> > +       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
>> > +               if (!strcmp(algo_name, hash_algo[i].name)) {
>> > +                       if (hash_algo[i].hash_init) {
>> > +                               *algop = &hash_algo[i];
>> > +                               return 0;
>> > +                       }
>> > +               }
>> > +       }
>>
>> Can't you just call hash_lookup_algo() and then check for hash_init?
> Hash_lookup_algo always searches from the start of hash_algo[]. So what you have suggested above wouldn't work.

OK I don't fully understand that, but let's go with what you have for
this series.

Regards,
Simon

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

* [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver
       [not found]     ` <1420537067401.77619@freescale.com>
@ 2015-01-06 20:30       ` Simon Glass
  0 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2015-01-06 20:30 UTC (permalink / raw)
  To: u-boot

Hi Ruchika,

On 6 January 2015 at 02:37, Ruchika Gupta <ruchika.gupta@freescale.com>
wrote:

> Hi Simon,
>
> > -----Original Message-----
> > From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
> > Sent: Saturday, January 03, 2015 3:54 AM
> > To: Gupta Ruchika-R66431
> > Cc: U-Boot Mailing List; Sun York-R58495
> > Subject: Re: [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular
> Exponentiation
> > DM driver
> >
> > Hi Ruchika,
> >
> > On 30 December 2014 at 02:30, Ruchika Gupta <ruchika.gupta@freescale.com
> >
> > wrote:
> > > Add a new rsa uclass for performing modular exponentiation and
> > > implement the software driver basing on this uclass.
> > >
> > > Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
> > > CC: Simon Glass <sjg@chromium.org>
> > > ---
> > > Changes in v4:
> > > Removed Kconfig option for DM_RSA
> > > Corrected driver name for sw rsa driver Updated the rsa_mod_exp
> > > operation to have output length
> > >
> > > Changes in v3:
> > > New patch with driver model for RSA UCLASS
> > >
> > >  drivers/crypto/Makefile         |  1 +
> > >  drivers/crypto/rsa/Makefile     |  7 +++++++
> > >  drivers/crypto/rsa/rsa_sw.c     | 39
> > +++++++++++++++++++++++++++++++++++++++
> > >  drivers/crypto/rsa/rsa_uclass.c | 31 +++++++++++++++++++++++++++++++
> > >  include/dm/uclass-id.h          |  1 +
> > >  include/u-boot/rsa-mod-exp.h    | 37
> +++++++++++++++++++++++++++++++++++++
> > >  6 files changed, 116 insertions(+)
> > >  create mode 100644 drivers/crypto/rsa/Makefile  create mode 100644
> > > drivers/crypto/rsa/rsa_sw.c  create mode 100644
> > > drivers/crypto/rsa/rsa_uclass.c
> >
> > Again I'm a bit worried we are going off into the weeds.
> >
> > Is this an RSA driver or a modular exponentiation driver? It seems like
> the
> > latter to me. If so, the uclass should be UCLASS_MOD_EXP, not
> UCLASS_RSA, and
> > the files and directories should be renames also. Some hardware will
> > implement the entire RSA algorithm, which would be a true RSA uclass.
> Here I
> > think you are only doing part of it.
> I did this to introduce a generic class for RSA which has mod_exp
> implementation for now and can be extended to have sign or any other algo
> added later.For now I will change it to UCLASS_MOD_EXP as you have
> suggested.
>

From what I understand the RSA API consists of two functions:

rsa_sign()
rsa_verify()

These are defined in rsa.h.

So if you are planning to implement an RSA uclass it should support these
two. In your case it seems like you are implementing a part of RSA, i.e.
lower-level functionality. That's why I'm saying it doesn't look like an
RSA uclass to me.


>
> >
> > Other than that rename the code looks fine.
> >
> > Minor point: again I don't see the value of returning the same value as
> > sig_len, so you may as well drop those last two args to mod_exp() -
> unless I
> > am missing something.
> I will do that and revert back to earlier implementation with uint8_t *out.
>
> >
> > >
> > > diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index
> > > 7b79237..a2f30fc 100644
> > > --- a/drivers/crypto/Makefile
> > > +++ b/drivers/crypto/Makefile
> > > @@ -6,4 +6,5 @@
> > >  #
> > >
> > >  obj-$(CONFIG_EXYNOS_ACE_SHA)   += ace_sha.o
> > > +obj-y += rsa/
> > >  obj-y += fsl/
> > > diff --git a/drivers/crypto/rsa/Makefile b/drivers/crypto/rsa/Makefile
> > > new file mode 100644 index 0000000..927c5bd
> > > --- /dev/null
> > > +++ b/drivers/crypto/rsa/Makefile
> > > @@ -0,0 +1,7 @@
> > > +#
> > > +# (C) Copyright 2014 Freescale Semiconductor, Inc.
> > > +#
> > > +# SPDX-License-Identifier:     GPL-2.0+
> > > +#
> > > +
> > > +obj-$(CONFIG_RSA) += rsa_uclass.o rsa_sw.o
> > > diff --git a/drivers/crypto/rsa/rsa_sw.c b/drivers/crypto/rsa/rsa_sw.c
> > > new file mode 100644 index 0000000..3dcd512
> > > --- /dev/null
> > > +++ b/drivers/crypto/rsa/rsa_sw.c
> > > @@ -0,0 +1,39 @@
> > > +/*
> > > + * (C) Copyright 2014 Freescale Semiconductor, Inc.
> > > + * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
> > > + *
> > > + * SPDX-License-Identifier:    GPL-2.0+
> > > + */
> > > +
> > > +#include <config.h>
> > > +#include <common.h>
> > > +#include <dm.h>
> > > +#include <u-boot/rsa-mod-exp.h>
> > > +
> > > +int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t
> sig_len,
> > > +               struct key_prop *prop, uint8_t **outp, uint32_t
> > > +*out_len) {
> > > +       int ret = 0;
> > > +
> > > +       ret = rsa_mod_exp_sw(sig, sig_len, prop, outp, out_len);
> > > +       if (ret) {
> > > +               debug("%s: RSA failed to verify: %d\n", __func__, ret);
> > > +               return ret;
> > > +       }
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static const struct rsa_ops rsa_ops_sw = {
> > > +       .mod_exp        = mod_exp_sw,
> > > +};
> > > +
> > > +U_BOOT_DRIVER(rsa_sw) = {
> > > +       .name   = "rsa_sw",
> > > +       .id     = UCLASS_RSA,
> > > +       .ops    = &rsa_ops_sw,
> > > +};
> > > +
> > > +U_BOOT_DEVICE(rsa_sw) = {
> > > +       .name = "rsa_sw",
> > > +};
> > > diff --git a/drivers/crypto/rsa/rsa_uclass.c
> > > b/drivers/crypto/rsa/rsa_uclass.c new file mode 100644 index
> > > 0000000..4d52dcc
> > > --- /dev/null
> > > +++ b/drivers/crypto/rsa/rsa_uclass.c
> > > @@ -0,0 +1,31 @@
> > > +/*
> > > + * (C) Copyright 2014 Freescale Semiconductor, Inc
> > > + * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
> > > + *
> > > + * SPDX-License-Identifier:    GPL-2.0+
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <dm.h>
> > > +#include <u-boot/rsa-mod-exp.h>
> > > +#include <errno.h>
> > > +#include <fdtdec.h>
> > > +#include <malloc.h>
> > > +#include <asm/io.h>
> > > +#include <linux/list.h>
> > > +
> > > +int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t
> sig_len,
> > > +               struct key_prop *node, uint8_t **out, uint32_t
> > > +*out_len) {
> > > +       const struct rsa_ops *ops = device_get_ops(dev);
> > > +
> > > +       if (!ops->mod_exp)
> > > +               return -ENOSYS;
> > > +
> > > +       return ops->mod_exp(dev, sig, sig_len, node, out, out_len); }
> > > +
> > > +UCLASS_DRIVER(rsa) = {
> > > +       .id             = UCLASS_RSA,
> > > +       .name           = "rsa",
> > > +};
> > > diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index
> > > f17c3c2..823e43c 100644
> > > --- a/include/dm/uclass-id.h
> > > +++ b/include/dm/uclass-id.h
> > > @@ -33,6 +33,7 @@ enum uclass_id {
> > >         UCLASS_I2C,             /* I2C bus */
> > >         UCLASS_I2C_GENERIC,     /* Generic I2C device */
> > >         UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
> > > +       UCLASS_RSA,             /* RSA Mod Exp device */
> > >
> > >         UCLASS_COUNT,
> > >         UCLASS_INVALID = -1,
> > > diff --git a/include/u-boot/rsa-mod-exp.h
> > > b/include/u-boot/rsa-mod-exp.h index 7b74f3c..417e468 100644
> > > --- a/include/u-boot/rsa-mod-exp.h
> > > +++ b/include/u-boot/rsa-mod-exp.h
> > > @@ -46,4 +46,41 @@ struct key_prop {
> > >  int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
> > >                 struct key_prop *node, uint8_t **outp, uint32_t
> > > *out_len);
> > >
> > > +int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t
> sig_len,
> > > +               struct key_prop *node, uint8_t **outp, uint32_t
> > > +*out_len);
> > > +
> > > +/**
> > > + * struct struct rsa_ops - Driver model for RSA operations
> > > + *
> > > + * The uclass interface is implemented by all crypto devices which
> > > +use
> > > + * driver model.
> > > + */
> > > +struct rsa_ops {
> > > +       /**
> > > +        * Perform Modular Exponentiation
> > > +        *
> > > +        * Operation: out[] = sig ^ exponent % modulus
> > > +        *
> > > +        * @dev:        RSA Device
> > > +        * @sig:        RSA PKCS1.5 signature
> > > +        * @sig_len:    Length of signature in number of bytes
> > > +        * @node:       Node with RSA key elements like modulus,
> exponent,
> > > +        *              R^2, n0inv
> > > +        * @outp:       Set to an allocated buffer holding the output
> hash
> > > +        * @out_len:    Set to length of hash(outp) calculated after
> > > +        *              exponentiation.
> > > +        *
> > > +        * This computes exponentiation over the signature. Resulting
> > > +        * hash value is placed in an allocated buffer, the pointer is
> > > +        * returned as *outp. The length of calulated hash is returned
> via
> > > +        * the out_len pointer argument. The caller should free *outp
> > > +        *
> > > +        * Returns: 0 if exponentiation is successful, or a negative
> value
> > > +        * if it wasn't.
> > > +        */
> > > +       int (*mod_exp)(struct udevice *dev, const uint8_t *sig,
> > > +                          uint32_t sig_len, struct key_prop *node,
> > > +                          uint8_t **outp, uint32_t *len); };
> > > +
> > >  #endif
> > > --
> > > 1.8.1.4
> > >
>
> Regards,
> Ruchika



Regards,
Simon

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

end of thread, other threads:[~2015-01-06 20:30 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-30  9:30 [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Ruchika Gupta
2014-12-30  9:30 ` [U-Boot] [PATCH 2/9] [v4] FIT: Modify option FIT_SIGNATURE in Kconfig Ruchika Gupta
2015-01-02 21:38   ` Simon Glass
2014-12-30  9:30 ` [U-Boot] [PATCH 3/9] [v4] DM: crypto/rsa: Add rsa Modular Exponentiation DM driver Ruchika Gupta
2015-01-02 22:24   ` Simon Glass
     [not found]     ` <1420537067401.77619@freescale.com>
2015-01-06 20:30       ` Simon Glass
2014-12-30  9:30 ` [U-Boot] [PATCH 4/9] [v4] configs: Move CONFIG_FIT_SIGNATURE to defconfig Ruchika Gupta
2014-12-30  9:30 ` [U-Boot] [PATCH 5/9] [v4] lib/rsa: Modify rsa to use DM driver Ruchika Gupta
2015-01-02 22:24   ` Simon Glass
2014-12-30  9:30 ` [U-Boot] [PATCH 6/9] [v4] DM: crypto/fsl - Add Freescale rsa " Ruchika Gupta
2014-12-30  9:30 ` [U-Boot] [PATCH 7/9] [v4] lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation Ruchika Gupta
2015-01-02 22:24   ` Simon Glass
2015-01-06  9:38     ` Ruchika Gupta
2014-12-30  9:30 ` [U-Boot] [PATCH 8/9] [v4] hash: Add function to find hash_algo struct with progressive hash Ruchika Gupta
2015-01-02 22:24   ` Simon Glass
2015-01-06  9:38     ` Ruchika Gupta
2015-01-06 15:42       ` Simon Glass
2014-12-30  9:30 ` [U-Boot] [PATCH 9/9] [v4] rsa: Use checksum algorithms from struct hash_algo Ruchika Gupta
2015-01-02 22:24   ` Simon Glass
2015-01-06  9:38     ` Ruchika Gupta
2015-01-02 22:24 ` [U-Boot] [PATCH 1/9] [v4] rsa: Split the rsa-verify to separate the modular exponentiation Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.