summaryrefslogtreecommitdiff
path: root/board/cr50/dcrypto/p256_ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/cr50/dcrypto/p256_ec.c')
-rw-r--r--board/cr50/dcrypto/p256_ec.c28
1 files changed, 26 insertions, 2 deletions
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);
+}