summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-08-09 17:50:21 -0700
committerCommit Bot <commit-bot@chromium.org>2021-08-12 20:38:26 +0000
commit2a590e25e8cc41d324abf56894b032ceda028832 (patch)
tree906739ca85cbbd9197cec0189d2c6b7b1f1a14d8
parent7ddbd2a9eab0dc54897d6b5bb8ee1d4b3be1fe27 (diff)
downloadchrome-ec-stabilize-14151.B-cr50_stab.tar.gz
cr50: drop cryptoc for p256 implementationstabilize-14151.B-cr50_stab
To implement FIPS module we need to bring many crypto functions in the module boundary. Unfortunately, cryptoc is a third-party library used by dcrypto code in cr50. Cryptoc is also not well-maintained and shared with other projects. While just making local copy of cryptoc would solve an issue, it's suboptimal as prevents from many optimizations and improvements. Removed redundant functions (dcrypto_p256_pick and dcrypto_p256_rand). Another improvement is separation of platform independent code in p256.c to support better host-side unit tests. For this purpose added fast random number generator using LFSR to replace use of TRNG for blinding and wiping secrets where security strength is not required. BUG=b:138578318 TEST=make BOARD=cr50 CRYPTO_TEST=1; test/tpm_test/tpmtest.py in console: dcrypto_ecdsa Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: I9bfd13b8006ddca55508635962be4502a56532b5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3087833 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/build.mk2
-rw-r--r--board/cr50/dcrypto/dcrypto_p256.c65
-rw-r--r--board/cr50/dcrypto/dcrypto_runtime.c13
-rw-r--r--board/cr50/dcrypto/hmac_drbg.c13
-rw-r--r--board/cr50/dcrypto/internal.h82
-rw-r--r--board/cr50/dcrypto/p256.c204
-rw-r--r--board/cr50/dcrypto/p256_ec.c28
-rw-r--r--board/cr50/dcrypto/p256_ecies.c1
-rw-r--r--board/cr50/fips.c24
-rw-r--r--board/cr50/fips_rand.c1
-rw-r--r--board/cr50/tpm2/ecc.c3
-rw-r--r--common/u2f.c1
-rw-r--r--include/u2f_impl.h5
13 files changed, 309 insertions, 133 deletions
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index 6d5996ddc5..1656cf24c1 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -155,8 +155,6 @@ CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=104
endif
# Configure TPM2 headers accordingly.
CFLAGS += -DEMBEDDED_MODE=1
-# Configure cryptoc headers to handle unaligned accesses.
-CFLAGS += -DSUPPORT_UNALIGNED=1
# Use absolute path as the destination to ensure that TPM2 makefile finds the
# place for output.
diff --git a/board/cr50/dcrypto/dcrypto_p256.c b/board/cr50/dcrypto/dcrypto_p256.c
index 4de8d22f9a..cdea597733 100644
--- a/board/cr50/dcrypto/dcrypto_p256.c
+++ b/board/cr50/dcrypto/dcrypto_p256.c
@@ -752,19 +752,6 @@ struct DMEM_ecc {
#define DMEM_OFFSET(p) (offsetof(struct DMEM_ecc, p))
#define DMEM_INDEX(p) (DMEM_OFFSET(p) / DMEM_CELL_SIZE)
-/* p256 elliptic curve characteristics */
-static const p256_int SECP256r1_nMin1 = {
- {
- 0xfc632551 - 1,
- 0xf3b9cac2,
- 0xa7179e84,
- 0xbce6faad,
- -1,
- -1,
- 0,
- -1,
- },
-};
/*
* Read-only pointer to read-only DMEM_ecc struct, use cp*w()
@@ -839,47 +826,26 @@ static void dcrypto_ecc_init(void)
CP1W(d, 0, 8);
}
-/* Return -1 if a < b */
-static int p256_lt(const p256_int *a, const p256_int *b)
-{
- p256_sddigit borrow = 0;
-
- for (int i = 0; i < P256_NDIGITS; ++i) {
- volatile uint32_t blinder = rand();
-
- borrow += ((p256_sddigit)P256_DIGIT(a, i) - blinder);
- borrow -= P256_DIGIT(b, i);
- borrow += blinder;
- borrow >>= P256_BITSPERDIGIT;
- }
- return (int)borrow;
-}
-
int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
const p256_int *message, p256_int *r, p256_int *s)
{
int i, result;
- p256_int rnd, k;
+ p256_int k;
dcrypto_init_and_lock();
dcrypto_ecc_init();
result = dcrypto_call(CF_p256init_adr);
/* Pick uniform 0 < k < R */
- do {
- hmac_drbg_generate_p256(drbg, &rnd);
- } while (p256_cmp(&SECP256r1_nMin2, &rnd) < 0);
+ result |= (p256_hmac_drbg_generate(drbg, &k) != HMAC_DRBG_SUCCESS);
drbg_exit(drbg);
- p256_add_d(&rnd, 1, &k);
-
CP8W(k, &k);
for (i = 0; i < 8; ++i)
- CP1W(rnd, i, rand());
+ CP1W(rnd, i, fast_random());
- /* Wipe temp rnd,k */
- rnd = dmem_ecc->rnd;
+ /* Wipe temp k */
k = dmem_ecc->rnd;
CP8W(msg, message);
@@ -891,8 +857,8 @@ int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
*s = dmem_ecc->s;
/* Wipe d,k */
- CP8W(d, &rnd);
- CP8W(k, &rnd);
+ CP8W(d, &k);
+ CP8W(k, &k);
dcrypto_unlock();
return result == 0;
@@ -997,22 +963,3 @@ int dcrypto_p256_is_valid_point(const p256_int *x, const p256_int *y)
dcrypto_unlock();
return result == 0;
}
-
-int dcrypto_p256_pick(struct drbg_ctx *drbg, p256_int *output)
-{
- int result = 0;
-
- /* make sure to return stirred output even if drbg fails */
- dcrypto_p256_rnd(output);
-
- do {
- result = hmac_drbg_generate_p256(drbg, output);
- } while ((result == 0) && (p256_lt(output, &SECP256r1_nMin1) >= 0));
- return result;
-}
-
-void dcrypto_p256_rnd(p256_int *output)
-{
- for (int i = 0; i < 8; ++i)
- output->a[i] = rand();
-}
diff --git a/board/cr50/dcrypto/dcrypto_runtime.c b/board/cr50/dcrypto/dcrypto_runtime.c
index 60a0365c92..7de990ea41 100644
--- a/board/cr50/dcrypto/dcrypto_runtime.c
+++ b/board/cr50/dcrypto/dcrypto_runtime.c
@@ -381,7 +381,7 @@ static int call_on_bigger_stack(uint32_t stack,
static int ecdsa_sign_go(p256_int *r, p256_int *s)
{
struct drbg_ctx drbg;
- p256_int d, tmp;
+ p256_int d;
int ret = 0;
p256_int message = *s;
@@ -389,23 +389,18 @@ static int ecdsa_sign_go(p256_int *r, p256_int *s)
hmac_drbg_init(&drbg, r->a, sizeof(r->a), NULL, 0, NULL, 0);
/* pick a key */
- ret = dcrypto_p256_pick(&drbg, &tmp);
- if (ret) {
+ if (p256_hmac_drbg_generate(&drbg, &d) != HMAC_DRBG_SUCCESS) {
/* to be consistent with ecdsa_sign error return */
- ret = 0;
- goto exit;
+ drbg_exit(&drbg);
+ return 0;
}
- /* add 1 */
- p256_add_d(&tmp, 1, &d);
-
/* drbg_reseed with entropy and message */
hmac_drbg_reseed(&drbg, r->a, sizeof(r->a), s->a, sizeof(s->a), NULL,
0);
ret = dcrypto_p256_ecdsa_sign(&drbg, &d, &message, r, s);
-exit:
drbg_exit(&drbg);
return ret;
}
diff --git a/board/cr50/dcrypto/hmac_drbg.c b/board/cr50/dcrypto/hmac_drbg.c
index 85c0fe863a..ff5ec14a57 100644
--- a/board/cr50/dcrypto/hmac_drbg.c
+++ b/board/cr50/dcrypto/hmac_drbg.c
@@ -136,11 +136,6 @@ enum hmac_result hmac_drbg_generate(struct drbg_ctx *ctx,
return HMAC_DRBG_SUCCESS;
}
-enum hmac_result hmac_drbg_generate_p256(struct drbg_ctx *ctx, p256_int *k_out)
-{
- return hmac_drbg_generate(ctx, k_out->a, sizeof(k_out->a), NULL, 0);
-}
-
void drbg_exit(struct drbg_ctx *ctx)
{
always_memset(ctx->k, 0x00, sizeof(ctx->k));
@@ -200,12 +195,10 @@ static int cmd_rfc6979(int argc, char **argv)
memcpy(&h1, SHA256_final(&ctx)->b8, SHA256_DIGEST_SIZE);
hmac_drbg_init_rfc6979(&drbg, x, &h1);
- do {
- hmac_drbg_generate_p256(&drbg, &k);
- ccprintf("K = %ph\n", HEX_BUF(&k, 32));
- } while (p256_cmp(&SECP256r1_nMin2, &k) < 0);
+ hmac_drbg_generate(&drbg, k.a, sizeof(k), NULL, 0);
+ ccprintf("K = %ph\n", HEX_BUF(&k, 32));
drbg_exit(&drbg);
- result = p256_cmp(&k, reference_k);
+ result = memcmp(&k, reference_k, sizeof(reference_k));
ccprintf("K generation: %s\n", result ? "FAIL" : "PASS");
return result ? EC_ERROR_INVAL : EC_SUCCESS;
diff --git a/board/cr50/dcrypto/internal.h b/board/cr50/dcrypto/internal.h
index 17430036cb..be217185c7 100644
--- a/board/cr50/dcrypto/internal.h
+++ b/board/cr50/dcrypto/internal.h
@@ -11,7 +11,6 @@
#include "common.h"
#include "util.h"
-#include "cryptoc/p256.h"
#include "hmacsha2.h"
#ifdef __cplusplus
@@ -135,10 +134,6 @@ void hmac_drbg_init(struct drbg_ctx *ctx,
const void *p0, size_t p0_len,
const void *p1, size_t p1_len,
const void *p2, size_t p2_len);
-/* Initialize for use as RFC6979 DRBG. */
-void hmac_drbg_init_rfc6979(struct drbg_ctx *ctx,
- const p256_int *key,
- const p256_int *message);
/* Initialize with at least nbits of random entropy. */
void hmac_drbg_init_rand(struct drbg_ctx *ctx, size_t nbits);
void hmac_drbg_reseed(struct drbg_ctx *ctx,
@@ -148,13 +143,73 @@ void hmac_drbg_reseed(struct drbg_ctx *ctx,
enum hmac_result hmac_drbg_generate(struct drbg_ctx *ctx, void *out,
size_t out_len, const void *input,
size_t input_len);
-/* Generate p256, with no additional input. */
-enum hmac_result hmac_drbg_generate_p256(struct drbg_ctx *ctx, p256_int *k_out);
void drbg_exit(struct drbg_ctx *ctx);
+/* Set seed for fast random number generator using LFSR. */
+void set_fast_random_seed(uint32_t seed);
+
+/* Generate week pseudorandom using LFSR for blinding purposes. */
+uint32_t fast_random(void);
+
/*
* Accelerated p256. FIPS PUB 186-4
*/
+#define P256_BITSPERDIGIT 32
+#define P256_NDIGITS 8
+#define P256_NBYTES 32
+
+typedef uint32_t p256_digit;
+typedef int32_t p256_sdigit;
+typedef uint64_t p256_ddigit;
+typedef int64_t p256_sddigit;
+
+#define P256_DIGITS(x) ((x)->a)
+#define P256_DIGIT(x, y) ((x)->a[y])
+
+/**
+ * P-256 integers internally represented as little-endian 32-bit integer
+ * digits in platform-specific format. On little-endian platform this would
+ * be regular 256-bit little-endian unsigned integer. On big-endian platform
+ * it would big-endian 32-bit digits in little-endian order.
+ *
+ * Defining p256_int as struct to leverage struct assignment.
+ */
+typedef struct p256_int {
+ union {
+ p256_digit a[P256_NDIGITS];
+ uint8_t b8[P256_NBYTES];
+ };
+} __packed p256_int;
+
+extern const p256_int SECP256r1_nMin2;
+
+/* Clear a p256_int to zero. */
+void p256_clear(p256_int *a);
+
+/* Check p256 is a zero. */
+int p256_is_zero(const p256_int *a);
+
+/* Check p256 is odd. */
+int p256_is_odd(const p256_int *a);
+
+/* c := a + (single digit)b, returns carry 1 on carry. */
+int p256_add_d(const p256_int *a, p256_digit b, p256_int *c);
+
+/* Returns -1, 0 or 1. */
+int p256_cmp(const p256_int *a, const p256_int *b);
+
+/* Return -1 if a < b. */
+int p256_lt_blinded(const p256_int *a, const p256_int *b);
+
+/* Outputs big-endian binary form. No leading zero skips. */
+void p256_to_bin(const p256_int *src, uint8_t dst[P256_NBYTES]);
+
+/**
+ * Reads from big-endian binary form, thus pre-pad with leading
+ * zeros if short. Input length is assumed P256_NBYTES bytes.
+ */
+void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int *dst);
+
int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
const p256_int *message, p256_int *r, p256_int *s)
__attribute__((warn_unused_result));
@@ -171,11 +226,16 @@ int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
int dcrypto_p256_is_valid_point(const p256_int *x, const p256_int *y)
__attribute__((warn_unused_result));
-/* Pick a p256 number between 1 < k < |p256| */
-int dcrypto_p256_pick(struct drbg_ctx *drbg, p256_int *output);
+/* Wipe content of rnd with pseudo-random values. */
+void p256_fast_random(p256_int *rnd);
-/* Overwrite with random p256 value */
-void dcrypto_p256_rnd(p256_int *output);
+/* Generate a p256 number between 1 < k < |p256| using provided DRBG. */
+enum hmac_result p256_hmac_drbg_generate(struct drbg_ctx *ctx, p256_int *k_out);
+
+/* Initialize for use as RFC6979 DRBG. */
+void hmac_drbg_init_rfc6979(struct drbg_ctx *ctx,
+ const p256_int *key,
+ const p256_int *message);
/*
* Accelerator runtime.
diff --git a/board/cr50/dcrypto/p256.c b/board/cr50/dcrypto/p256.c
index f75329d5bf..6c923b4699 100644
--- a/board/cr50/dcrypto/p256.c
+++ b/board/cr50/dcrypto/p256.c
@@ -5,25 +5,191 @@
#include "dcrypto.h"
-#include "cryptoc/p256.h"
+const p256_int SECP256r1_nMin2 = /* P-256 curve order - 2 */
+ { .a = { 0xfc632551 - 2, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, -1, -1, 0,
+ -1 } };
-static const p256_int p256_one = P256_ONE;
-
-/*
- * Key selection based on FIPS-186-4, section B.4.2 (Key Pair
- * Generation by Testing Candidates).
+/**
+ * The 32 bit LFSR whose maximum length feedback polynomial is represented
+ * as X^32 + X^22 + X^2 + X^1 + 1 will produce 2^32-1 PN sequence.
+ * Polynomial is bit reversed as we shift left, not right.
+ * This LFSR can be initialized with 0, but can't be initialized with
+ * 0xFFFFFFFF. This is handy to avoid non-zero initial values.
*/
-int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
- const uint8_t key_bytes[P256_NBYTES])
-{
- p256_int key;
-
- p256_from_bin(key_bytes, &key);
- if (p256_cmp(&SECP256r1_nMin2, &key) < 0)
- return 0;
- p256_add(&key, &p256_one, d);
- always_memset(&key, 0, sizeof(key));
- if (x == NULL || y == NULL)
- return 1;
- return dcrypto_p256_base_point_mul(d, x, y);
+static uint32_t next_fast_random(uint32_t seed)
+{
+ /**
+ * 12 22 32
+ * 1100 0000 0000 0000 0000 0100 0000 0001 = 0xC0000401
+ */
+ uint32_t mask = (-((int32_t)seed >= 0)) & 0xC0000401;
+
+ return (seed << 1) ^ mask;
+}
+static uint32_t fast_random_state;
+
+void set_fast_random_seed(uint32_t seed)
+{
+ /* Avoid prohibited value as LFSR seed value. */
+ if (next_fast_random(seed) == seed)
+ seed++;
+ fast_random_state = seed;
+}
+
+uint32_t fast_random(void)
+{
+ fast_random_state = next_fast_random(fast_random_state);
+ return fast_random_state;
+}
+
+void p256_clear(p256_int *a)
+{
+ always_memset(a, 0, sizeof(*a));
+}
+
+int p256_is_zero(const p256_int *a)
+{
+ int result = 0;
+
+ for (size_t i = 0; i < P256_NDIGITS; ++i)
+ result |= P256_DIGIT(a, i);
+ return !result;
+}
+
+/* b = a + d. Returns carry, 0 or 1. */
+int p256_add_d(const p256_int *a, uint32_t d, p256_int *b)
+{
+ p256_ddigit carry = d;
+
+ for (size_t i = 0; i < P256_NDIGITS; ++i) {
+ carry += (p256_ddigit)P256_DIGIT(a, i);
+ P256_DIGIT(b, i) = (p256_digit)carry;
+ carry >>= P256_BITSPERDIGIT;
+ }
+ return (int)carry;
+}
+
+/* Return -1 if a < b. */
+int p256_lt_blinded(const p256_int *a, const p256_int *b)
+{
+ p256_sddigit borrow = 0;
+
+ for (size_t i = 0; i < P256_NDIGITS; ++i) {
+ volatile uint32_t blinder = fast_random();
+
+ borrow += ((p256_sddigit)P256_DIGIT(a, i) - blinder);
+ borrow -= P256_DIGIT(b, i);
+ borrow += blinder;
+ borrow >>= P256_BITSPERDIGIT;
+ }
+ return (int)borrow;
+}
+
+/* Return -1, 0, 1 for a < b, a == b or a > b respectively. */
+int p256_cmp(const p256_int *a, const p256_int *b)
+{
+ p256_sddigit borrow = 0;
+ p256_digit notzero = 0;
+
+ for (size_t i = 0; i < P256_NDIGITS; ++i) {
+ borrow += (p256_sddigit)P256_DIGIT(a, i) - P256_DIGIT(b, i);
+ /**
+ * Track whether any result digit is ever not zero.
+ * Relies on !!(non-zero) evaluating to 1, e.g., !!(-1)
+ * evaluating to 1.
+ */
+ notzero |= !!((p256_digit)borrow);
+ borrow >>= P256_BITSPERDIGIT;
+ }
+ return (int)borrow | notzero;
+}
+
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+static inline void reverse_bytes(uint8_t *dst, const uint8_t *src,
+ size_t src_len)
+{
+ const uint8_t *pos = src + src_len - 1;
+
+ while (pos >= src)
+ *dst++ = *pos--;
+}
+#endif
+
+void p256_to_bin(const p256_int *src, uint8_t dst[P256_NBYTES])
+{
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+ /* reverse order of bytes from little-endian to big-endian. */
+ reverse_bytes(dst, src->b8, P256_NBYTES);
+#else
+ uint8_t *p = &dst[0];
+ /* p256 internally is little-endian, so reverse 32-bit digits. */
+ for (int i = P256_NDIGITS - 1; i >= 0; --i) {
+ p256_digit digit = P256_DIGIT(src, i);
+
+ p[0] = (uint8_t)(digit >> 24);
+ p[1] = (uint8_t)(digit >> 16);
+ p[2] = (uint8_t)(digit >> 8);
+ p[3] = (uint8_t)(digit);
+ p += 4;
+ }
+#endif
+}
+
+void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int *dst)
+{
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+ reverse_bytes(dst->b8, src, P256_NBYTES);
+#else
+ const uint8_t *p = &src[0];
+ /* p256 internally is little-endian, so reverse 32-bit digits. */
+ for (int i = P256_NDIGITS - 1; i >= 0; --i) {
+ P256_DIGIT(dst, i) = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) |
+ p[3];
+ p += 4;
+ }
+#endif
+}
+
+int p256_is_odd(const p256_int *a)
+{
+ return P256_DIGIT(a, 0) & 1;
+}
+
+void p256_fast_random(p256_int *rnd)
+{
+ for (size_t i = 0; i < P256_NDIGITS; i++)
+ P256_DIGIT(rnd, i) = fast_random();
+}
+
+enum hmac_result p256_hmac_drbg_generate(struct drbg_ctx *ctx, p256_int *rnd)
+{
+ enum hmac_result result;
+
+ /* Generate p256 candidates from DRBG until valid is found. */
+ do {
+ /* fill destination with something in case DRBG fails. */
+ p256_fast_random(rnd);
+ result = hmac_drbg_generate(ctx, rnd->a, sizeof(rnd->a), NULL,
+ 0);
+ /**
+ * We need key to be in the range 0 < key < SECP256r1 - 1.
+ * To achieve that, first check key < SECP256r1 - 2, and if
+ * so, add 1 to key. Since key is unsigned number this will
+ * bring key in proper range. The only invalid key which is
+ * less than SECP256r1 - 2 is key == 0. Adding 1 avoids it.
+ *
+ * This also complies with legacy approach for key gen from
+ * DRBG which deviates from RFC 6979 due to adding '1' and
+ * different check in the loop. We can't make it as in
+ * RFC 6979 due to dependency on exact signature/certificate
+ * by some consumers (hashes of certificates as example).
+ *
+ * Key comes from DRBG, it is ensured to be in valid
+ * range for the P-256 curve.
+ */
+ } while ((result == HMAC_DRBG_SUCCESS) &&
+ (p256_lt_blinded(rnd, &SECP256r1_nMin2) >= 0));
+ p256_add_d(rnd, 1, rnd);
+
+ return result;
}
diff --git a/board/cr50/dcrypto/p256_ec.c b/board/cr50/dcrypto/p256_ec.c
index cb33a15774..fee1434136 100644
--- a/board/cr50/dcrypto/p256_ec.c
+++ b/board/cr50/dcrypto/p256_ec.c
@@ -7,8 +7,6 @@
#include <stdint.h>
-#include "cryptoc/p256.h"
-
/* p256_base_point_mul sets {out_x,out_y} = nG, where n is < the
* order of the group. */
int DCRYPTO_p256_base_point_mul(p256_int *out_x, p256_int *out_y,
@@ -37,3 +35,29 @@ int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
return dcrypto_p256_point_mul(n, in_x, in_y, out_x, out_y);
}
+
+/**
+ * Key selection based on FIPS-186-4, section B.4.2 (Key Pair
+ * Generation by Testing Candidates).
+ */
+int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
+ const uint8_t key_bytes[P256_NBYTES])
+{
+ p256_int key;
+
+ p256_from_bin(key_bytes, &key);
+
+ /**
+ * We need key to be in the range 0 < key < SECP256r1 - 1.
+ * To achieve that, first check key < SECP256r1 - 2, and
+ * then add 1 to key. Since key is unsigned number this will
+ * bring key in proper range.
+ */
+ if (p256_lt_blinded(&key, &SECP256r1_nMin2) >= 0)
+ return 0;
+ p256_add_d(&key, 1, d);
+ always_memset(&key, 0, sizeof(key));
+ if (x == NULL || y == NULL)
+ return 1;
+ return dcrypto_p256_base_point_mul(d, x, y);
+}
diff --git a/board/cr50/dcrypto/p256_ecies.c b/board/cr50/dcrypto/p256_ecies.c
index 7b77efd507..d5afb2edbc 100644
--- a/board/cr50/dcrypto/p256_ecies.c
+++ b/board/cr50/dcrypto/p256_ecies.c
@@ -9,7 +9,6 @@
#include "trng.h"
#include "util.h"
-#include "cryptoc/p256.h"
#include "cryptoc/sha256.h"
#define AES_KEY_BYTES 16
diff --git a/board/cr50/fips.c b/board/cr50/fips.c
index 948bd2fba4..436e1588ae 100644
--- a/board/cr50/fips.c
+++ b/board/cr50/fips.c
@@ -369,18 +369,18 @@ static bool fips_hmac_drbg_kat(void)
/* Known-answer test for ECDSA NIST P-256 verify. */
static bool fips_ecdsa_verify_kat(void)
{
- static const p256_int qx = { { 0xf49abf3c, 0xf82e6e12, 0x7a67c074,
- 0x5134e16f, 0xf8957a0c, 0xef4344a7,
- 0xd4bb3cb7, 0xe424dc61 } };
- static const p256_int qy = { { 0xdfaee927, 0x3d6f60e7, 0xac85d124,
- 0x127e5965, 0xe1dddaf0, 0x1545949d,
- 0xa2bc4865, 0x970eed7a } };
- static const p256_int r = { { 0xd9347f4f, 0xb72f981f, 0x6349b9da,
- 0x2ff540c7, 0x42017c64, 0x910be331,
- 0xa49c705c, 0xbf96b99a } };
- static const p256_int s = { { 0x57ec871c, 0x920b9e0f, 0x75d98f31,
- 0x444e3230, 0x15abdf12, 0xe03b9cd4,
- 0x819089c2, 0x17c55095 } };
+ static const p256_int qx = { .a = { 0xf49abf3c, 0xf82e6e12, 0x7a67c074,
+ 0x5134e16f, 0xf8957a0c, 0xef4344a7,
+ 0xd4bb3cb7, 0xe424dc61 } };
+ static const p256_int qy = { .a = { 0xdfaee927, 0x3d6f60e7, 0xac85d124,
+ 0x127e5965, 0xe1dddaf0, 0x1545949d,
+ 0xa2bc4865, 0x970eed7a } };
+ static const p256_int r = { .a = { 0xd9347f4f, 0xb72f981f, 0x6349b9da,
+ 0x2ff540c7, 0x42017c64, 0x910be331,
+ 0xa49c705c, 0xbf96b99a } };
+ static const p256_int s = { .a = { 0x57ec871c, 0x920b9e0f, 0x75d98f31,
+ 0x444e3230, 0x15abdf12, 0xe03b9cd4,
+ 0x819089c2, 0x17c55095 } };
static const uint8_t msg[128] = {
0xe1, 0x13, 0x0a, 0xf6, 0xa3, 0x8c, 0xcb, 0x41, 0x2a, 0x9c,
0x8d, 0x13, 0xe1, 0x5d, 0xbf, 0xc9, 0xe6, 0x9a, 0x16, 0x38,
diff --git a/board/cr50/fips_rand.c b/board/cr50/fips_rand.c
index 1198c620a5..2b2f796767 100644
--- a/board/cr50/fips_rand.c
+++ b/board/cr50/fips_rand.c
@@ -314,6 +314,7 @@ bool fips_drbg_init(void)
&nonce.random_value, sizeof(nonce.random_value), NULL,
0);
+ set_fast_random_seed(fips_trng32(0).random_value);
rand_state.drbg_initialized = 1;
return true;
}
diff --git a/board/cr50/tpm2/ecc.c b/board/cr50/tpm2/ecc.c
index 5607aaff87..a8263b643e 100644
--- a/board/cr50/tpm2/ecc.c
+++ b/board/cr50/tpm2/ecc.c
@@ -13,9 +13,6 @@
#include "util.h"
#include "dcrypto.h"
-#include "cryptoc/p256.h"
-#include "cryptoc/p256_ecdsa.h"
-
static void reverse_tpm2b(TPM2B *b)
{
reverse(b->buffer, b->size);
diff --git a/common/u2f.c b/common/u2f.c
index c209be466e..f5f91376d1 100644
--- a/common/u2f.c
+++ b/common/u2f.c
@@ -6,7 +6,6 @@
/* APDU dispatcher and U2F command handlers. */
#include "console.h"
-#include "cryptoc/p256.h"
#include "dcrypto.h"
#include "extension.h"
diff --git a/include/u2f_impl.h b/include/u2f_impl.h
index d3f4800387..75e50cc6c7 100644
--- a/include/u2f_impl.h
+++ b/include/u2f_impl.h
@@ -10,11 +10,8 @@
#include "common.h"
-#ifdef TEST_BUILD
-#include "board/host/dcrypto.h"
-#endif
+#include "dcrypto.h"
-#include "cryptoc/p256.h"
#include "tpm_vendor_cmds.h"
#include "u2f.h"