summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/board.h9
-rw-r--r--board/cr50/rma_key_blob.p256.testbin0 -> 66 bytes
-rw-r--r--common/build.mk8
-rw-r--r--common/rma_auth.c137
-rw-r--r--include/config.h6
5 files changed, 123 insertions, 37 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h
index e0c38c6b2e..58d8faeb65 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -349,7 +349,6 @@ enum nvmem_users {
#define I2C_PORT_MASTER 0
#define CONFIG_BASE32
-#define CONFIG_CURVE25519
#define CONFIG_RMA_AUTH
#define CONFIG_RNG
@@ -358,4 +357,12 @@ enum nvmem_users {
/* Enable hardware backed brute force resistance feature */
#define CONFIG_PINWEAVER
+/*
+ * While RMA server support is not ready keep using x25519. Switching to P256
+ * saves 5336 bytes of flash space.
+ */
+/* #define CONFIG_RMA_AUTH_USE_P256 */
+#ifndef CONFIG_RMA_AUTH_USE_P256
+#define CONFIG_CURVE25519
+#endif
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/cr50/rma_key_blob.p256.test b/board/cr50/rma_key_blob.p256.test
new file mode 100644
index 0000000000..0e5cba1a6c
--- /dev/null
+++ b/board/cr50/rma_key_blob.p256.test
Binary files differ
diff --git a/common/build.mk b/common/build.mk
index d1d6f88ee4..f39c716d80 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -179,9 +179,15 @@ endif
ifeq ($(TEST_BUILD),)
+ifeq ($(CONFIG_RMA_AUTH_USE_P256),)
+BLOB_FILE = rma_key_blob.test
+else
+BLOB_FILE = rma_key_blob.p256.test
+endif
+
$(out)/RW/common/rma_auth.o: $(out)/rma_key_from_blob.h
-$(out)/rma_key_from_blob.h: board/$(BOARD)/rma_key_blob.test util/bin2h.sh
+$(out)/rma_key_from_blob.h: board/$(BOARD)/$(BLOB_FILE) util/bin2h.sh
$(Q)util/bin2h.sh RMA_KEY_BLOB $< $@
endif
diff --git a/common/rma_auth.c b/common/rma_auth.c
index 51516966b8..87894e70ad 100644
--- a/common/rma_auth.c
+++ b/common/rma_auth.c
@@ -11,7 +11,9 @@
#include "ccd_config.h"
#include "chip/g/board_id.h"
#include "console.h"
+#ifdef CONFIG_CURVE25519
#include "curve25519.h"
+#endif
#include "extension.h"
#include "hooks.h"
#include "rma_auth.h"
@@ -20,10 +22,17 @@
#include "timer.h"
#include "tpm_registers.h"
#include "tpm_vendor_cmds.h"
+#ifdef CONFIG_RMA_AUTH_USE_P256
+#include "trng.h"
+#endif
#include "util.h"
#ifndef TEST_BUILD
+#include "cryptoc/util.h"
#include "rma_key_from_blob.h"
+#else
+/* Cryptoc library is not available to the test layer. */
+#define always_memset memset
#endif
#ifdef CONFIG_DCRYPTO
@@ -40,12 +49,18 @@
/* Number of tries to properly enter auth code */
#define MAX_AUTHCODE_TRIES 3
+#ifdef CONFIG_RMA_AUTH_USE_P256
+#define RMA_SERVER_PUB_KEY_SZ 65
+#else
+#define RMA_SERVER_PUB_KEY_SZ 32
+#endif
+
/* Server public key and key ID */
static const struct {
union {
- uint8_t raw_blob[33];
+ uint8_t raw_blob[RMA_SERVER_PUB_KEY_SZ + 1];
struct {
- uint8_t server_pub_key[32];
+ uint8_t server_pub_key[RMA_SERVER_PUB_KEY_SZ];
volatile uint8_t server_key_id;
};
};
@@ -53,7 +68,7 @@ static const struct {
.raw_blob = RMA_KEY_BLOB
};
-BUILD_ASSERT(sizeof(rma_key_blob) == 33);
+BUILD_ASSERT(sizeof(rma_key_blob) == (RMA_SERVER_PUB_KEY_SZ + 1));
static char challenge[RMA_CHALLENGE_BUF_SIZE];
static char authcode[RMA_AUTHCODE_BUF_SIZE];
@@ -87,6 +102,71 @@ static void hash_buffer(void *dest, size_t dest_size,
memcpy(dest, temp, dest_size);
}
+#ifdef CONFIG_RMA_AUTH_USE_P256
+/*
+ * Generate a p256 key pair, such that Y coordinate component of the public
+ * key is an odd value. Use the X component value as the compressed public key
+ * to be sent to the server. Multiply server public key by our private key to
+ * generate the shared secret.
+ *
+ * @pub_key - array to return 32 bytes of the X coordinate public key
+ * component.
+ * @secet - array to return the X coordinate of the product of the server
+ * public key multiplied by our private key.
+ */
+static void p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
+ uint8_t secret[P256_NBYTES])
+{
+ uint8_t buf[SHA256_DIGEST_SIZE];
+ p256_int d;
+ p256_int pk_x;
+ p256_int pk_y;
+
+ /* Get some noise for private key. */
+ rand_bytes(buf, sizeof(buf));
+
+ /*
+ * By convention with the RMA server the Y coordinate of the Cr50
+ * public key component is required to be an odd value. Keep trying
+ * until the genreated bublic key has the compliant Y coordinate.
+ */
+ while (1) {
+ HASH_CTX sha;
+
+ if (DCRYPTO_p256_key_from_bytes(&pk_x, &pk_y, &d, buf)) {
+
+ /* Is Y coordinate an odd value? */
+ if (p256_is_odd(&pk_y))
+ break; /* Yes it is, got a good key. */
+ }
+
+ /* Did not succeed, rehash the private key and try again. */
+ DCRYPTO_SHA256_init(&sha, 0);
+ HASH_update(&sha, buf, sizeof(buf));
+ memcpy(buf, HASH_final(&sha), sizeof(buf));
+ }
+
+ /* X coordinate is passed to the server as the public key. */
+ p256_to_bin(&pk_x, pub_key);
+
+ /*
+ * Now let's calculate the secret as a the server pub key multiplied
+ * by our private key.
+ */
+ p256_from_bin(rma_key_blob.raw_blob + 1, &pk_x);
+ p256_from_bin(rma_key_blob.raw_blob + 1 + P256_NBYTES, &pk_y);
+
+ /* Use input space for storing multiplication results. */
+ DCRYPTO_p256_point_mul(&pk_x, &pk_y, &d, &pk_x, &pk_y);
+
+ /* X value is the seed for the shared secret. */
+ p256_to_bin(&pk_x, secret);
+
+ /* Wipe out the private key just in case. */
+ always_memset(&d, 0, sizeof(d));
+}
+#endif
+
/**
* Create a new RMA challenge/response
*
@@ -139,15 +219,18 @@ int rma_create_challenge(void)
device_id, unique_device_id_size);
}
- /* Calculate a new ephemeral key pair */
+ /* Calculate a new ephemeral key pair and the shared secret. */
+#ifdef CONFIG_RMA_AUTH_USE_P256
+ p256_get_pub_key_and_secret(c.device_pub_key, secret);
+#endif
+#ifdef CONFIG_CURVE25519
X25519_keypair(c.device_pub_key, temp);
-
+ X25519(secret, temp, rma_key_blob.server_pub_key);
+#endif
/* Encode the challenge */
if (base32_encode(challenge, sizeof(challenge), cptr, 8 * sizeof(c), 9))
return EC_ERROR_UNKNOWN;
- /* Calculate the shared secret */
- X25519(secret, temp, rma_key_blob.server_pub_key);
/*
* Auth code is a truncated HMAC of the ephemeral public key, BoardID,
@@ -206,6 +289,7 @@ int rma_try_authcode(const char *code)
static enum vendor_cmd_rc get_challenge(uint8_t *buf, size_t *buf_size)
{
int rv;
+ size_t i;
if (*buf_size < sizeof(challenge)) {
*buf_size = 1;
@@ -223,22 +307,19 @@ static enum vendor_cmd_rc get_challenge(uint8_t *buf, size_t *buf_size)
*buf_size = sizeof(challenge) - 1;
memcpy(buf, rma_get_challenge(), *buf_size);
+
+ CPRINTF("generated challenge:\n\n");
+ for (i = 0; i < *buf_size; i++)
+ CPRINTF("%c", ((uint8_t *)buf)[i]);
+ CPRINTF("\n\n");
+
#ifdef CR50_DEV
- {
- size_t i;
-
- CPRINTF("%s: generated challenge:\n", __func__);
- for (i = 0; i < *buf_size; i++)
- CPRINTF("%c", ((uint8_t *)buf)[i]);
- CPRINTF("\n");
-
- CPRINTF("%s: expected authcode: ", __func__);
- for (i = 0; i < RMA_AUTHCODE_CHARS; i++)
- CPRINTF("%c", authcode[i]);
- CPRINTF("\n");
- }
-#endif
+ CPRINTF("expected authcode: ");
+ for (i = 0; i < RMA_AUTHCODE_CHARS; i++)
+ CPRINTF("%c", authcode[i]);
+ CPRINTF("\n");
+#endif
return VENDOR_RC_SUCCESS;
}
@@ -429,20 +510,6 @@ static int rma_auth_cmd(int argc, char **argv)
if (tpmh->command_code) {
ccprintf("RMA Auth error 0x%x\n", be32toh(tpmh->command_code));
rv = EC_ERROR_UNKNOWN;
- } else {
- /* Success, let's print out the challenge. */
- int i;
- char *challenge = (char *)(tpmh + 1);
-
- for (i = 0; i < RMA_CHALLENGE_CHARS; i++) {
- if (!(i % 5)) {
- if (!(i % 20))
- ccprintf("\n");
- ccprintf(" ");
- }
- ccprintf("%c", challenge[i]);
- }
- ccprintf("\n");
}
shared_mem_release(tpmh);
diff --git a/include/config.h b/include/config.h
index faf6f42764..44dac98103 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2349,6 +2349,12 @@
/* Support RMA auth challenge-response */
#undef CONFIG_RMA_AUTH
+/*
+ * Use the p256 curve for RMA challenge-response calculations (x21559 is used
+ * by default).
+ */
+#undef CONFIG_RMA_AUTH_USE_P256
+
/* Enable hardware Random Number generator support */
#undef CONFIG_RNG