diff options
Diffstat (limited to 'board/cr50/dcrypto/p256_ec.c')
-rw-r--r-- | board/cr50/dcrypto/p256_ec.c | 28 |
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); +} |