From 00811382b0dc2e92ba5bac70b8d4b20f67cba697 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 23 Jan 2025 16:02:28 -0800 Subject: [PATCH] EK Cert Verification with TPM only (no wolfCrypt). Example assumes ST33KTPM2X. `./configure --disable-wolfcrypt && make && ./examples/endorsement/verify_ek_cert` --- .gitignore | 1 + examples/endorsement/README.md | 236 ++++++++++ examples/endorsement/endorsement.h | 1 + examples/endorsement/get_ek_certs.c | 14 +- examples/endorsement/include.am | 12 +- examples/endorsement/trusted_certs.h | 178 +++++++ examples/endorsement/verify_ek_cert.c | 649 ++++++++++++++++++++++++++ 7 files changed, 1085 insertions(+), 6 deletions(-) create mode 100644 examples/endorsement/verify_ek_cert.c diff --git a/.gitignore b/.gitignore index a65ce026..3f875239 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ examples/boot/secret_unseal examples/firmware/ifx_fw_extract examples/firmware/ifx_fw_update examples/endorsement/get_ek_certs +examples/endorsement/verify_ek_cert # Generated Cert Files certs/ca-*.pem diff --git a/examples/endorsement/README.md b/examples/endorsement/README.md index 5e0856c5..d3467476 100644 --- a/examples/endorsement/README.md +++ b/examples/endorsement/README.md @@ -44,3 +44,239 @@ Example: - STSAFE-TPM RSA intermediate CA 10 (http://sw-center.st.com/STSAFE/stsafetpmrsaint10.crt) - STSAFE ECC root CA 02 (http://sw-center.st.com/STSAFE/STSAFEEccRootCA02.crt) - STSAFE-TPM ECC intermediate CA 10 (http://sw-center.st.com/STSAFE/stsafetpmeccint10.crt) + +Sample Output: + +``` +$ ./examples/endorsement/verify_ek_cert +Endorsement Certificate Verify +TPM2: Caps 0x30000415, Did 0x0004, Vid 0x104a, Rid 0x 1 +TPM2_Startup pass +TPM2_NV_ReadPublic: Sz 14, Idx 0x1c00002, nameAlg 11, Attr 0x62076801, authPol 0, dataSz 1300, name 34 +TPM2_NV_ReadPublic: Sz 14, Idx 0x1c00002, nameAlg 11, Attr 0x62076801, authPol 0, dataSz 1300, name 34 +TPM2_NV_Read: Auth 0x1c00002, Idx 0x1c00002, Offset 0, Size 768 +TPM2_NV_Read: Auth 0x1c00002, Idx 0x1c00002, Offset 768, Size 532 +EK Data: 1300 + 30 82 05 10 30 82 02 f8 a0 03 02 01 02 02 14 58 | 0...0..........X + 63 86 17 74 73 22 ca 34 60 4a f6 cf d9 b4 44 9e | c..ts".4`J....D. + 4b ba 03 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0c | K..0...*.H...... + 05 00 30 59 31 0b 30 09 06 03 55 04 06 13 02 43 | ..0Y1.0...U....C + 48 31 1e 30 1c 06 03 55 04 0a 13 15 53 54 4d 69 | H1.0...U....STMi + 63 72 6f 65 6c 65 63 74 72 6f 6e 69 63 73 20 4e | croelectronics N + 56 31 2a 30 28 06 03 55 04 03 13 21 53 54 53 41 | V1*0(..U...!STSA + 46 45 20 54 50 4d 20 52 53 41 20 49 6e 74 65 72 | FE TPM RSA Inter + 6d 65 64 69 61 74 65 20 43 41 20 32 30 30 20 17 | mediate CA 200 . + 0d 32 33 30 36 30 31 30 39 34 39 33 35 5a 18 0f | .230601094935Z.. + 39 39 39 39 31 32 33 31 32 33 35 39 35 39 5a 30 | 99991231235959Z0 + 00 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 | .0.."0...*.H.... + 01 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82 01 | .........0...... + 01 00 b3 20 db 1a 10 d2 16 8c 5d 92 c0 47 87 b1 | ... ......]..G.. + dc ae af 5b f2 44 15 dd 84 9a 17 3f c6 76 61 29 | ...[.D.....?.va) + c6 c3 4c e5 50 27 a2 26 8b fd e0 9d 34 09 93 0f | ..L.P'.&....4... + 64 6a b0 46 f5 5b 19 1c 14 45 b7 24 d3 a9 a5 7d | dj.F.[...E.$...} + 4c a7 0a ba cc d4 72 a2 18 2e 1a 20 a5 33 6f 5f | L.....r.... .3o_ + f5 21 10 bf db af 74 7f 97 93 46 64 40 16 c2 e9 | .!....t...Fd@... + 8f cc e0 f2 4a 94 29 4e 73 87 6f a4 bb c8 f3 e1 | ....J.)Ns.o..... + 02 35 12 c9 c7 e8 4c f2 59 94 5f d2 5a ca 35 48 | .5....L.Y._.Z.5H + e3 0d 59 90 41 33 10 cd 4b f5 ff a7 0c 4e 94 ce | ..Y.A3..K....N.. + 86 45 fb 89 aa b4 76 10 8e ed 90 1e bf b9 6b 88 | .E....v.......k. + df 5a 1a b7 b5 cb a8 80 ff cf 4d a8 c1 05 b6 15 | .Z........M..... + 49 8d 22 74 29 56 95 56 e5 1d 4f 31 44 da 77 3c | I."t)V.V..O1D.w< + a7 46 a3 e2 d5 ee 18 51 0c 9c 51 52 49 ff d1 ba | .F.....Q..QRI... + 4f cd 33 42 0d 8e e9 c8 da a0 ff 10 02 0d dd e4 | O.3B............ + fa 49 21 98 e9 28 c7 c5 25 ac 7b 90 91 99 fb 99 | .I!..(..%.{..... + 36 63 dc 50 98 fa fd 32 37 c2 08 9c 43 fc 59 d6 | 6c.P...27...C.Y. + 27 5f 02 03 01 00 01 a3 82 01 25 30 82 01 21 30 | '_........%0..!0 + 1f 06 03 55 1d 23 04 18 30 16 80 14 8f e0 78 f8 | ...U.#..0.....x. + ca 88 59 fe fe 3f 7a 98 37 2c fc 02 c6 08 44 49 | ..Y..?z.7,....DI + 30 58 06 03 55 1d 11 01 01 ff 04 4e 30 4c a4 4a | 0X..U......N0L.J + 30 48 31 16 30 14 06 05 67 81 05 02 01 0c 0b 69 | 0H1.0...g......i + 64 3a 35 33 35 34 34 44 32 30 31 16 30 14 06 05 | d:53544D201.0... + 67 81 05 02 02 0c 0b 53 54 33 33 4b 54 50 4d 32 | g......ST33KTPM2 + 41 49 31 16 30 14 06 05 67 81 05 02 03 0c 0b 69 | AI1.0...g......i + 64 3a 30 30 30 41 30 31 30 31 30 22 06 03 55 1d | d:000A01010"..U. + 09 04 1b 30 19 30 17 06 05 67 81 05 02 10 31 0e | ...0.0...g....1. + 30 0c 0c 03 32 2e 30 02 01 00 02 02 00 9f 30 0c | 0...2.0.......0. + 06 03 55 1d 13 01 01 ff 04 02 30 00 30 10 06 03 | ..U.......0.0... + 55 1d 25 04 09 30 07 06 05 67 81 05 08 01 30 0e | U.%..0...g....0. + 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 20 30 50 | ..U.......... 0P + 06 08 2b 06 01 05 05 07 01 01 04 44 30 42 30 40 | ..+........D0B0@ + 06 08 2b 06 01 05 05 07 30 02 86 34 68 74 74 70 | ..+.....0..4http + 3a 2f 2f 73 77 2d 63 65 6e 74 65 72 2e 73 74 2e | ://sw-center.st. + 63 6f 6d 2f 53 54 53 41 46 45 2f 73 74 73 61 66 | com/STSAFE/stsaf + 65 74 70 6d 72 73 61 69 6e 74 32 30 2e 63 72 74 | etpmrsaint20.crt + 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0c 05 00 03 | 0...*.H......... + 82 02 01 00 b5 7a 68 4d aa d5 3a bf a2 6a 6f 1d | .....zhM..:..jo. + 1a 5e 35 74 47 f4 b7 ee a0 63 8e 08 42 8c a3 80 | .^5tG....c..B... + 3a 91 8e 92 1a 22 73 c8 a6 07 61 42 63 5f 4e c7 | :...."s...aBc_N. + 17 dc 5e c2 51 73 13 51 0f 57 17 01 63 9e da b5 | ..^.Qs.Q.W..c... + 4a fd 92 6d 0a 33 8b e4 dc 5f 63 96 7b 89 d3 3a | J..m.3..._c.{..: + 99 29 ac f0 7c 0a 99 ea 9c 40 33 86 4b 55 30 03 | .)..|....@3.KU0. + 24 41 05 f6 48 43 5f b9 39 b4 74 17 2c 71 bf 26 | $A..HC_.9.t.,q.& + f4 a3 7a 9f ae 80 0c 8b 92 c8 22 35 0f f8 64 da | ..z......."5..d. + 50 b1 2f 5f e2 a4 19 32 a6 7e 74 bb 31 74 93 10 | P./_...2.~t.1t.. + 85 a2 5f 10 9f 1d 0c 57 90 d2 56 e4 70 7f 54 99 | .._....W..V.p.T. + 87 c0 bd d7 8f c4 31 eb 9d bc cd ca 35 b2 64 d0 | ......1.....5.d. + ee 6b c8 e1 1b 34 bc 09 3f cd d1 f1 53 c2 18 dd | .k...4..?...S... + 82 85 2e 6c 44 9b 21 df eb 7b 5b 8f 07 f5 61 34 | ...lD.!..{[...a4 + 25 e5 97 ee bd 01 2e 1c 35 53 00 b0 be 92 96 80 | %.......5S...... + 50 9b 6e e0 f3 e3 1d 0c 0a 99 96 cd 42 64 e4 43 | P.n.........Bd.C + 6a 4a de c2 03 19 a2 a7 b6 fa 7d 25 37 04 53 30 | jJ........}%7.S0 + 3a 69 b2 38 6c c9 e9 e3 59 a4 8b 1e ae 62 5d eb | :i.8l...Y....b]. + 3c 85 e3 2f f1 cb 7b 3c 0d 2d bf 6e f0 9c 7c c9 | <../..{<.-.n..|. + c8 84 35 26 21 82 2a 83 f7 54 80 51 73 34 c2 7b | ..5&!.*..T.Qs4.{ + 2b 5d 32 b7 26 a6 8c b2 46 d6 c2 63 5c 38 0c 0b | +]2.&...F..c\8.. + 5e ba 81 ee 0b 55 c6 e7 ab 48 8d 6a e4 c7 ec 45 | ^....U...H.j...E + 0d 46 b9 2e 8e a9 be e1 26 b4 79 b5 56 4c 2a dd | .F......&.y.VL*. + 93 22 01 d5 2c ca bd c0 6a 30 ff 53 8c 08 98 22 | ."..,...j0.S..." + 33 3c 78 a1 59 25 43 cc db e1 26 cc 55 7f bb 4b | 3 - #if !defined(WOLFCRYPT_ONLY) #include "trusted_certs.h" - #endif #endif /******************************************************************************/ @@ -385,6 +383,9 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[]) printf("Endorsement Cert PEM\n"); puts(pem); } + + XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); + pem = NULL; #endif /* WOLFSSL_DER_TO_PEM */ } #endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_ASN */ @@ -395,6 +396,11 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[]) exit: + if (rc != 0) { + printf("Error getting EK certificates! %s (%d)\n", + TPM2_GetRCString(rc), rc); + } + #if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_ASN) #ifdef WOLFSSL_DER_TO_PEM XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/examples/endorsement/include.am b/examples/endorsement/include.am index 1b5e1f94..3e905575 100644 --- a/examples/endorsement/include.am +++ b/examples/endorsement/include.am @@ -10,11 +10,19 @@ if BUILD_EXAMPLES examples_endorsement_get_ek_certs_SOURCES = examples/endorsement/get_ek_certs.c examples_endorsement_get_ek_certs_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) examples_endorsement_get_ek_certs_DEPENDENCIES = src/libwolftpm.la + + noinst_PROGRAMS += examples/endorsement/verify_ek_cert + examples_endorsement_verify_ek_cert_SOURCES = examples/endorsement/verify_ek_cert.c + examples_endorsement_verify_ek_cert_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) + examples_endorsement_verify_ek_cert_DEPENDENCIES = src/libwolftpm.la endif EXTRA_DIST+=examples/endorsement/README.md example_endorsementdir = $(exampledir)/endorsement dist_example_endorsement_DATA = \ - examples/endorsement/get_ek_certs.c + examples/endorsement/get_ek_certs.c \ + examples/endorsement/verify_ek_cert.c -DISTCLEANFILES+= examples/endorsement/.libs/get_ek_certs +DISTCLEANFILES+= \ + examples/endorsement/.libs/get_ek_certs \ + examples/endorsement/.libs/verify_ek_cert diff --git a/examples/endorsement/trusted_certs.h b/examples/endorsement/trusted_certs.h index 004e7367..5aa6740f 100644 --- a/examples/endorsement/trusted_certs.h +++ b/examples/endorsement/trusted_certs.h @@ -13,6 +13,7 @@ * https://github.com/tpm2-software/tpm2-tss/blob/master/src/tss2-fapi/fapi_certificates.h */ +#if !defined(WOLFCRYPT_ONLY) static const char* trusted_certs[] = { /* ---------------------------------------------------------------*/ /* Infineon Technologies AG */ @@ -520,6 +521,48 @@ static const char* trusted_certs[] = { "uKErQfPEhjYLdzF8/OYW7w==\n" "-----END CERTIFICATE-----\n", + /* Subject: CN=STSAFE TPM RSA Intermediate CA 20 + * Issuer: CN=STSAFE RSA Root CA 02 + * RSA 4096-bit, SHA2-384 + * Validity: Jan 1 00:00:00 2043 GMT */ + "-----BEGIN CERTIFICATE-----\n" + "MIIGbDCCBFSgAwIBAgIEQAAAIDANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQGEwJD\n" + "SDEeMBwGA1UEChMVU1RNaWNyb2VsZWN0cm9uaWNzIE5WMR4wHAYDVQQDExVTVFNB\n" + "RkUgUlNBIFJvb3QgQ0EgMDIwHhcNMjIwMTIwMDAwMDAwWhcNNDMwMTAxMDAwMDAw\n" + "WjBZMQswCQYDVQQGEwJDSDEeMBwGA1UEChMVU1RNaWNyb2VsZWN0cm9uaWNzIE5W\n" + "MSowKAYDVQQDEyFTVFNBRkUgVFBNIFJTQSBJbnRlcm1lZGlhdGUgQ0EgMjAwggIi\n" + "MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDFXrmhNYt21t/tk6VmnRGT/UZC\n" + "/Uj3M2qW42RsKnS6Up5xSMbKQuEGoMe8xA1uSO0cX9yqRMH0XLOsIoWtX7Cw2fSO\n" + "UT4FcEGsz1z4DymqlFsko785M+kau1HeIrJSposnwaqS4TiAQK75BNDM1Ttyf9Vp\n" + "vJuAVf/CSoc+tXRVx4MEntns7vvHIdZRtMikbwNXPYyu/N/ZbKSAToMtlkBv4r9F\n" + "pQoywdbeaTVTJDfkeowvlraKjHQU61oFSv4jA9nOr57ELiO04v/kdhvOTWtUr7/8\n" + "wk4kbyTmvDRhyxUKzotbIgr9PyaTY7Sls0NqGiAUR9LZ/WVZrhMNYTw4uy5ZC/BJ\n" + "khLbnXMJQlQVDJfXFKS7Ol7of9ncdj3KNndSEljp0f8G5toFapx/pgVLLkhiJrAt\n" + "XKZ9yUkYy3YkTXpiBLS07kgkwBG6ePDK8PKXhBUKmd4KVhMwpvV2xsiVSkSUsf54\n" + "HlV+/EwuTzx6801prpVgUaBODOvjYkoMp2cQp6vnRObUljKgyAlFIC/MBBDBUzFf\n" + "5/vgNsgdCLTRogGhf2yUp4HpwccZDTC8T6Wt1ezdnGhYbEm5+uaSmzBqkISj65Bs\n" + "/o7WId9FI3gevgzBuQW9ow7vtpaVdZLQpQW3iJ5G/VSi8ZictQGsXFG4twUlUvYS\n" + "oeH0v7JOPie3cZ/U4QIDAQABo4IBRjCCAUIwHQYDVR0OBBYEFI/gePjKiFn+/j96\n" + "mDcs/ALGCERJMB8GA1UdIwQYMBaAFHzCjb5uWdhKVANGmxMIANL48G0nMEMGA1Ud\n" + "IAEB/wQ5MDcwNQYEVR0gADAtMCsGCCsGAQUFBwIBFh9odHRwOi8vc3ctY2VudGVy\n" + "LnN0LmNvbS9TVFNBRkUvMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/\n" + "AgEAMFAGCCsGAQUFBwEBBEQwQjBABggrBgEFBQcwAoY0aHR0cDovL3N3LWNlbnRl\n" + "ci5zdC5jb20vU1RTQUZFL1NUU0FGRVJzYVJvb3RDQTAyLmNydDBFBgNVHR8EPjA8\n" + "MDqgOKA2hjRodHRwOi8vc3ctY2VudGVyLnN0LmNvbS9TVFNBRkUvU1RTQUZFUnNh\n" + "Um9vdENBMDIuY3JsMA0GCSqGSIb3DQEBDAUAA4ICAQAdjgY6q/7v+/kedUQfP61Y\n" + "W5+Ixl4etRxs2WLDZVyNh7ievMJf4iTvsjKuycYoGkcq5yrX0vp9PjLpd+KEH0e/\n" + "T3j5GyQAsow63GzCS+KKTcoVlP6hbBg2A2nx+4WNzWo0xhv90oYfagqJuGivF7Ly\n" + "TCk9E91XRXpBQrfNwIdkN3zSdtsjX20RDYx80O+jIDBb4ycWJIQS1g/sbh8rQk5k\n" + "xX/2CbmKPKc+y3IdqxOM3FbZ5KkLbgxTo2uJxE2IpUkSh3FXFbnjtbYuCEFcZTNU\n" + "acJRKw5HSIwL2YeH6M9ok9bWT3rg7OdHiBAb1aZbxxlKSQ2HtIu4R7Z3Bji1KKVH\n" + "pOFMtXREWqcwRNUlNDXdISMl1siScGG8RqChCGyq5YnjyJQ5TVOm5yJk2qZnil5p\n" + "p2y/Gu1wxUDlyNtPY2RafHE8jmK7g7CWhJTTaNR4gUnD1icSx/X9gCRON1s9KP5X\n" + "1585SsH9gZFdwxpST7iFPt3P1XxPEDZtxafI+1Zb9cEXgWvrHHvM71PAwAfVtEjy\n" + "97M7UtBGOiYTO7LQMwMDEJZWftFj37joXuLDv/rxIR+nlCBjZGOsCRmox+N5cxhS\n" + "5iEHZK4dhlx/DEJ/vTLCiv8i749LJk+KpJDU3EuW5FOrCn52+Jz1q9FKPFTvUKrq\n" + "Oc+M31vSmqTgg6QftWF1iQ==\n" + "-----END CERTIFICATE-----\n", + /* Subject: CN=STM TPM EK Root CA * Algorithms: RSA 2048-bit, SHA2-256 * Validity: Dec 31 23:59:59 2039 GMT */ @@ -577,5 +620,140 @@ static const char* trusted_certs[] = { "-----END CERTIFICATE-----\n", }; +#endif /* !WOLFCRYPT_ONLY */ + + +/* ST33KTPM2X: C=CH, O=STMicroelectronics NV, CN=STSAFE TPM RSA Intermediate CA 20 */ +/* http://sw-center.st.com/STSAFE/stsafetpmrsaint20.crt */ +static const uint8_t kSTSAFEIntCa20[] = { + 0x30, 0x82, 0x06, 0x6C, 0x30, 0x82, 0x04, 0x54, 0xA0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x04, 0x40, 0x00, 0x00, 0x20, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C, 0x05, 0x00, 0x30, 0x4D, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31, 0x1E, 0x30, + 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x53, 0x54, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, + 0x20, 0x4E, 0x56, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x15, 0x53, 0x54, 0x53, 0x41, 0x46, 0x45, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x30, 0x32, 0x30, 0x1E, 0x17, 0x0D, + 0x32, 0x32, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, + 0x17, 0x0D, 0x34, 0x33, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5A, 0x30, 0x59, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x43, 0x48, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x53, 0x54, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x65, 0x6C, 0x65, 0x63, + 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x63, 0x73, 0x20, 0x4E, 0x56, 0x31, 0x2A, 0x30, + 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x53, 0x54, 0x53, 0x41, 0x46, + 0x45, 0x20, 0x54, 0x50, 0x4D, 0x20, 0x52, 0x53, 0x41, 0x20, 0x49, 0x6E, 0x74, + 0x65, 0x72, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0F, 0x00, + 0x30, 0x82, 0x02, 0x0A, 0x02, 0x82, 0x02, 0x01, 0x00, 0xC5, 0x5E, 0xB9, 0xA1, + 0x35, 0x8B, 0x76, 0xD6, 0xDF, 0xED, 0x93, 0xA5, 0x66, 0x9D, 0x11, 0x93, 0xFD, + 0x46, 0x42, 0xFD, 0x48, 0xF7, 0x33, 0x6A, 0x96, 0xE3, 0x64, 0x6C, 0x2A, 0x74, + 0xBA, 0x52, 0x9E, 0x71, 0x48, 0xC6, 0xCA, 0x42, 0xE1, 0x06, 0xA0, 0xC7, 0xBC, + 0xC4, 0x0D, 0x6E, 0x48, 0xED, 0x1C, 0x5F, 0xDC, 0xAA, 0x44, 0xC1, 0xF4, 0x5C, + 0xB3, 0xAC, 0x22, 0x85, 0xAD, 0x5F, 0xB0, 0xB0, 0xD9, 0xF4, 0x8E, 0x51, 0x3E, + 0x05, 0x70, 0x41, 0xAC, 0xCF, 0x5C, 0xF8, 0x0F, 0x29, 0xAA, 0x94, 0x5B, 0x24, + 0xA3, 0xBF, 0x39, 0x33, 0xE9, 0x1A, 0xBB, 0x51, 0xDE, 0x22, 0xB2, 0x52, 0xA6, + 0x8B, 0x27, 0xC1, 0xAA, 0x92, 0xE1, 0x38, 0x80, 0x40, 0xAE, 0xF9, 0x04, 0xD0, + 0xCC, 0xD5, 0x3B, 0x72, 0x7F, 0xD5, 0x69, 0xBC, 0x9B, 0x80, 0x55, 0xFF, 0xC2, + 0x4A, 0x87, 0x3E, 0xB5, 0x74, 0x55, 0xC7, 0x83, 0x04, 0x9E, 0xD9, 0xEC, 0xEE, + 0xFB, 0xC7, 0x21, 0xD6, 0x51, 0xB4, 0xC8, 0xA4, 0x6F, 0x03, 0x57, 0x3D, 0x8C, + 0xAE, 0xFC, 0xDF, 0xD9, 0x6C, 0xA4, 0x80, 0x4E, 0x83, 0x2D, 0x96, 0x40, 0x6F, + 0xE2, 0xBF, 0x45, 0xA5, 0x0A, 0x32, 0xC1, 0xD6, 0xDE, 0x69, 0x35, 0x53, 0x24, + 0x37, 0xE4, 0x7A, 0x8C, 0x2F, 0x96, 0xB6, 0x8A, 0x8C, 0x74, 0x14, 0xEB, 0x5A, + 0x05, 0x4A, 0xFE, 0x23, 0x03, 0xD9, 0xCE, 0xAF, 0x9E, 0xC4, 0x2E, 0x23, 0xB4, + 0xE2, 0xFF, 0xE4, 0x76, 0x1B, 0xCE, 0x4D, 0x6B, 0x54, 0xAF, 0xBF, 0xFC, 0xC2, + 0x4E, 0x24, 0x6F, 0x24, 0xE6, 0xBC, 0x34, 0x61, 0xCB, 0x15, 0x0A, 0xCE, 0x8B, + 0x5B, 0x22, 0x0A, 0xFD, 0x3F, 0x26, 0x93, 0x63, 0xB4, 0xA5, 0xB3, 0x43, 0x6A, + 0x1A, 0x20, 0x14, 0x47, 0xD2, 0xD9, 0xFD, 0x65, 0x59, 0xAE, 0x13, 0x0D, 0x61, + 0x3C, 0x38, 0xBB, 0x2E, 0x59, 0x0B, 0xF0, 0x49, 0x92, 0x12, 0xDB, 0x9D, 0x73, + 0x09, 0x42, 0x54, 0x15, 0x0C, 0x97, 0xD7, 0x14, 0xA4, 0xBB, 0x3A, 0x5E, 0xE8, + 0x7F, 0xD9, 0xDC, 0x76, 0x3D, 0xCA, 0x36, 0x77, 0x52, 0x12, 0x58, 0xE9, 0xD1, + 0xFF, 0x06, 0xE6, 0xDA, 0x05, 0x6A, 0x9C, 0x7F, 0xA6, 0x05, 0x4B, 0x2E, 0x48, + 0x62, 0x26, 0xB0, 0x2D, 0x5C, 0xA6, 0x7D, 0xC9, 0x49, 0x18, 0xCB, 0x76, 0x24, + 0x4D, 0x7A, 0x62, 0x04, 0xB4, 0xB4, 0xEE, 0x48, 0x24, 0xC0, 0x11, 0xBA, 0x78, + 0xF0, 0xCA, 0xF0, 0xF2, 0x97, 0x84, 0x15, 0x0A, 0x99, 0xDE, 0x0A, 0x56, 0x13, + 0x30, 0xA6, 0xF5, 0x76, 0xC6, 0xC8, 0x95, 0x4A, 0x44, 0x94, 0xB1, 0xFE, 0x78, + 0x1E, 0x55, 0x7E, 0xFC, 0x4C, 0x2E, 0x4F, 0x3C, 0x7A, 0xF3, 0x4D, 0x69, 0xAE, + 0x95, 0x60, 0x51, 0xA0, 0x4E, 0x0C, 0xEB, 0xE3, 0x62, 0x4A, 0x0C, 0xA7, 0x67, + 0x10, 0xA7, 0xAB, 0xE7, 0x44, 0xE6, 0xD4, 0x96, 0x32, 0xA0, 0xC8, 0x09, 0x45, + 0x20, 0x2F, 0xCC, 0x04, 0x10, 0xC1, 0x53, 0x31, 0x5F, 0xE7, 0xFB, 0xE0, 0x36, + 0xC8, 0x1D, 0x08, 0xB4, 0xD1, 0xA2, 0x01, 0xA1, 0x7F, 0x6C, 0x94, 0xA7, 0x81, + 0xE9, 0xC1, 0xC7, 0x19, 0x0D, 0x30, 0xBC, 0x4F, 0xA5, 0xAD, 0xD5, 0xEC, 0xDD, + 0x9C, 0x68, 0x58, 0x6C, 0x49, 0xB9, 0xFA, 0xE6, 0x92, 0x9B, 0x30, 0x6A, 0x90, + 0x84, 0xA3, 0xEB, 0x90, 0x6C, 0xFE, 0x8E, 0xD6, 0x21, 0xDF, 0x45, 0x23, 0x78, + 0x1E, 0xBE, 0x0C, 0xC1, 0xB9, 0x05, 0xBD, 0xA3, 0x0E, 0xEF, 0xB6, 0x96, 0x95, + 0x75, 0x92, 0xD0, 0xA5, 0x05, 0xB7, 0x88, 0x9E, 0x46, 0xFD, 0x54, 0xA2, 0xF1, + 0x98, 0x9C, 0xB5, 0x01, 0xAC, 0x5C, 0x51, 0xB8, 0xB7, 0x05, 0x25, 0x52, 0xF6, + 0x12, 0xA1, 0xE1, 0xF4, 0xBF, 0xB2, 0x4E, 0x3E, 0x27, 0xB7, 0x71, 0x9F, 0xD4, + 0xE1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x46, 0x30, 0x82, 0x01, + 0x42, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x8F, + 0xE0, 0x78, 0xF8, 0xCA, 0x88, 0x59, 0xFE, 0xFE, 0x3F, 0x7A, 0x98, 0x37, 0x2C, + 0xFC, 0x02, 0xC6, 0x08, 0x44, 0x49, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7C, 0xC2, 0x8D, 0xBE, 0x6E, 0x59, 0xD8, + 0x4A, 0x54, 0x03, 0x46, 0x9B, 0x13, 0x08, 0x00, 0xD2, 0xF8, 0xF0, 0x6D, 0x27, + 0x30, 0x43, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x01, 0x01, 0xFF, 0x04, 0x39, 0x30, + 0x37, 0x30, 0x35, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x2D, 0x30, 0x2B, + 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1F, 0x68, + 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x73, 0x77, 0x2D, 0x63, 0x65, 0x6E, 0x74, + 0x65, 0x72, 0x2E, 0x73, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x53, 0x54, 0x53, + 0x41, 0x46, 0x45, 0x2F, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, + 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1D, + 0x13, 0x01, 0x01, 0xFF, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01, + 0x00, 0x30, 0x50, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x02, 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x73, + 0x77, 0x2D, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x73, 0x74, 0x2E, 0x63, + 0x6F, 0x6D, 0x2F, 0x53, 0x54, 0x53, 0x41, 0x46, 0x45, 0x2F, 0x53, 0x54, 0x53, + 0x41, 0x46, 0x45, 0x52, 0x73, 0x61, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x30, + 0x32, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, + 0x3E, 0x30, 0x3C, 0x30, 0x3A, 0xA0, 0x38, 0xA0, 0x36, 0x86, 0x34, 0x68, 0x74, + 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x73, 0x77, 0x2D, 0x63, 0x65, 0x6E, 0x74, 0x65, + 0x72, 0x2E, 0x73, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x53, 0x54, 0x53, 0x41, + 0x46, 0x45, 0x2F, 0x53, 0x54, 0x53, 0x41, 0x46, 0x45, 0x52, 0x73, 0x61, 0x52, + 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x30, 0x32, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x0D, + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x01, 0x00, 0x1D, 0x8E, 0x06, 0x3A, 0xAB, 0xFE, 0xEF, 0xFB, + 0xF9, 0x1E, 0x75, 0x44, 0x1F, 0x3F, 0xAD, 0x58, 0x5B, 0x9F, 0x88, 0xC6, 0x5E, + 0x1E, 0xB5, 0x1C, 0x6C, 0xD9, 0x62, 0xC3, 0x65, 0x5C, 0x8D, 0x87, 0xB8, 0x9E, + 0xBC, 0xC2, 0x5F, 0xE2, 0x24, 0xEF, 0xB2, 0x32, 0xAE, 0xC9, 0xC6, 0x28, 0x1A, + 0x47, 0x2A, 0xE7, 0x2A, 0xD7, 0xD2, 0xFA, 0x7D, 0x3E, 0x32, 0xE9, 0x77, 0xE2, + 0x84, 0x1F, 0x47, 0xBF, 0x4F, 0x78, 0xF9, 0x1B, 0x24, 0x00, 0xB2, 0x8C, 0x3A, + 0xDC, 0x6C, 0xC2, 0x4B, 0xE2, 0x8A, 0x4D, 0xCA, 0x15, 0x94, 0xFE, 0xA1, 0x6C, + 0x18, 0x36, 0x03, 0x69, 0xF1, 0xFB, 0x85, 0x8D, 0xCD, 0x6A, 0x34, 0xC6, 0x1B, + 0xFD, 0xD2, 0x86, 0x1F, 0x6A, 0x0A, 0x89, 0xB8, 0x68, 0xAF, 0x17, 0xB2, 0xF2, + 0x4C, 0x29, 0x3D, 0x13, 0xDD, 0x57, 0x45, 0x7A, 0x41, 0x42, 0xB7, 0xCD, 0xC0, + 0x87, 0x64, 0x37, 0x7C, 0xD2, 0x76, 0xDB, 0x23, 0x5F, 0x6D, 0x11, 0x0D, 0x8C, + 0x7C, 0xD0, 0xEF, 0xA3, 0x20, 0x30, 0x5B, 0xE3, 0x27, 0x16, 0x24, 0x84, 0x12, + 0xD6, 0x0F, 0xEC, 0x6E, 0x1F, 0x2B, 0x42, 0x4E, 0x64, 0xC5, 0x7F, 0xF6, 0x09, + 0xB9, 0x8A, 0x3C, 0xA7, 0x3E, 0xCB, 0x72, 0x1D, 0xAB, 0x13, 0x8C, 0xDC, 0x56, + 0xD9, 0xE4, 0xA9, 0x0B, 0x6E, 0x0C, 0x53, 0xA3, 0x6B, 0x89, 0xC4, 0x4D, 0x88, + 0xA5, 0x49, 0x12, 0x87, 0x71, 0x57, 0x15, 0xB9, 0xE3, 0xB5, 0xB6, 0x2E, 0x08, + 0x41, 0x5C, 0x65, 0x33, 0x54, 0x69, 0xC2, 0x51, 0x2B, 0x0E, 0x47, 0x48, 0x8C, + 0x0B, 0xD9, 0x87, 0x87, 0xE8, 0xCF, 0x68, 0x93, 0xD6, 0xD6, 0x4F, 0x7A, 0xE0, + 0xEC, 0xE7, 0x47, 0x88, 0x10, 0x1B, 0xD5, 0xA6, 0x5B, 0xC7, 0x19, 0x4A, 0x49, + 0x0D, 0x87, 0xB4, 0x8B, 0xB8, 0x47, 0xB6, 0x77, 0x06, 0x38, 0xB5, 0x28, 0xA5, + 0x47, 0xA4, 0xE1, 0x4C, 0xB5, 0x74, 0x44, 0x5A, 0xA7, 0x30, 0x44, 0xD5, 0x25, + 0x34, 0x35, 0xDD, 0x21, 0x23, 0x25, 0xD6, 0xC8, 0x92, 0x70, 0x61, 0xBC, 0x46, + 0xA0, 0xA1, 0x08, 0x6C, 0xAA, 0xE5, 0x89, 0xE3, 0xC8, 0x94, 0x39, 0x4D, 0x53, + 0xA6, 0xE7, 0x22, 0x64, 0xDA, 0xA6, 0x67, 0x8A, 0x5E, 0x69, 0xA7, 0x6C, 0xBF, + 0x1A, 0xED, 0x70, 0xC5, 0x40, 0xE5, 0xC8, 0xDB, 0x4F, 0x63, 0x64, 0x5A, 0x7C, + 0x71, 0x3C, 0x8E, 0x62, 0xBB, 0x83, 0xB0, 0x96, 0x84, 0x94, 0xD3, 0x68, 0xD4, + 0x78, 0x81, 0x49, 0xC3, 0xD6, 0x27, 0x12, 0xC7, 0xF5, 0xFD, 0x80, 0x24, 0x4E, + 0x37, 0x5B, 0x3D, 0x28, 0xFE, 0x57, 0xD7, 0x9F, 0x39, 0x4A, 0xC1, 0xFD, 0x81, + 0x91, 0x5D, 0xC3, 0x1A, 0x52, 0x4F, 0xB8, 0x85, 0x3E, 0xDD, 0xCF, 0xD5, 0x7C, + 0x4F, 0x10, 0x36, 0x6D, 0xC5, 0xA7, 0xC8, 0xFB, 0x56, 0x5B, 0xF5, 0xC1, 0x17, + 0x81, 0x6B, 0xEB, 0x1C, 0x7B, 0xCC, 0xEF, 0x53, 0xC0, 0xC0, 0x07, 0xD5, 0xB4, + 0x48, 0xF2, 0xF7, 0xB3, 0x3B, 0x52, 0xD0, 0x46, 0x3A, 0x26, 0x13, 0x3B, 0xB2, + 0xD0, 0x33, 0x03, 0x03, 0x10, 0x96, 0x56, 0x7E, 0xD1, 0x63, 0xDF, 0xB8, 0xE8, + 0x5E, 0xE2, 0xC3, 0xBF, 0xFA, 0xF1, 0x21, 0x1F, 0xA7, 0x94, 0x20, 0x63, 0x64, + 0x63, 0xAC, 0x09, 0x19, 0xA8, 0xC7, 0xE3, 0x79, 0x73, 0x18, 0x52, 0xE6, 0x21, + 0x07, 0x64, 0xAE, 0x1D, 0x86, 0x5C, 0x7F, 0x0C, 0x42, 0x7F, 0xBD, 0x32, 0xC2, + 0x8A, 0xFF, 0x22, 0xEF, 0x8F, 0x4B, 0x26, 0x4F, 0x8A, 0xA4, 0x90, 0xD4, 0xDC, + 0x4B, 0x96, 0xE4, 0x53, 0xAB, 0x0A, 0x7E, 0x76, 0xF8, 0x9C, 0xF5, 0xAB, 0xD1, + 0x4A, 0x3C, 0x54, 0xEF, 0x50, 0xAA, 0xEA, 0x39, 0xCF, 0x8C, 0xDF, 0x5B, 0xD2, + 0x9A, 0xA4, 0xE0, 0x83, 0xA4, 0x1F, 0xB5, 0x61, 0x75, 0x89 +}; + #endif /* WOLFTPM_TRUSTED_CERTS_H */ diff --git a/examples/endorsement/verify_ek_cert.c b/examples/endorsement/verify_ek_cert.c new file mode 100644 index 00000000..1e575385 --- /dev/null +++ b/examples/endorsement/verify_ek_cert.c @@ -0,0 +1,649 @@ +/* verify_ek_cert.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* This example shows how to generate and validate an EK based on a + * trusted public key. This example is supported in stand-alone (no wolfCrypt) + * This example assumes ST33KTPM2X with signer + * "STSAFE TPM RSA Intermediate CA 20" : RSA 4096-bit key with SHA2-384 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include + +#ifndef WOLFTPM2_NO_WRAPPER + +#include +#include + +#include "trusted_certs.h" + +#ifndef WOLFTPM2_NO_WOLFCRYPT +#include +#include +#endif + +#ifndef MAX_CERT_SZ +#define MAX_CERT_SZ 2048 +#endif + + +#ifdef WOLFTPM2_NO_WOLFCRYPT +#define ASN_SEQUENCE 0x10 +#define ASN_CONSTRUCTED 0x20 +#define ASN_CONTEXT_SPECIFIC 0x80 + +#define ASN_LONG_LENGTH 0x80 /* indicates additional length fields */ + +#define ASN_INTEGER 0x02 +#define ASN_BIT_STRING 0x03 +#define ASN_OCTET_STRING 0x04 +#define ASN_TAG_NULL 0x05 +#define ASN_OBJECT_ID 0x06 +#endif + +#if defined(WOLFTPM2_NO_WOLFCRYPT) || defined(NO_RSA) +#define RSA_BLOCK_TYPE_1 1 +#define RSA_BLOCK_TYPE_2 2 +#endif + +typedef struct DecodedX509 { + word32 certBegin; + byte* cert; /* pointer to start of cert */ + word32 certSz; + byte* publicKey; /* pointer to public key */ + word32 pubKeySz; + byte* signature; /* pointer to signature */ + word32 sigSz; /* length of signature */ +} DecodedX509; + + +static void usage(void) +{ + printf("Expected usage:\n"); + printf("./examples/endorsement/verify_ek_cert\n"); +} + +static void dump_hex_bytes(const byte* buf, word32 sz) +{ + word32 i; + /* Print as : separated hex bytes - max 15 bytes per line */ + printf("\t"); + for (i=0; i0 && ((i+1)%16)==0) printf("\n\t"); + } + } + printf("\n"); +} + +/* Display EK public information */ +static void show_tpm_public(const char* desc, const TPM2B_PUBLIC* pub) +{ + printf("%s %s, Hash: %s, objAttr: 0x%X\n", + desc, + TPM2_GetAlgName(pub->publicArea.type), + TPM2_GetAlgName(pub->publicArea.nameAlg), + (unsigned int)pub->publicArea.objectAttributes); + + /* parameters and unique field depend on algType */ + if (pub->publicArea.type == TPM_ALG_RSA) { + printf("\tKeyBits: %d, exponent: 0x%X, unique size %d\n", + pub->publicArea.parameters.rsaDetail.keyBits, + (unsigned int)pub->publicArea.parameters.rsaDetail.exponent, + pub->publicArea.unique.rsa.size); + dump_hex_bytes(pub->publicArea.unique.rsa.buffer, + pub->publicArea.unique.rsa.size); + } + else if (pub->publicArea.type == TPM_ALG_ECC) { + const char* curveName = "NULL"; + #if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC) + curveName = wc_ecc_get_name( + TPM2_GetWolfCurve(pub->publicArea.parameters.eccDetail.curveID)); + #endif + printf("\tCurveID %s (0x%x), size %d, unique X/Y size %d/%d\n", + curveName, pub->publicArea.parameters.eccDetail.curveID, + TPM2_GetCurveSize(pub->publicArea.parameters.eccDetail.curveID), + pub->publicArea.unique.ecc.x.size, + pub->publicArea.unique.ecc.y.size); + dump_hex_bytes(pub->publicArea.unique.ecc.x.buffer, + pub->publicArea.unique.ecc.x.size); + dump_hex_bytes(pub->publicArea.unique.ecc.y.buffer, + pub->publicArea.unique.ecc.y.size); + } +} + +static int DecodeAsn1Tag(const uint8_t* input, int inputSz, int* inOutIdx, + int* tag_len, uint8_t tag) +{ + int rc = -1; /* default to fail case */ + int tag_len_bytes = 1; + + *tag_len = 0; /* reset tag length */ + if (input[*inOutIdx] == tag) { /* check tag is expected */ + (*inOutIdx)++; /* skip asn.1 tag */ + if (input[*inOutIdx] & ASN_LONG_LENGTH) { + tag_len_bytes = (int)(input[*inOutIdx] & 0x7F); + if (tag_len_bytes > 4) { + return -1; /* too long */ + } + (*inOutIdx)++; /* skip long length field */ + } + while (tag_len_bytes--) { + *tag_len = (*tag_len << 8) | input[*inOutIdx]; + (*inOutIdx)++; /* skip length */ + } + if (*tag_len + *inOutIdx <= inputSz) { /* check length */ + rc = 0; + } + } + return rc; +} + +static int RsaDecodeSignature(uint8_t** pInput, int inputSz) +{ + int rc; + uint8_t* input = *pInput; + int idx = 0; + int tot_len, algo_len, digest_len = 0; + + /* sequence - total size */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &tot_len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + if (rc == 0) { + /* sequence - algoid */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &algo_len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + idx += algo_len; /* skip algoid */ + + /* digest */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &digest_len, ASN_OCTET_STRING); + } + if (rc == 0) { + /* return digest buffer pointer */ + *pInput = &input[idx]; + + rc = digest_len; + } + return rc; +} + +static int DecodeX509Cert(uint8_t* input, int inputSz, DecodedX509* x509) +{ + int rc; + int idx = 0; + int tot_len, cert_len = 0, len, pubkey_len = 0, sig_len = 0; + + /* sequence - total size */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &tot_len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + if (rc == 0) { + x509->certBegin = idx; + x509->cert = &input[idx]; + + /* sequence - cert */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &cert_len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + x509->certSz = cert_len + (idx - x509->certBegin); + /* cert - version */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)); + } + if (rc == 0) { + /* check version == 1 */ + if (input[idx] != ASN_INTEGER && input[idx] != 1) { + rc = -1; + } + } + if (rc == 0) { + idx += len; /* skip version */ + + /* cert - serial */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, ASN_INTEGER); + } + if (rc == 0) { + idx += len; /* skip serial */ + + /* cert - signature oid */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + idx += len; /* skip signature oid */ + + /* cert - issuer */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + idx += len; /* skip issuer */ + + /* cert - validity */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + idx += len; /* skip validity */ + + /* cert - subject */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + idx += len; /* skip subject */ + + /* cert - subject public key info */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + /* cert - subject public key alg oid */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + idx += len; /* skip alg oid */ + + /* cert - subject public key alg params */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &pubkey_len, + ASN_BIT_STRING); + } + + if (rc == 0) { + /* skip leading zero for bit string */ + if (input[idx] == 0x00) { + idx++; + pubkey_len--; + } + /* return pointer to public key */ + x509->publicKey = &input[idx]; + x509->pubKeySz = pubkey_len; + } + if (rc == 0) { + /* skip to start of signature */ + idx = x509->certBegin + x509->certSz; + + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + } + if (rc == 0) { + /* signature oid */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, ASN_OBJECT_ID); + } + if (rc == 0) { + idx += len; /* skip oid */ + /* sig algo params */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &len, ASN_TAG_NULL); + } + if (rc == 0) { + idx += len; /* skip tag */ + + /* signature bit string */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &sig_len, + ASN_BIT_STRING); + } + if (rc == 0) { + /* skip leading zero for bit string */ + if (input[idx] == 0x00) { + idx++; + sig_len--; + } + + /* signature */ + x509->sigSz = sig_len; + x509->signature = &input[idx]; + } + + return rc; +} + +static int DecodeRsaPubKey(uint8_t* input, int inputSz, TPM2B_PUBLIC* pub) +{ + int rc; + int idx = 0; + int tot_len, mod_len = 0, exp_len = 0; + + /* sequence - total size */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &tot_len, + (ASN_SEQUENCE | ASN_CONSTRUCTED)); + if (rc == 0) { + /* modulus */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &mod_len, ASN_INTEGER); + } + if (rc == 0) { + /* skip leading zero if exists */ + if (input[idx] == 0x00) { + idx++; + mod_len--; + } + if (mod_len > (int)sizeof(pub->publicArea.unique.rsa.buffer)) { + rc = -1; + } + } + if (rc == 0) { + /* Populate Modulus */ + pub->publicArea.parameters.rsaDetail.keyBits = mod_len * 8; + pub->publicArea.unique.rsa.size = mod_len; + XMEMCPY(pub->publicArea.unique.rsa.buffer, &input[idx], mod_len); + } + if (rc == 0) { + idx += mod_len; /* skip modulus */ + + /* exponent */ + rc = DecodeAsn1Tag(input, inputSz, &idx, &exp_len, ASN_INTEGER); + /* skip leading zero if exists */ + if (input[idx] == 0x00) { + idx++; + exp_len--; + } + if (exp_len > + (int)sizeof(pub->publicArea.parameters.rsaDetail.exponent)) { + rc = -1; + } + } + if (rc == 0) { + XMEMCPY(&pub->publicArea.parameters.rsaDetail.exponent, &input[idx], + exp_len); + } + return rc; +} + +static int RsaUnpadPkcsv15(uint8_t** pSig, int* sigSz) +{ + int rc = -1; /* default to error */ + uint8_t* sig = *pSig; + int idx = 0; + + /* RSA PKCSv1.5 unpad */ + if (sig[idx++] == 0x00 && sig[idx++] == RSA_BLOCK_TYPE_1) { + + /* skip padding 0xFF's */ + while (idx < *sigSz) { + if (sig[idx] != 0xFF) + break; + idx++; + } + + /* verify 0x00 after pad */ + if (sig[idx++] == 0x00) { + /* success unpadding */ + rc = 0; + *pSig = &sig[idx]; + *sigSz -= idx; + } + } + return rc; +} + +int TPM2_EndorsementCertVerify_Example(void* userCtx, int argc, char *argv[]) +{ + int rc = -1; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY endorse; + TPMS_NV_PUBLIC nvPublic; + WOLFTPM2_KEY issuer; + WOLFTPM2_NV nv; + WOLFTPM2_HASH hash; + TPMT_PUBLIC publicTemplate; + TPM2B_PUBLIC ekPub; + DecodedX509 issuerX509, ekX509; + + uint32_t nvIndex = TPM2_NV_RSA_EK_CERT; /* RSA 2048-bit EK Cert Index */ + uint8_t cert[MAX_CERT_SZ]; /* buffer to hold device cert from NV */ + uint32_t certSz; + TPM_ALG_ID hashAlg = TPM_ALG_SHA384; /* Signer uses SHA2-384 */ + uint8_t hashBuf[TPM_MAX_DIGEST_SIZE]; /* hash of device cert, for verify */ + uint32_t hashSz = 0; + uint8_t sig[512]; /* 4096-bit max, hold decrypted signature */ + int sigSz = (int)sizeof(sig); + uint8_t* sigDigest; /* offset to digest in signature */ + int sigDigestSz = 0; + + XMEMSET(&endorse, 0, sizeof(endorse)); + XMEMSET(&nvPublic, 0, sizeof(nvPublic)); + XMEMSET(&issuer, 0, sizeof(issuer)); + XMEMSET(&nv, 0, sizeof(nv)); + XMEMSET(&hash, 0, sizeof(hash)); + XMEMSET(&issuerX509, 0, sizeof(issuerX509)); + XMEMSET(&ekX509, 0, sizeof(ekX509)); + XMEMSET(&ekPub, 0, sizeof(ekPub)); + + if (argc >= 2) { + if (XSTRCMP(argv[1], "-?") == 0 || + XSTRCMP(argv[1], "-h") == 0 || + XSTRCMP(argv[1], "--help") == 0) { + usage(); + return 0; + } + } + + printf("Endorsement Certificate Verify\n"); + + rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); + if (rc != TPM_RC_SUCCESS) { + printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc)); + goto exit; + } + + /* Get Endorsement Public Key template using NV index */ + rc = wolfTPM2_GetKeyTemplate_EKIndex(nvIndex, &publicTemplate); + if (rc != 0) { + printf("EK Index 0x%08x not valid\n", nvIndex); + goto exit; + } + + /* Read Public portion of NV to get actual size */ + if (rc == 0) + rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic); + if (rc != 0) { + printf("Failed to read public for NV Index 0x%08x\n", nvIndex); + } + if (rc == 0) { /* Read data */ + certSz = (uint32_t)sizeof(cert); + if (certSz > nvPublic.dataSize) { + certSz = nvPublic.dataSize; + } + rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, cert, &certSz, 0); + if (rc == 0) { + #ifdef DEBUG_WOLFTPM + printf("EK Data: %d\n", certSz); + TPM2_PrintBin(cert, certSz); + #endif + } + } + + /* Create Endorsement Key */ + if (rc == 0) { + /* Create Endorsement Key using EK auth policy */ + printf("Creating Endorsement Key\n"); + rc = wolfTPM2_CreatePrimaryKey(&dev, &endorse, TPM_RH_ENDORSEMENT, + &publicTemplate, NULL, 0); + if (rc != 0) goto exit; + printf("Endorsement key loaded at handle 0x%08x\n", + endorse.handle.hndl); + + /* Display EK public information */ + show_tpm_public("EK", &endorse.pub); + } + + if (rc == 0) { + /* Parse device certificate and extract public key */ + rc = DecodeX509Cert(cert, certSz, &ekX509); + if (rc == 0) { + /* Parse RSA Public Key Raw Modulus */ + rc = DecodeRsaPubKey((uint8_t*)ekX509.publicKey, ekX509.pubKeySz, + &ekPub); + } + } + + if (rc == 0) { + /* Compare certificate public key with generated EK public key */ + if (ekPub.publicArea.unique.rsa.size != + endorse.pub.publicArea.unique.rsa.size || + XMEMCMP(ekPub.publicArea.unique.rsa.buffer, + endorse.pub.publicArea.unique.rsa.buffer, + endorse.pub.publicArea.unique.rsa.size) != 0) + { + printf("Error: Generated EK public key does not match NV cert " + "public key!\n"); + rc = -1; + } + } + + if (rc == 0) { + /* Hash certificate (excluding signature) */ + rc = wolfTPM2_HashStart(&dev, &hash, hashAlg, NULL, 0); + if (rc == 0) { + rc = wolfTPM2_HashUpdate(&dev, &hash, ekX509.cert, ekX509.certSz); + if (rc == 0) { + hashSz = sizeof(hashBuf); + rc = wolfTPM2_HashFinish(&dev, &hash, hashBuf, &hashSz); + } + + printf("Cert Hash: %d\n", hashSz); + dump_hex_bytes(hashBuf, hashSz); + } + } + + if (rc == 0) { + /* Parse and extract the issuer's public key modulus from certificate */ + rc = DecodeX509Cert((uint8_t*)kSTSAFEIntCa20, + (int)sizeof(kSTSAFEIntCa20), &issuerX509); + if (rc == 0) { + /* Parse RSA Public Key Raw Modulus */ + rc = DecodeRsaPubKey((uint8_t*)issuerX509.publicKey, + issuerX509.pubKeySz, &issuer.pub); + } + } + if (rc == 0) { + printf("Issuer Public Exponent 0x%x, Modulus %d\n", + issuer.pub.publicArea.parameters.rsaDetail.exponent, + issuer.pub.publicArea.unique.rsa.size); + dump_hex_bytes(issuer.pub.publicArea.unique.rsa.buffer, + issuer.pub.publicArea.unique.rsa.size); + + /* Import issuer certificate public key */ + issuer.pub.publicArea.type = TPM_ALG_RSA; + issuer.pub.publicArea.nameAlg = hashAlg; + issuer.pub.publicArea.objectAttributes = (TPMA_OBJECT_decrypt); + issuer.pub.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; + issuer.pub.publicArea.parameters.rsaDetail.scheme.details.anySig.hashAlg = hashAlg; + issuer.pub.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL; + rc = wolfTPM2_LoadPublicKey(&dev, &issuer, &issuer.pub); + } + + if (rc == 0) { + /* Display Cert public information */ + show_tpm_public("Issuer", &issuer.pub); + + printf("EK Certificate Signature: %d\n", ekX509.sigSz); + dump_hex_bytes(ekX509.signature, ekX509.sigSz); + + /* RSA Public Decrypt EK certificate signature */ + rc = wolfTPM2_RsaEncrypt(&dev, &issuer, + TPM_ALG_NULL, /* no padding */ + ekX509.signature, ekX509.sigSz, + sig, &sigSz); + if (rc != 0) { + printf("RSA Public Failed!\n"); + goto exit; + } + printf("Decrypted Sig: %d\n", sigSz); + dump_hex_bytes(sig, sigSz); + } + + if (rc == 0) { + sigDigest = sig; + rc = RsaUnpadPkcsv15(&sigDigest, &sigSz); + } + if (rc == 0) { + rc = RsaDecodeSignature(&sigDigest, sigSz); + if (rc > 0) { + sigDigestSz = rc; + rc = 0; + } + } + if (rc == 0) { + printf("Expected Hash: %d\n", hashSz); + dump_hex_bytes(hashBuf, hashSz); + + printf("Sig Hash: %d\n", sigDigestSz); + dump_hex_bytes(sigDigest, sigDigestSz); + + /* Compare certificate hash with signature hash */ + if (sigDigestSz == (int)hashSz && + memcmp(sigDigest, hashBuf, hashSz) == 0) { + printf("Certificate signature is valid\n"); + } + else { + printf("Error: Certificate signature is invalid!\n"); + rc = -1; + } + } + +exit: + + if (rc != 0) { + printf("Error verifying EK certificate! %s (%d)\n", + TPM2_GetRCString(rc), rc); + } + + wolfTPM2_UnloadHandle(&dev, &issuer.handle); + wolfTPM2_UnloadHandle(&dev, &endorse.handle); + wolfTPM2_Cleanup(&dev); + + return rc; +} + +/******************************************************************************/ +/* --- END TPM2.0 Endorsement certificate tool -- */ +/******************************************************************************/ +#endif /* !WOLFTPM2_NO_WRAPPER */ + +#ifndef NO_MAIN_DRIVER +int main(int argc, char *argv[]) +{ + int rc = -1; +#ifndef WOLFTPM2_NO_WOLFCRYPT + (void)trusted_certs; /* not used */ +#endif + +#ifndef WOLFTPM2_NO_WRAPPER + rc = TPM2_EndorsementCertVerify_Example(NULL, argc, argv); +#else + printf("Wrapper code not compiled in\n"); + (void)argc; + (void)argv; +#endif /* !WOLFTPM2_NO_WRAPPER */ + + return rc; +} +#endif