Commit fc2f4246b4b3b750e8c5aa08440ec5e1c952088e

Authored by Ruchika Gupta
Committed by Simon Glass
1 parent 49cad54788

rsa: Split the rsa-verify to separate the modular exponentiation

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>
Acked-by: Simon Glass <sjg@chromium.org>

Showing 5 changed files with 404 additions and 276 deletions Side-by-side Diff

include/u-boot/rsa-mod-exp.h
  1 +/*
  2 + * Copyright (c) 2014, Ruchika Gupta.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 +*/
  6 +
  7 +#ifndef _RSA_MOD_EXP_H
  8 +#define _RSA_MOD_EXP_H
  9 +
  10 +#include <errno.h>
  11 +#include <image.h>
  12 +
  13 +/**
  14 + * struct key_prop - holder for a public key properties
  15 + *
  16 + * The struct has pointers to modulus (Typically called N),
  17 + * The inverse, R^2, exponent. These can be typecasted and
  18 + * used as byte arrays or converted to the required format
  19 + * as per requirement of RSA implementation.
  20 + */
  21 +struct key_prop {
  22 + const void *rr; /* R^2 can be treated as byte array */
  23 + const void *modulus; /* modulus as byte array */
  24 + const void *public_exponent; /* public exponent as byte array */
  25 + uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */
  26 + int num_bits; /* Key length in bits */
  27 + uint32_t exp_len; /* Exponent length in number of uint8_t */
  28 +};
  29 +
  30 +/**
  31 + * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
  32 + *
  33 + * Operation: out[] = sig ^ exponent % modulus
  34 + *
  35 + * @sig: RSA PKCS1.5 signature
  36 + * @sig_len: Length of signature in number of bytes
  37 + * @node: Node with RSA key elements like modulus, exponent, R^2, n0inv
  38 + * @out: Result in form of byte array
  39 + */
  40 +int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
  41 + struct key_prop *node, uint8_t *out);
  42 +
  43 +#endif
... ... @@ -7,5 +7,5 @@
7 7 # SPDX-License-Identifier: GPL-2.0+
8 8 #
9 9  
10   -obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
  10 +obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o rsa-mod-exp.o
