diff --git a/attest/tpm_windows.go b/attest/tpm_windows.go
index 5b0a042..d48174b 100644
--- a/attest/tpm_windows.go
+++ b/attest/tpm_windows.go
@@ -19,14 +19,22 @@ package attest
 import (
 	"crypto"
 	"crypto/rand"
+	"encoding/base64"
+	"encoding/binary"
 	"encoding/json"
 	"errors"
 	"fmt"
+	"io"
 
+	"github.com/golang/sys/windows/registry"
+	"github.com/google/certificate-transparency-go/x509"
+	tpm1 "github.com/google/go-tpm/tpm"
 	"github.com/google/go-tpm/tpm2"
 	tpmtbs "github.com/google/go-tpm/tpmutil/tbs"
 )
 
+var wellKnownAuth [20]byte
+
 // TPM interfaces with a TPM device on the system.
 type TPM struct {
 	version TPMVersion
@@ -94,17 +102,32 @@ func (t *TPM) Close() error {
 	return t.pcp.Close()
 }
 
+func readTPM12VendorAttributes(tpm io.ReadWriter) (TCGVendorID, string, error) {
+	vendor, err := tpm1.GetManufacturer(tpm)
+	if err != nil {
+		return TCGVendorID(0), "", fmt.Errorf("tpm1.GetCapability failed: %v", err)
+	}
+	vendorID := TCGVendorID(binary.BigEndian.Uint32(vendor))
+	return vendorID, vendorID.String(), nil
+}
+
 // Info returns information about the TPM.
 func (t *TPM) Info() (*TPMInfo, error) {
-	if t.version != TPMVersion20 {
-		return nil, ErrTPM12NotImplemented
-	}
-
+	var manufacturer TCGVendorID
+	var vendorInfo string
+	var err error
 	tpm, err := t.pcp.TPMCommandInterface()
 	if err != nil {
 		return nil, err
 	}
-	manufacturer, vendorInfo, err := readTPM2VendorAttributes(tpm)
+	switch t.version {
+	case TPMVersion12:
+		manufacturer, vendorInfo, err = readTPM12VendorAttributes(tpm)
+	case TPMVersion20:
+		manufacturer, vendorInfo, err = readTPM2VendorAttributes(tpm)
+	default:
+		return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
+	}
 	if err != nil {
 		return nil, err
 	}
@@ -117,11 +140,68 @@ func (t *TPM) Info() (*TPMInfo, error) {
 	}, nil
 }
 
+func getOwnerAuth() ([20]byte, error) {
+	var ret [20]byte
+	regkey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\\CurrentControlSet\\Services\\TPM\\WMI\\Admin`, registry.QUERY_VALUE)
+	if err != nil {
+		return ret, err
+	}
+	defer regkey.Close()
+
+	ownerAuthUTF16, _, err := regkey.GetStringValue("OwnerAuthFull")
+	if err != nil {
+		return ret, err
+	}
+	ownerAuthBytes, err := base64.StdEncoding.DecodeString(ownerAuthUTF16)
+	if err != nil {
+		return ret, err
+	}
+	if size := len(ownerAuthBytes); size != 20 {
+		return ret, fmt.Errorf("OwnerAuth is an unexpected size: %d", size)
+	}
+	// Check OwnerAuthStatus first maybe?
+	for i := range ret {
+		ret[i] = ownerAuthBytes[i]
+	}
+	return ret, nil
+}
+
+func (t *TPM) readEKCert12() ([]*x509.Certificate, error) {
+	tpm, err := t.pcp.TPMCommandInterface()
+	if err != nil {
+		return nil, err
+	}
+	ownAuth, err := getOwnerAuth()
+	if err != nil {
+		return nil, err
+	}
+	ekcert, err := tpm1.ReadEKCert(tpm, ownAuth)
+	if err != nil {
+		return nil, err
+	}
+	cert, err := x509.ParseCertificate(ekcert)
+	if err != nil {
+		return nil, err
+	}
+	return []*x509.Certificate{cert}, nil
+}
+
 // EKs returns the Endorsement Keys burned-in to the platform.
 func (t *TPM) EKs() ([]PlatformEK, error) {
-	ekCerts, err := t.pcp.EKCerts()
+	var ekCerts []*x509.Certificate
+	var err error
+	switch t.version {
+	case TPMVersion12:
+		ekCerts, err = t.readEKCert12()
+
+	case TPMVersion20:
+		ekCerts, err = t.pcp.EKCerts()
+
+	default:
+		return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
+	}
 	if err != nil {
-		return nil, fmt.Errorf("could not read EKCerts from PCP: %v", err)
+		return nil, fmt.Errorf("could not read EKCerts: %v", err)
 	}
 
 	var out []PlatformEK
@@ -140,11 +220,13 @@ func (t *TPM) EKs() ([]PlatformEK, error) {
 // Key represents a key bound to the TPM.
 type Key struct {
 	hnd         uintptr
+	hnd12       tpmutil.Handle
 	KeyEncoding KeyEncoding
 	TPMVersion  TPMVersion
 	Purpose     KeyPurpose
 
 	PCPKeyName        string
+	KeyBlob           []byte
 	Public            []byte
 	CreateData        []byte
 	CreateAttestation []byte
@@ -158,69 +240,151 @@ func (k *Key) Marshal() ([]byte, error) {
 }
 
 // ActivateCredential decrypts the specified credential using key.
-// This operation is synonymous with TPM2_ActivateCredential.
+// This operation is synonymous with TPM2_ActivateCredential for TPM2.0
+// and TPM_ActivateIdentity for TPM1.2.
 func (k *Key) ActivateCredential(tpm *TPM, in EncryptedCredential) ([]byte, error) {
-	if tpm.version != TPMVersion20 {
-		return nil, ErrTPM12NotImplemented
+	if k.TPMVersion != tpm.version {
+		return nil, fmt.Errorf("tpm and key version mismatch")
 	}
-	return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
+	switch tpm.version {
+	case TPMVersion12:
+		rw, err := tpm.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, fmt.Errorf("pcp.TPMCommandInterface() failed: %v", err)
+		}
+		ownAuth, err := getOwnerAuth()
+		if err != nil {
+			return nil, fmt.Errorf("getOwnerAuth failed: %v", err)
+		}
+		return tpm1.ActivateIdentity(rw, wellKnownAuth[:], ownAuth[:], k.hnd12, in.Credential, in.Secret)
+	case TPMVersion20:
+		return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
+	default:
+		return nil, fmt.Errorf("unsupported TPM version: %x", tpm.version)
+	}
+}
+
+func (k *Key) quote12(tpm io.ReadWriter, nonce []byte) (*Quote, error) {
+	selectedPCRs := make([]int, 24)
+	for _, pcr := range selectedPCRs {
+		selectedPCRs[pcr] = pcr
+	}
+
+	sig, quote, err := tpm1.Quote(tpm, k.hnd12, nonce, selectedPCRs[:], wellKnownAuth[:])
+	if err != nil {
+		return nil, fmt.Errorf("Quote() failed: %v", err)
+	}
+	return &Quote{
+		Quote:     quote,
+		Signature: sig,
+	}, nil
 }
 
 // Quote returns a quote over the platform state, signed by the key.
 func (k *Key) Quote(t *TPM, nonce []byte, alg tpm2.Algorithm) (*Quote, error) {
-	if t.version != TPMVersion20 {
-		return nil, ErrTPM12NotImplemented
+	switch t.version {
+	case TPMVersion12:
+		tpm, err := t.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
+		}
+		return k.quote12(tpm, nonce)
+
+	case TPMVersion20:
+		tpm, err := t.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
+		}
+		tpmKeyHnd, err := t.pcp.TPMKeyHandle(k.hnd)
+		if err != nil {
+			return nil, fmt.Errorf("TPMKeyHandle() failed: %v", err)
+		}
+		return quote20(tpm, tpmKeyHnd, alg, nonce)
+
+	default:
+		return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
 	}
-	tpm, err := t.pcp.TPMCommandInterface()
-	if err != nil {
-		return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
-	}
-	tpmKeyHnd, err := t.pcp.TPMKeyHandle(k.hnd)
-	if err != nil {
-		return nil, fmt.Errorf("TPMKeyHandle() failed: %v", err)
-	}
-	return quote20(tpm, tpmKeyHnd, alg, nonce)
 }
 
 // Close frees any resources associated with the key.
 func (k *Key) Close(tpm *TPM) error {
-	return closeNCryptObject(k.hnd)
+	switch tpm.version {
+	case TPMVersion12:
+		return nil
+	case TPMVersion20:
+		return closeNCryptObject(k.hnd)
+	default:
+		return fmt.Errorf("unsupported TPM version: %x", tpm.version)
+	}
 }
 
 // MintAIK creates a persistent attestation key. The returned key must be
 // closed with a call to key.Close() when the caller has finished using it.
 func (t *TPM) MintAIK(opts *MintOptions) (*Key, error) {
-	if t.version != TPMVersion20 {
-		return nil, ErrTPM12NotImplemented
-	}
+	switch t.version {
+	case TPMVersion12:
+		tpm, err := t.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, err
+		}
+		ownAuth, err := getOwnerAuth()
+		if err != nil {
+			return nil, err
+		}
+		blob, err := tpm1.MakeIdentity(tpm, wellKnownAuth[:], ownAuth[:], wellKnownAuth[:], nil, nil)
+		if err != nil {
+			return nil, fmt.Errorf("MakeIdentityEx failed: %v", err)
+		}
+		hnd, err := tpm1.LoadKey2(tpm, blob, wellKnownAuth[:])
+		if err != nil {
+			return nil, fmt.Errorf("LoadKey2 failed: %v", err)
+		}
+		pub, err := tpm1.GetPubKey(tpm, hnd, wellKnownAuth[:])
+		if err != nil {
+			return nil, fmt.Errorf("GetPubKey failed: %v", err)
+		}
 
-	nameHex := make([]byte, 5)
-	if n, err := rand.Read(nameHex); err != nil || n != len(nameHex) {
-		return nil, fmt.Errorf("rand.Read() failed with %d/%d bytes read and error: %v", n, len(nameHex), err)
-	}
-	name := fmt.Sprintf("aik-%x", nameHex)
+		return &Key{
+			hnd12:       hnd,
+			KeyEncoding: KeyEncodingOSManaged,
+			TPMVersion:  t.version,
+			Purpose:     AttestationKey,
+			KeyBlob:     blob,
+			Public:      pub,
+		}, nil
 
-	kh, err := t.pcp.MintAIK(name)
-	if err != nil {
-		return nil, fmt.Errorf("pcp failed to mint attestation key: %v", err)
-	}
-	props, err := t.pcp.AIKProperties(kh)
-	if err != nil {
-		closeNCryptObject(kh)
-		return nil, fmt.Errorf("pcp failed to read attestation key properties: %v", err)
-	}
+	case TPMVersion20:
+		nameHex := make([]byte, 5)
+		if n, err := rand.Read(nameHex); err != nil || n != len(nameHex) {
+			return nil, fmt.Errorf("rand.Read() failed with %d/%d bytes read and error: %v", n, len(nameHex), err)
+		}
+		name := fmt.Sprintf("aik-%x", nameHex)
 
-	return &Key{
-		hnd:               kh,
-		KeyEncoding:       KeyEncodingOSManaged,
-		TPMVersion:        t.version,
-		Purpose:           AttestationKey,
-		PCPKeyName:        name,
-		Public:            props.RawPublic,
-		CreateData:        props.RawCreationData,
-		CreateAttestation: props.RawAttest,
-		CreateSignature:   props.RawSignature,
-	}, nil
+		kh, err := t.pcp.MintAIK(name)
+		if err != nil {
+			return nil, fmt.Errorf("pcp failed to mint attestation key: %v", err)
+		}
+		props, err := t.pcp.AIKProperties(kh)
+		if err != nil {
+			closeNCryptObject(kh)
+			return nil, fmt.Errorf("pcp failed to read attestation key properties: %v", err)
+		}
+
+		return &Key{
+			hnd:               kh,
+			KeyEncoding:       KeyEncodingOSManaged,
+			TPMVersion:        t.version,
+			Purpose:           AttestationKey,
+			PCPKeyName:        name,
+			Public:            props.RawPublic,
+			CreateData:        props.RawCreationData,
+			CreateAttestation: props.RawAttest,
+			CreateSignature:   props.RawSignature,
+		}, nil
+
+	default:
+		return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
+	}
 }
 
 // LoadKey loads a previously-created key into the TPM for use.
@@ -242,24 +406,74 @@ func (t *TPM) LoadKey(opaqueBlob []byte) (*Key, error) {
 		return nil, fmt.Errorf("unsupported key kind: %x", k.Purpose)
 	}
 
-	if k.hnd, err = t.pcp.LoadKeyByName(k.PCPKeyName); err != nil {
-		return nil, fmt.Errorf("pcp failed to load key: %v", err)
+	switch t.version {
+	case TPMVersion12:
+		tpm, err := t.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, fmt.Errorf("failed to get interface to TPM: %v", err)
+		}
+		if k.hnd12, err = tpm1.LoadKey2(tpm, k.KeyBlob, wellKnownAuth[:]); err != nil {
+			return nil, fmt.Errorf("go-tpm failed to load key: %v", err)
+		}
+
+	case TPMVersion20:
+		if k.hnd, err = t.pcp.LoadKeyByName(k.PCPKeyName); err != nil {
+			return nil, fmt.Errorf("pcp failed to load key: %v", err)
+		}
+
+	default:
+		return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
 	}
 	return &k, nil
 }
 
+func allPCRs12(tpm io.ReadWriter) (map[uint32][]byte, error) {
+	numPCRs := 24
+	out := map[uint32][]byte{}
+
+	for pcr := 0; pcr < numPCRs; pcr++ {
+		pcrval, err := tpm1.ReadPCR(tpm, uint32(pcr))
+		if err != nil {
+			return nil, fmt.Errorf("tpm.ReadPCR() failed with err: %v", err)
+		}
+		out[uint32(pcr)] = pcrval
+	}
+
+	if len(out) != numPCRs {
+		return nil, fmt.Errorf("failed to read all PCRs, only read %d", len(out))
+	}
+
+	return out, nil
+}
+
 // PCRs returns the present value of all Platform Configuration Registers.
 func (t *TPM) PCRs() (map[int]PCR, tpm2.Algorithm, error) {
-	if t.version != TPMVersion20 {
-		return nil, 0, ErrTPM12NotImplemented
-	}
-	tpm, err := t.pcp.TPMCommandInterface()
-	if err != nil {
-		return nil, 0, fmt.Errorf("TPMCommandInterface() failed: %v", err)
-	}
-	PCRs, alg, err := allPCRs20(tpm)
-	if err != nil {
-		return nil, 0, fmt.Errorf("failed to read PCRs: %v", err)
+	var PCRs map[uint32][]byte
+	var alg crypto.Hash
+	switch t.version {
+	case TPMVersion12:
+		alg = crypto.SHA1
+		tpm, err := t.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, 0, fmt.Errorf("TPMCommandInterface() failed: %v", err)
+		}
+		PCRs, err = allPCRs12(tpm)
+		if err != nil {
+			return nil, 0, fmt.Errorf("failed to read PCRs: %v", err)
+		}
+
+	case TPMVersion20:
+		tpm, err := t.pcp.TPMCommandInterface()
+		if err != nil {
+			return nil, 0, fmt.Errorf("TPMCommandInterface() failed: %v", err)
+		}
+		PCRs, alg, err = allPCRs20(tpm)
+		if err != nil {
+			return nil, 0, fmt.Errorf("failed to read PCRs: %v", err)
+		}
+
+	default:
+		return nil, 0, fmt.Errorf("unsupported TPM version: %x", t.version)
 	}
 
 	out := map[int]PCR{}
@@ -285,7 +499,7 @@ func (t *TPM) PCRs() (map[int]PCR, tpm2.Algorithm, error) {
 
 // MeasurementLog returns the present value of the System Measurement Log.
 func (t *TPM) MeasurementLog() ([]byte, error) {
-	context, err := tpmtbs.CreateContext(tpmtbs.TPMVersion20, tpmtbs.IncludeTPM20)
+	context, err := tpmtbs.CreateContext(tpmtbs.TPMVersion20, tpmtbs.IncludeTPM20|tpmtbs.IncludeTPM12)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go.mod b/go.mod
index ba53576..7c2b2cd 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.12
 
 require (
 	github.com/google/certificate-transparency-go v1.0.22-0.20190403155334-84853901c6b8
-	github.com/google/go-tpm v0.1.1
+	github.com/google/go-tpm v0.1.2-0.20190409004434-20331edb0a91
 	github.com/google/go-tpm-tools v0.0.0-20190328013357-5d2fd7f4b3e5
 	github.com/google/go-tspi v0.2.0
 	golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
diff --git a/go.sum b/go.sum
index 2d4e1d4..b896212 100644
--- a/go.sum
+++ b/go.sum
@@ -4,6 +4,8 @@ github.com/google/certificate-transparency-go v1.0.22-0.20190403155334-84853901c
 github.com/google/certificate-transparency-go v1.0.22-0.20190403155334-84853901c6b8/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
 github.com/google/go-tpm v0.1.1 h1:Qwvy1ZQsQElHIb/7PCqE4OpiBwDRMMHpu2a2q16S2hI=
 github.com/google/go-tpm v0.1.1/go.mod h1:OGEdc1XfzTyNEQyahgeXVq+E0lMq3Vu/Y3bT9EfpRnE=
+github.com/google/go-tpm v0.1.2-0.20190409004434-20331edb0a91 h1:j37OZK/AlfYPxv4nMu3Mh9pxfqrjMswpSzWoWCt5uEY=
+github.com/google/go-tpm v0.1.2-0.20190409004434-20331edb0a91/go.mod h1:OGEdc1XfzTyNEQyahgeXVq+E0lMq3Vu/Y3bT9EfpRnE=
 github.com/google/go-tpm-tools v0.0.0-20190328013357-5d2fd7f4b3e5 h1:/moKuMi+BJ+OEva3jTms88ruyRkxaZn+f9EIZoGpQeY=
 github.com/google/go-tpm-tools v0.0.0-20190328013357-5d2fd7f4b3e5/go.mod h1:ApmLTU8fd5JJJ4J67y9sV16nOTR00GW2OabMwk7kSnE=
 github.com/google/go-tspi v0.2.0 h1:PMrHThARFgHtsCF6B8YNjLlnnGMDdFjVHZnxaqkcbzQ=