diff options
author | nagendra modadugu <ngm@google.com> | 2016-09-15 20:27:22 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-09-16 17:43:28 -0700 |
commit | 7f507212c1a3aa56a42d41f2d5b6be053903ea0d (patch) | |
tree | a11b1ba1295c9afed4329e3efbe4234c021fa59b | |
parent | b7cc2a20ff139c843cbb666819750e4f484c483a (diff) | |
download | chrome-ec-7f507212c1a3aa56a42d41f2d5b6be053903ea0d.tar.gz |
CR50: use vendor template for RSA endorsement primary keygen
When generating the RSA endorsement primary key, use the
CR50 vendor specific template. Doing so generates the
RSA key corresponding to the certificate issued at manufacture.
Also, always start the RSA key generation counter at 1. Doing
so matches the certificate generation process at manufacture;
and there is no harm in always starting at 1, since the key
generation process remains deterministic.
BUG=none
BRANCH=none
TESTED=generated key matches endorsement cert;
checked via attestation_client
Change-Id: I6a5c329e99292e32f880c0c5ea364d511cb6ea82
Signed-off-by: nagendra modadugu <ngm@google.com>
Reviewed-on: https://chromium-review.googlesource.com/386279
Commit-Ready: Nagendra Modadugu <ngm@google.com>
Tested-by: Nagendra Modadugu <ngm@google.com>
Tested-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | board/cr50/tpm2/rsa.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/board/cr50/tpm2/rsa.c b/board/cr50/tpm2/rsa.c index f01024fd7e..290ad9cfe5 100644 --- a/board/cr50/tpm2/rsa.c +++ b/board/cr50/tpm2/rsa.c @@ -4,6 +4,8 @@ */ #include "CryptoEngine.h" +#include "Global.h" +#include "Hierarchy_fp.h" #include "dcrypto.h" #include "trng.h" @@ -292,6 +294,33 @@ static const uint8_t VERIFY_SEED[32] = { }; #endif +/* The array below represents the output of ObjectComputeName() when + * applied to the TPMT_PUBLIC RSA template described in the TPM 2.0 + * EK Credential Profile specification: https://goo.gl/rbE6q7 + */ +static const uint8_t TPM2_RSA_EK_NAME_TEMPLATE[] = { + /* TPM_ALG_SHA256 in big endian. */ + 0x00, 0x0b, + /* SHA256 digest of the default template TPMT_PUBLIC. */ + 0x32, 0x50, 0x39, 0x29, 0xa1, 0x28, 0x7e, 0xed, + 0xaa, 0x3e, 0x89, 0xd9, 0x32, 0xf9, 0xb5, 0x1a, + 0x6f, 0x92, 0xab, 0xd0, 0xfa, 0x57, 0x72, 0x1f, + 0xfa, 0x6f, 0xc0, 0x41, 0xe0, 0x4f, 0x74, 0x98 +}; +BUILD_ASSERT(sizeof(TPM2_RSA_EK_NAME_TEMPLATE) == 2 + SHA256_DIGEST_SIZE); + +/* The array below represents the 'name' (corresponding to the + * parameter extra) used by the CR50 certificate authority when + * generating the endorsement certificate. + */ +static const uint8_t TPM2_RSA_EK_NAME_CR50[] = { + 0x68, 0xd1, 0xa2, 0x41, 0xfb, 0x27, 0x2f, 0x03, + 0x90, 0xbf, 0xd0, 0x42, 0x8d, 0xad, 0xee, 0xb0, + 0x2b, 0xf4, 0xa1, 0xcd, 0x46, 0xab, 0x6c, 0x39, + 0x1b, 0xa3, 0x1f, 0x51, 0x87, 0x06, 0x8e, 0x6a +}; +BUILD_ASSERT(sizeof(TPM2_RSA_EK_NAME_CR50) == SHA256_DIGEST_SIZE); + CRYPT_RESULT _cpri__GenerateKeyRSA( TPM2B *N_buf, TPM2B *p_buf, uint16_t num_bits, uint32_t e_buf, TPM_ALG_ID hashing, TPM2B *seed, @@ -314,8 +343,12 @@ CRYPT_RESULT _cpri__GenerateKeyRSA( struct LITE_BIGNUM q; struct LITE_BIGNUM N; - uint32_t counter; + uint32_t counter = 0; TPM2B_32_BYTE_VALUE local_seed = { .t = {32} }; + TPM2B_32_BYTE_VALUE local_extra = { .t = {32} }; + + const TPM2B_SEED *endorsement_seed = HierarchyGetPrimarySeed( + TPM_RH_ENDORSEMENT); if (num_bits & 0xF) return CRYPT_FAIL; @@ -325,6 +358,19 @@ CRYPT_RESULT _cpri__GenerateKeyRSA( if (seed == NULL || seed->size * 8 < 2 * security_strength) return CRYPT_FAIL; + /* When generating the endorsement primary key (based on the + * TPM 2.0 standard template, swap in the vendor specific + * template instead. + */ + if (extra->size == sizeof(TPM2_RSA_EK_NAME_TEMPLATE) && + memcmp(extra->buffer, TPM2_RSA_EK_NAME_TEMPLATE, + sizeof(TPM2_RSA_EK_NAME_TEMPLATE)) == 0 && + seed == &endorsement_seed->b) { + memcpy(local_extra.b.buffer, TPM2_RSA_EK_NAME_CR50, + sizeof(TPM2_RSA_EK_NAME_CR50)); + extra = &local_extra.b; + } + /* Hash down the primary seed for RSA key generation, so that * the derivation tree is distinct from ECC key derivation. */ @@ -353,10 +399,18 @@ CRYPT_RESULT _cpri__GenerateKeyRSA( if (label == NULL) label = label_p; + + /* The manufacture process uses a counter of 1, whereas the + * TPM2.0 library (CryptGenerateKeyRSA) passes in a counter + * value of 0. Having that the counter always start at least + * at 1 ensures that endorsement keys are correctly generated. + * For non-endorsement keys, the counter value used is + * immaterial, as the generation process remains deterministic. + */ if (counter_in != NULL) counter = *counter_in; - else - counter = 1; + counter++; + if (!generate_prime(&p, hashing, &local_seed.b, label, extra, &counter)) { if (counter_in != NULL) |