summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagendra modadugu <ngm@google.com>2016-09-15 20:27:22 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-09-16 17:43:28 -0700
commit7f507212c1a3aa56a42d41f2d5b6be053903ea0d (patch)
treea11b1ba1295c9afed4329e3efbe4234c021fa59b
parentb7cc2a20ff139c843cbb666819750e4f484c483a (diff)
downloadchrome-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.c60
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)