Hi Joseph,

Thanks so much for your detailed reply.  I have indeed gotten things
to work.  For the aid of others, here are some of the useful bits.  I
may post some more complete code in a week or two.

> First, you need to adjust your calculation per the comment about 
> 'SHA-256(SINIT) | EDX'.  Second, the SHA-256 of SINIT is not performed on the 
> entire binary.  Appendix A.1 "alludes" to how the hash is calculated (since 
> it is the same as what is used in the signature):

Indeed, the actual value of PCR 17 after the "first extend" turns out to be:

SHA1(0x00^20 | SHA1(SHA256(SINIT**) | EdxSenterFlags))

SINIT** denotes only part of the sinit module, as Joseph suggested.  More below.

> RSASig
> The PKCS #1.5 RSA Signature of the module. The RSA Signature signs an area 
> that includes the some of the module header and the USER AREA data field 
> (which represents the body of the module). Parts of the module header not 
> included are: the RSA Signature, public key, and scratch field.

Not including the RSA Signature, Public Key, or Scratch field still
leaves a little wiggle room with respect to whether any metadata
(e.g., size information) pertaining to those areas is included.  Here
is what is working for me:

I'm using the definition of acm_hdr_t from acmod.h from tboot-1.6, and
I created a big binary version of the SINIT of interest in a C array
using:
'xxd -i /boot/i5_i7_DUAL_SINIT_18.BIN > i5_i7_DUAL_SINIT_18.h'

(As an aside, xxd may be the greatest program you've never heard of ;-).

Here is a function that recomputes the PCR-17 value from the "first
extend" which should (and does for my tests) match
SinitMleData.SinitHash:

int validate_pcr17_sinit_hash_version7(sinit_mle_data_t *smd) {
  SHA_CTX c;
  unsigned char pcr17[20], inner[20];

  EVP_MD_CTX mdctx;
  const EVP_MD *md;
  unsigned char md_value[EVP_MAX_MD_SIZE];
  int md_len;

  acm_hdr_t *s = (acm_hdr_t*)i5_i7_DUAL_SINIT_18_BIN;

  OpenSSL_add_all_digests();
  if(!(md = EVP_get_digestbyname("sha256"))) return -1;

  EVP_MD_CTX_init(&mdctx);
  EVP_DigestInit_ex(&mdctx, md, NULL);

#define HASHIN(foo) EVP_DigestUpdate(&mdctx, &foo, sizeof(foo)); \
    printf("  size %d\n", sizeof(foo));
  HASHIN(s->module_type);
  HASHIN(s->module_subtype);
  HASHIN(s->header_len);
  HASHIN(s->header_ver);
  HASHIN(s->chipset_id);
  HASHIN(s->flags);
  HASHIN(s->module_vendor);
  HASHIN(s->date);
  HASHIN(s->size);
  HASHIN(s->reserved1);
  HASHIN(s->code_control);
  HASHIN(s->error_entry_point);
  HASHIN(s->gdt_limit);
  HASHIN(s->gdt_base);
  HASHIN(s->seg_sel);
  HASHIN(s->entry_point);
  EVP_DigestUpdate(&mdctx, s->reserved2, sizeof(s->reserved2));
  printf("  size reserved2 %d\n", sizeof(s->reserved2));
  HASHIN(s->key_size);
  HASHIN(s->scratch_size);

  uint32_t user_area_len = i5_i7_DUAL_SINIT_18_BIN_len -
      ((uint32_t)s->user_area - (uint32_t)s);
  printf("  user_area_len %d\n", user_area_len);
  EVP_DigestUpdate(&mdctx, s->user_area, user_area_len);

  EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
  dump_bytes1("sha256(): ", md_value, md_len);
  EVP_MD_CTX_cleanup(&mdctx);

  printf("  md_len %d\n", md_len);

  memset(pcr17, 0, sizeof(sha1_hash_t)); // PCR-17 reset to zero by
GETSEC[SENTER]

  // First compute "inner" SHA-1 (data sent in TPM_HASH_DATA sequence)
  SHA1_Init(&c);
  SHA1_Update(&c, md_value, md_len);
  SHA1_Update(&c, &smd->edx_senter_flags, sizeof(uint32_t));
  SHA1_Final(inner, &c);

  // Second compute Extend(inner)
  SHA1_Init(&c);
  SHA1_Update(&c, pcr17, sizeof(sha1_hash_t)); // First part of
payload existing 20 zeros
  SHA1_Update(&c, inner, sizeof(sha1_hash_t)); // Second part is
"inner" SHA-1 computed above
  SHA1_Final(pcr17, &c); // Compute final digest

  dump_bytes1("pcr17 (1st ext)", pcr17, sizeof(sha1_hash_t));

  if(!memcmp(pcr17, smd->sinit_hash, sizeof(sha1_hash_t))) {
      return 0; /* success */
  }
  return -1; /* failure */
}


So once again, thanks Joseph and JP for your responses.  JP, hopefully
this helps you to no longer take PCR-17 on faith.

Best,
-Jon

------------------------------------------------------------------------------
Doing More with Less: The Next Generation Virtual Desktop 
What are the key obstacles that have prevented many mid-market businesses
from deploying virtual desktops?   How do next-generation virtual desktops
provide companies an easier-to-deploy, easier-to-manage and more affordable
virtual desktop model.http://www.accelacomm.com/jaw/sfnl/114/51426474/
_______________________________________________
tboot-devel mailing list
tboot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tboot-devel

Reply via email to