From 50e3ce90b2f81075ed2e22a73ade0ed5cee35471 Mon Sep 17 00:00:00 2001 From: Vadim Sukhomlinov Date: Mon, 30 Aug 2021 18:13:38 -0700 Subject: cr50: add pair-wise consistency test for ECDSA key generation. FIPS requires pair-wise consistency test for asymmetric key generation algorithms. For U2F we use only ECDSA P-256, so adding this step into key generation function. BUG=b:198219806 TEST=make BOARD=cr50 CRYPTO_TEST=1; test/tpm_test/tpmtest.py This test covers U2F and TPM2 uses of ECDSA keygen. Signed-off-by: Vadim Sukhomlinov Change-Id: I520a233e700a68b19c863bad05271f97693b5ca9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3131949 Reviewed-by: Vadim Sukhomlinov Reviewed-by: Vadim Bendebury Tested-by: Vadim Sukhomlinov Commit-Queue: Vadim Sukhomlinov --- board/cr50/dcrypto/dcrypto.h | 10 ++++++++++ board/cr50/dcrypto/p256_ec.c | 40 +++++++++++++++++++++++++++++++++++++--- board/cr50/fips.h | 12 +++++++----- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h index b94bbd7eb3..284aa5dd51 100644 --- a/board/cr50/dcrypto/dcrypto.h +++ b/board/cr50/dcrypto/dcrypto.h @@ -255,6 +255,16 @@ int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y, const p256_int *n, int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d, const uint8_t bytes[P256_NBYTES]); +/** + * Pair-wise consistency test for private and public key. + * + * @param d - private key (scalar) + * @param x - public key part + * @param y - public key part + * @return !0 on success + */ +int DCRYPTO_p256_key_pwct(p256_int *d, p256_int *x, p256_int *y); + /* P256 based integration encryption (DH+AES128+SHA256). * Not FIPS 140-2 compliant, not used other than for tests * Authenticated data may be provided, where the first auth_data_len diff --git a/board/cr50/dcrypto/p256_ec.c b/board/cr50/dcrypto/p256_ec.c index fee1434136..4c97c521fc 100644 --- a/board/cr50/dcrypto/p256_ec.c +++ b/board/cr50/dcrypto/p256_ec.c @@ -4,6 +4,8 @@ */ #include "dcrypto.h" +#include "fips.h" +#include "fips_rand.h" #include @@ -36,6 +38,28 @@ 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); } +int DCRYPTO_p256_key_pwct(p256_int *d, p256_int *x, p256_int *y) +{ + p256_int message, r, s; + int result; + + if (p256_is_zero(d)) + return 0; + + /* set some pseudo-random message. */ + p256_fast_random(&message); + + if (fips_p256_ecdsa_sign(d, &message, &r, &s) == 0) + return 0; + +#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; +} + /** * Key selection based on FIPS-186-4, section B.4.2 (Key Pair * Generation by Testing Candidates). @@ -44,6 +68,7 @@ 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_int tx, ty; p256_from_bin(key_bytes, &key); @@ -57,7 +82,16 @@ int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d, 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); + + /* We need public key anyway for pair-wise consistency test. */ + if (!x) + x = &tx; + if (!y) + y = &ty; + + /* Compute public key (x,y) = d * G */ + if (dcrypto_p256_base_point_mul(d, x, y) == 0) + return 0; + + return DCRYPTO_p256_key_pwct(d, x, y); } diff --git a/board/cr50/fips.h b/board/cr50/fips.h index 5a3a67997c..52d8ec68c6 100644 --- a/board/cr50/fips.h +++ b/board/cr50/fips.h @@ -50,11 +50,12 @@ enum fips_break { FIPS_BREAK_HMAC_SHA256 = 3, FIPS_BREAK_HMAC_DRBG = 4, FIPS_BREAK_ECDSA = 5, + FIPS_BREAK_ECDSA_PWCT = 6, #ifdef CONFIG_FIPS_AES_CBC_256 - FIPS_BREAK_AES256 = 6, + FIPS_BREAK_AES256 = 7, #endif #ifdef CONFIG_FIPS_RSA2048 - FIPS_BREAK_RSA2048 = 7, + FIPS_BREAK_RSA2048 = 8, #endif }; @@ -75,13 +76,14 @@ enum fips_cmd { FIPS_CMD_BREAK_HMAC_SHA256 = 5, FIPS_CMD_BREAK_HMAC_DRBG = 6, FIPS_CMD_BREAK_ECDSA = 7, + FIPS_CMD_BREAK_ECDSA_PWCT = 8, #ifdef CONFIG_FIPS_AES_CBC_256 - FIPS_CMD_BREAK_AES256 = 8, + FIPS_CMD_BREAK_AES256 = 9, #endif #ifdef CONFIG_FIPS_RSA2048 - FIPS_CMD_BREAK_RSA2048 = 9, + FIPS_CMD_BREAK_RSA2048 = 10, #endif - FIPS_CMD_NO_BREAK = 10 + FIPS_CMD_NO_BREAK = 11 }; /* These symbols defined in core/cortex-m/ec.lds.S. */ -- cgit v1.2.1