Merge "Add support for selecting the RSA key used for signature validation"
diff --git a/arch/arm/lib/bootb.c b/arch/arm/lib/bootb.c
index 3ff3c5e..66ba42c 100644
--- a/arch/arm/lib/bootb.c
+++ b/arch/arm/lib/bootb.c
@@ -8,11 +8,13 @@
#include <malloc.h>
#include <secure_boot.h>
#include <sha1.h>
+#include <rsa_public_key.h>
#include <rsa_verify.h>
#include <xyzModem.h>
#include <mach/comcerto-2000.h>
#include <mach/gpio.h>
#include <asm/io.h>
+#include <board_id.h>
#define ULOADER_PART_SIZE 0x20000 /* 128 KB */
#define BAREBOX_PART_SIZE 0x80000
@@ -129,6 +131,7 @@
static int _verify_image(u8 *image_ptr, u32 max_image_len) {
sha1_context ctx;
+ const struct rsa_public_key *public_key = NULL;
u8 *sig, hash[20];
u32 image_len, sig_offset;
@@ -151,7 +154,12 @@
image_ptr += sig_offset;
sig = image_ptr;
- return rsa_verify(sig, 256, hash);
+ if (rsa_get_public_key(OPTIMUS_BOARD_ID, &public_key) != 0) {
+ printf("ERROR: could not verify barebox image (no public key)\n");
+ return -1;
+ }
+
+ return rsa_verify(public_key, sig, 256, hash);
}
static int verify_image(u8 *image_ptr, u32 max_image_len) {
@@ -245,4 +253,3 @@
}
late_initcall(do_bootb_barebox);
-
diff --git a/commands/bootm.c b/commands/bootm.c
index bd2f2de..eb48bba 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -43,10 +43,12 @@
#include <rtc.h>
#include <init.h>
#include <asm-generic/memory_layout.h>
+#include <rsa_public_key.h>
#include <rsa_verify.h>
#include <sha1.h>
#include <secure_boot.h>
#include <antirebootloop.h>
+#include <board_id.h>
#ifdef CONFIG_NAND_COMCERTO_ECC_HW_BCH
extern uint32_t temp_nand_ecc_errors[];
@@ -314,6 +316,8 @@
}
if (secure_boot) {
+ const struct rsa_public_key *public_key = NULL;
+
/* Finish off the SHA-1 hash. */
sha1_update(&ctx, handle->data, len);
sha1_update(&ctx, verity_table, verity_table_len);
@@ -327,7 +331,12 @@
goto err_out;
}
- if (rsa_verify(sig, SB_SIG_LEN, hash) != 0) {
+ if (rsa_get_public_key(OPTIMUS_BOARD_ID, &public_key) != 0) {
+ printf("Could not get public key!\n");
+ goto err_out;
+ }
+
+ if (rsa_verify(public_key, sig, SB_SIG_LEN, hash) != 0) {
printf("Authentication failed!\n");
goto err_out;
}
diff --git a/include/rsa_public_key.h b/include/rsa_public_key.h
index 7a98218..71a0825 100644
--- a/include/rsa_public_key.h
+++ b/include/rsa_public_key.h
@@ -1,9 +1,3 @@
-/*
- * Automatically generated from generate_public_key_code.c
- *
- * DO NOT EDIT.
- */
-
#ifndef _RSA_PUBLIC_KEY_H
#define _RSA_PUBLIC_KEY_H
@@ -11,32 +5,18 @@
#define KEY_LEN_WORDS 64
-uint32_t n0inv = 324625445u;
-uint32_t modulus[] = {
- 0xdd47e853, 0xcc40a072, 0xccc006f4, 0xc941d763, 0x8f53aa97, 0x26f1e34a,
- 0xb476f79a, 0xf4aaaaaa, 0x676ae350, 0xd8b0d648, 0x18fc6347, 0x984bb7d3,
- 0xa894b4a0, 0x51ea64c3, 0xeda9ea3c, 0xdcff20c7, 0x88afc95f, 0xa485fce7,
- 0xd7010b97, 0x6e821430, 0xf836bbda, 0x004b61fe, 0xcddcc51a, 0x8e2f01f0,
- 0x92647f40, 0xb60cc2e2, 0x570c6692, 0x40e51f0a, 0x34e9036f, 0x6b56ad55,
- 0xe4d044e4, 0x2d32bd77, 0xfed334b5, 0x7505311f, 0x98f0fc46, 0xa557619e,
- 0xb1158093, 0xf3a785c1, 0xf6e77d38, 0xe0e29c9b, 0x3aba8b7f, 0x212ee1f4,
- 0x636549c6, 0x5bc9597b, 0xf2f35938, 0xf0ab94b7, 0x63519a73, 0x62dd79e6,
- 0x3e0863f8, 0xf9d67dab, 0x2dbf66b7, 0x45bb69e6, 0xdc3836bb, 0xd253d7f4,
- 0x975d5f43, 0x40eac67c, 0xd27139fa, 0xb2c73104, 0xced1c1f2, 0x7353f693,
- 0xee23ed71, 0xc710fdf4, 0x330f3b81, 0xb4a49e97
+/**
+ * struct rsa_public_key - holder for a public key
+ *
+ * An RSA public key consists of a modulus (typically called N), the inverse
+ * and R^2, where R is 2^(# key bits).
+ */
+struct rsa_public_key {
+ uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */
+ uint32_t modulus[64]; /* modulus as little endian array */
+ uint32_t rr[64]; /* R^2 as little endian array */
};
-uint32_t rr[] = {
- 0xc416ec5a, 0x8f35e335, 0x7860fdb6, 0xe3dd9018, 0xb021e1a8, 0x950621cb,
- 0xb4d3c3e5, 0xe52c0288, 0x25366c47, 0xae481186, 0x8f4f42e4, 0x5203857d,
- 0x60517eb4, 0xa49474c0, 0x952bdc12, 0xbdba6b4b, 0xac90fe1d, 0xbf7e29f9,
- 0x41fb4116, 0xc2b9ca56, 0xf48e1cbd, 0xe7f43887, 0xebdf65f6, 0x694773f6,
- 0x1efd33be, 0x4d7c0c9d, 0xd01b12f9, 0xde65788a, 0x93db7132, 0x8a8e23b1,
- 0x0faab0b6, 0x7fd78d30, 0xe7e04e64, 0xdd0b2eab, 0xa93630d2, 0x07928be0,
- 0x4ff324a5, 0x494b52da, 0xbed79044, 0x93d5c5b6, 0xdfb6b89b, 0x3c0ad0f5,
- 0xdfaf19b6, 0x07d4e67f, 0xba2fc62a, 0x58697a86, 0x1c973e7f, 0x66a26c99,
- 0x45a0ded5, 0x4f69d633, 0xbe326828, 0xd9d31655, 0x699b6a54, 0x2cb1ee8b,
- 0x69dcbbc0, 0x9469b4fa, 0xf3b23e6b, 0x886ec86a, 0x2e9410a9, 0xa41074cf,
- 0xa4c4ca4f, 0xd3ec5963, 0xf36f1929, 0x22bf4a0b
-};
+
+int rsa_get_public_key(int board_id, const struct rsa_public_key **key);
#endif
diff --git a/include/rsa_verify.h b/include/rsa_verify.h
index fc7a89b..6c277f3 100644
--- a/include/rsa_verify.h
+++ b/include/rsa_verify.h
@@ -31,16 +31,18 @@
#define _RSA_VERIFY_H
#include <common.h>
+#include <rsa_public_key.h>
/**
* rsa_verify() - Verifies a RSA PKCS1.5 signature against a hash.
*
+ * @key: The RSA public key
* @sig: The RSA signature
* @sig_len: The signature length
* @hash: The hash to compare against
* @return: 0 if verified, -ve on error
*/
-int rsa_verify(uint8_t *sig, uint32_t sig_len, uint8_t hash[20]);
+int rsa_verify(const struct rsa_public_key * key, uint8_t *sig,
+ uint32_t sig_len, uint8_t hash[20]);
#endif
-
diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
index 3e63350..b9e452c 100644
--- a/lib/rsa/Makefile
+++ b/lib/rsa/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_RSA_VERIFY) += rsa_verify.o
+obj-$(CONFIG_RSA_VERIFY) += rsa_verify.o rsa_public_keys.o
diff --git a/lib/rsa/rsa_public_keys.c b/lib/rsa/rsa_public_keys.c
new file mode 100644
index 0000000..a23eb19
--- /dev/null
+++ b/lib/rsa/rsa_public_keys.c
@@ -0,0 +1,66 @@
+#include <common.h>
+#include <stdint.h>
+#include <rsa_public_key.h>
+#include <board_id.h>
+
+#define MAX_BOARD_ID SIDESWIPE_BOARD_ID
+
+static int board_id_to_key_index[] = {
+ 0, /* OPTIMUS_BOARD_ID */
+ 0, /* SIDESWIPE_BOARD_ID */
+};
+
+/*
+ * The keys are generated from generate_public_key_code.c
+ */
+static const struct rsa_public_key public_keys[] = {
+ /* Optimus / Sideswipe */
+ { .n0inv = 324625445u,
+ .modulus = {
+ 0xdd47e853, 0xcc40a072, 0xccc006f4, 0xc941d763, 0x8f53aa97, 0x26f1e34a,
+ 0xb476f79a, 0xf4aaaaaa, 0x676ae350, 0xd8b0d648, 0x18fc6347, 0x984bb7d3,
+ 0xa894b4a0, 0x51ea64c3, 0xeda9ea3c, 0xdcff20c7, 0x88afc95f, 0xa485fce7,
+ 0xd7010b97, 0x6e821430, 0xf836bbda, 0x004b61fe, 0xcddcc51a, 0x8e2f01f0,
+ 0x92647f40, 0xb60cc2e2, 0x570c6692, 0x40e51f0a, 0x34e9036f, 0x6b56ad55,
+ 0xe4d044e4, 0x2d32bd77, 0xfed334b5, 0x7505311f, 0x98f0fc46, 0xa557619e,
+ 0xb1158093, 0xf3a785c1, 0xf6e77d38, 0xe0e29c9b, 0x3aba8b7f, 0x212ee1f4,
+ 0x636549c6, 0x5bc9597b, 0xf2f35938, 0xf0ab94b7, 0x63519a73, 0x62dd79e6,
+ 0x3e0863f8, 0xf9d67dab, 0x2dbf66b7, 0x45bb69e6, 0xdc3836bb, 0xd253d7f4,
+ 0x975d5f43, 0x40eac67c, 0xd27139fa, 0xb2c73104, 0xced1c1f2, 0x7353f693,
+ 0xee23ed71, 0xc710fdf4, 0x330f3b81, 0xb4a49e97
+ },
+ .rr = {
+ 0xc416ec5a, 0x8f35e335, 0x7860fdb6, 0xe3dd9018, 0xb021e1a8, 0x950621cb,
+ 0xb4d3c3e5, 0xe52c0288, 0x25366c47, 0xae481186, 0x8f4f42e4, 0x5203857d,
+ 0x60517eb4, 0xa49474c0, 0x952bdc12, 0xbdba6b4b, 0xac90fe1d, 0xbf7e29f9,
+ 0x41fb4116, 0xc2b9ca56, 0xf48e1cbd, 0xe7f43887, 0xebdf65f6, 0x694773f6,
+ 0x1efd33be, 0x4d7c0c9d, 0xd01b12f9, 0xde65788a, 0x93db7132, 0x8a8e23b1,
+ 0x0faab0b6, 0x7fd78d30, 0xe7e04e64, 0xdd0b2eab, 0xa93630d2, 0x07928be0,
+ 0x4ff324a5, 0x494b52da, 0xbed79044, 0x93d5c5b6, 0xdfb6b89b, 0x3c0ad0f5,
+ 0xdfaf19b6, 0x07d4e67f, 0xba2fc62a, 0x58697a86, 0x1c973e7f, 0x66a26c99,
+ 0x45a0ded5, 0x4f69d633, 0xbe326828, 0xd9d31655, 0x699b6a54, 0x2cb1ee8b,
+ 0x69dcbbc0, 0x9469b4fa, 0xf3b23e6b, 0x886ec86a, 0x2e9410a9, 0xa41074cf,
+ 0xa4c4ca4f, 0xd3ec5963, 0xf36f1929, 0x22bf4a0b
+ }
+ },
+};
+
+static int get_key_id(int board_id) {
+ if ((board_id < 0) || (board_id > MAX_BOARD_ID)) {
+ printf("Invalid board ID: %d\n", board_id);
+ return -1;
+ }
+
+ return board_id_to_key_index[board_id];
+}
+
+int rsa_get_public_key(int board_id, const struct rsa_public_key **key) {
+ int index = get_key_id(board_id);
+ if (index < 0) {
+ return -1;
+ }
+
+ *key = &public_keys[index];
+
+ return 0;
+}
diff --git a/lib/rsa/rsa_verify.c b/lib/rsa/rsa_verify.c
index b756b68..6ecf838 100644
--- a/lib/rsa/rsa_verify.c
+++ b/lib/rsa/rsa_verify.c
@@ -30,22 +30,8 @@
#include <sha1.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
-
-/* The file that contains the public key; autogenerated. */
#include <rsa_public_key.h>
-/**
- * struct rsa_public_key - holder for a public key
- *
- * An RSA public key consists of a modulus (typically called N), the inverse
- * and R^2, where R is 2^(# key bits).
- */
-struct rsa_public_key {
- uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */
- uint32_t *modulus; /* modulus as little endian array */
- uint32_t *rr; /* R^2 as little endian array */
-};
-
#define RSA2048_BYTES (2048 / 8)
/* This is the maximum key size we support, in bits */
@@ -219,9 +205,9 @@
return 0;
}
-int rsa_verify(uint8_t *sig, uint32_t sig_len, uint8_t *hash)
+int rsa_verify(const struct rsa_public_key *key, uint8_t *sig, uint32_t sig_len,
+ uint8_t *hash)
{
- struct rsa_public_key key;
const uint8_t *padding;
int ret, pad_len;
@@ -233,13 +219,8 @@
return -EIO;
}
- /* Set up the public key with the information from the header. */
- key.n0inv = n0inv;
- key.modulus = modulus;
- key.rr = rr;
-
- if (!sig || !hash) {
- printf("!sig || !hash\n");
+ if (!key || !sig || !hash) {
+ printf("!key || !sig || !hash\n");
ret = -EIO;
goto end;
}
@@ -268,7 +249,7 @@
goto end;
}
- ret = pow_mod(&key, buf);
+ ret = pow_mod(key, buf);
/* Determine padding to use depending on the signature type. */
padding = padding_sha1_rsa2048;
@@ -290,4 +271,3 @@
free(buf);
return ret;
}
-