lib/rsa/rsa-mod-exp.c
  1 +/*
  2 + * Copyright (c) 2013, Google Inc.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#ifndef USE_HOSTCC
  8 +#include <common.h>
  9 +#include <fdtdec.h>
  10 +#include <asm/types.h>
  11 +#include <asm/byteorder.h>
  12 +#include <asm/errno.h>
  13 +#include <asm/types.h>
  14 +#include <asm/unaligned.h>
  15 +#else
  16 +#include "fdt_host.h"
  17 +#include "mkimage.h"
  18 +#include <fdt_support.h>
  19 +#endif
  20 +#include <u-boot/rsa.h>
  21 +#include <u-boot/rsa-mod-exp.h>
  22 +
  23 +#define UINT64_MULT32(v, multby) (((uint64_t)(v)) * ((uint32_t)(multby)))
  24 +
  25 +#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
  26 +#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
  27 +
  28 +/* Default public exponent for backward compatibility */
  29 +#define RSA_DEFAULT_PUBEXP 65537
  30 +
  31 +/**
  32 + * subtract_modulus() - subtract modulus from the given value
  33 + *
  34 + * @key: Key containing modulus to subtract
  35 + * @num: Number to subtract modulus from, as little endian word array
  36 + */
  37 +static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
  38 +{
  39 + int64_t acc = 0;
  40 + uint i;
  41 +
  42 + for (i = 0; i < key->len; i++) {
  43 + acc += (uint64_t)num[i] - key->modulus[i];
  44 + num[i] = (uint32_t)acc;
  45 + acc >>= 32;
  46 + }
  47 +}
  48 +
  49 +/**
  50 + * greater_equal_modulus() - check if a value is >= modulus
  51 + *
  52 + * @key: Key containing modulus to check
  53 + * @num: Number to check against modulus, as little endian word array
  54 + * @return 0 if num < modulus, 1 if num >= modulus
  55 + */
  56 +static int greater_equal_modulus(const struct rsa_public_key *key,
  57 + uint32_t num[])
  58 +{
  59 + int i;
  60 +
  61 + for (i = (int)key->len - 1; i >= 0; i--) {
  62 + if (num[i] < key->modulus[i])
  63 + return 0;
  64 + if (num[i] > key->modulus[i])
  65 + return 1;
  66 + }
  67 +
  68 + return 1; /* equal */
  69 +}
  70 +
  71 +/**
  72 + * montgomery_mul_add_step() - Perform montgomery multiply-add step
  73 + *
  74 + * Operation: montgomery result[] += a * b[] / n0inv % modulus
  75 + *
  76 + * @key: RSA key
  77 + * @result: Place to put result, as little endian word array
  78 + * @a: Multiplier
  79 + * @b: Multiplicand, as little endian word array
  80 + */
  81 +static void montgomery_mul_add_step(const struct rsa_public_key *key,
  82 + uint32_t result[], const uint32_t a, const uint32_t b[])
  83 +{
  84 + uint64_t acc_a, acc_b;
  85 + uint32_t d0;
  86 + uint i;
  87 +
  88 + acc_a = (uint64_t)a * b[0] + result[0];
  89 + d0 = (uint32_t)acc_a * key->n0inv;
  90 + acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
  91 + for (i = 1; i < key->len; i++) {
  92 + acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
  93 + acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
  94 + (uint32_t)acc_a;
  95 + result[i - 1] = (uint32_t)acc_b;
  96 + }
  97 +
  98 + acc_a = (acc_a >> 32) + (acc_b >> 32);
  99 +
  100 + result[i - 1] = (uint32_t)acc_a;
  101 +
  102 + if (acc_a >> 32)
  103 + subtract_modulus(key, result);
  104 +}
  105 +
  106 +/**
  107 + * montgomery_mul() - Perform montgomery mutitply
  108 + *
  109 + * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
  110 + *
  111 + * @key: RSA key
  112 + * @result: Place to put result, as little endian word array
  113 + * @a: Multiplier, as little endian word array
  114 + * @b: Multiplicand, as little endian word array
  115 + */
  116 +static void montgomery_mul(const struct rsa_public_key *key,
  117 + uint32_t result[], uint32_t a[], const uint32_t b[])
  118 +{
  119 + uint i;
  120 +
  121 + for (i = 0; i < key->len; ++i)
  122 + result[i] = 0;
  123 + for (i = 0; i < key->len; ++i)
  124 + montgomery_mul_add_step(key, result, a[i], b);
  125 +}
  126 +
  127 +/**
  128 + * num_pub_exponent_bits() - Number of bits in the public exponent
  129 + *
  130 + * @key: RSA key
  131 + * @num_bits: Storage for the number of public exponent bits
  132 + */
  133 +static int num_public_exponent_bits(const struct rsa_public_key *key,
  134 + int *num_bits)
  135 +{
  136 + uint64_t exponent;
  137 + int exponent_bits;
  138 + const uint max_bits = (sizeof(exponent) * 8);
  139 +
  140 + exponent = key->exponent;
  141 + exponent_bits = 0;
  142 +
  143 + if (!exponent) {
  144 + *num_bits = exponent_bits;
  145 + return 0;
  146 + }
  147 +
  148 + for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits)
  149 + if (!(exponent >>= 1)) {
  150 + *num_bits = exponent_bits;
  151 + return 0;
  152 + }
  153 +
  154 + return -EINVAL;
  155 +}
  156 +
  157 +/**
  158 + * is_public_exponent_bit_set() - Check if a bit in the public exponent is set
  159 + *
  160 + * @key: RSA key
  161 + * @pos: The bit position to check
  162 + */
  163 +static int is_public_exponent_bit_set(const struct rsa_public_key *key,
  164 + int pos)
  165 +{
  166 + return key->exponent & (1ULL << pos);
  167 +}
  168 +
  169 +/**
  170 + * pow_mod() - in-place public exponentiation
  171 + *
  172 + * @key: RSA key
  173 + * @inout: Big-endian word array containing value and result
  174 + */
  175 +static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
  176 +{
  177 + uint32_t *result, *ptr;
  178 + uint i;
  179 + int j, k;
  180 +
  181 + /* Sanity check for stack size - key->len is in 32-bit words */
  182 + if (key->len > RSA_MAX_KEY_BITS / 32) {
  183 + debug("RSA key words %u exceeds maximum %d\n", key->len,
  184 + RSA_MAX_KEY_BITS / 32);
  185 + return -EINVAL;
  186 + }
  187 +
  188 + uint32_t val[key->len], acc[key->len], tmp[key->len];
  189 + uint32_t a_scaled[key->len];
  190 + result = tmp; /* Re-use location. */
  191 +
  192 + /* Convert from big endian byte array to little endian word array. */
  193 + for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--)
  194 + val[i] = get_unaligned_be32(ptr);
  195 +
  196 + if (0 != num_public_exponent_bits(key, &k))
  197 + return -EINVAL;
  198 +
  199 + if (k < 2) {
  200 + debug("Public exponent is too short (%d bits, minimum 2)\n",
  201 + k);
  202 + return -EINVAL;
  203 + }
  204 +
  205 + if (!is_public_exponent_bit_set(key, 0)) {
  206 + debug("LSB of RSA public exponent must be set.\n");
  207 + return -EINVAL;
  208 + }
  209 +
  210 + /* the bit at e[k-1] is 1 by definition, so start with: C := M */
  211 + montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */
  212 + /* retain scaled version for intermediate use */
  213 + memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0]));
  214 +
  215 + for (j = k - 2; j > 0; --j) {
  216 + montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
  217 +
  218 + if (is_public_exponent_bit_set(key, j)) {
  219 + /* acc = tmp * val / R mod n */
  220 + montgomery_mul(key, acc, tmp, a_scaled);
  221 + } else {
  222 + /* e[j] == 0, copy tmp back to acc for next operation */
  223 + memcpy(acc, tmp, key->len * sizeof(acc[0]));
  224 + }
  225 + }
  226 +
  227 + /* the bit at e[0] is always 1 */
  228 + montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
  229 + montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */
  230 + memcpy(result, acc, key->len * sizeof(result[0]));
  231 +
  232 + /* Make sure result < mod; result is at most 1x mod too large. */
  233 + if (greater_equal_modulus(key, result))
  234 + subtract_modulus(key, result);
  235 +
  236 + /* Convert to bigendian byte array */
  237 + for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
  238 + put_unaligned_be32(result[i], ptr);
  239 + return 0;
  240 +}
  241 +
  242 +static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
  243 +{
  244 + int i;
  245 +
  246 + for (i = 0; i < len; i++)
  247 + dst[i] = fdt32_to_cpu(src[len - 1 - i]);
  248 +}
  249 +
  250 +int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
  251 + struct key_prop *prop, uint8_t *out)
  252 +{
  253 + struct rsa_public_key key;
  254 + int ret;
  255 +
  256 + if (!prop) {
  257 + debug("%s: Skipping invalid prop", __func__);
  258 + return -EBADF;
  259 + }
  260 + key.n0inv = prop->n0inv;
  261 + key.len = prop->num_bits;
  262 +
  263 + if (!prop->public_exponent)
  264 + key.exponent = RSA_DEFAULT_PUBEXP;
  265 + else
  266 + key.exponent =
  267 + fdt64_to_cpu(*((uint64_t *)(prop->public_exponent)));
  268 +
  269 + if (!key.len || !prop->modulus || !prop->rr) {
  270 + debug("%s: Missing RSA key info", __func__);
  271 + return -EFAULT;
  272 + }
  273 +
  274 + /* Sanity check for stack size */
  275 + if (key.len > RSA_MAX_KEY_BITS || key.len < RSA_MIN_KEY_BITS) {
  276 + debug("RSA key bits %u outside allowed range %d..%d\n",
  277 + key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
  278 + return -EFAULT;
  279 + }
  280 + key.len /= sizeof(uint32_t) * 8;
  281 + uint32_t key1[key.len], key2[key.len];
  282 +
  283 + key.modulus = key1;
  284 + key.rr = key2;
  285 + rsa_convert_big_endian(key.modulus, (uint32_t *)prop->modulus, key.len);
  286 + rsa_convert_big_endian(key.rr, (uint32_t *)prop->rr, key.len);
  287 + if (!key.modulus || !key.rr) {
  288 + debug("%s: Out of memory", __func__);
  289 + return -ENOMEM;
  290 + }
  291 +
  292 + uint32_t buf[sig_len / sizeof(uint32_t)];
  293 +
  294 + memcpy(buf, sig, sig_len);
  295 +
  296 + ret = pow_mod(&key, buf);
  297 + if (ret)
  298 + return ret;
  299 +
  300 + memcpy(out, buf, sig_len);
  301 +
  302 + return 0;
  303 +}
lib/rsa/rsa-verify.c
... ... @@ -17,230 +17,26 @@
17 17 #include "mkimage.h"
18 18 #include <fdt_support.h>
19 19 #endif
  20 +#include <u-boot/rsa-mod-exp.h>
20 21 #include <u-boot/rsa.h>
21   -#include <u-boot/sha1.h>
22   -#include <u-boot/sha256.h>
23 22  
24   -#define UINT64_MULT32(v, multby) (((uint64_t)(v)) * ((uint32_t)(multby)))
25   -
26   -#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
27   -#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
28   -
29 23 /* Default public exponent for backward compatibility */
30 24 #define RSA_DEFAULT_PUBEXP 65537
31 25  
32 26 /**
33   - * subtract_modulus() - subtract modulus from the given value
  27 + * rsa_verify_key() - Verify a signature against some data using RSA Key
34 28 *
35   - * @key: Key containing modulus to subtract
36   - * @num: Number to subtract modulus from, as little endian word array
37   - */
38   -static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
39   -{
40   - int64_t acc = 0;
41   - uint i;
42   -
43   - for (i = 0; i < key->len; i++) {
44   - acc += (uint64_t)num[i] - key->modulus[i];
45   - num[i] = (uint32_t)acc;
46   - acc >>= 32;
47   - }
48   -}
49   -
50   -/**
51   - * greater_equal_modulus() - check if a value is >= modulus
  29 + * Verify a RSA PKCS1.5 signature against an expected hash using
  30 + * the RSA Key properties in prop structure.
52 31 *
53   - * @key: Key containing modulus to check
54   - * @num: Number to check against modulus, as little endian word array
55   - * @return 0 if num < modulus, 1 if num >= modulus
  32 + * @prop: Specifies key
  33 + * @sig: Signature
  34 + * @sig_len: Number of bytes in signature
  35 + * @hash: Pointer to the expected hash
  36 + * @algo: Checksum algo structure having information on RSA padding etc.
  37 + * @return 0 if verified, -ve on error
56 38 */
57   -static int greater_equal_modulus(const struct rsa_public_key *key,
58   - uint32_t num[])
59   -{
60   - int i;
61   -
62   - for (i = (int)key->len - 1; i >= 0; i--) {
63   - if (num[i] < key->modulus[i])
64   - return 0;
65   - if (num[i] > key->modulus[i])
66   - return 1;
67   - }
68   -
69   - return 1; /* equal */
70   -}
71   -
72   -/**
73   - * montgomery_mul_add_step() - Perform montgomery multiply-add step
74   - *
75   - * Operation: montgomery result[] += a * b[] / n0inv % modulus
76   - *
77   - * @key: RSA key
78   - * @result: Place to put result, as little endian word array
79   - * @a: Multiplier
80   - * @b: Multiplicand, as little endian word array
81   - */
82   -static void montgomery_mul_add_step(const struct rsa_public_key *key,
83   - uint32_t result[], const uint32_t a, const uint32_t b[])
84   -{
85   - uint64_t acc_a, acc_b;
86   - uint32_t d0;
87   - uint i;
88   -
89   - acc_a = (uint64_t)a * b[0] + result[0];
90   - d0 = (uint32_t)acc_a * key->n0inv;
91   - acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
92   - for (i = 1; i < key->len; i++) {
93   - acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
94   - acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
95   - (uint32_t)acc_a;
96   - result[i - 1] = (uint32_t)acc_b;
97   - }
98   -
99   - acc_a = (acc_a >> 32) + (acc_b >> 32);
100   -
101   - result[i - 1] = (uint32_t)acc_a;
102   -
103   - if (acc_a >> 32)
104   - subtract_modulus(key, result);
105   -}
106   -
107   -/**
108   - * montgomery_mul() - Perform montgomery mutitply
109   - *
110   - * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
111   - *
112   - * @key: RSA key
113   - * @result: Place to put result, as little endian word array
114   - * @a: Multiplier, as little endian word array
115   - * @b: Multiplicand, as little endian word array
116   - */
117   -static void montgomery_mul(const struct rsa_public_key *key,
118   - uint32_t result[], uint32_t a[], const uint32_t b[])
119   -{
120   - uint i;
121   -
122   - for (i = 0; i < key->len; ++i)
123   - result[i] = 0;
124   - for (i = 0; i < key->len; ++i)
125   - montgomery_mul_add_step(key, result, a[i], b);
126   -}
127   -
128   -/**
129   - * num_pub_exponent_bits() - Number of bits in the public exponent
130   - *
131   - * @key: RSA key
132   - * @num_bits: Storage for the number of public exponent bits
133   - */
134   -static int num_public_exponent_bits(const struct rsa_public_key *key,
135   - int *num_bits)
136   -{
137   - uint64_t exponent;
138   - int exponent_bits;
139   - const uint max_bits = (sizeof(exponent) * 8);
140   -
141   - exponent = key->exponent;
142   - exponent_bits = 0;
143   -
144   - if (!exponent) {
145   - *num_bits = exponent_bits;
146   - return 0;
147   - }
148   -
149   - for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits)
150   - if (!(exponent >>= 1)) {
151   - *num_bits = exponent_bits;
152   - return 0;
153   - }
154   -
155   - return -EINVAL;
156   -}
157   -
158   -/**
159   - * is_public_exponent_bit_set() - Check if a bit in the public exponent is set
160   - *
161   - * @key: RSA key
162   - * @pos: The bit position to check
163   - */
164   -static int is_public_exponent_bit_set(const struct rsa_public_key *key,
165   - int pos)
166   -{
167   - return key->exponent & (1ULL << pos);
168   -}
169   -
170   -/**
171   - * pow_mod() - in-place public exponentiation
172   - *
173   - * @key: RSA key
174   - * @inout: Big-endian word array containing value and result
175   - */
176   -static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
177   -{
178   - uint32_t *result, *ptr;
179   - uint i;
180   - int j, k;
181   -
182   - /* Sanity check for stack size - key->len is in 32-bit words */
183   - if (key->len > RSA_MAX_KEY_BITS / 32) {
184   - debug("RSA key words %u exceeds maximum %d\n", key->len,
185   - RSA_MAX_KEY_BITS / 32);
186   - return -EINVAL;
187   - }
188   -
189   - uint32_t val[key->len], acc[key->len], tmp[key->len];
190   - uint32_t a_scaled[key->len];
191   - result = tmp; /* Re-use location. */
192   -
193   - /* Convert from big endian byte array to little endian word array. */
194   - for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--)
195   - val[i] = get_unaligned_be32(ptr);
196   -
197   - if (0 != num_public_exponent_bits(key, &k))
198   - return -EINVAL;
199   -
200   - if (k < 2) {
201   - debug("Public exponent is too short (%d bits, minimum 2)\n",
202   - k);
203   - return -EINVAL;
204   - }
205   -
206   - if (!is_public_exponent_bit_set(key, 0)) {
207   - debug("LSB of RSA public exponent must be set.\n");
208   - return -EINVAL;
209   - }
210   -
211   - /* the bit at e[k-1] is 1 by definition, so start with: C := M */
212   - montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */
213   - /* retain scaled version for intermediate use */
214   - memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0]));
215   -
216   - for (j = k - 2; j > 0; --j) {
217   - montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
218   -
219   - if (is_public_exponent_bit_set(key, j)) {
220   - /* acc = tmp * val / R mod n */
221   - montgomery_mul(key, acc, tmp, a_scaled);
222   - } else {
223   - /* e[j] == 0, copy tmp back to acc for next operation */
224   - memcpy(acc, tmp, key->len * sizeof(acc[0]));
225   - }
226   - }
227   -
228   - /* the bit at e[0] is always 1 */
229   - montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
230   - montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */
231   - memcpy(result, acc, key->len * sizeof(result[0]));
232   -
233   - /* Make sure result < mod; result is at most 1x mod too large. */
234   - if (greater_equal_modulus(key, result))
235   - subtract_modulus(key, result);
236   -
237   - /* Convert to bigendian byte array */
238   - for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
239   - put_unaligned_be32(result[i], ptr);
240   - return 0;
241   -}
242   -
243   -static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
  39 +static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
