summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-09-23 10:08:49 -0700
committerCommit Bot <commit-bot@chromium.org>2021-09-24 00:14:58 +0000
commit5044b81a4c797a058a21e95349437f04ab33e2ed (patch)
tree73a3592d60e2acaf46cd0a8bfb027b4b49f79a2d
parent78d460f72b65a2a01f81c2bc115da96bc331f5df (diff)
downloadchrome-ec-5044b81a4c797a058a21e95349437f04ab33e2ed.tar.gz
cr50: switch ECDSA to use enum dcrypto_result, added FIPS checks
We have to block access to crypto functions when FIPS errors occurred. To achieve this: 1. Provide wrappers for ECDSA P-256 sign and verify functions a) DCRYPTO_p256_ecdsa_verify as wrapper for dcrypto_p256_ecdsa_verify b) DCRYPTO_p256_ecdsa_sign as wrapper for dcrypto_p256_fips_sign_internal with additional check for FIPS DRBG initialization which is needed for signing. 2. Switch all ECDSA functions, both internal and external to use enum dcrypto_result instead of inconsistent 0/1 values. 3. Added warning for unused result code for ECDSA functions. 4. Updated documentation for public APIs 5. In DCRYPTO_p256_key_from_bytes() implemented clear distinction between bad candidate and failures due to FIPS or pair-wise consistency. 6. U2F, rma_auth, TPM ecc, etc updated to use new return codes. BUG=b:197893750 TEST=make BOARD=cr50 CRYPTO_TEST=1; rma_auth, u2f_test, etc. test/tpm_test/tpmtest.py TCG tests ----------------------------- Test Result Summary ---------------------- Test executed on: Thu Sep 23 09:56:42 2021 Performed Tests: 248 Passed Tests: 248 Failed Tests: 0 Errors: 0 Warnings: 0 ======================================================================== Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: I0251bf511771c1c1fd281f6db706d1dedac3e8b8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3179708 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Auto-Submit: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/dcrypto/dcrypto.h91
-rw-r--r--board/cr50/dcrypto/dcrypto_p256.c43
-rw-r--r--board/cr50/dcrypto/dcrypto_runtime.c31
-rw-r--r--board/cr50/dcrypto/fips.c10
-rw-r--r--board/cr50/dcrypto/fips_rand.c11
-rw-r--r--board/cr50/dcrypto/internal.h127
-rw-r--r--board/cr50/dcrypto/p256.c1
-rw-r--r--board/cr50/dcrypto/p256_ec.c86
-rw-r--r--board/cr50/dcrypto/p256_ecies.c14
-rw-r--r--board/cr50/dcrypto/u2f.c49
-rw-r--r--board/cr50/dcrypto/x509.c2
-rw-r--r--board/cr50/tpm2/ecc.c37
-rw-r--r--board/host/dcrypto.h6
-rw-r--r--common/rma_auth.c12
-rw-r--r--test/u2f.c20
15 files changed, 353 insertions, 187 deletions
diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h
index 36f2c40fee..d7ce9ebc8c 100644
--- a/board/cr50/dcrypto/dcrypto.h
+++ b/board/cr50/dcrypto/dcrypto.h
@@ -46,6 +46,10 @@ enum hashing_mode {
HASH_NULL = 4 /* Only supported for PKCS#1 signing */
};
+#ifndef __warn_unused_result
+#define __warn_unused_result __attribute__((warn_unused_result))
+#endif
+
/*
* AES implementation, based on a hardware AES block.
* FIPS Publication 197, The Advanced Encryption Standard (AES)
@@ -333,53 +337,92 @@ bool p256_from_be_bin_size(const uint8_t *src, size_t len, p256_int *dst);
*
* @param x point coordinate
* @param y point coordinate
+ *
* @return DCRYPTO_OK if (x,y) is a valid point, DCRYPTO_FAIL otherwise
*/
-enum dcrypto_result DCRYPTO_p256_is_valid_point(const p256_int *x,
- const p256_int *y);
+enum dcrypto_result DCRYPTO_p256_is_valid_point(
+ const p256_int *x, const p256_int *y) __warn_unused_result;
-/* DCRYPTO_p256_base_point_mul sets {out_x,out_y} = nG, where n is < the
- * order of the group.
+/**
+ * Base point multiplications (compute public key from private).
+ * Sets {out_x,out_y} = nG, where n is < the order of the group.
+ *
+ * @param out_x output public key component x
+ * @param out_y output public key component y
+ * @param n private key
+ *
+ * @return DCRYPTO_OK if successful
*/
-int DCRYPTO_p256_base_point_mul(p256_int *out_x, p256_int *out_y,
- const p256_int *n);
+enum dcrypto_result DCRYPTO_p256_base_point_mul(
+ p256_int *out_x, p256_int *out_y,
+ const p256_int *n) __warn_unused_result;
/**
* DCRYPTO_p256_point_mul sets {out_x,out_y} = n*{in_x,in_y}, where n is <
* the order of the group. Prior to computation check than {in_x,in_y} is
- * on NIST P-256 curve.
+ * on NIST P-256 curve. Used to implement ECDH.
*
* @param out_x output shared coordinate x
* @param out_y output shared coordinate y
* @param n private key
* @param in_x input public point x
* @param in_y input public point y
- * @return 1 if success
+ *
+ * @return DCRYPTO_OK if success
*/
-int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y, const p256_int *n,
- const p256_int *in_x, const p256_int *in_y);
-/*
+enum dcrypto_result DCRYPTO_p256_point_mul(
+ p256_int *out_x, p256_int *out_y, const p256_int *n,
+ const p256_int *in_x, const p256_int *in_y) __warn_unused_result;
+
+/**
* Key selection based on FIPS-186-4, section B.4.2 (Key Pair
* Generation by Testing Candidates).
- * Produce uniform private key from seed.
+ *
+ * @param x output public key component x
+ * @param y output public key component y
+ * @param d output private key
+ * @param bytes 32 byte random seed
+ *
+ * d = p256_from_bytes(bytes) + 1
+ *
* If x or y is NULL, the public key part is not computed.
- * Returns !0 on success.
+ *
+ * @return DCRYPTO_OK on success, DCRYPTO_RETRY if d is out of range, try
+ * with another seed bytes and DCRYPTO_FAIL for any other error.
*/
-int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
- const uint8_t bytes[P256_NBYTES]);
+enum dcrypto_result DCRYPTO_p256_key_from_bytes(
+ p256_int *x, p256_int *y, p256_int *d,
+ const uint8_t bytes[P256_NBYTES]) __warn_unused_result;
/**
- * TODO: Provide provide proper wrappers for dcrypto_p256_ecdsa_verify()
- * and fips_p256_ecdsa_sign()
+ * Verify NIST P-256 signature.
+ *
+ * @param key_x public key coordinate x
+ * @param key_y public key coordinate x
+ * @param message message digest to verify
+ * @param r signature component r
+ * @param s signature component s
+ *
+ * @return DCRYPTO_OK if success
*/
-int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
- const p256_int *message, const p256_int *r,
- const p256_int *s)
- __attribute__((warn_unused_result));
+enum dcrypto_result DCRYPTO_p256_ecdsa_verify(
+ const p256_int *key_x, const p256_int *key_y, const p256_int *message,
+ const p256_int *r, const p256_int *s) __warn_unused_result;
-/* wrapper around dcrypto_p256_ecdsa_sign using FIPS-compliant HMAC_DRBG */
-int fips_p256_ecdsa_sign(const p256_int *key, const p256_int *message,
- p256_int *r, p256_int *s);
+/**
+ * NIST ECDSA P-256 Sign.
+ *
+ * @param key private key
+ * @param message message digest (in p256_int form)
+ * @param r output signature component r
+ * @param s output signature component s
+ *
+ * @return DCRYPTO_OK if success.
+ */
+enum dcrypto_result DCRYPTO_p256_ecdsa_sign(const p256_int *key,
+ const p256_int *message,
+ p256_int *r,
+ p256_int *s) __warn_unused_result;
/************************************************************/
diff --git a/board/cr50/dcrypto/dcrypto_p256.c b/board/cr50/dcrypto/dcrypto_p256.c
index 841259cef7..bb9aff456c 100644
--- a/board/cr50/dcrypto/dcrypto_p256.c
+++ b/board/cr50/dcrypto/dcrypto_p256.c
@@ -134,8 +134,10 @@ static void dcrypto_ecc_init(void)
CP1W(d, 0, 8);
}
-int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
- const p256_int *message, p256_int *r, p256_int *s)
+enum dcrypto_result dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg,
+ const p256_int *key,
+ const p256_int *message,
+ p256_int *r, p256_int *s)
{
int result;
p256_int nonce;
@@ -143,17 +145,19 @@ int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
/* Pick uniform 0 < k < R */
result = (p256_hmac_drbg_generate(drbg, &nonce) != HMAC_DRBG_SUCCESS);
- result |= dcrypto_p256_ecdsa_sign_raw(&nonce, key, message, r, s) - 1;
+ result |= dcrypto_p256_ecdsa_sign_raw(&nonce, key, message, r, s) -
+ DCRYPTO_OK;
/* Wipe temp nonce */
p256_clear(&nonce);
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
-int dcrypto_p256_ecdsa_sign_raw(const p256_int *nonce, const p256_int *key,
- const p256_int *message, p256_int *r,
- p256_int *s)
+enum dcrypto_result dcrypto_p256_ecdsa_sign_raw(const p256_int *nonce,
+ const p256_int *key,
+ const p256_int *message,
+ p256_int *r, p256_int *s)
{
int result;
p256_int rnd;
@@ -186,10 +190,11 @@ int dcrypto_p256_ecdsa_sign_raw(const p256_int *nonce, const p256_int *key,
CP8W(k, &rnd);
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
-int dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x, p256_int *y)
+enum dcrypto_result dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x,
+ p256_int *y)
{
int result;
p256_int rnd;
@@ -217,11 +222,13 @@ int dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x, p256_int *y)
CP8W(d, &dmem_ecc->rnd);
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
-int dcrypto_p256_point_mul(const p256_int *k, const p256_int *in_x,
- const p256_int *in_y, p256_int *x, p256_int *y)
+enum dcrypto_result dcrypto_p256_point_mul(const p256_int *k,
+ const p256_int *in_x,
+ const p256_int *in_y, p256_int *x,
+ p256_int *y)
{
int result;
p256_int rnd;
@@ -254,12 +261,14 @@ int dcrypto_p256_point_mul(const p256_int *k, const p256_int *in_x,
CP8W(y, &rnd);
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
-int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
- const p256_int *message, const p256_int *r,
- const p256_int *s)
+enum dcrypto_result dcrypto_p256_ecdsa_verify(const p256_int *key_x,
+ const p256_int *key_y,
+ const p256_int *message,
+ const p256_int *r,
+ const p256_int *s)
{
int i, result;
@@ -279,7 +288,7 @@ int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
result |= (dmem_ecc->rnd.a[i] ^ r->a[i]);
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
enum dcrypto_result dcrypto_p256_is_valid_point(const p256_int *x,
diff --git a/board/cr50/dcrypto/dcrypto_runtime.c b/board/cr50/dcrypto/dcrypto_runtime.c
index 618d355362..0c79d34310 100644
--- a/board/cr50/dcrypto/dcrypto_runtime.c
+++ b/board/cr50/dcrypto/dcrypto_runtime.c
@@ -367,11 +367,11 @@ static const p256_int s_golden = {
0xd55d07a0, 0x1efb1274, 0x94afb5c9 },
};
-static int call_on_bigger_stack(uint32_t stack,
- int (*func)(p256_int *, p256_int *),
- p256_int *r, p256_int *s)
+static enum dcrypto_result call_on_bigger_stack(
+ uint32_t stack, enum dcrypto_result (*func)(p256_int *, p256_int *),
+ p256_int *r, p256_int *s)
{
- int result = 0;
+ enum dcrypto_result result = DCRYPTO_FAIL;
/* Move to new stack and call the function */
__asm__ volatile("mov r4, sp\n"
@@ -384,10 +384,8 @@ static int call_on_bigger_stack(uint32_t stack,
: [result] "=r"(result) /* output */
: [new_stack] "r"(stack), [r] "r"(r), [s] "r"(s),
[func] "r"(func) /* input */
- : "r0", "r1", "r2", "r3", "r4",
- "lr" /* clobbered registers */
- );
-
+ : /* clobbered registers */
+ "r0", "r1", "r2", "r3", "r4", "lr");
return result;
}
@@ -396,11 +394,11 @@ static int call_on_bigger_stack(uint32_t stack,
* in: r - ptr to entropy, s - ptr to message.
* out: r,s - generated signature.
*/
-static int ecdsa_sign_go(p256_int *r, p256_int *s)
+static enum dcrypto_result ecdsa_sign_go(p256_int *r, p256_int *s)
{
struct drbg_ctx drbg;
p256_int d;
- int ret = 0;
+ enum dcrypto_result ret = 0;
p256_int message = *s;
/* drbg init with same entropy */
@@ -410,7 +408,7 @@ static int ecdsa_sign_go(p256_int *r, p256_int *s)
if (p256_hmac_drbg_generate(&drbg, &d) != HMAC_DRBG_SUCCESS) {
/* to be consistent with ecdsa_sign error return */
drbg_exit(&drbg);
- return 0;
+ return DCRYPTO_FAIL;
}
/* drbg_reseed with entropy and message */
@@ -427,7 +425,8 @@ static int command_dcrypto_ecdsa_test(int argc, char *argv[])
{
p256_int entropy, message, r, s;
struct sha256_ctx hsh;
- int result = 0;
+ enum dcrypto_result result = DCRYPTO_FAIL;
+ enum ec_error_list ret;
char *new_stack;
const uint32_t new_stack_size = 2 * 1024;
@@ -444,11 +443,11 @@ static int command_dcrypto_ecdsa_test(int argc, char *argv[])
r = entropy;
s = message;
- result = shared_mem_acquire(new_stack_size, &new_stack);
+ ret = shared_mem_acquire(new_stack_size, &new_stack);
- if (result != EC_SUCCESS) {
+ if (ret != EC_SUCCESS) {
ccprintf("Failed to acquire stack memory: %d\n", result);
- return result;
+ return ret;
}
for (uint32_t i = 0; i < ECDSA_TEST_ITERATIONS; i++) {
@@ -456,7 +455,7 @@ static int command_dcrypto_ecdsa_test(int argc, char *argv[])
new_stack_size,
ecdsa_sign_go, &r, &s);
- if (!result) {
+ if (result != DCRYPTO_OK) {
ccprintf("ECDSA TEST fail: %d\n", result);
return EC_ERROR_INVAL;
}
diff --git a/board/cr50/dcrypto/fips.c b/board/cr50/dcrypto/fips.c
index b3b401fdfb..391fee5657 100644
--- a/board/cr50/dcrypto/fips.c
+++ b/board/cr50/dcrypto/fips.c
@@ -389,7 +389,7 @@ static bool fips_ecdsa_sign_pwct(void)
* Note, fips_drbg is not instantiated yet, but rather is in
* pre-determined state with K=[0], V=[0].
*/
- return DCRYPTO_p256_key_pwct(&fips_drbg, &d, &x, &y);
+ return dcrypto_p256_key_pwct(&fips_drbg, &d, &x, &y) == DCRYPTO_OK;
}
#endif
@@ -452,7 +452,7 @@ static bool fips_ecdsa_sign_verify_kat(void)
p256_from_bin(msg_digest, &msg);
/* KAT for ECDSA signing with fixed k. */
- passed = dcrypto_p256_ecdsa_sign_raw(&k, &d, &msg, &r, &s) - 1;
+ passed = dcrypto_p256_ecdsa_sign_raw(&k, &d, &msg, &r, &s) - DCRYPTO_OK;
passed |= DCRYPTO_equals(r.a, R.a, sizeof(R)) - DCRYPTO_OK;
passed |= DCRYPTO_equals(s.a, S.a, sizeof(S)) - DCRYPTO_OK;
@@ -461,14 +461,16 @@ static bool fips_ecdsa_sign_verify_kat(void)
msg.a[0] ^= 1;
/* KAT for verification */
- passed |= dcrypto_p256_ecdsa_verify(&Qx, &Qy, &msg, &r, &s) - 1;
+ passed |=
+ dcrypto_p256_ecdsa_verify(&Qx, &Qy, &msg, &r, &s) - DCRYPTO_OK;
/**
* Flip 1 bit in digest. Signature verification should fail.
*/
msg.a[5] ^= 0x10;
- passed |= dcrypto_p256_ecdsa_verify(&Qx, &Qy, &msg, &r, &s);
+ passed |= dcrypto_p256_ecdsa_verify(&Qx, &Qy, &msg, &r, &s) -
+ DCRYPTO_FAIL;
return passed == 0;
}
diff --git a/board/cr50/dcrypto/fips_rand.c b/board/cr50/dcrypto/fips_rand.c
index 3c3b4bbfb6..0a0609b0cd 100644
--- a/board/cr50/dcrypto/fips_rand.c
+++ b/board/cr50/dcrypto/fips_rand.c
@@ -352,17 +352,6 @@ enum hmac_result fips_p256_hmac_drbg_generate(struct drbg_ctx *drbg,
return err;
}
-/* return codes match dcrypto_p256_ecdsa_sign */
-int fips_p256_ecdsa_sign(const p256_int *key, const p256_int *message,
- p256_int *r, p256_int *s)
-{
- /* Also check for fips_crypto_allowed(). */
- if (!fips_drbg_init())
- return 0;
-
- return dcrypto_p256_fips_sign_internal(&fips_drbg, key, message, r, s);
-}
-
#ifndef CRYPTO_TEST_CMD_RAND_PERF
#define CRYPTO_TEST_CMD_RAND_PERF 0
#endif
diff --git a/board/cr50/dcrypto/internal.h b/board/cr50/dcrypto/internal.h
index 7d64fc69b3..cd5e351dbd 100644
--- a/board/cr50/dcrypto/internal.h
+++ b/board/cr50/dcrypto/internal.h
@@ -207,37 +207,94 @@ 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);
-
/**
* Raw sign with provided nonce (k). Used internally and for testing.
*
- * @param k - valid nonce for ECDSA sign
- * @param key - valid private key for ECDSA sign
- * @param message - message to sign encoded as p-256 int
- * @param r - generated signature
- * @param s - generated signature
- * @return !0 if success
+ * @param k valid random per-message nonce for ECDSA sign
+ * @param key valid private key for ECDSA sign
+ * @param message message to sign encoded as p-256 int
+ * @param r generated signature
+ * @param s generated signature
+ *
+ * @return DCRYPTO_OK if successful
+ */
+enum dcrypto_result dcrypto_p256_ecdsa_sign_raw(
+ const p256_int *k, const p256_int *key, const p256_int *message,
+ p256_int *r, p256_int *s) __warn_unused_result;
+
+/**
+ * ECDSA P-256 Sign using provide DRBG as source for per-message random
+ * nonces. Used primarily for deterministic signatures per RFC 6979.
+ *
+ * @param drbg initialized DRBG
+ * @param key valid private key for ECDSA sign
+ * @param message message to sign encoded as p-256 int
+ * @param r generated signature
+ * @param s generated signature
+ *
+ * @return DCRYPTO_OK if successful
+ */
+enum dcrypto_result dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg,
+ const p256_int *key,
+ const p256_int *message,
+ p256_int *r,
+ p256_int *s) __warn_unused_result;
+
+/**
+ * Compute k*G (base point multiplication). Used to compute public key
+ * from private scalar.
+ *
+ * @param k private key
+ * @param x output component x
+ * @param y output component y
+ *
+ * @return DCRYPTO_OK if successful
+ */
+enum dcrypto_result dcrypto_p256_base_point_mul(
+ const p256_int *k, p256_int *x, p256_int *y) __warn_unused_result;
+
+/**
+ * Compute multiplication of input point (in_x, in_y) by scalar k.
+ * Used to compute shared point in ECDH.
+ *
+ * @param k private key
+ * @param in_x input public component x
+ * @param in_y input public component y
+ * @param x output shared component x
+ * @param y output shared component y
+ *
+ * @return DCRYPTO_OK if successful
+ */
+enum dcrypto_result dcrypto_p256_point_mul(const p256_int *k,
+ const p256_int *in_x,
+ const p256_int *in_y, p256_int *x,
+ p256_int *y) __warn_unused_result;
+
+/**
+ * Verify ECDSA NIST P-256 signature.
+ *
+ * @param key_x public key component x
+ * @param key_y public key component y
+ * @param message message digest converted to p256_int
+ * @param r signature component r
+ * @param s signature component s
+ *
+ * @return DCRYPTO_OK if signature is valid
*/
-int dcrypto_p256_ecdsa_sign_raw(const p256_int *k, const p256_int *key,
- const p256_int *message, p256_int *r,
- p256_int *s);
-
-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));
-int dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x, p256_int *y)
- __attribute__((warn_unused_result));
-int dcrypto_p256_point_mul(const p256_int *k,
- const p256_int *in_x, const p256_int *in_y,
- p256_int *x, p256_int *y)
- __attribute__((warn_unused_result));
-int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
- const p256_int *message, const p256_int *r,
- const p256_int *s)
- __attribute__((warn_unused_result));
-enum dcrypto_result dcrypto_p256_is_valid_point(const p256_int *x,
- const p256_int *y)
- __attribute__((warn_unused_result));
+enum dcrypto_result dcrypto_p256_ecdsa_verify(
+ const p256_int *key_x, const p256_int *key_y, const p256_int *message,
+ const p256_int *r, const p256_int *s) __warn_unused_result;
+
+/**
+ * Verify that provided point is on NIST P-256 curve.
+ *
+ * @param x public key component x
+ * @param y public key component y
+ *
+ * @return DCRYPTO_OK if point is on curve
+ */
+enum dcrypto_result dcrypto_p256_is_valid_point(
+ const p256_int *x, const p256_int *y) __warn_unused_result;
/**
* Pair-wise consistency test for private and public key.
@@ -246,10 +303,12 @@ enum dcrypto_result dcrypto_p256_is_valid_point(const p256_int *x,
* @param d - private key (scalar)
* @param x - public key part
* @param y - public key part
- * @return !0 on success
+ *
+ * @return DCRYPTO_OK on success
*/
-int DCRYPTO_p256_key_pwct(struct drbg_ctx *drbg, const p256_int *d,
- const p256_int *x, const p256_int *y);
+enum dcrypto_result dcrypto_p256_key_pwct(
+ struct drbg_ctx *drbg, const p256_int *d, const p256_int *x,
+ const p256_int *y) __warn_unused_result;
/* Wipe content of rnd with pseudo-random values. */
void p256_fast_random(p256_int *rnd);
@@ -266,11 +325,11 @@ enum hmac_result p256_hmac_drbg_generate(struct drbg_ctx *ctx, p256_int *k_out);
* @param message - Message to sign as P-256 (in little-endian)
* @param r - Generated signature
* @param s - Generated signature
- * @return int
+ * @return DCRYPTO_OK if success
*/
-int dcrypto_p256_fips_sign_internal(struct drbg_ctx *drbg, const p256_int *key,
- const p256_int *message, p256_int *r,
- p256_int *s);
+enum dcrypto_result dcrypto_p256_fips_sign_internal(
+ struct drbg_ctx *drbg, const p256_int *key, const p256_int *message,
+ p256_int *r, p256_int *s) __warn_unused_result;
/* Initialize for use as RFC6979 DRBG. */
void hmac_drbg_init_rfc6979(struct drbg_ctx *ctx,
diff --git a/board/cr50/dcrypto/p256.c b/board/cr50/dcrypto/p256.c
index cfbf068b7a..52d65fbaae 100644
--- a/board/cr50/dcrypto/p256.c
+++ b/board/cr50/dcrypto/p256.c
@@ -190,6 +190,7 @@ void p256_fast_random(p256_int *rnd)
P256_DIGIT(rnd, i) = fast_random();
}
+/* B.5.2 Per-Message Secret Number Generation by Testing Candidates */
enum hmac_result p256_hmac_drbg_generate(struct drbg_ctx *ctx, p256_int *rnd)
{
enum hmac_result result;
diff --git a/board/cr50/dcrypto/p256_ec.c b/board/cr50/dcrypto/p256_ec.c
index 5c7f355a67..d9e87b699a 100644
--- a/board/cr50/dcrypto/p256_ec.c
+++ b/board/cr50/dcrypto/p256_ec.c
@@ -4,15 +4,38 @@
*/
#include "internal.h"
+enum dcrypto_result DCRYPTO_p256_ecdsa_verify(const p256_int *key_x,
+ const p256_int *key_y,
+ const p256_int *message,
+ const p256_int *r,
+ const p256_int *s)
+{
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ return dcrypto_p256_ecdsa_verify(key_x, key_y, message, r, s);
+}
+
+/* return codes match dcrypto_p256_ecdsa_sign */
+enum dcrypto_result DCRYPTO_p256_ecdsa_sign(const p256_int *key,
+ const p256_int *message,
+ p256_int *r, p256_int *s)
+{
+ if (!fips_drbg_init()) /* Also check for fips_crypto_allowed(). */
+ return DCRYPTO_FAIL;
+
+ return dcrypto_p256_fips_sign_internal(&fips_drbg, key, message, r, s);
+}
+
/* 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,
- const p256_int *n)
+enum dcrypto_result DCRYPTO_p256_base_point_mul(p256_int *out_x,
+ p256_int *out_y, const p256_int *n)
{
- if (p256_is_zero(n) != 0) {
+ if (!fips_crypto_allowed() || p256_is_zero(n)) {
p256_clear(out_x);
p256_clear(out_y);
- return 0;
+ return DCRYPTO_FAIL;
}
return dcrypto_p256_base_point_mul(n, out_x, out_y);
@@ -21,27 +44,29 @@ int DCRYPTO_p256_base_point_mul(p256_int *out_x, p256_int *out_y,
enum dcrypto_result DCRYPTO_p256_is_valid_point(const p256_int *x,
const p256_int *y)
{
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
return dcrypto_p256_is_valid_point(x, y);
}
/* DCRYPTO_p256_point_mul sets {out_x,out_y} = n*{in_x,in_y}, where n is <
* the order of the group. */
-int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y, const p256_int *n,
- const p256_int *in_x, const p256_int *in_y)
+enum dcrypto_result DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
+ const p256_int *n, const p256_int *in_x, const p256_int *in_y)
{
- if (p256_is_zero(n) != 0 ||
+ if (!fips_crypto_allowed() || p256_is_zero(n) ||
(dcrypto_p256_is_valid_point(in_x, in_y) != DCRYPTO_OK)) {
p256_clear(out_x);
p256_clear(out_y);
- return 0;
+ return DCRYPTO_FAIL;
}
return dcrypto_p256_point_mul(n, in_x, in_y, out_x, out_y);
}
-
-int dcrypto_p256_fips_sign_internal(struct drbg_ctx *drbg, const p256_int *key,
- const p256_int *message, p256_int *r,
- p256_int *s)
+enum dcrypto_result dcrypto_p256_fips_sign_internal(struct drbg_ctx *drbg,
+ const p256_int *key,
+ const p256_int *message,
+ p256_int *r, p256_int *s)
{
int result;
p256_int k;
@@ -49,47 +74,52 @@ int dcrypto_p256_fips_sign_internal(struct drbg_ctx *drbg, const p256_int *key,
/* Pick uniform 0 < k < R */
result = fips_p256_hmac_drbg_generate(drbg, &k) - HMAC_DRBG_SUCCESS;
- result |= dcrypto_p256_ecdsa_sign_raw(&k, key, message, r, s) - 1;
+ result |= dcrypto_p256_ecdsa_sign_raw(&k, key, message, r, s) -
+ DCRYPTO_OK;
/* Wipe temp k */
p256_clear(&k);
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
-int DCRYPTO_p256_key_pwct(struct drbg_ctx *drbg, const p256_int *d,
- const p256_int *x, const p256_int *y)
+enum dcrypto_result dcrypto_p256_key_pwct(struct drbg_ctx *drbg,
+ const p256_int *d, const p256_int *x,
+ const p256_int *y)
{
p256_int message, r, s;
- int result;
+ enum dcrypto_result result;
if (p256_is_zero(d))
- return 0;
+ return DCRYPTO_FAIL;
/* set some pseudo-random message. */
p256_fast_random(&message);
- if (dcrypto_p256_fips_sign_internal(drbg, d, &message, &r, &s) == 0)
- return 0;
+ result = dcrypto_p256_fips_sign_internal(drbg, d, &message, &r, &s);
+ if (result != DCRYPTO_OK)
+ return result;
#ifdef CRYPTO_TEST_SETUP
if (fips_break_cmd == FIPS_BREAK_ECDSA_PWCT)
message.a[0] = ~message.a[0];
#endif
- result = dcrypto_p256_ecdsa_verify(x, y, &message, &r, &s);
- return result;
+ return dcrypto_p256_ecdsa_verify(x, y, &message, &r, &s);
}
/**
* 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])
+enum dcrypto_result 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_int tx, ty;
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
p256_from_bin(key_bytes, &key);
/**
@@ -99,7 +129,7 @@ int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
* bring key in proper range.
*/
if (p256_lt_blinded(&key, &SECP256r1_nMin2) >= 0)
- return 0;
+ return DCRYPTO_RETRY;
p256_add_d(&key, 1, d);
always_memset(&key, 0, sizeof(key));
@@ -110,8 +140,8 @@ int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
y = &ty;
/* Compute public key (x,y) = d * G */
- if (dcrypto_p256_base_point_mul(d, x, y) == 0)
- return 0;
+ if (dcrypto_p256_base_point_mul(d, x, y) != DCRYPTO_OK)
+ return DCRYPTO_FAIL;
- return DCRYPTO_p256_key_pwct(&fips_drbg, d, x, y);
+ return dcrypto_p256_key_pwct(&fips_drbg, d, x, y);
}
diff --git a/board/cr50/dcrypto/p256_ecies.c b/board/cr50/dcrypto/p256_ecies.c
index 1edef5f67d..e7324eccc2 100644
--- a/board/cr50/dcrypto/p256_ecies.c
+++ b/board/cr50/dcrypto/p256_ecies.c
@@ -6,7 +6,6 @@
#include "internal.h"
#include "dcrypto.h"
-#include "trng.h"
#include "util.h"
#define AES_KEY_BYTES 16
@@ -47,12 +46,14 @@ size_t DCRYPTO_ecies_encrypt(
return 0;
/* Generate emphemeral EC key. */
- rand_bytes(seed, sizeof(seed));
- if (!DCRYPTO_p256_key_from_bytes(&eph_x, &eph_y, &eph_d, seed))
+ if (!fips_rand_bytes(seed, sizeof(seed)))
+ return 0;
+ if (DCRYPTO_p256_key_from_bytes(&eph_x, &eph_y, &eph_d, seed) !=
+ DCRYPTO_OK)
return 0;
/* Compute DH point. */
- if (!DCRYPTO_p256_point_mul(&secret_x, &secret_y,
- &eph_d, pub_x, pub_y))
+ if (DCRYPTO_p256_point_mul(&secret_x, &secret_y, &eph_d, pub_x,
+ pub_y) != DCRYPTO_OK)
return 0;
/* Check for computational errors. */
if (dcrypto_p256_is_valid_point(&secret_x, &secret_y) != DCRYPTO_OK)
@@ -140,7 +141,8 @@ size_t DCRYPTO_ecies_decrypt(
* Verify that the public point is on the curve and compute the DH
* point.
*/
- if (!DCRYPTO_p256_point_mul(&secret_x, &secret_y, d, &eph_x, &eph_y))
+ if (DCRYPTO_p256_point_mul(&secret_x, &secret_y, d, &eph_x, &eph_y) !=
+ DCRYPTO_OK)
return 0;
/* Check for computational errors. */
if (!dcrypto_p256_is_valid_point(&secret_x, &secret_y) != DCRYPTO_OK)
diff --git a/board/cr50/dcrypto/u2f.c b/board/cr50/dcrypto/u2f.c
index e8f6584c69..414a8fe41a 100644
--- a/board/cr50/dcrypto/u2f.c
+++ b/board/cr50/dcrypto/u2f.c
@@ -158,6 +158,7 @@ static enum ec_error_list u2f_origin_user_key_pair(
struct drbg_ctx drbg;
size_t key_handle_size = 0;
uint8_t *key_handle = NULL;
+ enum dcrypto_result result;
if (kh_version == 0) {
key_handle_size = sizeof(struct u2f_key_handle_v0);
@@ -205,8 +206,12 @@ static enum ec_error_list u2f_origin_user_key_pair(
hmac_drbg_generate(&drbg, key_seed, sizeof(key_seed), dev_salt,
P256_NBYTES);
}
- if (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, key_seed))
+ result = DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, key_seed);
+
+ if (result == DCRYPTO_RETRY)
return EC_ERROR_TRY_AGAIN;
+ else if (result != DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
#ifdef CR50_DEV_U2F_VERBOSE
ccprintf("user private key %ph\n", HEX_BUF(d, sizeof(*d)));
@@ -418,7 +423,8 @@ enum ec_error_list u2f_sign(const struct u2f_state *state,
/* Sign. */
hmac_drbg_init_rfc6979(&ctx, &origin_d, &h);
- result = (dcrypto_p256_ecdsa_sign(&ctx, &origin_d, &h, &r, &s) != 0) ?
+ result = (dcrypto_p256_ecdsa_sign(&ctx, &origin_d, &h, &r, &s) ==
+ DCRYPTO_OK) ?
EC_SUCCESS :
EC_ERROR_HW_INTERNAL;
@@ -443,10 +449,11 @@ enum ec_error_list u2f_sign(const struct u2f_state *state,
static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
p256_int *pk_x, p256_int *pk_y)
{
- uint32_t buf[SHA256_DIGEST_WORDS];
+ struct sha256_digest buf;
+ enum dcrypto_result result;
/* Incorporate HIK & diversification constant. */
- if (!app_hw_device_id(U2F_ATTEST, state->salt, buf))
+ if (!app_hw_device_id(U2F_ATTEST, state->salt, buf.b32))
return false;
/* Check that U2F state is valid. */
@@ -455,14 +462,19 @@ static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
if (state->drbg_entropy_size != 64) {
/* Generate unbiased private key (non-FIPS path). */
- while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
- (uint8_t *)buf)) {
- struct sha256_ctx sha;
-
- SHA256_hw_init(&sha);
- SHA256_update(&sha, buf, sizeof(buf));
- memcpy(buf, SHA256_final(&sha), sizeof(buf));
- }
+ do {
+ result = DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
+ buf.b8);
+ switch (result) {
+ case DCRYPTO_OK:
+ break;
+ case DCRYPTO_RETRY:
+ SHA256_hw_hash(buf.b8, sizeof(buf), &buf);
+ break;
+ default: /* Any other result is error. */
+ return false;
+ }
+ } while (result != DCRYPTO_OK);
} else {
struct drbg_ctx drbg;
uint8_t key_candidate[P256_NBYTES];
@@ -480,10 +492,14 @@ static bool g2f_individual_key_pair(const struct u2f_state *state, p256_int *d,
* Additional data = constant coming from HW.
*/
hmac_drbg_generate(&drbg, key_candidate,
- sizeof(key_candidate), buf,
+ sizeof(key_candidate), buf.b32,
sizeof(buf));
- } while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
- key_candidate));
+ result = DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d,
+ key_candidate);
+ } while (result == DCRYPTO_RETRY);
+
+ if (result != DCRYPTO_OK)
+ return false;
}
return true;
@@ -554,7 +570,8 @@ enum ec_error_list u2f_attest(const struct u2f_state *state,
/* Sign over the response w/ the attestation key. */
hmac_drbg_init_rfc6979(&dr_ctx, &d, &h);
- result = (dcrypto_p256_ecdsa_sign(&dr_ctx, &d, &h, &r, &s) != 0) ?
+ result = (dcrypto_p256_ecdsa_sign(&dr_ctx, &d, &h, &r, &s) ==
+ DCRYPTO_OK) ?
EC_SUCCESS :
EC_ERROR_HW_INTERNAL;
p256_clear(&d);
diff --git a/board/cr50/dcrypto/x509.c b/board/cr50/dcrypto/x509.c
index 6c4a8f0b15..e8f5220e23 100644
--- a/board/cr50/dcrypto/x509.c
+++ b/board/cr50/dcrypto/x509.c
@@ -516,7 +516,7 @@ int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
SHA256_update(&sha, body, (ctx.p + ctx.n) - body);
p256_from_bin(SHA256_final(&sha)->b8, &h);
hmac_drbg_init_rfc6979(&drbg, d, &h);
- result = dcrypto_p256_ecdsa_sign(&drbg, d, &h, &r, &s);
+ result = dcrypto_p256_ecdsa_sign(&drbg, d, &h, &r, &s) - DCRYPTO_OK;
drbg_exit(&drbg);
if (!result)
return 0;
diff --git a/board/cr50/tpm2/ecc.c b/board/cr50/tpm2/ecc.c
index 5cd8e320b7..6e8f5792ed 100644
--- a/board/cr50/tpm2/ecc.c
+++ b/board/cr50/tpm2/ecc.c
@@ -41,7 +41,7 @@ CRYPT_RESULT _cpri__EccPointMultiply(
TPMS_ECC_POINT *out, TPM_ECC_CURVE curve_id,
TPM2B_ECC_PARAMETER *n1, TPMS_ECC_POINT *in, TPM2B_ECC_PARAMETER *n2)
{
- int result;
+ enum dcrypto_result result;
p256_int n, in_x, in_y, out_x, out_y;
switch (curve_id) {
@@ -75,7 +75,7 @@ CRYPT_RESULT _cpri__EccPointMultiply(
}
p256_clear(&n);
- if (result) {
+ if (result == DCRYPTO_OK) {
out->x.b.size = sizeof(p256_int);
out->y.b.size = sizeof(p256_int);
p256_to_bin(&out_x, out->x.b.buffer);
@@ -161,12 +161,17 @@ CRYPT_RESULT _cpri__GenerateKeyEcc(
for (; count != 0; count++) {
p256_int x, y, key;
+ enum dcrypto_result result;
memcpy(marshaled_counter.t.buffer, &count, sizeof(count));
_cpri__KDFa(hash_alg, &local_seed.b, label, local_extra,
&marshaled_counter.b, sizeof(key_bytes) * 8, key_bytes,
NULL, FALSE);
- if (DCRYPTO_p256_key_from_bytes(&x, &y, &key, key_bytes)) {
+
+ result = DCRYPTO_p256_key_from_bytes(&x, &y, &key, key_bytes);
+ if (result == DCRYPTO_RETRY)
+ continue;
+ else if (result == DCRYPTO_OK) {
q->x.b.size = sizeof(p256_int);
p256_to_bin(&x, q->x.b.buffer);
@@ -177,6 +182,10 @@ CRYPT_RESULT _cpri__GenerateKeyEcc(
p256_to_bin(&key, d->b.buffer);
p256_clear(&key);
break;
+ } else {
+ /* Any other value for result is failure. */
+ count = 0;
+ break;
}
}
@@ -199,7 +208,7 @@ CRYPT_RESULT _cpri__SignEcc(
uint8_t digest_local[sizeof(p256_int)];
const size_t digest_len = MIN(digest->size, sizeof(digest_local));
p256_int p256_digest, key, p256_r, p256_s;
- int result;
+ enum dcrypto_result result;
if (curve_id != TPM_ECC_NIST_P256)
return CRYPT_PARAMETER;
@@ -215,8 +224,8 @@ CRYPT_RESULT _cpri__SignEcc(
digest->buffer, digest_len);
p256_from_bin(digest_local, &p256_digest);
- result = fips_p256_ecdsa_sign(&key, &p256_digest, &p256_r,
- &p256_s);
+ result = DCRYPTO_p256_ecdsa_sign(&key, &p256_digest, &p256_r,
+ &p256_s);
p256_clear(&key);
r->b.size = sizeof(p256_int);
@@ -224,7 +233,7 @@ CRYPT_RESULT _cpri__SignEcc(
p256_to_bin(&p256_r, r->b.buffer);
p256_to_bin(&p256_s, s->b.buffer);
- if (result)
+ if (result == DCRYPTO_OK)
return CRYPT_SUCCESS;
else
return CRYPT_FAIL;
@@ -242,7 +251,6 @@ CRYPT_RESULT _cpri__ValidateSignatureEcc(
uint8_t digest_local[sizeof(p256_int)];
const size_t digest_len = MIN(digest->size, sizeof(digest_local));
p256_int p256_digest, q_x, q_y, p256_r, p256_s;
- int result;
if (curve_id != TPM_ECC_NIST_P256)
return CRYPT_PARAMETER;
@@ -261,13 +269,10 @@ CRYPT_RESULT _cpri__ValidateSignatureEcc(
digest->buffer, digest_len);
p256_from_bin(digest_local, &p256_digest);
- result = dcrypto_p256_ecdsa_verify(&q_x, &q_y, &p256_digest,
- &p256_r, &p256_s);
-
- if (result)
+ if (DCRYPTO_p256_ecdsa_verify(&q_x, &q_y, &p256_digest, &p256_r,
+ &p256_s) == DCRYPTO_OK)
return CRYPT_SUCCESS;
- else
- return CRYPT_FAIL;
+ return CRYPT_FAIL;
}
default:
return CRYPT_PARAMETER;
@@ -277,7 +282,7 @@ CRYPT_RESULT _cpri__ValidateSignatureEcc(
CRYPT_RESULT _cpri__GetEphemeralEcc(TPMS_ECC_POINT *q, TPM2B_ECC_PARAMETER *d,
TPM_ECC_CURVE curve_id)
{
- int result;
+ enum dcrypto_result result;
uint8_t key_bytes[P256_NBYTES] __aligned(4);
p256_int x, y, key;
@@ -291,7 +296,7 @@ CRYPT_RESULT _cpri__GetEphemeralEcc(TPMS_ECC_POINT *q, TPM2B_ECC_PARAMETER *d,
always_memset(key_bytes, 0, sizeof(key_bytes));
- if (result) {
+ if (result == DCRYPTO_OK) {
q->x.b.size = sizeof(p256_int);
q->y.b.size = sizeof(p256_int);
p256_to_bin(&x, q->x.b.buffer);
diff --git a/board/host/dcrypto.h b/board/host/dcrypto.h
index 481d724986..b9bd5b8be8 100644
--- a/board/host/dcrypto.h
+++ b/board/host/dcrypto.h
@@ -74,8 +74,10 @@ struct drbg_ctx {
uint32_t reseed_counter;
};
-int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
- const p256_int *message, p256_int *r, p256_int *s);
+enum dcrypto_result dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg,
+ const p256_int *key,
+ const p256_int *message,
+ p256_int *r, p256_int *s);
void hmac_drbg_init_rfc6979(struct drbg_ctx *ctx, const p256_int *key,
const p256_int *message);
diff --git a/common/rma_auth.c b/common/rma_auth.c
index e2dcc4dea8..9de2d9984b 100644
--- a/common/rma_auth.c
+++ b/common/rma_auth.c
@@ -133,8 +133,14 @@ static int p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
*/
while (1) {
struct sha256_ctx sha;
+ enum dcrypto_result result;
- if (DCRYPTO_p256_key_from_bytes(&pk_x, &pk_y, &d, buf)) {
+ result = DCRYPTO_p256_key_from_bytes(&pk_x, &pk_y, &d, buf);
+
+ if (result == DCRYPTO_FAIL)
+ return EC_ERROR_HW_INTERNAL;
+
+ if (result == DCRYPTO_OK) {
/* Is Y coordinate an odd value? */
if (p256_is_odd(&pk_y))
@@ -158,7 +164,9 @@ static int p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
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);
+ if (DCRYPTO_p256_point_mul(&pk_x, &pk_y, &d, &pk_x, &pk_y) !=
+ DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
/* X value is the seed for the shared secret. */
p256_to_bin(&pk_x, secret);
diff --git a/test/u2f.c b/test/u2f.c
index 36c1b5a1d4..21c5d6ea69 100644
--- a/test/u2f.c
+++ b/test/u2f.c
@@ -54,33 +54,33 @@ int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
return 0;
}
-int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
- const uint8_t key_bytes[P256_NBYTES])
+enum dcrypto_result 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_lt_blinded(&key, &SECP256r1_nMin2) >= 0)
- return 0;
+ return DCRYPTO_RETRY;
p256_add_d(&key, 1, d);
if (x == NULL || y == NULL)
- return 1;
+ return DCRYPTO_OK;
memset(x, 0, P256_NBYTES);
memset(y, 0, P256_NBYTES);
- return 1;
+ return DCRYPTO_OK;
}
-int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
- const p256_int *message, p256_int *r, p256_int *s)
+enum dcrypto_result dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg,
+ const p256_int *key,
+ const p256_int *message,
+ p256_int *r, p256_int *s)
{
memset(r, 0, sizeof(p256_int));
memset(s, 0, sizeof(p256_int));
- /* Return 1 for success, 0 for error. */
- return 1;
+ return DCRYPTO_OK;
}
-
/******************************************************************************/
/* Mock implementations of U2F functionality.
*/