summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-10-05 18:34:26 -0700
committerCommit Bot <commit-bot@chromium.org>2021-10-06 02:56:18 +0000
commit0fe84e193c648d30a0e45b2332bd4854a3e1d8bb (patch)
treeadcbb17b592dbea0723ba493824ac36e1d77ca7c
parent7f5d2a30a4add6125d2ecf33e14efdbccc0e8087 (diff)
downloadchrome-ec-0fe84e193c648d30a0e45b2332bd4854a3e1d8bb.tar.gz
cr50: update RSA public API to block access on FIPS errors
1. Switched RSA public and internal functions to use enum dcrypto_result 2. Added checks for FIPS errors. 3. Updated call sites to properly handle result values. BUG=b:197893750 TEST=make BOARD=cr50 CRYPTO_TEST=1; test/tpm_test/tpm_test.py TCG tests: ---------------------- Test Result Summary ----------------------------- Test executed on: Mon Oct 5 18:26:07 2021 Performed Tests: 248 Passed Tests: 248 Failed Tests: 0 Errors: 0 Warnings: 0 ======================================================================== Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: I23d391322e55b541d72388b2a4661991a61dd020 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3207348 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Andrey Pronin <apronin@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/dcrypto/bn.c40
-rw-r--r--board/cr50/dcrypto/dcrypto.h56
-rw-r--r--board/cr50/dcrypto/dcrypto_bn.c25
-rw-r--r--board/cr50/dcrypto/fips.c13
-rw-r--r--board/cr50/dcrypto/internal.h57
-rw-r--r--board/cr50/dcrypto/rsa.c170
-rw-r--r--board/cr50/dcrypto/x509.c19
-rw-r--r--board/cr50/tpm2/endorsement.c10
-rw-r--r--board/cr50/tpm2/rsa.c26
-rw-r--r--common/ap_ro_integrity_check.c5
10 files changed, 233 insertions, 188 deletions
diff --git a/board/cr50/dcrypto/bn.c b/board/cr50/dcrypto/bn.c
index 6949eb0a0c..e92f366aeb 100644
--- a/board/cr50/dcrypto/bn.c
+++ b/board/cr50/dcrypto/bn.c
@@ -397,8 +397,10 @@ static void bn_modexp_internal(struct LITE_BIGNUM *output,
}
/* output = input ^ exp % N */
-int bn_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp, const struct LITE_BIGNUM *N)
+enum dcrypto_result bn_modexp(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N)
{
#ifndef CR50_NO_BN_ASM
if ((bn_bits(N) & 255) == 0) {
@@ -407,12 +409,13 @@ int bn_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
}
#endif
bn_modexp_internal(output, input, exp, N);
- return 1;
+ return DCRYPTO_OK;
}
/* output = input ^ exp % N */
-int bn_modexp_word(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
- uint32_t exp, const struct LITE_BIGNUM *N)
+enum dcrypto_result bn_modexp_word(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ uint32_t exp, const struct LITE_BIGNUM *N)
{
#ifndef CR50_NO_BN_ASM
if ((bn_bits(N) & 255) == 0) {
@@ -421,16 +424,16 @@ int bn_modexp_word(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
}
#endif
{
- struct LITE_BIGNUM pubexp;
+ struct LITE_BIGNUM pubexp;
- DCRYPTO_bn_wrap(&pubexp, &exp, sizeof(exp));
- bn_modexp_internal(output, input, &pubexp, N);
- return 1;
+ DCRYPTO_bn_wrap(&pubexp, &exp, sizeof(exp));
+ bn_modexp_internal(output, input, &pubexp, N);
+ return DCRYPTO_OK;
}
}
/* output = input ^ exp % N */
-int bn_modexp_blinded(struct LITE_BIGNUM *output,
+enum dcrypto_result bn_modexp_blinded(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N,
@@ -443,7 +446,7 @@ int bn_modexp_blinded(struct LITE_BIGNUM *output,
}
#endif
bn_modexp_internal(output, input, exp, N);
- return 1;
+ return DCRYPTO_OK;
}
/* c[] += a * b[] */
@@ -795,8 +798,9 @@ int DCRYPTO_bn_div(struct LITE_BIGNUM *quotient,
* if t < 0 then t := t + n
* return t
*/
-int bn_modinv_vartime(struct LITE_BIGNUM *dst, const struct LITE_BIGNUM *src,
- const struct LITE_BIGNUM *mod)
+enum dcrypto_result bn_modinv_vartime(struct LITE_BIGNUM *dst,
+ const struct LITE_BIGNUM *src,
+ const struct LITE_BIGNUM *mod)
{
struct LITE_BIGNUM R;
struct LITE_BIGNUM nR;
@@ -907,7 +911,7 @@ int bn_modinv_vartime(struct LITE_BIGNUM *dst, const struct LITE_BIGNUM *src,
if (r_len != 1 || BN_DIGIT(pR, 0) != 1) {
/* gcd not 1; no direct inverse */
- return 0;
+ return DCRYPTO_FAIL;
}
if (t_neg)
@@ -915,7 +919,7 @@ int bn_modinv_vartime(struct LITE_BIGNUM *dst, const struct LITE_BIGNUM *src,
bn_set_bn(dst, pT, bn_digits(pT));
- return 1;
+ return DCRYPTO_OK;
}
#define PRIME1 3
@@ -1289,7 +1293,7 @@ static void print_primes(uint16_t prime)
#endif
}
-int DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p)
+enum dcrypto_result DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p)
{
size_t i;
size_t j;
@@ -1355,10 +1359,10 @@ int DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p)
/* Make sure prime will work with F4 public exponent. */
if (bn_mod_f4(p) >= 2) {
if (bn_probable_prime(p))
- return 1;
+ return DCRYPTO_OK;
}
}
always_memset(composites_buf, 0, sizeof(composites_buf));
- return 0;
+ return DCRYPTO_FAIL;
}
diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h
index bd87c1efe9..c162b1c66c 100644
--- a/board/cr50/dcrypto/dcrypto.h
+++ b/board/cr50/dcrypto/dcrypto.h
@@ -777,38 +777,46 @@ enum padding_mode {
/* RSA support, FIPS PUB 186-4 *
* Calculate r = m ^ e mod N
*/
-int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
- const uint8_t *in, size_t in_len,
- enum padding_mode padding, enum hashing_mode hashing,
- const char *label);
+enum dcrypto_result DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out,
+ size_t *out_len, const uint8_t *in,
+ size_t in_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing,
+ const char *label);
/* Calculate r = m ^ d mod N
- * return 0 if error
+ * return DCRYPTO_OK if success
*/
-int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
- const uint8_t *in, const size_t in_len,
- enum padding_mode padding, enum hashing_mode hashing,
- const char *label);
+enum dcrypto_result DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out,
+ size_t *out_len, const uint8_t *in,
+ const size_t in_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing,
+ const char *label);
/* Calculate r = m ^ d mod N
- * return 0 if error
+ * return DCRYPTO_OK if success
*/
-int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, size_t *out_len,
- const uint8_t *in, const size_t in_len,
- enum padding_mode padding, enum hashing_mode hashing);
+enum dcrypto_result DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out,
+ size_t *out_len, const uint8_t *in,
+ const size_t in_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing);
/* Calculate r = m ^ e mod N
- * return 0 if error
+ * return DCRYPTO_OK if success
*/
-int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
- size_t digest_len, const uint8_t *sig,
- const size_t sig_len, enum padding_mode padding,
- enum hashing_mode hashing);
+enum dcrypto_result DCRYPTO_rsa_verify(const struct RSA *rsa,
+ const uint8_t *digest, size_t digest_len,
+ const uint8_t *sig, const size_t sig_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing);
/* Calculate n = p * q, d = e ^ -1 mod phi. */
-int DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N, struct LITE_BIGNUM *d,
- struct LITE_BIGNUM *p, struct LITE_BIGNUM *q,
- uint32_t e);
+enum dcrypto_result DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N,
+ struct LITE_BIGNUM *d,
+ struct LITE_BIGNUM *p,
+ struct LITE_BIGNUM *q, uint32_t e);
/*
* EC.
@@ -990,9 +998,9 @@ int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len, const uint8_t *salt,
*/
/* Apply Miller-Rabin test for prime candidate p.
- * Returns 1 if test passed, 0 otherwise
+ * Returns DCRYPTO_OK if test passed, DCRYPTO_FAIL otherwise
*/
-int DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p);
+enum dcrypto_result DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p);
void DCRYPTO_bn_wrap(struct LITE_BIGNUM *b, void *buf, size_t len);
void DCRYPTO_bn_mul(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a,
const struct LITE_BIGNUM *b);
@@ -1029,7 +1037,7 @@ size_t DCRYPTO_asn1_pubp(uint8_t *buf, const p256_int *x, const p256_int *y);
* Accepts only certs with OID: sha256WithRSAEncryption:
* 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00
*/
-int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
+enum dcrypto_result DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
const struct RSA *ca_pub_key);
/* Generate U2F Certificate and sign it
diff --git a/board/cr50/dcrypto/dcrypto_bn.c b/board/cr50/dcrypto/dcrypto_bn.c
index 009f92332e..9679b8b238 100644
--- a/board/cr50/dcrypto/dcrypto_bn.c
+++ b/board/cr50/dcrypto/dcrypto_bn.c
@@ -1280,7 +1280,7 @@ static int modexp(struct DMEM_ctx *ctx, uint32_t adr, uint32_t rr, uint32_t pIn,
}
/* output = input ** exp % N. */
-int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
+enum dcrypto_result dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N, uint32_t pubexp)
@@ -1304,7 +1304,7 @@ int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
* We cannot tolerate risk of 0 since 0 breaks computation.
*/
if (!rand64(r_buf))
- return 0;
+ return DCRYPTO_FAIL;
/*
* compute 1/r mod N
@@ -1320,7 +1320,7 @@ int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
/* Pick !0 64-bit random for exponent blinding */
if (!rand64(ctx->rnd))
- return 0;
+ return DCRYPTO_FAIL;
result = setup_and_lock(N, input);
@@ -1353,12 +1353,14 @@ int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
memcpy(output->d, ctx->out, bn_size(output));
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
/* output = input ** exp % N. */
-int dcrypto_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp, const struct LITE_BIGNUM *N)
+enum dcrypto_result dcrypto_modexp(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N)
{
int result;
size_t i;
@@ -1386,11 +1388,11 @@ int dcrypto_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
memcpy(output->d, ctx->out, bn_size(output));
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
/* output = input ** exp % N. */
-int dcrypto_modexp_word(struct LITE_BIGNUM *output,
+enum dcrypto_result dcrypto_modexp_word(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input, uint32_t exp,
const struct LITE_BIGNUM *N)
{
@@ -1429,7 +1431,7 @@ int dcrypto_modexp_word(struct LITE_BIGNUM *output,
memcpy(output->d, ctx->out, bn_size(output));
dcrypto_unlock();
- return result == 0;
+ return dcrypto_ok_if_zero(result);
}
#ifndef CRYPTO_TEST_CMD_GENP
@@ -1457,8 +1459,9 @@ static int genp_core(void)
DCRYPTO_bn_wrap(&prime, &prime_buf, sizeof(prime_buf));
genp_start = get_time();
- result = (DCRYPTO_bn_generate_prime(&prime) != 0) ? EC_SUCCESS
- : EC_ERROR_UNKNOWN;
+ result = (DCRYPTO_bn_generate_prime(&prime) == DCRYPTO_OK) ?
+ EC_SUCCESS :
+ EC_ERROR_UNKNOWN;
genp_end = get_time();
return result;
diff --git a/board/cr50/dcrypto/fips.c b/board/cr50/dcrypto/fips.c
index 7e70146522..5e9422d2c3 100644
--- a/board/cr50/dcrypto/fips.c
+++ b/board/cr50/dcrypto/fips.c
@@ -605,20 +605,17 @@ static bool fips_rsa2048_verify_kat(void)
.d = (struct access_helper *)pub }
};
- int passed;
-
SHA256_hw_hash(msg, sizeof(msg), &digest);
- passed = DCRYPTO_rsa_verify(&rsa, digest.b8, sizeof(digest), sig,
- sizeof(sig), PADDING_MODE_PKCS1,
- HASH_SHA256);
- if (!passed)
+ if (DCRYPTO_rsa_verify(&rsa, digest.b8, sizeof(digest), sig,
+ sizeof(sig), PADDING_MODE_PKCS1,
+ HASH_SHA256) != DCRYPTO_OK)
return false;
SHA256_hw_hash(bad_msg, sizeof(bad_msg), &digest);
/* now signature should fail */
- return !DCRYPTO_rsa_verify(&rsa, digest.b8, sizeof(digest), sig,
+ return DCRYPTO_rsa_verify(&rsa, digest.b8, sizeof(digest), sig,
sizeof(sig), PADDING_MODE_PKCS1,
- HASH_SHA256);
+ HASH_SHA256) == DCRYPTO_OK;
}
#endif
diff --git a/board/cr50/dcrypto/internal.h b/board/cr50/dcrypto/internal.h
index 696ad2de9d..fc3a0a5d30 100644
--- a/board/cr50/dcrypto/internal.h
+++ b/board/cr50/dcrypto/internal.h
@@ -207,41 +207,42 @@ void bn_init(struct LITE_BIGNUM *bn, void *buf, size_t len);
int bn_eq(const struct LITE_BIGNUM *a, const struct LITE_BIGNUM *b);
int bn_check_topbit(const struct LITE_BIGNUM *N);
-int bn_modexp(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp,
- const struct LITE_BIGNUM *N);
-int bn_modexp_word(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- uint32_t pubexp,
- const struct LITE_BIGNUM *N);
-int bn_modexp_blinded(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp,
- const struct LITE_BIGNUM *N,
- uint32_t pubexp);
+enum dcrypto_result bn_modexp(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N);
+enum dcrypto_result bn_modexp_word(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ uint32_t pubexp,
+ const struct LITE_BIGNUM *N);
+enum dcrypto_result bn_modexp_blinded(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N,
+ uint32_t pubexp);
uint32_t bn_add(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a);
int32_t bn_sub(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a);
-int bn_modinv_vartime(struct LITE_BIGNUM *r, const struct LITE_BIGNUM *e,
- const struct LITE_BIGNUM *MOD);
+enum dcrypto_result bn_modinv_vartime(struct LITE_BIGNUM *r,
+ const struct LITE_BIGNUM *e,
+ const struct LITE_BIGNUM *MOD);
int bn_is_bit_set(const struct LITE_BIGNUM *a, size_t n);
/*
* Accelerated bn.
*/
-int dcrypto_modexp(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp,
- const struct LITE_BIGNUM *N);
-int dcrypto_modexp_word(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- uint32_t pubexp,
- const struct LITE_BIGNUM *N);
-int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp,
- const struct LITE_BIGNUM *N,
- uint32_t pubexp);
+enum dcrypto_result dcrypto_modexp(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N);
+enum dcrypto_result dcrypto_modexp_word(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ uint32_t pubexp,
+ const struct LITE_BIGNUM *N);
+enum dcrypto_result dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N,
+ uint32_t pubexp);
/**
* NIST SP 800-90A HMAC_DRBG_SHA2-256.
diff --git a/board/cr50/dcrypto/rsa.c b/board/cr50/dcrypto/rsa.c
index 3a9a7b10be..d0259ebaf1 100644
--- a/board/cr50/dcrypto/rsa.c
+++ b/board/cr50/dcrypto/rsa.c
@@ -530,10 +530,12 @@ static enum dcrypto_result check_modulus_params(const struct RSA *rsa,
return DCRYPTO_OK;
}
-int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
- const uint8_t *in, size_t in_len,
- enum padding_mode padding, enum hashing_mode hashing,
- const char *label)
+enum dcrypto_result DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out,
+ size_t *out_len, const uint8_t *in,
+ size_t in_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing,
+ const char *label)
{
uint8_t *p;
size_t n_len;
@@ -541,10 +543,14 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
struct LITE_BIGNUM padded;
struct LITE_BIGNUM encrypted;
- int ret;
+ enum dcrypto_result ret;
- if (check_modulus_params(rsa, out_len) != DCRYPTO_OK)
- return 0;
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ ret = check_modulus_params(rsa, out_len);
+ if (ret != DCRYPTO_OK)
+ return ret;
n_len = bn_size(&rsa->N);
padded_buf = alloca(n_len);
@@ -554,22 +560,20 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
switch (padding) {
case PADDING_MODE_OAEP:
- if (oaep_pad((uint8_t *)padded.d, bn_size(&padded),
+ ret = oaep_pad((uint8_t *)padded.d, bn_size(&padded),
(const uint8_t *)in, in_len, hashing,
- label) != DCRYPTO_OK)
- return 0;
+ label);
break;
case PADDING_MODE_PKCS1:
- if (pkcs1_type2_pad((uint8_t *)padded.d, bn_size(&padded),
- (const uint8_t *)in, in_len) != DCRYPTO_OK)
- return 0;
+ ret = pkcs1_type2_pad((uint8_t *)padded.d, bn_size(&padded),
+ (const uint8_t *)in, in_len);
break;
case PADDING_MODE_NULL:
/* Input is allowed to have more bytes than N, in
* which case the excess must be zero. */
for (; in_len > bn_size(&padded); in_len--)
if (*in++ != 0)
- return 0;
+ return DCRYPTO_FAIL;
p = (uint8_t *) padded.d;
/* If in_len < bn_size(&padded), padded will
* have leading zero bytes. */
@@ -578,9 +582,12 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
* handle this case. */
break;
default:
- return 0; /* Unsupported padding mode. */
+ /* Unsupported padding mode. */
+ ret = DCRYPTO_FAIL;
+ break;
}
-
+ if (ret != DCRYPTO_OK)
+ return ret;
/* Reverse from big-endian to little-endian notation. */
reverse((uint8_t *) padded.d, bn_size(&padded));
ret = bn_modexp_word(&encrypted, &padded, rsa->e, &rsa->N);
@@ -592,21 +599,27 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
return ret;
}
-int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
- const uint8_t *in, const size_t in_len,
- enum padding_mode padding, enum hashing_mode hashing,
- const char *label)
+enum dcrypto_result DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out,
+ size_t *out_len, const uint8_t *in,
+ const size_t in_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing,
+ const char *label)
{
uint8_t *buf = NULL;
struct LITE_BIGNUM encrypted;
struct LITE_BIGNUM padded;
- int ret;
+ enum dcrypto_result ret;
- if (check_modulus_params(rsa, NULL) != DCRYPTO_OK)
- return 0;
- if (in_len != bn_size(&rsa->N))
- return 0; /* Invalid input length. */
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ ret = check_modulus_params(rsa, NULL);
+ if (ret != DCRYPTO_OK)
+ return ret;
+ if (in_len != bn_size(&rsa->N)) /* Invalid input length. */
+ return DCRYPTO_FAIL;
buf = alloca(in_len * 2);
/* TODO: this copy can be eliminated if input may be modified. */
bn_init(&encrypted, buf, in_len);
@@ -621,20 +634,18 @@ int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
switch (padding) {
case PADDING_MODE_OAEP:
- if (check_oaep_pad(out, out_len, (uint8_t *)padded.d,
+ ret |= check_oaep_pad(out, out_len, (uint8_t *)padded.d,
bn_size(&padded), hashing,
- label) != DCRYPTO_OK)
- ret = 0;
+ label);
break;
case PADDING_MODE_PKCS1:
- if (check_pkcs1_type2_pad(out, out_len,
+ ret |= check_pkcs1_type2_pad(out, out_len,
(const uint8_t *)padded.d,
- bn_size(&padded)) != DCRYPTO_OK)
- ret = 0;
+ bn_size(&padded));
break;
case PADDING_MODE_NULL:
if (*out_len < bn_size(&padded)) {
- ret = 0;
+ ret = DCRYPTO_FAIL;
} else {
*out_len = bn_size(&padded);
memcpy(out, padded.d, *out_len);
@@ -642,27 +653,34 @@ int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
break;
default:
/* Unsupported padding mode. */
- ret = 0;
+ ret = DCRYPTO_FAIL;
break;
}
-
+ if (ret != DCRYPTO_OK)
+ ret = DCRYPTO_FAIL;
always_memset(buf, 0, in_len * 2);
return ret;
}
-int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, size_t *out_len,
- const uint8_t *in, const size_t in_len,
- enum padding_mode padding, enum hashing_mode hashing)
+enum dcrypto_result DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out,
+ size_t *out_len, const uint8_t *in,
+ const size_t in_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing)
{
uint8_t *padded_buf;
size_t n_len;
struct LITE_BIGNUM padded;
struct LITE_BIGNUM signature;
- int ret;
+ enum dcrypto_result ret;
+
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
- if (check_modulus_params(rsa, out_len) != DCRYPTO_OK)
- return 0;
+ ret = check_modulus_params(rsa, out_len);
+ if (ret != DCRYPTO_OK)
+ return ret;
n_len = bn_size(&rsa->N);
padded_buf = alloca(n_len);
@@ -671,20 +689,20 @@ int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, size_t *out_len,
switch (padding) {
case PADDING_MODE_PKCS1:
- if (pkcs1_type1_pad((uint8_t *)padded.d, bn_size(&padded),
+ ret = pkcs1_type1_pad((uint8_t *)padded.d, bn_size(&padded),
(const uint8_t *)in, in_len,
- hashing) != DCRYPTO_OK)
- return 0;
+ hashing);
break;
case PADDING_MODE_PSS:
- if (pkcs1_pss_pad((uint8_t *)padded.d, bn_size(&padded),
+ ret = pkcs1_pss_pad((uint8_t *)padded.d, bn_size(&padded),
(const uint8_t *)in, in_len,
- hashing) != DCRYPTO_OK)
- return 0;
+ hashing);
break;
default:
- return 0;
+ ret = DCRYPTO_FAIL;
}
+ if (ret != DCRYPTO_OK)
+ return ret;
/* Reverse from big-endian to little-endian notation. */
reverse((uint8_t *) padded.d, bn_size(&padded));
@@ -697,21 +715,26 @@ int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, size_t *out_len,
return ret;
}
-int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
- size_t digest_len, const uint8_t *sig,
- const size_t sig_len, enum padding_mode padding,
- enum hashing_mode hashing)
+enum dcrypto_result DCRYPTO_rsa_verify(const struct RSA *rsa,
+ const uint8_t *digest, size_t digest_len,
+ const uint8_t *sig, const size_t sig_len,
+ enum padding_mode padding,
+ enum hashing_mode hashing)
{
uint8_t *buf;
struct LITE_BIGNUM padded;
struct LITE_BIGNUM signature;
- int ret;
+ enum dcrypto_result ret;
- if (check_modulus_params(rsa, NULL) != DCRYPTO_OK)
- return 0;
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ ret = check_modulus_params(rsa, NULL);
+ if (ret != DCRYPTO_OK)
+ return ret;
if (sig_len != bn_size(&rsa->N))
- return 0; /* Invalid input length. */
+ return DCRYPTO_FAIL; /* Invalid input length. */
buf = alloca(sig_len * 2);
bn_init(&signature, buf, sig_len);
@@ -719,27 +742,25 @@ int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
bn_init(&padded, buf + sig_len, sig_len);
/* Reverse from big-endian to little-endian notation. */
- reverse((uint8_t *) signature.d, bn_size(&signature));
+ reverse((uint8_t *)signature.d, bn_size(&signature));
ret = bn_modexp_word(&padded, &signature, rsa->e, &rsa->N);
/* Back to big-endian notation. */
- reverse((uint8_t *) padded.d, bn_size(&padded));
+ reverse((uint8_t *)padded.d, bn_size(&padded));
switch (padding) {
case PADDING_MODE_PKCS1:
- if (check_pkcs1_type1_pad(digest, digest_len,
- (uint8_t *)padded.d, bn_size(&padded),
- hashing) != DCRYPTO_OK)
- ret = 0;
+ ret = check_pkcs1_type1_pad(digest, digest_len,
+ (uint8_t *)padded.d,
+ bn_size(&padded), hashing);
break;
case PADDING_MODE_PSS:
- if (check_pkcs1_pss_pad(digest, digest_len, (uint8_t *)padded.d,
- bn_size(&padded),
- hashing) != DCRYPTO_OK)
- ret = 0;
+ ret = check_pkcs1_pss_pad(digest, digest_len,
+ (uint8_t *)padded.d, bn_size(&padded),
+ hashing);
break;
default:
/* Unsupported padding mode. */
- ret = 0;
+ ret = DCRYPTO_FAIL;
break;
}
@@ -747,9 +768,11 @@ int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
return ret;
}
-int DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N, struct LITE_BIGNUM *d,
- struct LITE_BIGNUM *p, struct LITE_BIGNUM *q,
- uint32_t e_buf)
+enum dcrypto_result DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N,
+ struct LITE_BIGNUM *d,
+ struct LITE_BIGNUM *p,
+ struct LITE_BIGNUM *q,
+ uint32_t e_buf)
{
uint32_t ONE_buf = 1;
uint8_t *buf;
@@ -759,11 +782,14 @@ int DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N, struct LITE_BIGNUM *d,
struct LITE_BIGNUM phi;
struct LITE_BIGNUM q_local;
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
n_len = bn_size(N);
p_len = bn_size(p);
if (n_len > RSA_BYTES_4K || p_len > RSA_BYTES_2K || !(e_buf & 1))
- return 0;
+ return DCRYPTO_FAIL;
buf = alloca(n_len + p_len);
DCRYPTO_bn_wrap(&ONE, &ONE_buf, sizeof(ONE_buf));
@@ -774,12 +800,12 @@ int DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N, struct LITE_BIGNUM *d,
q = &q_local;
if (!DCRYPTO_bn_div(q, NULL, N, p))
- return 0;
+ return DCRYPTO_FAIL;
/* Check that p * q == N */
DCRYPTO_bn_mul(&phi, p, q);
if (!bn_eq(N, &phi))
- return 0;
+ return DCRYPTO_FAIL;
} else {
DCRYPTO_bn_mul(N, p, q);
memcpy(phi.d, N->d, n_len);
diff --git a/board/cr50/dcrypto/x509.c b/board/cr50/dcrypto/x509.c
index a4bcdf2630..2094f8dad4 100644
--- a/board/cr50/dcrypto/x509.c
+++ b/board/cr50/dcrypto/x509.c
@@ -355,8 +355,8 @@ static size_t asn1_parse_signature_value(const uint8_t **p, size_t *available,
* where signatureValue = SIGN(HASH(tbsCertificate)), with SIGN and
* HASH specified by signatureAlgorithm.
*/
-int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
- const struct RSA *ca_pub_key)
+enum dcrypto_result DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
+ const struct RSA *ca_pub_key)
{
const uint8_t *p = cert;
const uint8_t *tbs;
@@ -366,32 +366,35 @@ int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
struct sha256_digest digest;
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
/* Read Certificate SEQUENCE. */
if (!asn1_parse_certificate(&p, &len))
- return 0;
+ return DCRYPTO_FAIL;
/* Read tbsCertificate SEQUENCE. */
tbs = p;
if (!asn1_parse_tbs(&p, &len, &tbs_len))
- return 0;
+ return DCRYPTO_FAIL;
/* Read signatureAlgorithm SEQUENCE. */
if (!asn1_parse_signature_algorithm(&p, &len))
- return 0;
+ return DCRYPTO_FAIL;
/* Read signatureValue BIT STRING. */
if (!asn1_parse_signature_value(&p, &len, &sig, &sig_len))
- return 0;
+ return DCRYPTO_FAIL;
/* Check that the signature length corresponds to the issuer's
* public key size. */
if (sig_len != bn_size(&ca_pub_key->N) &&
sig_len != bn_size(&ca_pub_key->N) + 1)
- return 0;
+ return DCRYPTO_FAIL;
/* Check that leading signature bytes (if any) are zero. */
if (sig_len == bn_size(&ca_pub_key->N) + 1) {
if (sig[0] != 0)
- return 0;
+ return DCRYPTO_FAIL;
sig++;
sig_len--;
}
diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c
index b4d2b91775..fe4434bbec 100644
--- a/board/cr50/tpm2/endorsement.c
+++ b/board/cr50/tpm2/endorsement.c
@@ -364,10 +364,12 @@ static int validate_cert(
* certificates serve as roots for the installed endorsement
* certificate.
*/
- return DCRYPTO_x509_verify(cert->cert, cert->cert_len,
- &PROD_ENDORSEMENT_CA_RSA_PUB) ||
- DCRYPTO_x509_verify(cert->cert, cert->cert_len,
- &TEST_ENDORSEMENT_CA_RSA_PUB);
+ return (DCRYPTO_x509_verify(cert->cert, cert->cert_len,
+ &PROD_ENDORSEMENT_CA_RSA_PUB) ==
+ DCRYPTO_OK) ||
+ (DCRYPTO_x509_verify(cert->cert, cert->cert_len,
+ &TEST_ENDORSEMENT_CA_RSA_PUB) ==
+ DCRYPTO_OK);
}
static int store_cert(enum cros_perso_component_type component_type,
diff --git a/board/cr50/tpm2/rsa.c b/board/cr50/tpm2/rsa.c
index 97797d440a..9fc7f3b085 100644
--- a/board/cr50/tpm2/rsa.c
+++ b/board/cr50/tpm2/rsa.c
@@ -94,7 +94,7 @@ CRYPT_RESULT _cpri__EncryptRSA(uint32_t *out_len, uint8_t *out,
struct RSA rsa;
enum padding_mode padding;
enum hashing_mode hashing;
- int result;
+ enum dcrypto_result result;
if (!check_key(key))
return CRYPT_FAIL;
@@ -113,7 +113,7 @@ CRYPT_RESULT _cpri__EncryptRSA(uint32_t *out_len, uint8_t *out,
reverse_tpm2b(key->publicKey);
- if (result)
+ if (result == DCRYPTO_OK)
return CRYPT_SUCCESS;
else
return CRYPT_FAIL;
@@ -127,7 +127,7 @@ CRYPT_RESULT _cpri__DecryptRSA(uint32_t *out_len, uint8_t *out,
struct RSA rsa;
enum padding_mode padding;
enum hashing_mode hashing;
- int result;
+ enum dcrypto_result result;
if (!check_key(key))
return CRYPT_FAIL;
@@ -149,7 +149,7 @@ CRYPT_RESULT _cpri__DecryptRSA(uint32_t *out_len, uint8_t *out,
reverse_tpm2b(key->publicKey);
reverse_tpm2b(key->privateKey);
- if (result)
+ if (result == DCRYPTO_OK)
return CRYPT_SUCCESS;
else
return CRYPT_FAIL;
@@ -162,7 +162,7 @@ CRYPT_RESULT _cpri__SignRSA(uint32_t *out_len, uint8_t *out,
struct RSA rsa;
enum padding_mode padding;
enum hashing_mode hashing;
- int result;
+ enum dcrypto_result result;
if (!check_key(key))
return CRYPT_FAIL;
@@ -186,7 +186,7 @@ CRYPT_RESULT _cpri__SignRSA(uint32_t *out_len, uint8_t *out,
reverse_tpm2b(key->publicKey);
reverse_tpm2b(key->privateKey);
- if (result)
+ if (result == DCRYPTO_OK)
return CRYPT_SUCCESS;
else
return CRYPT_FAIL;
@@ -200,7 +200,7 @@ CRYPT_RESULT _cpri__ValidateSignatureRSA(
struct RSA rsa;
enum padding_mode padding;
enum hashing_mode hashing;
- int result;
+ enum dcrypto_result result;
if (!check_key(key))
return CRYPT_FAIL;
@@ -220,7 +220,7 @@ CRYPT_RESULT _cpri__ValidateSignatureRSA(
reverse_tpm2b(key->publicKey);
- if (result)
+ if (result == DCRYPTO_OK)
return CRYPT_SUCCESS;
else
return CRYPT_FAIL;
@@ -233,7 +233,7 @@ CRYPT_RESULT _cpri__TestKeyRSA(TPM2B *d_buf, uint32_t e,
struct LITE_BIGNUM p;
struct LITE_BIGNUM q;
struct LITE_BIGNUM d;
- int result;
+ enum dcrypto_result result;
if (!p_buf)
return CRYPT_PARAMETER;
@@ -262,7 +262,7 @@ CRYPT_RESULT _cpri__TestKeyRSA(TPM2B *d_buf, uint32_t e,
if (q_buf)
reverse_tpm2b(q_buf);
- if (result) {
+ if (result == DCRYPTO_OK) {
d_buf->size = N_buf->size;
reverse_tpm2b(d_buf);
return CRYPT_SUCCESS;
@@ -290,7 +290,7 @@ static int generate_prime(struct LITE_BIGNUM *b, TPM_ALG_ID hashing,
bn_bits(b), (uint8_t *) b->d, NULL, FALSE);
(*counter)++; /* Mark as used. */
- if (DCRYPTO_bn_generate_prime(b))
+ if (DCRYPTO_bn_generate_prime(b) == DCRYPTO_OK)
return 1;
}
@@ -1132,7 +1132,7 @@ static void rsa_command_handler(void *cmd_body,
}
DCRYPTO_bn_wrap(&bn, bn_buf, in_len);
memcpy(bn_buf, in, in_len);
- if (DCRYPTO_bn_generate_prime(&bn)) {
+ if (DCRYPTO_bn_generate_prime(&bn) == DCRYPTO_OK) {
memcpy(out, bn.d, bn_size(&bn));
*response_size = bn_size(&bn);
} else {
@@ -1160,7 +1160,7 @@ static void rsa_command_handler(void *cmd_body,
sizeof(RSA_2048_CERT), &rsa);
reverse_tpm2b(key.publicKey);
- if (!result) {
+ if (result != DCRYPTO_OK) {
*response_size = 0;
return;
}
diff --git a/common/ap_ro_integrity_check.c b/common/ap_ro_integrity_check.c
index 203bd967c0..8465983eea 100644
--- a/common/ap_ro_integrity_check.c
+++ b/common/ap_ro_integrity_check.c
@@ -450,8 +450,9 @@ static int verify_signature(struct memory_block *blocks,
digest = HASH_final(&ctx);
- return !DCRYPTO_rsa_verify(&pubk->rsa, digest, digest_size, sig_body,
- sig_size, PADDING_MODE_PKCS1, pubk->hashing);
+ return DCRYPTO_rsa_verify(&pubk->rsa, digest, digest_size, sig_body,
+ sig_size, PADDING_MODE_PKCS1, pubk->hashing) -
+ DCRYPTO_OK;
}
/**