// GetEKCert reads the Endorsement Key certificate from the TPM's NVRAM and // returns it, along with any error generated. func GetEKCert(context *tspi.Context) (ekcert []byte, err error) { var wellKnown [20]byte tpm := context.GetTPM() nv, err := context.CreateNV() if err != nil { return nil, err } policy, err := tpm.GetPolicy(tspi.TSS_POLICY_USAGE) if err != nil { return nil, err } policy.SetSecret(tspi.TSS_SECRET_MODE_SHA1, wellKnown[:]) nv.SetIndex(0x1000f000) nv.AssignPolicy(policy) data, err := nv.ReadValue(0, 5) if err != nil { return nil, err } tag := (uint)((uint)(data[0])<<8 | (uint)(data[1])) if tag != 0x1001 { return nil, fmt.Errorf("Invalid tag: %x", tag) } if data[2] != 0 { return nil, fmt.Errorf("Invalid certificate") } ekbuflen := (uint)(uint(data[3])<<8 | (uint)(data[4])) offset := (uint)(5) data, err = nv.ReadValue(offset, 2) tag = (uint)((uint)(data[0])<<8 | (uint)(data[1])) if tag == 0x1002 { offset += 2 ekbuflen -= 2 } else if data[0] != 0x30 { return nil, fmt.Errorf("Invalid header: %x\n", tag) } ekoffset := (uint)(0) var ekbuf []byte for ekoffset < ekbuflen { length := (uint)(ekbuflen - ekoffset) if length > 128 { length = 128 } data, err = nv.ReadValue(offset, length) if err != nil { return nil, err } ekbuf = append(ekbuf, data...) offset += length ekoffset += length } return ekbuf, nil }
// AIKChallengeResponse takes the output from GenerateChallenge along with the // encrypted AIK key blob. The TPM then decrypts the asymmetric challenge with // its EK in order to obtain the AES key, and uses the AES key to decrypt the // symmetrically encrypted data. It verifies that this data blob corresponds // to the AIK it was given, and if so hands back the secret contained within // the symmetrically encrypted data. func AIKChallengeResponse(context *tspi.Context, aikblob []byte, asymchallenge []byte, symchallenge []byte) (secret []byte, err error) { var wellKnown [20]byte srk, err := context.LoadKeyByUUID(tspi.TSS_PS_TYPE_SYSTEM, tspi.TSS_UUID_SRK) if err != nil { return nil, err } srkpolicy, err := srk.GetPolicy(tspi.TSS_POLICY_USAGE) if err != nil { return nil, err } srkpolicy.SetSecret(tspi.TSS_SECRET_MODE_SHA1, wellKnown[:]) tpm := context.GetTPM() tpmpolicy, err := context.CreatePolicy(tspi.TSS_POLICY_USAGE) if err != nil { return nil, err } tpm.AssignPolicy(tpmpolicy) tpmpolicy.SetSecret(tspi.TSS_SECRET_MODE_SHA1, wellKnown[:]) aik, err := context.LoadKeyByBlob(srk, aikblob) if err != nil { return nil, err } secret, err = tpm.ActivateIdentity(aik, asymchallenge, symchallenge) return secret, err }
// CreateAIK asks the TPM to generate an Attestation Identity Key. It returns // the unencrypted public half of the AIK along with an encrypted blob // containing both halves of the key, and any error. func CreateAIK(context *tspi.Context) ([]byte, []byte, error) { var wellKnown [20]byte n := make([]byte, 2048/8) for i := 0; i < 2048/8; i++ { n[i] = 0xff } srk, err := context.LoadKeyByUUID(tspi.TSS_PS_TYPE_SYSTEM, tspi.TSS_UUID_SRK) if err != nil { return nil, nil, err } keypolicy, err := srk.GetPolicy(tspi.TSS_POLICY_USAGE) if err != nil { return nil, nil, err } err = keypolicy.SetSecret(tspi.TSS_SECRET_MODE_SHA1, wellKnown[:]) if err != nil { return nil, nil, err } tpm := context.GetTPM() tpmpolicy, err := tpm.GetPolicy(tspi.TSS_POLICY_USAGE) if err != nil { return nil, nil, err } err = tpm.AssignPolicy(tpmpolicy) if err != nil { return nil, nil, err } err = tpmpolicy.SetSecret(tspi.TSS_SECRET_MODE_SHA1, wellKnown[:]) if err != nil { return nil, nil, err } pcakey, err := context.CreateKey(tspi.TSS_KEY_TYPE_LEGACY | tspi.TSS_KEY_SIZE_2048) if err != nil { return nil, nil, err } err = pcakey.SetModulus(n) if err != nil { return nil, nil, err } aik, err := context.CreateKey(tspi.TSS_KEY_TYPE_IDENTITY | tspi.TSS_KEY_SIZE_2048) if err != nil { return nil, nil, err } _, err = tpm.CollateIdentityRequest(srk, pcakey, aik) if err != nil { return nil, nil, err } pubkey, err := aik.GetPubKeyBlob() if err != nil { return nil, nil, err } blob, err := aik.GetKeyBlob() if err != nil { return nil, nil, err } _, err = aik.GetModulus() return pubkey, blob, nil }