244 40 const uint32_t sig_len, const uint8_t *hash,
245 41 struct checksum_algo *algo)
246 42 {
247 43  
... ... @@ -248,10 +44,10 @@
248 44 int pad_len;
249 45 int ret;
250 46  
251   - if (!key || !sig || !hash || !algo)
  47 + if (!prop || !sig || !hash || !algo)
252 48 return -EIO;
253 49  
254   - if (sig_len != (key->len * sizeof(uint32_t))) {
  50 + if (sig_len != (prop->num_bits / 8)) {
255 51 debug("Signature is of incorrect length %d\n", sig_len);
256 52 return -EINVAL;
257 53 }
258 54  
259 55  
... ... @@ -265,13 +61,13 @@
265 61 return -EINVAL;
266 62 }
267 63  
268   - uint32_t buf[sig_len / sizeof(uint32_t)];
  64 + uint8_t buf[sig_len];
269 65  
270   - memcpy(buf, sig, sig_len);
271   -
272   - ret = pow_mod(key, buf);
273   - if (ret)
  66 + ret = rsa_mod_exp_sw(sig, sig_len, prop, buf);
  67 + if (ret) {
  68 + debug("Error in Modular exponentation\n");
274 69 return ret;
  70 + }
275 71  
276 72 padding = algo->rsa_padding;
277 73 pad_len = algo->pad_len - algo->checksum_len;
278 74  
279 75  
280 76  
281 77  
282 78  
283 79  
284 80  
285 81  
... ... @@ -291,72 +87,57 @@
291 87 return 0;
292 88 }
293 89  
294   -static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
295   -{
296   - int i;
297   -
298   - for (i = 0; i < len; i++)
299   - dst[i] = fdt32_to_cpu(src[len - 1 - i]);
300   -}
301   -
  90 +/**
  91 + * rsa_verify_with_keynode() - Verify a signature against some data using
  92 + * information in node with prperties of RSA Key like modulus, exponent etc.
  93 + *
  94 + * Parse sign-node and fill a key_prop structure with properties of the
  95 + * key. Verify a RSA PKCS1.5 signature against an expected hash using
  96 + * the properties parsed
  97 + *
  98 + * @info: Specifies key and FIT information
  99 + * @hash: Pointer to the expected hash
  100 + * @sig: Signature
  101 + * @sig_len: Number of bytes in signature
  102 + * @node: Node having the RSA Key properties
  103 + * @return 0 if verified, -ve on error
  104 + */
