]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
image: Added RSA support for zynq
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Fri, 29 Nov 2013 13:31:24 +0000 (19:01 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Fri, 29 Nov 2013 14:04:28 +0000 (15:04 +0100)
Added RSA support for zynq. This uses the
montogomery multiplications while verifying
the authenticated image.
Modified Makefile to compile rsa-verify.c if
CONFIG_CMD_ZYNQ_RSA was enabled to get rid of
unrequired FDT functionality incase of zynq.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
include/rsa.h
lib/rsa/Makefile
lib/rsa/rsa-verify.c

index add4c789f335488f3ed5442365acf9a95dc49d84..6f07ae368a0506fd7ad8091a8a9798d2bfd62ddb 100644 (file)
@@ -89,4 +89,6 @@ static inline int rsa_verify(struct image_sign_info *info,
 }
 #endif
 
+int zynq_pow_mod(uint32_t *keyptr, uint32_t *inout);
+
 #endif
index decd6e509dfbaabe57dc78f43923da5d3f004131..27c3bc3f9cd215343a5e7569c33b3c60eee83881 100644 (file)
@@ -15,6 +15,8 @@ ifdef CONFIG_FIT_SIGNATURE
 COBJS-$(CONFIG_RSA) += rsa-verify.o
 endif
 
+COBJS-$(CONFIG_CMD_ZYNQ_RSA) += rsa-verify.o
+
 COBJS  := $(sort $(COBJS-y))
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
index 02cc4e335309becf02288fff81167cdca6734bab..ccebf27d14354336b4b61a4ca0a6a8894cd0b054 100644 (file)
@@ -164,7 +164,7 @@ static void montgomery_mul(const struct rsa_public_key *key,
        for (i = 0; i < key->len; ++i)
                montgomery_mul_add_step(key, result, a[i], b);
 }
-
+#if IMAGE_ENABLE_VERIFY
 /**
  * pow_mod() - in-place public exponentiation
  *
@@ -370,3 +370,48 @@ int rsa_verify(struct image_sign_info *info,
 
        return ret;
 }
+#endif
+
+/**
+ * zynq_pow_mod() - in-place public exponentiation
+ *
+ * @keyptr:    RSA key
+ * @inout:     Big-endian word array containing value and result
+ */
+int zynq_pow_mod(uint32_t *keyptr, uint32_t *inout)
+{
+       uint32_t *result, *ptr;
+       uint i;
+       struct rsa_public_key *key;
+
+       key = (struct rsa_public_key *)keyptr;
+
+       /* 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];
+       result = tmp;  /* Re-use location. */
+
+       for (i = 0, ptr = inout; i < key->len; i++, ptr++)
+               val[i] = *(ptr);
+
+       montgomery_mul(key, acc, val, key->rr);  /* axx = a * RR / R mod M */
+       for (i = 0; i < 16; i += 2) {
+               montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod M */
+               montgomery_mul(key, acc, tmp, tmp); /* acc = tmp^2 / R mod M */
+       }
+       montgomery_mul(key, result, acc, val);  /* result = XX * a / R mod M */
+
+       /* Make sure result < mod; result is at most 1x mod too large. */
+       if (greater_equal_modulus(key, result))
+               subtract_modulus(key, result);
+
+       for (i = 0, ptr = inout; i < key->len; i++, ptr++)
+               *ptr = result[i];
+
+       return 0;
+}