diff -Nru tboot-1.9.5/CHANGELOG tboot-1.9.6/CHANGELOG --- tboot-1.9.5/CHANGELOG 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/CHANGELOG 2017-07-11 23:03:58.000000000 +0000 @@ -1,3 +1,16 @@ +20170711: v1.9.6 + GCC7 fix, adds generic FALLTHROUGH notations to avoid warnings appearing on GCC7 + Ensure Tboot never overwrites modules in the process of moving them. + Add support to x2APIC, which uses 32 bit APIC ID. + Fix S3 secrets sealing/unsealing failures + Support OpenSSL 1.1.0+ for ECDSA signature verification. + Support OpenSSL 1.1.0+ for RSA key manipulation. + Adds additional checks to prevent the kernel image from being overwritten. + Added TCG TPM event log support. + Pass through the EFI memory map that's provided by grub2. + Fix a null pointer dereference bug when Intel TXT is disabled in BIOS. + Adjust KERNEL_CMDLINE_OFFSET from 0x9000 to 0x8D00. + Bounds checking on the kernel_cmdline string. 20161216: v1.9.5 Add 2nd generation of LCP creation tool source codes for TPM 2.0 platforms. Add user guide for 2nd generation LCP creation tool diff -Nru tboot-1.9.5/debian/changelog tboot-1.9.6/debian/changelog --- tboot-1.9.5/debian/changelog 2017-02-16 15:19:14.000000000 +0000 +++ tboot-1.9.6/debian/changelog 2017-09-13 08:23:11.000000000 +0000 @@ -1,3 +1,24 @@ +tboot (1.9.6-0ubuntu1) artful; urgency=medium + + * Update to 1.9.6 (LP:#1696029) + - GCC7 fix, adds generic FALLTHROUGH notations to avoid warnings appearing on GCC7 + - Ensure Tboot never overwrites modules in the process of moving them. + - Add support to x2APIC, which uses 32 bit APIC ID. + - Fix S3 secrets sealing/unsealing failures + - Support OpenSSL 1.1.0+ for ECDSA signature verification. + - Support OpenSSL 1.1.0+ for RSA key manipulation. + - Adds additional checks to prevent the kernel image from being overwritten. + - Added TCG TPM event log support. + - Pass through the EFI memory map that's provided by grub2. + - Fix a null pointer dereference bug when Intel TXT is disabled in BIOS. + - Adjust KERNEL_CMDLINE_OFFSET from 0x9000 to 0x8D00. + - Bounds checking on the kernel_cmdline string. + * Update Standards-Version to 4.0.0 + * Update debhelper to >= 9.0.0 + * Update debian/compat to 9 + + -- Colin King Wed, 13 Sep 2017 09:23:11 +0100 + tboot (1.9.5-0ubuntu1) zesty; urgency=medium * Update to 1.9.5 (LP:#1645532) diff -Nru tboot-1.9.5/debian/compat tboot-1.9.6/debian/compat --- tboot-1.9.5/debian/compat 2014-02-07 14:14:05.000000000 +0000 +++ tboot-1.9.6/debian/compat 2017-09-13 08:23:11.000000000 +0000 @@ -1 +1 @@ -8 +9 diff -Nru tboot-1.9.5/debian/control tboot-1.9.6/debian/control --- tboot-1.9.5/debian/control 2014-02-07 14:14:05.000000000 +0000 +++ tboot-1.9.6/debian/control 2017-09-13 08:23:11.000000000 +0000 @@ -3,8 +3,8 @@ Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Gang Wei -Build-Depends: debhelper (>= 8.0.0), libtspi-dev, libssl-dev -Standards-Version: 3.9.3 +Build-Depends: debhelper (>= 9.0.0), libtspi-dev, libssl-dev +Standards-Version: 4.0.0 Homepage: http://sourceforge.net/projects/tboot/ Package: tboot diff -Nru tboot-1.9.5/.hgignore tboot-1.9.6/.hgignore --- tboot-1.9.5/.hgignore 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/.hgignore 2017-07-11 23:03:58.000000000 +0000 @@ -44,6 +44,11 @@ ^lcptools/lcp_crtpolelt$ ^lcptools/lcp_crtpollist$ ^lcptools/trousers_dep$ +^lcptools-v2/lcp2_crtpol$ +^lcptools-v2/lcp2_crtpolelt$ +^lcptools-v2/lcp2_crtpollist$ +^lcptools-v2/lcp2_mlehash$ +^lcptools-v2/trousers_dep$ ^tb_polgen/tb_polgen$ ^utils/acminfo$ ^utils/txt-stat$ diff -Nru tboot-1.9.5/.hgtags tboot-1.9.6/.hgtags --- tboot-1.9.5/.hgtags 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/.hgtags 2017-07-11 23:03:58.000000000 +0000 @@ -15,3 +15,4 @@ 6a1500686f57d92ff6de0391624587ee805e7497 v1.8.3 9d8ee7ff40107fde7512b0a9196c568152ce1c72 v1.9.4 698548a9b9fe6201361d19099100f8eb59fad4f6 v1.9.5 +61c17659bb8670e466c3bac8913459848f5f36d5 v1.9.6 diff -Nru tboot-1.9.5/include/mle.h tboot-1.9.6/include/mle.h --- tboot-1.9.5/include/mle.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/include/mle.h 2017-07-11 23:03:58.000000000 +0000 @@ -50,7 +50,8 @@ uint32_t pcr_map_da : 1; uint32_t platform_type : 2; uint32_t max_phy_addr : 1; - uint32_t reserved1 : 23; + uint32_t tcg_event_log_format: 1; + uint32_t reserved1 : 22; }; } txt_caps_t; @@ -79,8 +80,8 @@ * values supported by current version of tboot */ #define MLE_HDR_VER 0x00020001 /* 2.1 */ -#define MLE_HDR_CAPS 0x00000027 /* rlp_wake_{getsec, monitor} = 1, - ecx_pgtbl = 1, nolg = 0, da = 1 */ +#define MLE_HDR_CAPS 0x000000227 /* rlp_wake_{getsec, monitor} = 1, + ecx_pgtbl = 1, nolg = 0, da = 1 tcg_event_log_format =1 */ #endif /* __MLE_H__ */ diff -Nru tboot-1.9.5/include/tb_error.h tboot-1.9.6/include/tb_error.h --- tboot-1.9.5/include/tb_error.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/include/tb_error.h 2017-07-11 23:03:58.000000000 +0000 @@ -39,33 +39,30 @@ typedef enum { TB_ERR_NONE = 0, /* succeed */ TB_ERR_FIXED = 1, /* previous error has been fixed */ - TB_ERR_GENERIC, /* non-fatal generic error */ - TB_ERR_TPM_NOT_READY, /* tpm not ready */ TB_ERR_SMX_NOT_SUPPORTED, /* smx not supported */ TB_ERR_VMX_NOT_SUPPORTED, /* vmx not supported */ + TB_ERR_VTD_NOT_SUPPORTED, /* Vt-D not enabled in BIOS */ TB_ERR_TXT_NOT_SUPPORTED, /* txt not supported */ - TB_ERR_MODULE_VERIFICATION_FAILED, /* module failed to verify against policy */ TB_ERR_MODULES_NOT_IN_POLICY, /* modules in mbi but not in policy */ TB_ERR_POLICY_INVALID, /* policy is invalid */ TB_ERR_POLICY_NOT_PRESENT, /* no policy in TPM NV */ - TB_ERR_SINIT_NOT_PRESENT, /* SINIT ACM not provided */ TB_ERR_ACMOD_VERIFY_FAILED, /* verifying AC module failed */ - TB_ERR_POST_LAUNCH_VERIFICATION, /* verification of post-launch failed */ TB_ERR_S3_INTEGRITY, /* creation or verification of S3 integrity measurements failed */ - TB_ERR_FATAL, /* generic fatal error */ TB_ERR_NV_VERIFICATION_FAILED, /* NV failed to verify against policy */ + TB_ERR_PREV_TXT_ERROR, /* previous measured launch + failed */ TB_ERR_MAX } tb_error_t; diff -Nru tboot-1.9.5/lcp-gen2/NewPlatform.pdef tboot-1.9.6/lcp-gen2/NewPlatform.pdef --- tboot-1.9.5/lcp-gen2/NewPlatform.pdef 1970-01-01 00:00:00.000000000 +0000 +++ tboot-1.9.6/lcp-gen2/NewPlatform.pdef 2017-07-11 23:03:58.000000000 +0000 @@ -0,0 +1,146 @@ +ccopy_reg +_reconstructor +p1 +(cpdef +PDEF +p2 +c__builtin__ +object +p3 +NtRp4 +(dp5 +S'LcpSignAlgMask' +p6 +I8 +sS'PolicyHashHex' +p7 +(lp8 +sS'LastBuildDateStampYear' +p9 +I2000 +sS'FileTypeSignature' +p10 +S'TXT Policy Definition v2' +p11 +sS'PolVersionMinor' +p12 +I1 +sS'LcpHashAlgMask' +p13 +I8 +sS'DefCompany' +p14 +S'Intel' +p15 +sS'ToolVersionMajor' +p16 +I2 +sS'ToolDate' +p17 +S'20161216' +p18 +sS'NumLists' +p19 +I0 +sS'AuxHashAlgMask' +p20 +I8 +sS'MaxSinitMinVersion' +p21 +I255 +sS'MaxLists' +p22 +I8 +sS'MaxHashSize' +p23 +I64 +sS'Rules' +p24 +I1 +sS'LastBuildTimeStampMinute' +p25 +I0 +sS'StructVersion' +p26 +I2 +sS'PolicyHash' +p27 +(lp28 +sS'ToolVersionMinor' +p29 +I0 +sS'WorkingDirectory' +p30 +V/home/nsun/tboot-code/trunk +p31 +sS'CurrentListView' +p32 +I0 +sS'Modified' +p33 +I00 +sS'HashAlg' +p34 +I11 +sS'DataRevocationCounters' +p35 +(lp36 +I0 +aI0 +aI0 +aI0 +aI0 +aI0 +aI0 +aI0 +asS'SinitMinVersion' +p37 +I0 +sS'LastBuildTimeStampSecond' +p38 +I0 +sS'PolListInfo' +p39 +(dp40 +S'1' +NsS'0' +NsS'3' +NsS'2' +NsS'5' +NsS'4' +NsS'7' +NsS'6' +NssS'MaxHashes' +p41 +I16 +sS'PolVersionMajor' +p42 +I3 +sS'LastBuildTimeStampHour' +p43 +I0 +sS'MaxBiosMinVersion' +p44 +I255 +sS'MaxFileNameSize' +p45 +I32 +sS'PolicyControl' +p46 +I8 +sS'LastBuildDateStampDay' +p47 +I1 +sS'LastBuildTimeStampLowByte' +p48 +I0 +sS'PolicyType' +p49 +I1 +sS'LastBuildDateStampMonth' +p50 +I1 +sS'MaxElements' +p51 +I2 +sb. \ No newline at end of file diff -Nru tboot-1.9.5/lcp-gen2/NewPlatform.pdef.txt tboot-1.9.6/lcp-gen2/NewPlatform.pdef.txt --- tboot-1.9.5/lcp-gen2/NewPlatform.pdef.txt 1970-01-01 00:00:00.000000000 +0000 +++ tboot-1.9.6/lcp-gen2/NewPlatform.pdef.txt 2017-07-11 23:03:58.000000000 +0000 @@ -0,0 +1,48 @@ +PDEF file: NewPlatform.pdef.txt written on: Fri Dec 16 08:00:19 2016 + + +FileTypeSignature = TXT Policy Definition v2 +DefCompany = Intel +StructVersion = 2 +MaxLists = 8 +MaxElements = 2 +MaxHashSize = 64 +MaxHashes = 16 +MaxFileNameSize = 32 +ToolDate = 20161216 +ToolVersion = 2.0 +Rules = 1 +Modified = False +PolVersion = 3.1 +HashAlg = 11 +PolicyType = 1 +SinitMinVersion = 0 +DataRevocationCounters = [0, 0, 0, 0, 0, 0, 0, 0] +PolicyControl = 8 +MaxSinitMinVersion = 255 +MaxBiosMinVersion = 255 +LcpHashAlgMask = 8 +LcpSignAlgMask = 8 +AuxHashAlgMask = 8 +LastBuildDateStamp (YYYYMMDD) = 20000101 +LastBuildTimeStamp (HHMMSS) = 000000 +CurrentListView = 0 +NumLists = 0 +PolListInfo[0] = None +PolListInfo[1] = None +PolListInfo[2] = None +PolListInfo[3] = None +PolListInfo[4] = None +PolListInfo[5] = None +PolListInfo[6] = None +PolListInfo[7] = None + + +PlistInfo 1 = None +PlistInfo 2 = None +PlistInfo 3 = None +PlistInfo 4 = None +PlistInfo 5 = None +PlistInfo 6 = None +PlistInfo 7 = None +PlistInfo 8 = None Binary files /tmp/tmpioC1b4/R0YuGSwCLW/tboot-1.9.5/lcp-gen2/NewPlatform.pol and /tmp/tmpioC1b4/bGmwDrsh1L/tboot-1.9.6/lcp-gen2/NewPlatform.pol differ diff -Nru tboot-1.9.5/lcp-gen2/NewPlatform.txt tboot-1.9.6/lcp-gen2/NewPlatform.txt --- tboot-1.9.5/lcp-gen2/NewPlatform.txt 1970-01-01 00:00:00.000000000 +0000 +++ tboot-1.9.6/lcp-gen2/NewPlatform.txt 2017-07-11 23:03:58.000000000 +0000 @@ -0,0 +1,21 @@ +#Policy Data +word=0300 # Version +word=0011 # Hash Alg (4=Sha1[20], 11=Sha256[32] +byte=01 # PolicyType (0 = LIST, 1 = ANY) +byte=00 # SinitMinVersion +word=0000 # DataRevocationCounters[0] +word=0000 # DataRevocationCounters[1] +word=0000 # DataRevocationCounters[2] +word=0000 # DataRevocationCounters[3] +word=0000 # DataRevocationCounters[4] +word=0000 # DataRevocationCounters[5] +word=0000 # DataRevocationCounters[6] +word=0000 # DataRevocationCounters[7] +dword=0x0000000e # PolicyControl (Bit 1=Allow NPW, 2=PCR17, 3=Force Owner 15=Aux Delete) +byte=255 # MaxSinitMinVersion +byte=255 # MaxBiosMinVersion +word=0009 # LcpHashAlgMask +dword=0008 # LcpSignAlgMask +word=0008 # AuxHashAlgMask +byte=00 # Reserved +byte=0000000000000000000000000000000000000000000000000000000000000000 # Hash diff -Nru tboot-1.9.5/lcptools/crtpollist.c tboot-1.9.6/lcptools/crtpollist.c --- tboot-1.9.5/lcptools/crtpollist.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools/crtpollist.c 2017-07-11 23:03:58.000000000 +0000 @@ -155,14 +155,17 @@ memset(sig, 0, sizeof(*sig) + 2*keysize); sig->pubkey_size = keysize; - if ( (unsigned int)BN_num_bytes(pubkey->n) != keysize ) { - ERROR("Error: modulus size not match key size\n"); - free(sig); - RSA_free(pubkey); - return NULL; - } + + BIGNUM *modulus = BN_new(); + /* OpenSSL Version 1.1.0 and later don't allow direct access to RSA + stuct */ + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + RSA_get0_key(pubkey, (const BIGNUM **)&modulus, NULL, NULL); + #else + modulus = pubkey->n; + #endif unsigned char key[keysize]; - BN_bn2bin(pubkey->n, key); + BN_bn2bin(modulus, key); /* openssl key is big-endian and policy requires little-endian, so reverse bytes */ for ( unsigned int i = 0; i < keysize; i++ ) @@ -172,7 +175,8 @@ LOG("signature:\n"); display_signature(" ", sig, false); } - + + BN_free(modulus); RSA_free(pubkey); return sig; } diff -Nru tboot-1.9.5/lcptools/hash.c tboot-1.9.6/lcptools/hash.c --- tboot-1.9.5/lcptools/hash.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools/hash.c 2017-07-11 23:03:58.000000000 +0000 @@ -101,16 +101,17 @@ return false; if ( hash_alg == TB_HALG_SHA1_LG ) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; memcpy(buf, &(hash1->sha1), sizeof(hash1->sha1)); memcpy(buf + sizeof(hash1->sha1), &(hash2->sha1), sizeof(hash1->sha1)); md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, 2*sizeof(hash1->sha1)); - EVP_DigestFinal(&ctx, hash1->sha1, NULL); - return true; + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, 2*sizeof(hash1->sha1)); + EVP_DigestFinal(ctx, hash1->sha1, NULL); + EVP_MD_CTX_destroy(ctx); + return true; } else return false; diff -Nru tboot-1.9.5/lcptools/lcputils2.c tboot-1.9.6/lcptools/lcputils2.c --- tboot-1.9.5/lcptools/lcputils2.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools/lcputils2.c 2017-07-11 23:03:58.000000000 +0000 @@ -274,19 +274,31 @@ ERROR("Error: failed to allocate key\n"); return false; } - rsa_pubkey->n = BN_bin2bn(key, pubkey_size, NULL); + BIGNUM *modulus = BN_new(); + BIGNUM *exponent = BN_new(); + modulus = BN_bin2bn(key, pubkey_size, NULL); /* uses fixed exponent (LCP_SIG_EXPONENT) */ char exp[32]; snprintf(exp, sizeof(exp), "%u", LCP_SIG_EXPONENT); - rsa_pubkey->e = NULL; - BN_dec2bn(&rsa_pubkey->e, exp); - rsa_pubkey->d = rsa_pubkey->p = rsa_pubkey->q = NULL; + BN_dec2bn(&exponent, exp); + + /* OpenSSL Version 1.1.0 and later don't allow direct access to RSA + stuct */ + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + RSA_set0_key(rsa_pubkey, modulus, exponent, NULL); + #else + rsa_pubkey->n = modulus; + rsa_pubkey->e = exponent; + rsa_pubkey->d = rsa_pubkey->p = rsa_pubkey->q = NULL; + #endif /* first create digest of data */ tb_hash_t digest; if ( !hash_buffer(data, data_size, &digest, TB_HALG_SHA1_LG) ) { ERROR("Error: failed to hash list\n"); + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return false; } @@ -327,10 +339,14 @@ ERROR("Error: failed to verify list: %s\n", ERR_error_string(ERR_get_error(), NULL)); ERR_free_strings(); - RSA_free(rsa_pubkey); + BN_free(modulus); + BN_free(exponent); + RSA_free(rsa_pubkey); return false; } - + + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return true; } diff -Nru tboot-1.9.5/lcptools/mlehash.c tboot-1.9.6/lcptools/mlehash.c --- tboot-1.9.5/lcptools/mlehash.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools/mlehash.c 2017-07-11 23:03:58.000000000 +0000 @@ -336,7 +336,7 @@ bool help = false; char *mle_file; extern int optind; /* current index of get_opt() */ - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; char *cmdline = NULL; @@ -418,10 +418,10 @@ /* SHA-1 the MLE portion of the image */ md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, exp_start + mle_hdr->mle_start_off, + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, exp_start + mle_hdr->mle_start_off, mle_hdr->mle_end_off - mle_hdr->mle_start_off); - EVP_DigestFinal(&ctx, (unsigned char *)hash, NULL); + EVP_DigestFinal(ctx, (unsigned char *)hash, NULL); log_info("SHA-1 = "); /* we always print the hash regardless of verbose mode */ @@ -432,11 +432,13 @@ } printf("\n"); + EVP_MD_CTX_destroy(ctx); free(base); free(exp_start); return 0; error: + EVP_MD_CTX_destroy(ctx); free(base); free(exp_start); return 1; diff -Nru tboot-1.9.5/lcptools-v2/crtpollist.c tboot-1.9.6/lcptools-v2/crtpollist.c --- tboot-1.9.5/lcptools-v2/crtpollist.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools-v2/crtpollist.c 2017-07-11 23:03:58.000000000 +0000 @@ -160,14 +160,19 @@ memset(sig, 0, sizeof(lcp_rsa_signature_t) + 2*keysize); sig->rsa_signature.pubkey_size = keysize; - if ( (unsigned int)BN_num_bytes(pubkey->n) != keysize ) { - ERROR("Error: modulus size not match key size\n"); - free(sig); - RSA_free(pubkey); - return NULL; - } + + BIGNUM *modulus = BN_new(); + + /* OpenSSL Version 1.1.0 and later don't allow direct access to RSA + stuct */ + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + RSA_get0_key(pubkey, (const BIGNUM **)&modulus, NULL, NULL); + #else + modulus = pubkey->n; + #endif + unsigned char key[keysize]; - BN_bn2bin(pubkey->n, key); + BN_bn2bin(modulus, key); /* openssl key is big-endian and policy requires little-endian, so reverse bytes */ for ( unsigned int i = 0; i < keysize; i++ ) @@ -179,6 +184,7 @@ } LOG("read rsa pubkey succeed!\n"); + BN_free(modulus); RSA_free(pubkey); return sig; } @@ -383,9 +389,16 @@ BIGNUM *r = BN_new(); BIGNUM *s = BN_new(); - r = ecdsasig->r; - s = ecdsasig->s; - unsigned int BN_r_size = BN_num_bytes(r); + + /* OpenSSL Version 1.1.0 and later don't allow direct access to + ECDSA_SIG stuct */ + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + ECDSA_SIG_get0(ecdsasig, (const BIGNUM **)&r, (const BIGNUM **)&s); + #else + r = ecdsasig->r; + s = ecdsasig->s; + #endif + unsigned int BN_r_size = BN_num_bytes(r); unsigned int BN_s_size = BN_num_bytes(s); unsigned char key_r[BN_r_size]; unsigned char key_s[BN_s_size]; @@ -403,6 +416,8 @@ display_tpm20_signature(" ", sig, pollist->sig_alg, false); } + BN_free(r); + BN_free(s); return true; } return false; diff -Nru tboot-1.9.5/lcptools-v2/hash.c tboot-1.9.6/lcptools-v2/hash.c --- tboot-1.9.5/lcptools-v2/hash.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools-v2/hash.c 2017-07-11 23:03:58.000000000 +0000 @@ -82,33 +82,36 @@ return false; if ( hash_alg == TB_HALG_SHA1 ) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, size); - EVP_DigestFinal(&ctx, hash->sha1, NULL); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, size); + EVP_DigestFinal(ctx, hash->sha1, NULL); + EVP_MD_CTX_destroy(ctx); return true; } else if (hash_alg == TB_HALG_SHA256) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; md = EVP_sha256(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, size); - EVP_DigestFinal(&ctx, hash->sha256, NULL); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, size); + EVP_DigestFinal(ctx, hash->sha256, NULL); + EVP_MD_CTX_destroy(ctx); return true; } else if (hash_alg == TB_HALG_SHA384) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; md = EVP_sha384(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, size); - EVP_DigestFinal(&ctx, hash->sha384, NULL); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, size); + EVP_DigestFinal(ctx, hash->sha384, NULL); + EVP_MD_CTX_destroy(ctx); return true; } else @@ -129,15 +132,16 @@ return false; if ( hash_alg == TB_HALG_SHA1 ) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; memcpy(buf, &(hash1->sha1), sizeof(hash1->sha1)); memcpy(buf + sizeof(hash1->sha1), &(hash2->sha1), sizeof(hash1->sha1)); md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, 2*sizeof(hash1->sha1)); - EVP_DigestFinal(&ctx, hash1->sha1, NULL); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, 2*sizeof(hash1->sha1)); + EVP_DigestFinal(ctx, hash1->sha1, NULL); + EVP_MD_CTX_destroy(ctx); return true; } else diff -Nru tboot-1.9.5/lcptools-v2/lcputils.c tboot-1.9.6/lcptools-v2/lcputils.c --- tboot-1.9.5/lcptools-v2/lcputils.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/lcptools-v2/lcputils.c 2017-07-11 23:03:58.000000000 +0000 @@ -370,14 +370,24 @@ ERROR("Error: failed to allocate key\n"); return false; } - rsa_pubkey->n = BN_bin2bn(key, pubkey_size, NULL); + + BIGNUM *modulus = BN_new(); + BIGNUM *exponent = BN_new(); + modulus = BN_bin2bn(key, pubkey_size, NULL); /* uses fixed exponent (LCP_SIG_EXPONENT) */ char exp[32]; snprintf(exp, sizeof(exp), "%u", LCP_SIG_EXPONENT); - rsa_pubkey->e = NULL; - BN_dec2bn(&rsa_pubkey->e, exp); - rsa_pubkey->d = rsa_pubkey->p = rsa_pubkey->q = NULL; + BN_dec2bn(&exponent, exp); + /* OpenSSL Version 1.1.0 and later don't allow direct access to RSA + stuct */ + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + RSA_set0_key(rsa_pubkey, modulus, exponent, NULL); + #else + rsa_pubkey->n = modulus; + rsa_pubkey->e = exponent; + rsa_pubkey->d = rsa_pubkey->p = rsa_pubkey->q = NULL; + #endif uint16_t hashalg = TPM_ALG_SHA1; lcp_mle_element_t2 *mle; @@ -397,6 +407,8 @@ tb_hash_t digest; if ( !hash_buffer(data, data_size, &digest, hashalg) ) { ERROR("Error: failed to hash list\n"); + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return false; } @@ -439,6 +451,8 @@ ERROR("Error: failed to verify list: %s\n", ERR_error_string(ERR_get_error(), NULL)); ERR_free_strings(); + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return false; } @@ -453,6 +467,8 @@ ERROR("Error: failed to verify list: %s\n", ERR_error_string(ERR_get_error(), NULL)); ERR_free_strings(); + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return false; } @@ -467,6 +483,8 @@ ERROR("Error: failed to verify list: %s\n", ERR_error_string(ERR_get_error(), NULL)); ERR_free_strings(); + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return false; } @@ -481,6 +499,8 @@ ERROR("Error: failed to verify list: %s\n", ERR_error_string(ERR_get_error(), NULL)); ERR_free_strings(); + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return false; } @@ -488,9 +508,13 @@ default : LOG("unknown hash alg\n"); + BN_free(modulus); + BN_free(exponent); return false; } + BN_free(modulus); + BN_free(exponent); RSA_free(rsa_pubkey); return true; } diff -Nru tboot-1.9.5/README tboot-1.9.6/README --- tboot-1.9.5/README 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/README 2017-07-11 23:03:58.000000000 +0000 @@ -272,6 +272,24 @@ It means tboot will use this algorithm to compute hash and use TPM2_PCR_Extend to extend it into PCRs. +o Recovering from measured launch failures. + When there's an error during SENTER, the system usually reboots. + Since the underlying cause is some sort of configuration error, the system can + end up in a loop rebooting endlessly after each attempted measured launch. In + some environments it make more sense to fall back to booting the kernel directly + so that the system comes up and is remotely accessible. After that the issue can + be diagnosed and the system power-cycled to clear the error. To enable this + behavior, a command line option can be used: + ignore_prev_err=false|true // defaults to true + + The option defaults to true, which preserves the original behavior i.e. try a + measured launch even if the previous measured launch had errors. + Setting the value to false will check if the previous measured launch was + successful by inspecting the TXT.ERRORCODE value. If measured launch failed, + tboot will launch the kernel directly without trying to perform a measured launch. + + Note: TXT.ERRORCODE is only cleared if the system is power cycled. A reboot is not + sufficient to clear the error code. PCR Usage: --------- diff -Nru tboot-1.9.5/tboot/20_linux_tboot tboot-1.9.6/tboot/20_linux_tboot --- tboot-1.9.5/tboot/20_linux_tboot 2016-12-20 22:29:15.000000000 +0000 +++ tboot-1.9.6/tboot/20_linux_tboot 2017-07-11 23:03:58.000000000 +0000 @@ -26,6 +26,8 @@ . /usr/share/grub/grub-mkconfig_lib elif test -e ${libdir}/grub/grub-mkconfig_lib; then . ${libdir}/grub/grub-mkconfig_lib +elif test -e /usr/share/grub2/grub-mkconfig_lib; then + . /usr/share/grub2/grub-mkconfig_lib fi if test -e ${sysconfdir}/default/grub-tboot; then @@ -199,7 +201,7 @@ tboot_dirname=`dirname ${current_tboot}` rel_tboot_dirname=`make_system_path_relative_to_its_root $tboot_dirname` # tboot_version=`echo $tboot_basename | sed -e "s,.gz$,,g;s,^tboot-,,g"` - tboot_version="1.9.5" + tboot_version="1.9.6" echo "submenu \"tboot ${tboot_version}\" {" while [ "x$list" != "x" ] ; do linux=`version_find_latest $list` diff -Nru tboot-1.9.5/tboot/20_linux_xen_tboot tboot-1.9.6/tboot/20_linux_xen_tboot --- tboot-1.9.5/tboot/20_linux_xen_tboot 2016-12-20 22:29:54.000000000 +0000 +++ tboot-1.9.6/tboot/20_linux_xen_tboot 2017-07-11 23:03:58.000000000 +0000 @@ -26,6 +26,8 @@ . /usr/share/grub/grub-mkconfig_lib elif test -e ${libdir}/grub/grub-mkconfig_lib; then . ${libdir}/grub/grub-mkconfig_lib +elif test -e /usr/share/grub2/grub-mkconfig_lib; then + . /usr/share/grub2/grub-mkconfig_lib fi if test -e ${sysconfdir}/default/grub-tboot; then @@ -214,7 +216,7 @@ tboot_basename=`basename ${current_tboot}` tboot_dirname=`dirname ${current_tboot}` rel_tboot_dirname=`make_system_path_relative_to_its_root $tboot_dirname` - tboot_version="1.9.5" + tboot_version="1.9.6" list="${linux_list}" echo "submenu \"Xen ${xen_version}\" \"Tboot ${tboot_version}\"{" while [ "x$list" != "x" ] ; do diff -Nru tboot-1.9.5/tboot/common/acpi.c tboot-1.9.6/tboot/common/acpi.c --- tboot-1.9.5/tboot/common/acpi.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/acpi.c 2017-07-11 23:03:58.000000000 +0000 @@ -212,7 +212,7 @@ } } - printk(TBOOT_ERR"cann't find %s table.\n", table_name); + printk(TBOOT_ERR"can't find %s table.\n", table_name); return NULL; } @@ -221,6 +221,11 @@ return (struct acpi_dmar *)find_table(DMAR_SIG); } +bool vtd_bios_enabled(void) +{ + return find_table(DMAR_SIG) != NULL; +} + bool save_vtd_dmar_table(void) { /* find DMAR table and save it */ diff -Nru tboot-1.9.5/tboot/common/boot.S tboot-1.9.6/tboot/common/boot.S --- tboot-1.9.5/tboot/common/boot.S 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/boot.S 2017-07-11 23:03:58.000000000 +0000 @@ -240,22 +240,21 @@ or $CR4_MCE,%eax mov %eax,%cr4 - # get initial APIC ID for this processor - mov $0x01, %eax - xor %ebx, %ebx + # get initial 32-bit local APIC ID for this processor + mov $0x0b, %eax + xor %edx, %edx cpuid - shr $24, %ebx # set stack as id-based offset from AP stack base # spin hlt if we exceed, since C code can't handle shared stack - cmp $NR_CPUS, %ebx + cmp $NR_CPUS, %edx jl 3f # TBD: increment global counter so BSP can tell we exceeded NR_CPUS 2: cli hlt jmp 2b 3: mov $AP_STACK_SIZE, %eax - mul %ebx + mul %edx mov $ap_stacks, %ecx sub %eax, %ecx mov %ecx, %esp diff -Nru tboot-1.9.5/tboot/common/cmdline.c tboot-1.9.6/tboot/common/cmdline.c --- tboot-1.9.5/tboot/common/cmdline.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/cmdline.c 2017-07-11 23:03:58.000000000 +0000 @@ -32,7 +32,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * */ - +#ifndef IS_INCLUDED #include #include #include @@ -49,7 +49,7 @@ #include #include #include - +#endif /* * copy of original command line * part of tboot measurement (hence in .text section) @@ -83,7 +83,8 @@ { "min_ram", "0" }, /* size in bytes | 0 for no min */ { "call_racm", "false" }, /* true|false|check */ { "measure_nv", "false" }, /* true|false */ - { "extpol", "sha1" }, /* agile|embedded|sha1|sha256|sm3|... */ + { "extpol", "sha1" }, /*agile|embedded|sha1|sha256|sm3|... */ + { "ignore_prev_err", "true"}, /* true|false */ { NULL, NULL } }; static char g_tboot_param_values[ARRAY_SIZE(g_tboot_cmdline_options)][MAX_VALUE_LEN]; @@ -499,10 +500,9 @@ return true; } - void get_tboot_extpol(void) { - const char *extpol = get_option_val(g_tboot_cmdline_options, g_tboot_param_values, "extpol"); + const char *extpol = get_option_val(g_tboot_cmdline_options, g_tboot_param_values, "extpol"); if ( extpol == NULL ) { g_tpm->extpol = TB_EXTPOL_FIXED; @@ -528,6 +528,17 @@ } } +bool get_tboot_ignore_prev_err(void) +{ + const char *ignore_prev_err = + get_option_val(g_tboot_cmdline_options, + g_tboot_param_values, + "ignore_prev_err"); + if ( ignore_prev_err == NULL || strcmp(ignore_prev_err, "true") == 0 ) + return true; + return false; +} + /* * linux kernel command line parsing */ diff -Nru tboot-1.9.5/tboot/common/e820.c tboot-1.9.6/tboot/common/e820.c --- tboot-1.9.5/tboot/common/e820.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/e820.c 2017-07-11 23:03:58.000000000 +0000 @@ -60,14 +60,10 @@ static unsigned int g_nr_map; static memory_map_t *g_copy_e820_map = (memory_map_t *)TBOOT_E820_COPY_ADDR; -static efi_memory_desc_t *efi_memmap_addr = NULL; -static uint32_t efi_memmap_size = 0; - -static inline void split64b(uint64_t val, uint32_t *val_lo, uint32_t *val_hi) -{ - *val_lo = (uint32_t)(val & 0xffffffff); - *val_hi = (uint32_t)(val >> 32); -} +static inline void split64b(uint64_t val, uint32_t *val_lo, uint32_t *val_hi) { + *val_lo = (uint32_t)(val & 0xffffffff); + *val_hi = (uint32_t)(val >> 32); + } static inline uint64_t combine64b(uint32_t val_lo, uint32_t val_hi) { @@ -691,72 +687,6 @@ *ram_size = last_fit_size; } -#define PAGE_4K (1 << 12) - -efi_memory_desc_t -*get_efi_memmap(uint32_t *memmap_size) -{ - unsigned int i; - memory_map_t *mp; - efi_memory_desc_t *ep; - uint32_t space_required; - - if (efi_memmap_addr == NULL){ - /* we haven't done the conversion yet--is there room? */ - space_required = sizeof(memory_map_t) * g_nr_map + - sizeof(efi_memory_desc_t) * g_nr_map + 0xf; - if (space_required >= TBOOT_E820_COPY_SIZE){ - printk(TBOOT_ERR - "Insufficient space to make EFI copy of E820 [%d => %d]\n", - space_required, TBOOT_E820_COPY_SIZE); - return NULL; - } - /* for fun, we'll align the entries to 0x10 */ - ep = efi_memmap_addr = (efi_memory_desc_t *) - ((TBOOT_E820_COPY_ADDR + sizeof(memory_map_t) * g_nr_map + 0xf) - & ~0xf); - /* printk(TBOOT_INFO"efi memmap base now at %p\n", ep); */ - mp = g_copy_e820_map; - for (i = 0; i < g_nr_map; i++){ - uint64_t length; - ep[i].phys_addr = ep[i].virt_addr = e820_base_64(mp + i); - ep[i].pad = 0; - length = e820_length_64(mp + i); - length += PAGE_4K - 1; - length &= ~(PAGE_4K - 1); - ep[i].num_pages = length / PAGE_4K; - switch (mp[i].type){ - case E820_RAM: - ep[i].type = EFI_CONVENTIONAL_MEMORY; - ep[i].attribute |= EFI_MEMORY_WB; - break; - case E820_ACPI: - ep[i].type = EFI_ACPI_RECLAIM_MEMORY; - break; - case E820_NVS: - ep[i].type = EFI_ACPI_MEMORY_NVS; - break; - case E820_UNUSABLE: - ep[i].type = EFI_UNUSABLE_MEMORY; - break; - case E820_GAP: - case E820_MIXED: - case E820_RESERVED: - default: - ep[i].type = EFI_RESERVED_TYPE; - break; - } - /* - printk(TBOOT_INFO - "EFI entry %d at %016Lx type %d with %Lx pages\n", - i, ep[i].phys_addr, ep[i].type, ep[i].num_pages); - */ - efi_memmap_size += sizeof(efi_memory_desc_t); - } - } - *memmap_size = efi_memmap_size; - return efi_memmap_addr; -} /* * Local variables: diff -Nru tboot-1.9.5/tboot/common/linux.c tboot-1.9.6/tboot/common/linux.c --- tboot-1.9.5/tboot/common/linux.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/linux.c 2017-07-11 23:03:58.000000000 +0000 @@ -120,8 +120,8 @@ /* recommended layout 0x0000 - 0x7FFF Real mode kernel - 0x8000 - 0x8FFF Stack and heap - 0x9000 - 0x90FF Kernel command line + 0x8000 - 0x8CFF Stack and heap + 0x8D00 - 0x90FF Kernel command line for details, see linux_defns.h */ @@ -161,54 +161,71 @@ hdr->loadflags |= FLAG_CAN_USE_HEAP; /* can use heap */ hdr->heap_end_ptr = KERNEL_CMDLINE_OFFSET - BOOT_SECTOR_OFFSET; - /* load initrd and set ramdisk_image and ramdisk_size */ - /* The initrd should typically be located as high in memory as - possible, as it may otherwise get overwritten by the early - kernel initialization sequence. */ - - /* check if Linux command line explicitly specified a memory limit */ - uint64_t mem_limit; - get_linux_mem(&mem_limit); - if ( mem_limit > 0x100000000ULL || mem_limit == 0 ) - mem_limit = 0x100000000ULL; - - uint64_t max_ram_base, max_ram_size; - get_highest_sized_ram(initrd_size, mem_limit, - &max_ram_base, &max_ram_size); - if ( max_ram_size == 0 ) { - printk(TBOOT_ERR"not enough RAM for initrd\n"); - return false; - } - if ( initrd_size > max_ram_size ) { - printk(TBOOT_ERR"initrd_size is too large\n"); - return false; - } - if ( max_ram_base > ((uint64_t)(uint32_t)(~0)) ) { - printk(TBOOT_ERR"max_ram_base is too high\n"); - return false; - } - if ( plus_overflow_u32((uint32_t)max_ram_base, - (uint32_t)(max_ram_size - initrd_size)) ) { - printk(TBOOT_ERR"max_ram overflows\n"); - return false; - } - initrd_base = (max_ram_base + max_ram_size - initrd_size) & PAGE_MASK; - - /* should not exceed initrd_addr_max */ - if ( initrd_base + initrd_size > hdr->initrd_addr_max ) { - if ( hdr->initrd_addr_max < initrd_size ) { - printk(TBOOT_ERR"initrd_addr_max is too small\n"); + if ( initrd_size > 0 ) { + /* load initrd and set ramdisk_image and ramdisk_size */ + /* The initrd should typically be located as high in memory as + possible, as it may otherwise get overwritten by the early + kernel initialization sequence. */ + + /* check if Linux command line explicitly specified a memory limit */ + uint64_t mem_limit; + get_linux_mem(&mem_limit); + if ( mem_limit > 0x100000000ULL || mem_limit == 0 ) + mem_limit = 0x100000000ULL; + + uint64_t max_ram_base, max_ram_size; + get_highest_sized_ram(initrd_size, mem_limit, + &max_ram_base, &max_ram_size); + if ( max_ram_size == 0 ) { + printk(TBOOT_ERR"not enough RAM for initrd\n"); return false; } - initrd_base = hdr->initrd_addr_max - initrd_size; - initrd_base = initrd_base & PAGE_MASK; - } + if ( initrd_size > max_ram_size ) { + printk(TBOOT_ERR"initrd_size is too large\n"); + return false; + } + if ( max_ram_base > ((uint64_t)(uint32_t)(~0)) ) { + printk(TBOOT_ERR"max_ram_base is too high\n"); + return false; + } + if ( plus_overflow_u32((uint32_t)max_ram_base, + (uint32_t)(max_ram_size - initrd_size)) ) { + printk(TBOOT_ERR"max_ram overflows\n"); + return false; + } + initrd_base = (max_ram_base + max_ram_size - initrd_size) & PAGE_MASK; - memmove((void *)initrd_base, initrd_image, initrd_size); - printk(TBOOT_DETA"Initrd from 0x%lx to 0x%lx\n", - (unsigned long)initrd_base, - (unsigned long)(initrd_base + initrd_size)); + /* should not exceed initrd_addr_max */ + if ( initrd_base + initrd_size > hdr->initrd_addr_max ) { + if ( hdr->initrd_addr_max < initrd_size ) { + printk(TBOOT_ERR"initrd_addr_max is too small\n"); + return false; + } + initrd_base = hdr->initrd_addr_max - initrd_size; + initrd_base = initrd_base & PAGE_MASK; + } + + /* check for overlap with a kernel image placed high in memory */ + if( (initrd_base < ((uint32_t)linux_image + linux_size)) + && ((uint32_t)linux_image < (initrd_base+initrd_size)) ){ + /* set the starting address just below the image */ + initrd_base = (uint32_t)linux_image - initrd_size; + initrd_base = initrd_base & PAGE_MASK; + /* make sure we're still in usable RAM and above tboot end address*/ + if( initrd_base < max_ram_base ){ + printk(TBOOT_ERR"no available memory for initrd\n"); + return false; + } + } + memmove((void *)initrd_base, initrd_image, initrd_size); + printk(TBOOT_DETA"Initrd from 0x%lx to 0x%lx\n", + (unsigned long)initrd_base, + (unsigned long)(initrd_base + initrd_size)); + + } + else + initrd_base = (uint32_t)initrd_image; hdr->ramdisk_image = initrd_base; hdr->ramdisk_size = initrd_size; @@ -288,6 +305,11 @@ /* set cmd_line_ptr */ hdr->cmd_line_ptr = real_mode_base + KERNEL_CMDLINE_OFFSET; + /* Save linux header struct to temp memory, in case the it is overwritten by memmove below*/ + linux_kernel_header_t temp_hdr; + memmove(&temp_hdr, hdr, sizeof(temp_hdr)); + hdr = &temp_hdr; + /* load protected-mode part */ memmove((void *)protected_mode_base, linux_image + real_mode_size, protected_mode_size); @@ -303,14 +325,17 @@ /* copy cmdline */ const char *kernel_cmdline = get_cmdline(g_ldr_ctx); - - printk(TBOOT_INFO"Linux cmdline placed in header: "); - printk_long(kernel_cmdline); - printk(TBOOT_INFO"\n"); - - memset((void *)hdr->cmd_line_ptr,0,TBOOT_KERNEL_CMDLINE_SIZE); - - memcpy((void *)hdr->cmd_line_ptr, kernel_cmdline, strlen(kernel_cmdline)); + const size_t kernel_cmdline_size = REAL_END_OFFSET - KERNEL_CMDLINE_OFFSET; + size_t kernel_cmdline_strlen = strlen(kernel_cmdline); + if (kernel_cmdline_strlen > kernel_cmdline_size - 1) + kernel_cmdline_strlen = kernel_cmdline_size - 1; + memset((void *)hdr->cmd_line_ptr, 0, kernel_cmdline_size); + memcpy((void *)hdr->cmd_line_ptr, kernel_cmdline, kernel_cmdline_strlen); + + printk(TBOOT_INFO"Linux cmdline from 0x%lx to 0x%lx:\n", + (unsigned long)hdr->cmd_line_ptr, + (unsigned long)(hdr->cmd_line_ptr + kernel_cmdline_size)); + printk_long((void *)hdr->cmd_line_ptr); /* need to put boot_params in real mode area so it gets mapped */ boot_params = (boot_params_t *)(real_mode_base + real_mode_size); @@ -325,6 +350,10 @@ uint32_t address = 0; uint64_t long_address = 0UL; + uint32_t descr_size = 0, descr_vers = 0, mmap_size = 0, efi_mmap_addr = 0; + + + /* loader signature */ memcpy(&efi->efi_ldr_sig, "EL64", sizeof(uint32_t)); @@ -343,26 +372,30 @@ } } - /* EFI memmap descriptor size */ - efi->efi_memdescr_size = 0x30; - - /* EFI memmap descriptor version */ - efi->efi_memdescr_ver = 1; - -#if 1 /* EFI memmap addr */ - { - uint32_t length; - efi->efi_memmap = (uint32_t) get_efi_memmap(&length); - /* EFI memmap size */ - efi->efi_memmap_size = length; - } -#else - efi->efi_memmap = 0; - efi->efi_memmap_size = 0x70; -#endif + efi_mmap_addr = find_efi_memmap(g_ldr_ctx, &descr_size, + &descr_vers, &mmap_size); + if (!efi_mmap_addr) { + printk(TBOOT_INFO"failed to get EFI memory map\n"); + efi->efi_memdescr_size = 0x1; // Avoid div by 0 in kernel. + efi->efi_memmap_size = 0; + efi->efi_memmap = 0; + } else { + efi->efi_memdescr_size = descr_size; + efi->efi_memdescr_ver = descr_vers; + efi->efi_memmap_size = mmap_size; + efi->efi_memmap = efi_mmap_addr; + /* From Multiboot2 spec: + * The bootloader must not load any part of the kernel, the modules, + * the Multiboot2 information structure, etc. higher than 4 GiB - 1. + */ + efi->efi_memmap_hi = 0; + + printk(TBOOT_INFO "EFI memmap: memmap base: 0x%x, memmap size: 0x%x\n", + efi->efi_memmap, efi->efi_memmap_size); + printk(TBOOT_INFO "EFI memmap: descr size: 0x%x, descr version: 0x%x\n", + efi->efi_memdescr_size, efi->efi_memdescr_ver); + } - /* EFI memmap high--since we're consing our own, we know this == 0 */ - efi->efi_memmap_hi = 0; /* if we're here, GRUB2 probably threw a framebuffer tag at us */ load_framebuffer_info(g_ldr_ctx, (void *)scr); } diff -Nru tboot-1.9.5/tboot/common/loader.c tboot-1.9.6/tboot/common/loader.c --- tboot-1.9.5/tboot/common/loader.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/loader.c 2017-07-11 23:03:58.000000000 +0000 @@ -774,98 +774,160 @@ /* * Move all mbi components/modules/mbi to end of memory */ -static bool move_modules_to_high_memory(loader_ctx *lctx) +static bool move_modules_to_high_memory(loader_ctx *lctx) { - uint64_t max_ram_base = 0, - max_ram_size = 0; - uint32_t memRequired = 0; + uint32_t memRequired; + uint64_t max_ram_base, max_ram_size, ld_ceiling; - uint32_t module_count = get_module_count(lctx); + uint32_t module_count, mod_i, mods_remaining; + module_t *m; - for ( unsigned int i = 0; i < module_count; i++ ) - { - module_t *m = get_module(lctx,i); + if (LOADER_CTX_BAD(lctx)) + return false; + + /* Determine the size of memory required to pack all modules together */ + module_count = get_module_count(lctx); + for( memRequired=0, mod_i=0; mod_i < module_count; mod_i++ ){ + m = get_module(lctx, mod_i); memRequired += PAGE_UP(m->mod_end - m->mod_start); } - get_highest_sized_ram(memRequired, 0x100000000ULL, &max_ram_base, &max_ram_size); - if(!max_ram_base || !max_ram_size) - { - printk(TBOOT_INFO"ERROR No suitable memory area found for image relocation!\n"); - printk(TBOOT_INFO"required 0x%X\n", memRequired); + /* NOTE: the e820 map has been modified already to reserve critical + memory regions (tboot memory, etc ...). get_highest_sized_ram + will return a range that excludes critical memory regions. */ + get_highest_sized_ram( memRequired, 0x100000000ULL, + &max_ram_base, &max_ram_size); + if(!max_ram_base || !max_ram_size){ + printk(TBOOT_INFO"ERROR No memory area found for image relocation!\n"); + printk(TBOOT_INFO"required 0x%X\n", memRequired); return false; } + printk(TBOOT_INFO"highest suitable area @ 0x%llX (size 0x%llX)\n", + max_ram_base, max_ram_size); + ld_ceiling = PAGE_DOWN(max_ram_base + max_ram_size); + + /* Move modules below the load ceiling upto the ceiling: + Prevent module corruption: + - Move modules in order of highest to lowest. + - Only move modules completely below the load ceiling. + */ + for( mods_remaining=module_count; mods_remaining > 0; mods_remaining--){ + uint32_t highest_mod_i = 0, + highest_mod_base = 0, + highest_mod_end = 0; + bool mod_found = false; + for( mod_i=0; mod_imod_start < ld_ceiling) ){ + if( (m->mod_end > highest_mod_end) || !mod_found ){ + highest_mod_i = mod_i; + highest_mod_base= m->mod_start; + highest_mod_end = m->mod_end; + mod_found = true; + } + } + } - printk(TBOOT_INFO"highest suitable area @ 0x%llX (size 0x%llX)\n", max_ram_base, max_ram_size); - - unsigned long target_addr = PAGE_DOWN(max_ram_base + max_ram_size); - - for ( unsigned int i = 0; i < module_count; i++ ) - { - unsigned long base, size; - module_t *m = get_module(lctx,i); - base = m->mod_start; - size = m->mod_end - m->mod_start; - printk(TBOOT_INFO"moving module %u (%lu bytes) from 0x%08X ", i, size, (uint32_t)base); + /* If no modules found, all modules are above ld_ceiling, We're done. */ + if( !mod_found ) + break; - //calculate target addresses - target_addr = PAGE_DOWN(target_addr - size); - printk(TBOOT_INFO"to 0x%08X\n", (uint32_t)target_addr); - - memcpy((void *)target_addr, (void *)base, size); - m->mod_start = target_addr; - m->mod_end = target_addr + size; + m = get_module(lctx, highest_mod_i); + /* only move the highest module if explicitly below the ceiling */ + if(highest_mod_end < ld_ceiling){ + uint32_t size = highest_mod_end - highest_mod_base; + uint32_t highest_mod_newbase = PAGE_DOWN(ld_ceiling-size); + printk(TBOOT_INFO"moving module %u (%u B) from 0x%08X to 0x%08X\n", + highest_mod_i, size, highest_mod_base, highest_mod_newbase); + memcpy((void *)highest_mod_newbase, (void *)highest_mod_base, size); + m->mod_start= highest_mod_newbase; + m->mod_end = highest_mod_newbase+size; + } + /* lower the celing to the base address of the highest module */ + ld_ceiling = PAGE_DOWN(m->mod_start); } - return true; } /* * Move any mbi components/modules/mbi that just above the kernel */ -static bool move_modules_above_elf_kernel(loader_ctx *lctx, elf_header_t *kernel_image) +static bool move_modules_above_elf_kernel( loader_ctx *lctx, + elf_header_t *kernel_image) { + void *elf_start, *elf_end; + uint32_t ld_floor, ld_ceiling; + + uint32_t module_count, mod_i, mods_remaining; + module_t *m; + if (LOADER_CTX_BAD(lctx)) return false; /* get end address of loaded elf image */ - void *elf_start=NULL, *elf_end=NULL; - if ( !get_elf_image_range(kernel_image, &elf_start, &elf_end) ) - { - printk(TBOOT_INFO"ERROR: failed tget elf image range\n"); + if ( !get_elf_image_range(kernel_image, &elf_start, &elf_end) ){ + printk(TBOOT_INFO"ERROR: failed to get elf image range\n"); + return false; } - printk(TBOOT_INFO"ELF kernel top is at 0x%X\n", (uint32_t)elf_end); - uint32_t target_addr = (uint32_t)elf_end; - - /* stay above tboot if elf kernel is loaded below tboot */ - if ( target_addr < get_tboot_mem_end() ) - target_addr = get_tboot_mem_end(); - - /* keep modules page aligned */ - target_addr = PAGE_UP(target_addr); - - uint32_t module_count = get_module_count(lctx); - - for ( unsigned int i = 0; i < module_count; i++ ) - { - unsigned long base, size; - module_t *m = get_module(lctx,i); - base = m->mod_start; - size = m->mod_end - m->mod_start; - printk(TBOOT_INFO"moving module %u (%lu bytes) from 0x%08X ", i, size, (uint32_t)base); - - //calculate target addresses - printk(TBOOT_INFO"to 0x%08X\n", (uint32_t)target_addr); + /* compute the lowest base address of all the modules: the ld ceiling */ + module_count = get_module_count(lctx); + for( mod_i=0, ld_ceiling=0; mod_i < module_count; mod_i++ ){ + m = get_module(lctx,mod_i); + ld_ceiling = (ld_ceiling < m->mod_start)? m->mod_start : ld_ceiling; + } + + /* set ld_floor to the highest of tboot end address or the ELF-image + end address, and then page align */ + ld_floor = get_tboot_mem_end(); + ld_floor = (ld_floor < (uint32_t)elf_end)? (uint32_t)elf_end : ld_floor; + ld_floor = PAGE_UP(ld_floor); + + /* Ensures all modules are above ld_floor: only move mods down, never up. + Failing this check is an indication ELF-loading may have corrupted one + of the modules. */ + if( (uint32_t)ld_floor > ld_ceiling ){ + printk( TBOOT_INFO"Load floor (0x%08X) > load ceiling (0x%08X)\n", + ld_floor, ld_ceiling); + return false; + } - memcpy((void *)target_addr, (void *)base, size); - m->mod_start = target_addr; - m->mod_end = target_addr + size; + /* the i-th iteration of this loop will + move the i-th lowest module in memory to ld_floor + and raise ld_floor to the new end address of the i-th lowest module */ + for( mods_remaining = module_count; mods_remaining > 0; mods_remaining--){ + uint32_t lowest_mod_i = 0, + lowest_mod_base = 0, + lowest_mod_end = 0; + bool mod_found = false; + /* find the lowest module above the floor */ + for( mod_i=0; mod_imod_start >= ld_floor){ + if( (m->mod_start < lowest_mod_base) || !mod_found ){ + lowest_mod_i = mod_i; + lowest_mod_base= m->mod_start; + lowest_mod_end = m->mod_end; + mod_found = true; + } + } + } + m = get_module(lctx, lowest_mod_i); - target_addr = PAGE_UP(target_addr + size); + /* only move the lowest module if not already at the floor */ + if(lowest_mod_base > ld_floor){ + uint32_t size = lowest_mod_end - lowest_mod_base; + uint32_t lowest_mod_newbase = ld_floor; /* already page aligned */ + printk(TBOOT_INFO"moving module %u (%u B) from 0x%08X to 0x%08X\n", + lowest_mod_i, size, lowest_mod_base, lowest_mod_newbase); + memcpy((void *)lowest_mod_newbase, (void *)lowest_mod_base, size); + m->mod_start= lowest_mod_newbase; + m->mod_end = lowest_mod_newbase+size; + } + /* raise the floor to the end address of the lowest module */ + ld_floor = PAGE_UP(m->mod_end); } - return true; } @@ -1899,6 +1961,26 @@ return false; } + +uint32_t +find_efi_memmap(loader_ctx *lctx, uint32_t *descr_size, + uint32_t *descr_vers, uint32_t *mmap_size) { + struct mb2_tag *start = NULL, *hit = NULL; + struct mb2_tag_efi_mmap *efi_mmap = NULL; + + start = (struct mb2_tag *)(lctx->addr + 8); + hit = find_mb2_tag_type(start, MB2_TAG_TYPE_EFI_MMAP); + if (hit == NULL) { + return 0; + } + + efi_mmap = (struct mb2_tag_efi_mmap *)hit; + *descr_size = efi_mmap->descr_size; + *descr_vers = efi_mmap->descr_vers; + *mmap_size = efi_mmap->size; + return (uint32_t)(&efi_mmap->efi_mmap); +} + bool is_loader_launch_efi(loader_ctx *lctx) { diff -Nru tboot-1.9.5/tboot/common/policy.c tboot-1.9.6/tboot/common/policy.c --- tboot-1.9.5/tboot/common/policy.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/policy.c 2017-07-11 23:03:58.000000000 +0000 @@ -97,10 +97,12 @@ { TB_POLTYPE_CONT_NON_FATAL, TB_POLACT_CONTINUE, { {TB_ERR_FATAL, TB_POLACT_HALT}, + {TB_ERR_PREV_TXT_ERROR, TB_POLACT_UNMEASURED_LAUNCH}, {TB_ERR_TPM_NOT_READY, TB_POLACT_UNMEASURED_LAUNCH}, {TB_ERR_SMX_NOT_SUPPORTED, TB_POLACT_UNMEASURED_LAUNCH}, {TB_ERR_VMX_NOT_SUPPORTED, TB_POLACT_UNMEASURED_LAUNCH}, - {TB_ERR_TXT_NOT_SUPPORTED, TB_POLACT_UNMEASURED_LAUNCH}, + {TB_ERR_VTD_NOT_SUPPORTED, TB_POLACT_UNMEASURED_LAUNCH}, + {TB_ERR_TXT_NOT_SUPPORTED, TB_POLACT_UNMEASURED_LAUNCH}, {TB_ERR_SINIT_NOT_PRESENT, TB_POLACT_UNMEASURED_LAUNCH}, {TB_ERR_ACMOD_VERIFY_FAILED, TB_POLACT_UNMEASURED_LAUNCH}, {TB_ERR_NONE, TB_POLACT_CONTINUE}, diff -Nru tboot-1.9.5/tboot/common/tb_error.c tboot-1.9.6/tboot/common/tb_error.c --- tboot-1.9.5/tboot/common/tb_error.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/tb_error.c 2017-07-11 23:03:58.000000000 +0000 @@ -81,7 +81,10 @@ case TB_ERR_VMX_NOT_SUPPORTED: printk(TBOOT_ERR"VMX not supported.\n"); break; - case TB_ERR_TXT_NOT_SUPPORTED: + case TB_ERR_VTD_NOT_SUPPORTED: + printk(TBOOT_ERR"DMAR table not found. Check if Vt-D is enabled in BIOS.\n"); + break; + case TB_ERR_TXT_NOT_SUPPORTED: printk(TBOOT_ERR"TXT not supported.\n"); break; case TB_ERR_MODULES_NOT_IN_POLICY: @@ -114,6 +117,9 @@ case TB_ERR_NV_VERIFICATION_FAILED: printk(TBOOT_ERR"verifying nv against policy failed.\n"); break; + case TB_ERR_PREV_TXT_ERROR: + printk(TBOOT_ERR"previous measured launch had errors, skipping measured launch...\n"); + break; default: printk(TBOOT_ERR"unknown error (%d).\n", error); break; @@ -181,7 +187,7 @@ /* check TB_LAUNCH_ERR_IDX */ if ( read_tb_error_code(&error) ) { - if ( error != TB_ERR_FIXED ) + if ( error != TB_ERR_FIXED && error != TB_ERR_NONE ) return true; } diff -Nru tboot-1.9.5/tboot/common/tboot.c tboot-1.9.6/tboot/common/tboot.c --- tboot-1.9.5/tboot/common/tboot.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/tboot.c 2017-07-11 23:03:58.000000000 +0000 @@ -69,14 +69,17 @@ #include #include #include +#include extern void _prot_to_real(uint32_t dist_addr); extern bool set_policy(void); extern void verify_all_modules(loader_ctx *lctx); extern void verify_all_nvindices(void); extern void apply_policy(tb_error_t error); +extern void verify_IA32_se_svn_status(const acm_hdr_t *acm_hdr); void s3_launch(void); - +extern __data u32 handle2048; +extern __data tpm_contextsave_out tpm2_context_saved; /* counter timeout for waiting for all APs to exit guests */ #define AP_GUEST_EXIT_TIMEOUT 0x01000000 @@ -94,6 +97,7 @@ __data loader_ctx *g_ldr_ctx = &g_loader_ctx; __data uint32_t g_mb_orig_size = 0; + /* MLE/kernel shared data page (in boot.S) */ extern tboot_shared_t _tboot_shared; @@ -168,7 +172,7 @@ if ( s3_flag ) s3_launch(); - /* remove all TXT modules before verifying modules */ + /* remove all TXT sinit acm modules before verifying modules */ remove_txt_modules(g_ldr_ctx); /* @@ -198,14 +202,16 @@ size = (uint64_t)get_tboot_mem_end() - base; uint32_t mem_type = is_kernel_linux() ? E820_RESERVED : E820_UNUSABLE; printk(TBOOT_INFO"protecting tboot (%Lx - %Lx) in e820 table\n", base, (base + size - 1)); - if ( !e820_protect_region(base, size, mem_type) ) apply_policy(TB_ERR_FATAL); + if ( !e820_protect_region(base, size, mem_type) ) + apply_policy(TB_ERR_FATAL); /* if using memory logging, reserve log area */ if ( g_log_targets & TBOOT_LOG_TARGET_MEMORY ) { base = TBOOT_SERIAL_LOG_ADDR; size = TBOOT_SERIAL_LOG_SIZE; - printk(TBOOT_INFO"reserving tboot memory log (%Lx - %Lx) in e820 table\n", base, (base + size - 1)); - if ( !e820_protect_region(base, size, E820_RESERVED) ) apply_policy(TB_ERR_FATAL); + printk(TBOOT_INFO"reserving tboot memory log (%Lx - %Lx) in e820 table\n", base, (base + size - 1)); + if ( !e820_protect_region(base, size, E820_RESERVED) ) + apply_policy(TB_ERR_FATAL); } /* replace map in loader context with copy */ @@ -222,14 +228,21 @@ /* * verify nv indices against policy */ - if ( (g_tpm->major == TPM12_VER_MAJOR) && get_tboot_measure_nv() ) verify_all_nvindices(); + if ( (g_tpm->major == TPM12_VER_MAJOR) && get_tboot_measure_nv() ) + verify_all_nvindices(); /* * seal hashes of modules and VL policy to current value of PCR17 & 18 */ - if ( !seal_pre_k_state() ) apply_policy(TB_ERR_S3_INTEGRITY); + if ( !seal_pre_k_state() ) + apply_policy(TB_ERR_S3_INTEGRITY); - /* + + if ( g_tpm->major == TPM20_VER_MAJOR ) { + g_tpm->context_save(g_tpm, g_tpm->cur_loc, handle2048, &tpm2_context_saved); + } + + /* * init MLE/kernel shared data page */ memset(&_tboot_shared, 0, PAGE_SIZE); @@ -378,10 +391,6 @@ if ( !copy_e820_map(g_ldr_ctx) ) apply_policy(TB_ERR_FATAL); } - /* make TPM ready for measured launch */ - if (!tpm_detect()) - apply_policy(TB_ERR_TPM_NOT_READY); - /* we need to make sure this is a (TXT-) capable platform before using */ /* any of the features, incl. those required to check if the environment */ /* has already been launched */ @@ -395,8 +404,13 @@ if (!verify_acmod(g_sinit)) apply_policy(TB_ERR_ACMOD_VERIFY_FAILED); } + + /* make TPM ready for measured launch */ + if (!tpm_detect()) + apply_policy(TB_ERR_TPM_NOT_READY); - + /* verify SE enablement status */ + verify_IA32_se_svn_status(g_sinit); /* read tboot verified launch control policy from TPM-NV (will use default if none in TPM-NV) */ err = set_policy(); @@ -412,7 +426,10 @@ apply_policy(err); /* print any errors on last boot, which must be from TXT launch */ - txt_get_error(); + txt_display_errors(); + if (txt_has_error() && get_tboot_ignore_prev_err() == false) { + apply_policy(TB_ERR_PREV_TXT_ERROR); + } /* need to verify that platform can perform measured launch */ err = verify_platform(); @@ -425,7 +442,7 @@ /* this is being called post-measured launch */ if ( is_launched() ){ printk(TBOOT_INFO"Post_launch started ...\n"); - post_launch(); + post_launch(); } /* make the CPU ready for measured launch */ @@ -461,6 +478,13 @@ /* restore backed-up s3 wakeup page */ restore_saved_s3_wakeup_page(); + /* load saved tpm2 context for unseal */ + if ( g_tpm->major == TPM20_VER_MAJOR ) { + g_tpm->context_flush(g_tpm, g_tpm->cur_loc, handle2048); + g_tpm->context_load(g_tpm, g_tpm->cur_loc, &tpm2_context_saved, &handle2048); + } + + /* remove DMAR table if necessary */ remove_vtd_dmar_table(); @@ -501,11 +525,13 @@ /* write our S3 resume vector to ACPI resume addr */ set_s3_resume_vector(&_tboot_shared.acpi_sinfo, TBOOT_S3_WAKEUP_ADDR); /* fall through for rest of Sx handling */ + /* FALLTHROUGH */ case TB_SHUTDOWN_S4: case TB_SHUTDOWN_S5: machine_sleep(&_tboot_shared.acpi_sinfo); /* if machine_sleep() fails, fall through to reset */ + /* FALLTHROUGH */ case TB_SHUTDOWN_REBOOT: if ( txt_is_powercycle_required() ) { /* powercycle by writing 0x0a+0x0e to port 0xcf9 */ @@ -524,6 +550,7 @@ outb(0xcf9, 0x06); } + /* FALLTHROUGH */ case TB_SHUTDOWN_HALT: default: while ( true ) @@ -573,12 +600,18 @@ if ( _tboot_shared.shutdown_type == TB_SHUTDOWN_S3 ) { /* restore DMAR table if needed */ restore_vtd_dmar_table(); + if ( g_tpm->major == TPM20_VER_MAJOR ) { + g_tpm->context_flush(g_tpm, g_tpm->cur_loc, handle2048); + g_tpm->context_load(g_tpm, g_tpm->cur_loc, &tpm2_context_saved, &handle2048); + } - /* save kernel/VMM resume vector for sealing */ + + /* save kernel/VMM resume vector for sealing */ g_post_k_s3_state.kernel_s3_resume_vector = _tboot_shared.acpi_sinfo.kernel_s3_resume_vector; /* create and seal memory integrity measurement */ - if ( !seal_post_k_state() ) apply_policy(TB_ERR_S3_INTEGRITY); + if ( !seal_post_k_state() ) + apply_policy(TB_ERR_S3_INTEGRITY); /* OK to leave key in memory on failure since if user cared they would have policy that doesn't continue for TB_ERR_S3_INTEGRITY error */ diff -Nru tboot-1.9.5/tboot/common/tpm_20.c tboot-1.9.6/tboot/common/tpm_20.c --- tboot-1.9.5/tboot/common/tpm_20.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/tpm_20.c 2017-07-11 23:03:58.000000000 +0000 @@ -910,6 +910,36 @@ *other += reverse_copy_sized_buf_out((TPM2B *)&(ticket->digest), (TPM2B *)*other); } +static void reverse_copy_context_in(void **other, TPMS_CONTEXT *context) +{ + if (context == NULL) + return; + + reverse_copy_in(*other, context->sequence); + + reverse_copy_in(*other, context->savedHandle); + + reverse_copy_in(*other, context->hierarchy); + + *other += reverse_copy_sized_buf_in((TPM2B *)*other, (TPM2B *)&context->contextBlob); + +} + +static void reverse_copy_context_out(TPMS_CONTEXT *context, void **other) +{ + if (context == NULL) + return; + + reverse_copy_out(context->sequence, *other); + + reverse_copy_out(context->savedHandle, *other); + + reverse_copy_out(context->hierarchy, *other); + + reverse_copy_sized_buf_out((TPM2B *)&context->contextBlob, (TPM2B *)*other); + +} + static uint32_t _tpm20_pcr_read(u32 locality, tpm_pcr_read_in *in, tpm_pcr_read_out *out) @@ -1466,7 +1496,7 @@ return ret; } -static __data u32 handle2048 = 0; +__data u32 handle2048 = 0; static const char auth_str[] = "test"; static uint32_t _tpm20_create_primary(uint32_t locality, tpm_create_primary_in *in, @@ -1738,6 +1768,139 @@ return ret; } +static uint32_t _tpm20_context_save(uint32_t locality, + tpm_contextsave_in *in, + tpm_contextsave_out *out) +{ + u32 ret; + u32 cmd_size, rsp_size; + u16 rsp_tag; + void *other; + + reverse_copy_header(TPM_CC_ContextSave, 0); + other = (void *)cmd_buf + CMD_HEAD_SIZE; + reverse_copy_in(other, in->saveHandle); + + /* Now set the command size field, now that we know the size of the whole command */ + cmd_size = (u8 *)other - cmd_buf; + reverse_copy(cmd_buf + CMD_SIZE_OFFSET, &cmd_size, sizeof(cmd_size)); + + rsp_size = sizeof(*out); + + if (g_tpm_family == TPM_IF_20_FIFO) { + if (!tpm_submit_cmd(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size)) + return TPM_RC_FAILURE; + } + if (g_tpm_family == TPM_IF_20_CRB) { + if (!tpm_submit_cmd_crb(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size)) + return TPM_RC_FAILURE; + } + + reverse_copy(&ret, rsp_buf + RSP_RST_OFFSET, sizeof(ret)); + if ( ret != TPM_RC_SUCCESS ) + return ret; + + other = (void *)rsp_buf + RSP_HEAD_SIZE; + reverse_copy(&rsp_tag, rsp_buf, sizeof(rsp_tag)); + + if (rsp_tag == TPM_ST_SESSIONS) + other += sizeof(u32); /* Skip past parameter size field */ + + reverse_copy_context_out(&out->context, &other); + + return ret; + +} + +static uint32_t _tpm20_context_load(uint32_t locality, + tpm_contextload_in *in, + tpm_contextload_out *out) +{ + u32 ret; + u32 cmd_size, rsp_size; + u16 rsp_tag; + void *other; + + reverse_copy_header(TPM_CC_ContextLoad, 0); + other = (void *)cmd_buf + CMD_HEAD_SIZE; + + reverse_copy_context_in(&other, &in->context); + + /* Now set the command size field, now that we know the size of the whole command */ + cmd_size = (u8 *)other - cmd_buf; + reverse_copy(cmd_buf + CMD_SIZE_OFFSET, &cmd_size, sizeof(cmd_size)); + + rsp_size = RSP_HEAD_SIZE + sizeof(*out); + + if (g_tpm_family == TPM_IF_20_FIFO) { + if (!tpm_submit_cmd(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size)) + return TPM_RC_FAILURE; + } + if (g_tpm_family == TPM_IF_20_CRB) { + if (!tpm_submit_cmd_crb(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size)) + return TPM_RC_FAILURE; + } + + reverse_copy(&ret, rsp_buf + RSP_RST_OFFSET, sizeof(ret)); + if ( ret != TPM_RC_SUCCESS ) + return ret; + + other = (void *)rsp_buf + RSP_HEAD_SIZE; + reverse_copy(&rsp_tag, rsp_buf, sizeof(rsp_tag)); + + if (rsp_tag == TPM_ST_SESSIONS) + other += sizeof(u32); /* Skip past parameter size field */ + + reverse_copy_out(out->loadedHandle, other); + + return ret; +} + +static uint32_t _tpm20_context_flush(uint32_t locality, + tpm_flushcontext_in *in) +{ + u32 ret; + u32 cmd_size, rsp_size; + u16 rsp_tag; + void *other; + + + reverse_copy_header(TPM_CC_FlushContext, 0); + other = (void *)cmd_buf + CMD_HEAD_SIZE; + reverse_copy_in(other, in->flushHandle); + + /* Now set the command size field, now that we know the size of the whole command */ + cmd_size = (u8 *)other - cmd_buf; + reverse_copy(cmd_buf + CMD_SIZE_OFFSET, &cmd_size, sizeof(cmd_size)); + + rsp_size = RSP_HEAD_SIZE; + + if (g_tpm_family == TPM_IF_20_FIFO) { + if (!tpm_submit_cmd(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size)) + return TPM_RC_FAILURE; + } + if (g_tpm_family == TPM_IF_20_CRB) { + if (!tpm_submit_cmd_crb(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size)) + return TPM_RC_FAILURE; + } + + reverse_copy(&ret, rsp_buf + RSP_RST_OFFSET, sizeof(ret)); + + if ( ret != TPM_RC_SUCCESS ) + return ret; + + other = (void *)rsp_buf + RSP_HEAD_SIZE; + + reverse_copy(&rsp_tag, rsp_buf, sizeof(rsp_tag)); + + if (rsp_tag == TPM_ST_SESSIONS) + other += sizeof(u32); + + return ret; + +} + + TPM_CMD_SESSION_DATA_IN pw_session; static void create_pw_session(TPM_CMD_SESSION_DATA_IN *ses) { @@ -2243,6 +2406,75 @@ return false; } +__data tpm_contextsave_out tpm2_context_saved; + +static bool tpm20_context_save(struct tpm_if *ti, u32 locality, TPM_HANDLE handle, void *context_saved) +{ + tpm_contextsave_in in; + tpm_contextsave_out out; + u32 ret; + + if ( ti == NULL || locality >= TPM_NR_LOCALITIES ){ + return false; + } + if ( handle == 0 ) + return false; + in.saveHandle = handle; + ret =_tpm20_context_save(locality, &in, &out); + if ( ret != TPM_RC_SUCCESS ) { + printk(TBOOT_WARN"TPM: tpm2 context save failed, return value = %08X\n", ret); + ti->error = ret; + return false; + } + else + printk(TBOOT_WARN"TPM: tpm2 context save successful, return value = %08X\n", ret); + memcpy((tpm_contextsave_out *)context_saved, &out, sizeof(tpm_contextsave_out)); + return true; +} + +static bool tpm20_context_load(struct tpm_if *ti, u32 locality, void *context_saved, TPM_HANDLE *handle) +{ + tpm_contextload_in in; + tpm_contextload_out out; + u32 ret; + + if ( ti == NULL || locality >= TPM_NR_LOCALITIES ) + return false; + + memcpy(&in, (tpm_contextsave_out *)context_saved, sizeof(tpm_contextsave_out)); + + ret = _tpm20_context_load(locality, &in, &out); + if ( ret != TPM_RC_SUCCESS ) { + printk(TBOOT_WARN"TPM: tpm2 context load failed, return value = %08X\n", ret); + ti->error = ret; + return false; + } + else + printk(TBOOT_WARN"TPM: tpm2 context load successful, return value = %08X\n", ret); + *handle = out.loadedHandle; + return true; +} + +static bool tpm20_context_flush(struct tpm_if *ti, u32 locality, TPM_HANDLE handle) +{ + tpm_flushcontext_in in; + u32 ret; + + if ( ti == NULL || locality >= TPM_NR_LOCALITIES ) + return false; + if ( handle == 0 ) + return false; + in.flushHandle = handle; + ret = _tpm20_context_flush(locality, &in); + if ( ret != TPM_RC_SUCCESS ) { + printk(TBOOT_WARN"TPM: tpm2 context flush returned , return value = %08X\n", ret); + ti->error = ret; + return false; + } + else + printk(TBOOT_WARN"TPM: tpm2 context flush successful, return value = %08X\n", ret); + return true; +} static bool tpm20_init(struct tpm_if *ti) { @@ -2319,9 +2551,9 @@ ti->alg_count++; } } - printk(TBOOT_INFO"TPM: supported alg count = %08X\n", ti->alg_count); + printk(TBOOT_INFO"tboot: supported alg count = %d\n", ti->alg_count); for (unsigned int i=0; ialg_count; i++) - printk(TBOOT_INFO"\t\t %08X\n", ti->algs[i]); + printk(TBOOT_INFO"tboot: hash alg = %08X\n", ti->algs[i]); if (handle2048 != 0) goto out; @@ -2393,6 +2625,9 @@ .get_random = tpm20_get_random, .save_state = tpm20_save_state, .cap_pcrs = tpm20_cap_pcrs, + .context_save = tpm20_context_save, + .context_load = tpm20_context_load, + .context_flush = tpm20_context_flush, }; diff -Nru tboot-1.9.5/tboot/common/tpm.c tboot-1.9.6/tboot/common/tpm.c --- tboot-1.9.5/tboot/common/tpm.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/tpm.c 2017-07-11 23:03:58.000000000 +0000 @@ -116,15 +116,15 @@ printk(TBOOT_INFO"1. reg_ctrl_sts.tpmsts: 0x%x\n", reg_ctrl_sts.tpmsts); #endif - if ( reg_ctrl_sts.tpmidle== 1) { - reg_ctrl_request._raw[0] = 0; + if ( reg_ctrl_sts.tpmidle == 1) { + memset(®_ctrl_request,0,sizeof(reg_ctrl_request)); reg_ctrl_request.cmdReady = 1; write_tpm_reg(locality, TPM_CRB_CTRL_REQ, ®_ctrl_request); return true; } - reg_ctrl_request._raw[0] = 0; + memset(®_ctrl_request,0,sizeof(reg_ctrl_request)); reg_ctrl_request.goIdle = 1; write_tpm_reg(locality, TPM_CRB_CTRL_REQ, ®_ctrl_request); @@ -158,7 +158,7 @@ printk(TBOOT_INFO"2. reg_ctrl_sts.tpmsts: 0x%x\n", reg_ctrl_sts.tpmsts); #endif - reg_ctrl_request._raw[0] = 0; + memset(®_ctrl_request,0,sizeof(reg_ctrl_request)); reg_ctrl_request.cmdReady = 1; write_tpm_reg(locality, TPM_CRB_CTRL_REQ, ®_ctrl_request); @@ -724,7 +724,7 @@ if ( reg_loc_state.loc_assigned == 0 ) return true; /* make inactive by writing a 1 */ - reg_loc_ctrl._raw[0] = 0; + memset(®_loc_ctrl,0,sizeof(reg_loc_ctrl)); reg_loc_ctrl.relinquish = 1; write_tpm_reg(locality, TPM_REG_LOC_CTRL, ®_loc_ctrl); @@ -778,7 +778,7 @@ tpm_reg_loc_state_t reg_loc_state; tpm_reg_loc_ctrl_t reg_loc_ctrl; /* request access to the TPM from locality N */ - reg_loc_ctrl._raw[0] = 0; + memset(®_loc_ctrl,0,sizeof(reg_loc_ctrl)); reg_loc_ctrl.requestAccess = 1; write_tpm_reg(locality, TPM_REG_LOC_CTRL, ®_loc_ctrl); diff -Nru tboot-1.9.5/tboot/common/vsprintf.c tboot-1.9.6/tboot/common/vsprintf.c --- tboot-1.9.5/tboot/common/vsprintf.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/common/vsprintf.c 2017-07-11 23:03:58.000000000 +0000 @@ -404,6 +404,7 @@ case 'p': mods.flag |= PREFIX; /* print prefix 0x for %p */ mods.flag_long = LONG; + /* FALLTHROUGH */ case 'x': mods.base = 16; buf_pos = write_number_to_buffer(buf, size, buf_pos, mods); diff -Nru tboot-1.9.5/tboot/Config.mk tboot-1.9.6/tboot/Config.mk --- tboot-1.9.5/tboot/Config.mk 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/Config.mk 2017-07-11 23:03:58.000000000 +0000 @@ -33,7 +33,7 @@ CFLAGS += $(call cc-option,$(CC),-fno-stack-check,) # changeset variable for banner -CFLAGS += -DTBOOT_CHANGESET=\""$(shell ((hg parents --template "{isodate|isodate} {rev}:{node|short}" >/dev/null && hg parents --template "{isodate|isodate} {rev}:{node|short}") || echo "2016-12-16 12:00 -0800 1.9.5") 2>/dev/null)"\" +CFLAGS += -DTBOOT_CHANGESET=\""$(shell ((hg parents --template "{isodate|isodate} {rev}:{node|short}" >/dev/null && hg parents --template "{isodate|isodate} {rev}:{node|short}") || echo "2017-07-11 12:00 -0800 1.9.6") 2>/dev/null)"\" AFLAGS += -D__ASSEMBLY__ diff -Nru tboot-1.9.5/tboot/include/acpi.h tboot-1.9.6/tboot/include/acpi.h --- tboot-1.9.5/tboot/include/acpi.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/acpi.h 2017-07-11 23:03:58.000000000 +0000 @@ -491,7 +491,7 @@ #define ACPI_DEV_THINKPAD "IBM0068" /* ThinkPad support */ #endif - +extern bool vtd_bios_enabled(void); extern bool save_vtd_dmar_table(void); extern bool restore_vtd_dmar_table(void); extern bool remove_vtd_dmar_table(void); diff -Nru tboot-1.9.5/tboot/include/cmdline.h tboot-1.9.6/tboot/include/cmdline.h --- tboot-1.9.5/tboot/include/cmdline.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/cmdline.h 2017-07-11 23:03:58.000000000 +0000 @@ -52,6 +52,7 @@ extern void get_tboot_min_ram(void); extern bool get_tboot_call_racm(void); extern bool get_tboot_call_racm_check(void); +extern bool get_tboot_ignore_prev_err(void); extern bool get_tboot_measure_nv(void); extern void get_tboot_extpol(void); diff -Nru tboot-1.9.5/tboot/include/e820.h tboot-1.9.6/tboot/include/e820.h --- tboot-1.9.5/tboot/include/e820.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/e820.h 2017-07-11 23:03:58.000000000 +0000 @@ -89,9 +89,6 @@ extern void get_highest_sized_ram(uint64_t size, uint64_t limit, uint64_t *ram_base, uint64_t *ram_size); -/* EFI memory map support */ -extern efi_memory_desc_t *get_efi_memmap(uint32_t *memmap_size); - /* * Memory map descriptor: */ diff -Nru tboot-1.9.5/tboot/include/linux_defns.h tboot-1.9.6/tboot/include/linux_defns.h --- tboot-1.9.5/tboot/include/linux_defns.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/linux_defns.h 2017-07-11 23:03:58.000000000 +0000 @@ -207,7 +207,7 @@ #define REAL_KERNEL_OFFSET 0x0000 #define BOOT_SECTOR_OFFSET 0x0200 -#define KERNEL_CMDLINE_OFFSET 0x9000 +#define KERNEL_CMDLINE_OFFSET 0x8D00 #define REAL_END_OFFSET 0x9100 #define REAL_MODE_SIZE REAL_END_OFFSET - REAL_KERNEL_OFFSET diff -Nru tboot-1.9.5/tboot/include/loader.h tboot-1.9.6/tboot/include/loader.h --- tboot-1.9.5/tboot/include/loader.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/loader.h 2017-07-11 23:03:58.000000000 +0000 @@ -74,8 +74,11 @@ extern bool find_lcp_module(loader_ctx *lctx, void **base, uint32_t *size); - extern bool is_kernel_linux(void); + +extern uint32_t find_efi_memmap(loader_ctx *lctx, uint32_t *descr_size, + uint32_t *descr_vers, uint32_t *mmap_size); + extern bool launch_kernel(bool is_measured_launch); extern bool verify_loader_context(loader_ctx *lctx); extern bool verify_modules(loader_ctx *lctx); diff -Nru tboot-1.9.5/tboot/include/multiboot.h tboot-1.9.6/tboot/include/multiboot.h --- tboot-1.9.5/tboot/include/multiboot.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/multiboot.h 2017-07-11 23:03:58.000000000 +0000 @@ -98,6 +98,8 @@ #define MB2_TAG_TYPE_ACPI_OLD 14 #define MB2_TAG_TYPE_ACPI_NEW 15 #define MB2_TAG_TYPE_NETWORK 16 +#define MB2_TAG_TYPE_EFI_MMAP 17 +#define MB2_TAG_TYPE_EFI_BS 18 #ifndef __ASSEMBLY__ @@ -314,6 +316,17 @@ struct mb2_vbe_mode_info_block vbe_mode_info; }; +struct mb2_tag_efi_mmap +{ + uint32_t type; + uint32_t size; + uint32_t descr_size; + uint32_t descr_vers; + uint8_t efi_mmap[0]; +}; + + + struct mb2_fb_common { uint32_t type; diff -Nru tboot-1.9.5/tboot/include/processor.h tboot-1.9.6/tboot/include/processor.h --- tboot-1.9.5/tboot/include/processor.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/processor.h 2017-07-11 23:03:58.000000000 +0000 @@ -152,7 +152,15 @@ return regs[2]; } +static always_inline uint32_t cpuid_edx(unsigned int op) +{ + /* eax: regs[0], ebx: regs[1], ecx: regs[2], edx: regs[3] */ + uint32_t regs[4]; + + do_cpuid(op, regs); + return regs[3]; +} #define CPUID_X86_FEATURE_XMM3 (1<<0) #define CPUID_X86_FEATURE_VMX (1<<5) #define CPUID_X86_FEATURE_SMX (1<<6) @@ -238,7 +246,7 @@ static inline unsigned int get_apicid(void) { - return cpuid_ebx(1) >> 24; + return cpuid_edx(0xb); } diff -Nru tboot-1.9.5/tboot/include/tpm_20.h tboot-1.9.6/tboot/include/tpm_20.h --- tboot-1.9.5/tboot/include/tpm_20.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/tpm_20.h 2017-07-11 23:03:58.000000000 +0000 @@ -544,6 +544,11 @@ #define TPM_RH_PLATFORM (TPM_RH)(0x4000000C) #define TPM_RH_LAST (TPM_RH)(0x4000000C) +#define RC_ContextSave_saveHandle (TPM_RC_P + TPM_RC_1) +#define RC_ContextLoad_context (TPM_RC_P + TPM_RC_1) +#define RC_FlushContext_flushHandle (TPM_RC_P + TPM_RC_1) + + // Table 29 -- TPMA_ALGORITHM Bits typedef struct { unsigned int asymmetric : 1; @@ -597,6 +602,10 @@ unsigned int TPM_LOC_FOUR : 1; unsigned int reserved6 : 3; } TPMA_LOCALITY; +// Table 47 Definition of TPMI_DH_CONTEXT Type +typedef TPM_HANDLE TPMI_DH_CONTEXT; +// Table 48 Definition of TPMI_RH_HIERARCHY Type +typedef TPM_HANDLE TPMI_RH_HIERARCHY; // Table 66 -- TPMU_HA Union typedef union { @@ -1216,6 +1225,38 @@ TPM2B b; } TPM2B_NV_PUBLIC; +// Table 198 Definition of TPM2B_CONTEXT_SENSITIVE Structure < IN/OUT> +typedef union { + struct { + u16 size; + u8 buffer[MAX_CONTEXT_SIZE]; + } t; + TPM2B b; +} TPM2B_CONTEXT_SENSITIVE; + +// Table 199 Definition of TPMS_CONTEXT_DATA Structure < IN/OUT, S> +typedef struct { + TPM2B_DIGEST integrity; + TPM2B_CONTEXT_SENSITIVE encrypted; +} TPMS_CONTEXT_DATA; + +// Table 200 Definition of TPM2B_CONTEXT_DATA Structure < IN/OUT> +typedef union { + struct { + u16 size; + u8 buffer[sizeof(TPMS_CONTEXT_DATA)]; + } t; + TPM2B b; +} TPM2B_CONTEXT_DATA; + +// Table 201 Definition of TPMS_CONTEXT Structure +typedef struct { + u64 sequence; + TPMI_DH_CONTEXT savedHandle; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_CONTEXT_DATA contextBlob; +} TPMS_CONTEXT; + // Table 203 -- TPMS_CREATION_DATA Structure typedef struct { TPML_PCR_SELECTION pcr_select; @@ -1491,6 +1532,25 @@ TPM_CMD_SESSIONS_OUT sessions; } tpm_unseal_out; +typedef struct { + TPMI_DH_CONTEXT saveHandle; +} tpm_contextsave_in; + +typedef struct { + TPMS_CONTEXT context; +} tpm_contextsave_out; + +typedef struct { + TPMS_CONTEXT context; +} tpm_contextload_in; + +typedef struct { + TPMI_DH_CONTEXT loadedHandle; +} tpm_contextload_out; + +typedef struct { + TPMI_DH_CONTEXT flushHandle; +} tpm_flushcontext_in; #endif /* __TPM20_H__ */ diff -Nru tboot-1.9.5/tboot/include/tpm.h tboot-1.9.6/tboot/include/tpm.h --- tboot-1.9.5/tboot/include/tpm.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/tpm.h 2017-07-11 23:03:58.000000000 +0000 @@ -474,6 +474,10 @@ bool (*get_random)(struct tpm_if *ti, u32 locality, u8 *random_data, u32 *data_size); uint32_t (*save_state)(struct tpm_if *ti, u32 locality); + + bool (*context_save)(struct tpm_if *ti, u32 locality, u32 handle, void *context_saved); + bool (*context_load)(struct tpm_if *ti, u32 locality, void *context_saved, u32 *handle); + bool (*context_flush)(struct tpm_if *ti, u32 locality, u32 handle); bool (*cap_pcrs)(struct tpm_if *ti, u32 locality, int pcr); bool (*check)(void); diff -Nru tboot-1.9.5/tboot/include/txt/heap.h tboot-1.9.6/tboot/include/txt/heap.h --- tboot-1.9.5/tboot/include/txt/heap.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/txt/heap.h 2017-07-11 23:03:58.000000000 +0000 @@ -35,7 +35,6 @@ #ifndef __TXT_HEAP_H__ #define __TXT_HEAP_H__ - /* * Extensible TXT heap data structure */ @@ -101,6 +100,66 @@ uint8_t data[]; } tpm12_pcr_event_t; + +//Event Log Header + +/* +To allow parsers to identify the log format based on the content of the log, the first event +of the log is formatted as a TCG_PCR_EVENT structure independent of the format for +the rest of the log. A parser may read the first event of type TCG_PCR_EVENT and +because of its fixed size, easily find the event data. The fields of the event log header are +defined to be PCRIndex of 0, EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and +Event content defined as TCG_EfiSpecIDEventStruct. This first event is the event log +header. +*/ + +typedef struct __packed { + uint32_t pcr_index; //pcr_index event extended to + uint32_t event_type; //Type of event (see EFI specs) + uint8_t digest[20];//Value extended into pcr_index + uint32_t event_data_size; //Size of the event data + uint8_t event_data[]; //The event data Structure to be added to the Event Log +} tcg_pcr_event; + +typedef struct { + uint16_t hash_alg; + uint8_t digest[]; +} TPMT_HA_1; + +typedef struct { + uint32_t count; + TPMT_HA_1 digests[5]; +} TPML_DIGEST_VALUES_1; + +//TCG compliant TPM event log +typedef struct __packed { + uint32_t pcr_index; + uint32_t event_type; + TPML_DIGEST_VALUES_1 digest; //List of digests extended to pcr_index banks + uint32_t event_size; + uint8_t event[]; +} tcg_pcr_event2; + + +typedef struct __packed { + uint16_t algorithm_id; + uint16_t digest_size; +} tcg_efi_spec_id_event_algorithm_size; + + +typedef struct __packed { + uint8_t signature[16]; + uint32_t platform_class; + uint8_t spec_version_minor; + uint8_t spec_version_major; + uint8_t spec_errata; + uint8_t uintn_size; + uint32_t number_of_algorithms; + tcg_efi_spec_id_event_algorithm_size digestSizes[5]; + uint8_t vendor_info_size; + uint8_t vendor_info[]; +} tcg_efi_specid_event_strcut; + #define EVTLOG_SIGNATURE "TXT Event Container\0" #define EVTLOG_CNTNR_MAJOR_VER 1 #define EVTLOG_CNTNR_MINOR_VER 0 @@ -115,7 +174,7 @@ uint8_t pcr_event_ver_minor; uint32_t size; uint32_t pcr_events_offset; - uint32_t next_event_offset; + uint32_t next_event_offset; tpm12_pcr_event_t pcr_events[]; } event_log_container_t; @@ -123,6 +182,7 @@ * HEAP_EVENT_LOG_POINTER_ELEMENT2 */ #define HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2 7 +#define HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2_1 8 #define DIGEST_ALG_ID_SHA_1 0x00000001 #define DIGEST_ALG_ID_SHA_256 0x00000002 @@ -166,6 +226,12 @@ heap_event_log_descr_t event_log_descr[]; } heap_event_log_ptr_elt2_t; +typedef struct { + uint64_t phys_addr; + uint32_t allcoated_event_container_size; + uint32_t first_record_offset; + uint32_t next_record_offset; +} heap_event_log_ptr_elt2_1_t; /* * data-passing structures contained in TXT heap: diff -Nru tboot-1.9.5/tboot/include/txt/txt.h tboot-1.9.6/tboot/include/txt/txt.h --- tboot-1.9.5/tboot/include/txt/txt.h 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/include/txt/txt.h 2017-07-11 23:03:58.000000000 +0000 @@ -39,7 +39,8 @@ // #include extern bool txt_is_launched(void); -extern bool txt_get_error(void); +extern void txt_display_errors(void); +extern bool txt_has_error(void); extern void txt_get_racm_error(void); extern tb_error_t supports_txt(void); extern tb_error_t txt_verify_platform(void); diff -Nru tboot-1.9.5/tboot/Makefile tboot-1.9.6/tboot/Makefile --- tboot-1.9.5/tboot/Makefile 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/Makefile 2017-07-11 23:03:58.000000000 +0000 @@ -32,7 +32,7 @@ TARGET_LDS := $(CURDIR)/common/tboot.lds $(TARGET).gz : $(TARGET) - gzip -f -9 < $< > $@ + gzip -n -f -9 < $< > $@ $(TARGET) : $(OBJS) $(TARGET_LDS) $(LD) $(LDFLAGS) -T $(TARGET_LDS) -N $(OBJS) -o $(@D)/.$(@F).0 diff -Nru tboot-1.9.5/tboot/txt/acmod.c tboot-1.9.6/tboot/txt/acmod.c --- tboot-1.9.5/tboot/txt/acmod.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/txt/acmod.c 2017-07-11 23:03:58.000000000 +0000 @@ -289,6 +289,7 @@ printk(TBOOT_DETA"%s pcr_map_da: %d\n", prefix, caps.pcr_map_da); printk(TBOOT_DETA"%s platform_type: %d\n", prefix, caps.platform_type); printk(TBOOT_DETA"%s max_phy_addr: %d\n", prefix, caps.max_phy_addr); + printk(TBOOT_DETA"%s tcg_event_log_format: %d\n", prefix, caps.tcg_event_log_format); } static void print_acm_hdr(const acm_hdr_t *hdr, const char *mod_name) @@ -650,6 +651,8 @@ #ifndef IS_INCLUDED acm_hdr_t *get_bios_sinit(const void *sinit_region_base) { + if ( sinit_region_base == NULL ) + return NULL; txt_heap_t *txt_heap = get_txt_heap(); bios_data_t *bios_data = get_bios_data_start(txt_heap); @@ -737,6 +740,9 @@ return NULL; } + if ( sinit_region_base == NULL ) + return NULL; + /* copy it there */ memcpy(sinit_region_base, sinit, sinit->size*4); @@ -906,9 +912,6 @@ /* print it for debugging */ print_acm_hdr(acm_hdr, "SINIT"); - /* verify SE enablement status */ - verify_IA32_se_svn_status(acm_hdr); - /* entry point is offset from base addr so make sure it is within module */ if ( acm_hdr->entry_point >= size ) { printk(TBOOT_ERR"AC mod entry (%08x) >= AC mod size (%08x)\n", diff -Nru tboot-1.9.5/tboot/txt/errors.c tboot-1.9.6/tboot/txt/errors.c --- tboot-1.9.5/tboot/txt/errors.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/txt/errors.c 2017-07-11 23:03:58.000000000 +0000 @@ -45,8 +45,7 @@ #include #include - -static void display_errors(void) +void txt_display_errors(void) { txt_errorcode_t err; txt_ests_t ests; @@ -58,7 +57,7 @@ * display TXT.ERRORODE error */ err = (txt_errorcode_t)read_pub_config_reg(TXTCR_ERRORCODE); - if (err._raw == 0 || err._raw == 0xc0000001 || err._raw == 0xc0000009) + if (txt_has_error() == false) printk(TBOOT_INFO"TXT.ERRORCODE: 0x%Lx\n", err._raw); else printk(TBOOT_ERR"TXT.ERRORCODE: 0x%Lx\n", err._raw); @@ -112,17 +111,17 @@ printk(TBOOT_ERR"TXT.E2STS: 0x%Lx\n", e2sts._raw); } -bool txt_get_error(void) +bool txt_has_error(void) { txt_errorcode_t err; - - display_errors(); - + err = (txt_errorcode_t)read_pub_config_reg(TXTCR_ERRORCODE); - if ( err.valid ) + if (err._raw == 0 || err._raw == 0xc0000001 || err._raw == 0xc0000009) { return false; - else + } + else { return true; + } } #define CLASS_ACM_ENTRY 0x1 diff -Nru tboot-1.9.5/tboot/txt/heap.c tboot-1.9.6/tboot/txt/heap.c --- tboot-1.9.5/tboot/txt/heap.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/txt/heap.c 2017-07-11 23:03:58.000000000 +0000 @@ -174,7 +174,7 @@ printk(TBOOT_DETA"\t\t\t PCREventVer: %u.%u\n", elog->pcr_event_ver_major, elog->pcr_event_ver_minor); printk(TBOOT_DETA"\t\t\t Size: %u\n", elog->size); - printk(TBOOT_DETA"\t\t\t EventsOffset: [%u,%u)\n", + printk(TBOOT_DETA"\t\t\t EventsOffset: [%u,%u]\n", elog->pcr_events_offset, elog->next_event_offset); const tpm12_pcr_event_t *curr, *next; @@ -289,6 +289,102 @@ printk(TBOOT_DETA"\n"); } +uint32_t print_event_2_1_log_header(void *evt){ + + tcg_pcr_event *evt_ptr = (tcg_pcr_event *)evt; + tcg_efi_specid_event_strcut *evt_data_ptr = (tcg_efi_specid_event_strcut *) evt_ptr->event_data; + + printk(TBOOT_DETA"\t TCG Event Log Header:\n"); + printk(TBOOT_DETA"\t\t pcr_index: %u\n", evt_ptr->pcr_index); + printk(TBOOT_DETA"\t\t event_type: %u\n", evt_ptr->event_type); + printk(TBOOT_DETA"\t\t digest: %s\n", evt_ptr->digest); + printk(TBOOT_DETA"\t\t event_data_size: %u\n", evt_ptr->event_data_size); + + // print out event log header data + + printk(TBOOT_DETA"\t\t header event data: \n"); + printk(TBOOT_DETA"\t\t\t signature: %s\n", evt_data_ptr->signature); + printk(TBOOT_DETA"\t\t\t platform_class: %u\n", evt_data_ptr->platform_class); + printk(TBOOT_DETA"\t\t\t spec_version_major: %u\n", evt_data_ptr->spec_version_major); + printk(TBOOT_DETA"\t\t\t spec_version_minor: %u\n", evt_data_ptr->spec_version_minor); + printk(TBOOT_DETA"\t\t\t spec_errata: %u\n", evt_data_ptr->spec_errata); + printk(TBOOT_DETA"\t\t\t uintn_size: %u\n", evt_data_ptr->uintn_size); + printk(TBOOT_DETA"\t\t\t number_of_algorithms: %u\n", evt_data_ptr->number_of_algorithms); + + for ( uint32_t i = 0; i < evt_data_ptr->number_of_algorithms; i++){ + printk(TBOOT_DETA"\t\t\t\t algorithm_id: 0x%x \n", evt_data_ptr->digestSizes[i].algorithm_id); + printk(TBOOT_DETA"\t\t\t\t digest_size: %u\n", evt_data_ptr->digestSizes[i].digest_size); + } + + printk(TBOOT_DETA"\t\t\t vendor_info: %u bytes\n", evt_data_ptr->vendor_info_size); + print_hex(NULL, evt_data_ptr->vendor_info, evt_data_ptr->vendor_info_size); + + return evt_ptr->event_data_size; +} +uint32_t print_event_2_1(void *evt) +{ + + tcg_pcr_event2 *evt_ptr = (tcg_pcr_event2 *)evt; + uint8_t *evt_data_ptr; + uint16_t hash_alg; + uint32_t event_size = 0; + printk(TBOOT_DETA"\t\t\t TCG Event:\n"); + printk(TBOOT_DETA"\t\t\t pcr_index: %u\n", evt_ptr->pcr_index); + printk(TBOOT_DETA"\t\t\t event_type: 0x%x\n", evt_ptr->event_type); + printk(TBOOT_DETA"\t\t\t count: %u\n", evt_ptr->digest.count); + if (evt_ptr->digest.count != 0) { + evt_data_ptr = (uint8_t *)evt_ptr->digest.digests[0].digest; + hash_alg = evt_ptr->digest.digests[0].hash_alg; + for (uint32_t i = 0; i < evt_ptr->digest.count; i++ ) { + switch (hash_alg) { + case TB_HALG_SHA1: + printk(TBOOT_INFO"SHA1: \n"); + print_hex(NULL, evt_data_ptr, SHA1_LENGTH); + evt_data_ptr += SHA1_LENGTH; + break; + + case TB_HALG_SHA256: + printk(TBOOT_INFO"SHA256: \n"); + print_hex(NULL, evt_data_ptr, SHA256_LENGTH); + evt_data_ptr += SHA256_LENGTH; + break; + + case TB_HALG_SM3: + printk(TBOOT_INFO"SM3_256: \n"); + print_hex(NULL, evt_data_ptr, SM3_LENGTH); + evt_data_ptr += SM3_LENGTH; + break; + + case TB_HALG_SHA384: + printk(TBOOT_INFO"SHA384: \n"); + print_hex(NULL, evt_data_ptr, SHA384_LENGTH); + evt_data_ptr += SHA384_LENGTH; + break; + + case TB_HALG_SHA512: + printk(TBOOT_INFO"SHA512: \n"); + print_hex(NULL, evt_data_ptr, SHA512_LENGTH); + evt_data_ptr += SHA512_LENGTH; + break; + default: + printk(TBOOT_ERR"Unsupported algorithm: %u\n", evt_ptr->digest.digests[i].hash_alg); + } + hash_alg = (uint16_t)*evt_data_ptr; + evt_data_ptr += sizeof(uint16_t); + } + evt_data_ptr -= sizeof(uint16_t); + event_size = (uint32_t)*evt_data_ptr; + printk(TBOOT_DETA"\t\t\t event_data: %u bytes", event_size); + evt_data_ptr += sizeof(uint32_t); + print_hex("\t\t\t ", evt_data_ptr, event_size); + } + else { + printk(TBOOT_DETA"sth wrong in TCG event log: algoritm count = %u\n", evt_ptr->digest.count); + evt_data_ptr= (uint8_t *)evt +12; + } + return (evt_data_ptr + event_size - (uint8_t *)evt); +} + static void print_evt_log_ptr_elt_2(const heap_ext_data_element_t *elt) { const heap_event_log_ptr_elt2_t *elog_elt = @@ -348,6 +444,36 @@ } } + +static void print_evt_log_ptr_elt_2_1(const heap_ext_data_element_t *elt) +{ + const heap_event_log_ptr_elt2_1_t *elog_elt = (const heap_event_log_ptr_elt2_1_t *)elt->data; + + printk(TBOOT_DETA"\t TCG EVENT_LOG_PTR:\n"); + printk(TBOOT_DETA"\t\t type: %d\n", elt->type); + printk(TBOOT_DETA"\t\t size: %u\n", elt->size); + printk(TBOOT_DETA"\t TCG Event Log Descrption:\n"); + printk(TBOOT_DETA"\t allcoated_event_container_size: %u\n", elog_elt->allcoated_event_container_size); + printk(TBOOT_DETA"\t EventsOffset: [%u,%u]\n", + elog_elt->first_record_offset, elog_elt->next_record_offset); + + if (elog_elt->first_record_offset == elog_elt->next_record_offset) { + printk(TBOOT_DETA"\t\t\t No Event Log found.\n"); + return; + } + void *curr, *next; + + curr = (void *)(unsigned long)elog_elt->phys_addr + elog_elt->first_record_offset; + next = (void *)(unsigned long)elog_elt->phys_addr + elog_elt->next_record_offset; + uint32_t event_header_data_size = print_event_2_1_log_header(curr); + + curr += sizeof(tcg_pcr_event) + event_header_data_size; + while ( curr < next ) { + curr += print_event_2_1(curr); + } +} + + static bool verify_evt_log_ptr_elt_2(const heap_ext_data_element_t *elt) { if ( !elt ) @@ -378,6 +504,9 @@ case HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2: print_evt_log_ptr_elt_2(elt); break; + case HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2_1: + print_evt_log_ptr_elt_2_1(elt); + break; default: printk(TBOOT_WARN"\t\t unknown element: type: %u, size: %u\n", elt->type, elt->size); @@ -580,19 +709,30 @@ 2 * sizeof(heap_ext_data_element_t) + sizeof(heap_event_log_ptr_elt_t) }; - + txt_caps_t sinit_caps; + if ( g_tpm->major == TPM20_VER_MAJOR ) { - u32 count; - if ( g_tpm->extpol == TB_EXTPOL_AGILE ) - count = g_tpm->banks; - else if ( g_tpm->extpol == TB_EXTPOL_EMBEDDED ) - count = g_tpm->alg_count; - else - count = 1; - - size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) + - 2 * sizeof(heap_ext_data_element_t) + - 4 + count*sizeof(heap_event_log_descr_t); + if (g_sinit != NULL) { + sinit_caps = get_sinit_capabilities(g_sinit); + } + if (sinit_caps.tcg_event_log_format) { + size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) + + 2 * sizeof(heap_ext_data_element_t) + + sizeof(heap_event_log_ptr_elt2_1_t); + } + else { + u32 count; + if ( g_tpm->extpol == TB_EXTPOL_AGILE ) + count = g_tpm->banks; + else + if ( g_tpm->extpol == TB_EXTPOL_EMBEDDED ) + count = g_tpm->alg_count; + else + count = 1; + size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) + + 2 * sizeof(heap_ext_data_element_t) + + 4 + count*sizeof(heap_event_log_descr_t); + } } if ( version >= 6 ) @@ -616,8 +756,7 @@ printk(TBOOT_DETA"\t vtd_pmr_hi_base: 0x%Lx\n", os_sinit_data->vtd_pmr_hi_base); printk(TBOOT_DETA"\t vtd_pmr_hi_size: 0x%Lx\n", os_sinit_data->vtd_pmr_hi_size); printk(TBOOT_DETA"\t lcp_po_base: 0x%Lx\n", os_sinit_data->lcp_po_base); - printk(TBOOT_DETA"\t lcp_po_size: 0x%Lx (%Lu)\n", os_sinit_data->lcp_po_size, - os_sinit_data->lcp_po_size); + printk(TBOOT_DETA"\t lcp_po_size: 0x%Lx (%Lu)\n", os_sinit_data->lcp_po_size, os_sinit_data->lcp_po_size); print_txt_caps("\t ", os_sinit_data->capabilities); if ( os_sinit_data->version >= 5 ) printk(TBOOT_DETA"\t efi_rsdt_ptr: 0x%Lx\n", os_sinit_data->efi_rsdt_ptr); diff -Nru tboot-1.9.5/tboot/txt/txt.c tboot-1.9.6/tboot/txt/txt.c --- tboot-1.9.5/tboot/txt/txt.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/txt/txt.c 2017-07-11 23:03:58.000000000 +0000 @@ -67,7 +67,7 @@ #include /* counter timeout for waiting for all APs to enter wait-for-sipi */ -#define AP_WFS_TIMEOUT 0x01000000 +#define AP_WFS_TIMEOUT 0x10000000 __data struct acpi_rsdp g_rsdp; extern char _start[]; /* start of module */ @@ -206,6 +206,7 @@ static __data event_log_container_t *g_elog = NULL; static __data heap_event_log_ptr_elt2_t *g_elog_2 = NULL; +static __data heap_event_log_ptr_elt2_1_t *g_elog_2_1 = NULL; /* should be called after os_mle_data initialized */ static void *init_event_log(void) @@ -226,11 +227,26 @@ return (void *)g_elog; } +/* initialize TCG compliant TPM 2.0 event log descriptor */ +static void init_evtlog_desc_1(heap_event_log_ptr_elt2_1_t *evt_log) +{ + os_mle_data_t *os_mle_data = get_os_mle_data_start(get_txt_heap()); + + evt_log->phys_addr = (uint64_t)(unsigned long)(os_mle_data->event_log_buffer); + evt_log->allcoated_event_container_size = 2*PAGE_SIZE; + evt_log->first_record_offset = 0; + evt_log->next_record_offset = 0; + printk(TBOOT_DETA"TCG compliant TPM 2.0 event log descriptor:\n"); + printk(TBOOT_DETA"\t phys_addr = 0x%LX\n", evt_log->phys_addr); + printk(TBOOT_DETA"\t allcoated_event_container_size = 0x%x \n", evt_log->allcoated_event_container_size); + printk(TBOOT_DETA"\t first_record_offset = 0x%x \n", evt_log->first_record_offset); + printk(TBOOT_DETA"\t next_record_offset = 0x%x \n", evt_log->next_record_offset); +} + static void init_evtlog_desc(heap_event_log_ptr_elt2_t *evt_log) { unsigned int i; os_mle_data_t *os_mle_data = get_os_mle_data_start(get_txt_heap()); - switch (g_tpm->extpol) { case TB_EXTPOL_AGILE: for (i=0; icount; i++) { @@ -268,30 +284,47 @@ static void init_os_sinit_ext_data(heap_ext_data_element_t* elts) { heap_ext_data_element_t* elt = elts; - heap_event_log_ptr_elt_t *evt_log; - + heap_event_log_ptr_elt_t* evt_log; + txt_caps_t sinit_caps; + if ( g_tpm->major == TPM12_VER_MAJOR ) { evt_log = (heap_event_log_ptr_elt_t *)elt->data; evt_log->event_log_phys_addr = (uint64_t)(unsigned long)init_event_log(); elt->type = HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR; elt->size = sizeof(*elt) + sizeof(*evt_log); - } else if ( g_tpm->major == TPM20_VER_MAJOR ) { - g_elog_2 = (heap_event_log_ptr_elt2_t *)elt->data; - - if ( g_tpm->extpol == TB_EXTPOL_AGILE ) - g_elog_2->count = g_tpm->banks; - else if ( g_tpm->extpol == TB_EXTPOL_EMBEDDED ) - g_elog_2->count = g_tpm->alg_count; - else - g_elog_2->count = 1; - - init_evtlog_desc(g_elog_2); - - elt->type = HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2; - elt->size = sizeof(*elt) + sizeof(u32) + + } + else + if ( g_tpm->major == TPM20_VER_MAJOR ) { + if (g_sinit != NULL) { + sinit_caps = get_sinit_capabilities(g_sinit); + } + else + return; + if (sinit_caps.tcg_event_log_format) { + g_elog_2_1 = (heap_event_log_ptr_elt2_1_t *)elt->data; + init_evtlog_desc_1(g_elog_2_1); + elt->type = HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2_1; + elt->size = sizeof(*elt) + sizeof(heap_event_log_ptr_elt2_1_t); + printk(TBOOT_DETA"heap_ext_data_element TYPE = %d \n", elt->type); + printk(TBOOT_DETA"heap_ext_data_element SIZE = %d \n", elt->size); + + } + else { + g_elog_2 = (heap_event_log_ptr_elt2_t *)elt->data; + if ( g_tpm->extpol == TB_EXTPOL_AGILE ) + g_elog_2->count = g_tpm->banks; + else + if ( g_tpm->extpol == TB_EXTPOL_EMBEDDED ) + g_elog_2->count = g_tpm->alg_count; + else + g_elog_2->count = 1; + init_evtlog_desc(g_elog_2); + elt->type = HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR_2; + elt->size = sizeof(*elt) + sizeof(u32) + g_elog_2->count * sizeof(heap_event_log_descr_t); - } - + printk(TBOOT_DETA"INTEL TXT LOG elt SIZE = %d \n", elt->size); + } + } elt = (void *)elt + elt->size; elt->type = HEAP_EXTDATA_TYPE_END; elt->size = sizeof(*elt); @@ -501,10 +534,15 @@ else if ( sinit_caps.rlp_wake_getsec ) os_sinit_data->capabilities.rlp_wake_getsec = 1; else { /* should have been detected in verify_acmod() */ - printk(TBOOT_ERR"SINIT capabilities are incompatible (0x%x)\n", - sinit_caps._raw); + printk(TBOOT_ERR"SINIT capabilities are incompatible (0x%x)\n", sinit_caps._raw); return NULL; } + + if ( sinit_caps.tcg_event_log_format ){ + printk(TBOOT_INFO"SINIT ACM supports TCG compliant TPM 2.0 event log format, tcg_event_log_format = %d \n", + sinit_caps.tcg_event_log_format); + os_sinit_data->capabilities.tcg_event_log_format = 1; + } /* capabilities : require MLE pagetable in ECX on launch */ /* TODO: when SINIT ready * os_sinit_data->capabilities.ecx_pgtbl = 1; @@ -611,8 +649,7 @@ /* choose wakeup mechanism based on capabilities used */ if ( os_sinit_data->capabilities.rlp_wake_monitor ) { printk(TBOOT_INFO"joining RLPs to MLE with MONITOR wakeup\n"); - printk(TBOOT_DETA"rlp_wakeup_addr = 0x%x\n", - sinit_mle_data->rlp_wakeup_addr); + printk(TBOOT_DETA"rlp_wakeup_addr = 0x%x\n", sinit_mle_data->rlp_wakeup_addr); *((uint32_t *)(unsigned long)(sinit_mle_data->rlp_wakeup_addr)) = 0x01; } else { @@ -741,18 +778,25 @@ /* initial launch's TXT heap data is still in place and assumed valid */ /* so don't re-create; this is OK because it was untrusted initially */ /* and would be untrusted now */ - - /* initialize event log in os_sinit_data, so that events will not */ - /* repeat when s3 */ - if ( g_tpm->major == TPM12_VER_MAJOR && g_elog ) - g_elog = (event_log_container_t *)init_event_log(); - else if ( g_tpm->major == TPM20_VER_MAJOR && g_elog_2 ) - init_evtlog_desc(g_elog_2); + txt_caps_t sinit_caps; /* get sinit binary loaded */ g_sinit = (acm_hdr_t *)(uint32_t)read_pub_config_reg(TXTCR_SINIT_BASE); - if ( g_sinit == NULL ) + if ( g_sinit == NULL ){ return false; + } + /* initialize event log in os_sinit_data, so that events will not */ + /* repeat when s3 */ + if ( g_tpm->major == TPM12_VER_MAJOR && g_elog ) + g_elog = (event_log_container_t *)init_event_log(); + else + if ( g_tpm->major == TPM20_VER_MAJOR ){ + sinit_caps = get_sinit_capabilities(g_sinit); + if (sinit_caps.tcg_event_log_format && g_elog_2_1) + init_evtlog_desc_1(g_elog_2_1); + if(!sinit_caps.tcg_event_log_format && g_elog_2) + init_evtlog_desc(g_elog_2); + } /* set MTRRs properly for AC module (SINIT) */ set_mtrrs_for_acmod(g_sinit); @@ -1018,8 +1062,7 @@ } msr_apicbase = rdmsr(MSR_APICBASE); if ( madt_apicbase != (msr_apicbase & ~0xFFFULL) ) { - printk(TBOOT_INFO"cpu %u restore apic base to %llx\n", - cpuid, madt_apicbase); + printk(TBOOT_INFO"cpu %u restore apic base to %llx\n", cpuid, madt_apicbase); wrmsr(MSR_APICBASE, (msr_apicbase & 0xFFFULL) | madt_apicbase); } diff -Nru tboot-1.9.5/tboot/txt/verify.c tboot-1.9.6/tboot/txt/verify.c --- tboot-1.9.5/tboot/txt/verify.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/txt/verify.c 2017-07-11 23:03:58.000000000 +0000 @@ -183,8 +183,7 @@ bool use_mwait(void) { - return get_tboot_mwait() && - (g_cpuid_ext_feat_info & CPUID_X86_FEATURE_XMM3); + return get_tboot_mwait() && (g_cpuid_ext_feat_info & CPUID_X86_FEATURE_XMM3); } tb_error_t supports_txt(void) @@ -372,6 +371,10 @@ if ( err != TB_ERR_NONE ) return err; + if ( !vtd_bios_enabled() ) { + return TB_ERR_VTD_NOT_SUPPORTED; + } + /* check is TXT_RESET.STS is set, since if it is SENTER will fail */ txt_ests_t ests = (txt_ests_t)read_pub_config_reg(TXTCR_ESTS); if ( ests.txt_reset_sts ) { diff -Nru tboot-1.9.5/tboot/txt/vmcs.c tboot-1.9.6/tboot/txt/vmcs.c --- tboot-1.9.5/tboot/txt/vmcs.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tboot/txt/vmcs.c 2017-07-11 23:03:58.000000000 +0000 @@ -490,7 +490,7 @@ unsigned int apicid = get_apicid(); unsigned int exit_reason = __vmread(VM_EXIT_REASON); - /*printk("vmx_vmexit_handler, exit_reason=%x.\n", exit_reason);*/ + /*printk("vmx_vmexit_handler, cpu= %d, exit_reason=%x.\n", apicid, exit_reason);*/ if ( (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) ) { print_failed_vmentry_reason(exit_reason); @@ -511,7 +511,7 @@ /* disable VT then jump to xen code */ unsigned long exit_qual = __vmread(EXIT_QUALIFICATION); uint32_t sipi_vec = (exit_qual & 0xffUL) << PAGE_SHIFT; - /* printk("exiting due to SIPI: vector=%x\n", sipi_vec); */ + /*printk("exiting due to SIPI: vector=%x\n", sipi_vec); */ stop_vmx(apicid); atomic_dec(&ap_wfs_count); atomic_dec((atomic_t *)&_tboot_shared.num_in_wfs); diff -Nru tboot-1.9.5/tb_polgen/commands.c tboot-1.9.6/tb_polgen/commands.c --- tboot-1.9.5/tb_polgen/commands.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tb_polgen/commands.c 2017-07-11 23:03:58.000000000 +0000 @@ -55,7 +55,6 @@ { FILE *f; static char buf[1024]; - EVP_MD_CTX ctx; const EVP_MD *md; int read_cnt; @@ -69,8 +68,9 @@ return false; } + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); md = EVP_sha1(); - EVP_DigestInit(&ctx, md); + EVP_DigestInit(ctx, md); do { if ( unzip ) read_cnt = gzread((gzFile)f, buf, sizeof(buf)); @@ -79,15 +79,16 @@ if ( read_cnt == 0 ) break; - EVP_DigestUpdate(&ctx, buf, read_cnt); + EVP_DigestUpdate(ctx, buf, read_cnt); } while ( true ); - EVP_DigestFinal(&ctx, hash->sha1, NULL); + EVP_DigestFinal(ctx, hash->sha1, NULL); if ( unzip ) gzclose((gzFile)f); else fclose(f); - + + EVP_MD_CTX_destroy(ctx); return true; } @@ -165,17 +166,17 @@ /* hash command line and files */ if ( params->hash_type == TB_HTYPE_IMAGE ) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; tb_hash_t final_hash, hash; /* hash command line */ info_msg("hashing command line \"%s\"...\n", params->cmdline); md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, (unsigned char *)params->cmdline, + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, (unsigned char *)params->cmdline, strlen(params->cmdline)); - EVP_DigestFinal(&ctx, (unsigned char *)&final_hash, NULL); + EVP_DigestFinal(ctx, (unsigned char *)&final_hash, NULL); if ( verbose ) { info_msg("hash is..."); print_hash(&final_hash, TB_HALG_SHA1); @@ -183,15 +184,19 @@ /* hash file */ info_msg("hashing image file %s...\n", params->image_file); - if ( !hash_file(params->image_file, true, &hash) ) + if ( !hash_file(params->image_file, true, &hash) ) { + EVP_MD_CTX_destroy(ctx); return false; + } if ( verbose ) { info_msg("hash is..."); print_hash(&hash, TB_HALG_SHA1); } - if ( !extend_hash(&final_hash, &hash, TB_HALG_SHA1) ) + if ( !extend_hash(&final_hash, &hash, TB_HALG_SHA1) ){ + EVP_MD_CTX_destroy(ctx); return false; + } if ( verbose ) { info_msg("cummulative hash is..."); @@ -200,6 +205,7 @@ if ( !add_hash(pol_entry, &final_hash) ) { error_msg("cannot add another hash\n"); + EVP_MD_CTX_destroy(ctx); return false; } } diff -Nru tboot-1.9.5/tb_polgen/hash.c tboot-1.9.6/tb_polgen/hash.c --- tboot-1.9.5/tb_polgen/hash.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/tb_polgen/hash.c 2017-07-11 23:03:58.000000000 +0000 @@ -83,13 +83,14 @@ } if ( hash_alg == TB_HALG_SHA1 ) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, size); - EVP_DigestFinal(&ctx, hash->sha1, NULL); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, size); + EVP_DigestFinal(ctx, hash->sha1, NULL); + EVP_MD_CTX_destroy(ctx); return true; } else { @@ -114,15 +115,16 @@ } if ( hash_alg == TB_HALG_SHA1 ) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); const EVP_MD *md; memcpy(buf, &(hash1->sha1), sizeof(hash1->sha1)); memcpy(buf + sizeof(hash1->sha1), &(hash2->sha1), sizeof(hash1->sha1)); md = EVP_sha1(); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, buf, 2*sizeof(hash1->sha1)); - EVP_DigestFinal(&ctx, hash1->sha1, NULL); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, buf, 2*sizeof(hash1->sha1)); + EVP_DigestFinal(ctx, hash1->sha1, NULL); + EVP_MD_CTX_destroy(ctx); return true; } else { diff -Nru tboot-1.9.5/utils/txt-stat.c tboot-1.9.6/utils/txt-stat.c --- tboot-1.9.5/utils/txt-stat.c 2016-12-17 03:19:38.000000000 +0000 +++ tboot-1.9.6/utils/txt-stat.c 2017-07-11 23:03:58.000000000 +0000 @@ -62,7 +62,6 @@ void print_hex(const char* prefix, const void *start, size_t len); #include "../include/hash.h" #include "../tboot/include/txt/heap.h" - #include "../tboot/txt/heap.c" #include "../tboot/include/lz.h" #include "../tboot/common/lz.c"