302 105 static int rsa_verify_with_keynode(struct image_sign_info *info,
303   - const void *hash, uint8_t *sig, uint sig_len, int node)
  106 + const void *hash, uint8_t *sig,
  107 + uint sig_len, int node)
304 108 {
305 109 const void *blob = info->fdt_blob;
306   - struct rsa_public_key key;
307   - const void *modulus, *rr;
308   - const uint64_t *public_exponent;
  110 + struct key_prop prop;
309 111 int length;
310   - int ret;
  112 + int ret = 0;
311 113  
312 114 if (node < 0) {
313 115 debug("%s: Skipping invalid node", __func__);
314 116 return -EBADF;
315 117 }
316   - if (!fdt_getprop(blob, node, "rsa,n0-inverse", NULL)) {
317   - debug("%s: Missing rsa,n0-inverse", __func__);
318   - return -EFAULT;
319   - }
320   - key.len = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
321   - key.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
322   - public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
323   - if (!public_exponent || length < sizeof(*public_exponent))
324   - key.exponent = RSA_DEFAULT_PUBEXP;
325   - else
326   - key.exponent = fdt64_to_cpu(*public_exponent);
327   - modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
328   - rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
329   - if (!key.len || !modulus || !rr) {
330   - debug("%s: Missing RSA key info", __func__);
331   - return -EFAULT;
332   - }
333 118  
334   - /* Sanity check for stack size */
335   - if (key.len > RSA_MAX_KEY_BITS || key.len < RSA_MIN_KEY_BITS) {
336   - debug("RSA key bits %u outside allowed range %d..%d\n",
337   - key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
338   - return -EFAULT;
339   - }
340   - key.len /= sizeof(uint32_t) * 8;
341   - uint32_t key1[key.len], key2[key.len];
  119 + prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
342 120  
343   - key.modulus = key1;
344   - key.rr = key2;
345   - rsa_convert_big_endian(key.modulus, modulus, key.len);
346   - rsa_convert_big_endian(key.rr, rr, key.len);
347   - if (!key.modulus || !key.rr) {
348   - debug("%s: Out of memory", __func__);
349   - return -ENOMEM;
350   - }
  121 + prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
351 122  
352   - debug("key length %d\n", key.len);
353   - ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
354   - if (ret) {
355   - printf("%s: RSA failed to verify: %d\n", __func__, ret);
356   - return ret;
  123 + prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
  124 + if (!prop.public_exponent || length < sizeof(uint64_t))
  125 + prop.public_exponent = NULL;
  126 +
  127 + prop.exp_len = sizeof(uint64_t);
  128 +
  129 + prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
  130 +
  131 + prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
  132 +
  133 + if (!prop.num_bits || !prop.modulus) {
  134 + debug("%s: Missing RSA key info", __func__);
  135 + return -EFAULT;
357 136 }
358 137  
359   - return 0;
  138 + ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum);
  139 +
  140 + return ret;
360 141 }
361 142  
362 143 int rsa_verify(struct image_sign_info *info,
... ... @@ -60,7 +60,8 @@
60 60 LIBFDT_OBJS := $(addprefix lib/libfdt/, \
61 61 fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
62 62 RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
63   - rsa-sign.o rsa-verify.o rsa-checksum.o)
  63 + rsa-sign.o rsa-verify.o rsa-checksum.o \
  64 + rsa-mod-exp.o)
64 65  
65 66 # common objs for dumpimage and mkimage
66 67 dumpimage-mkimage-objs := aisimage.o \