github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tpm2/tpm2.go (about)

     1  // Copyright (c) 2014, Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package tpm2 supports direct communication with a tpm 2.0 device under Linux.
    16  
    17  package tpm2
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/aes"
    22  	"crypto/cipher"
    23  	"crypto/hmac"
    24  	"crypto/rand"
    25  	"crypto/rsa"
    26  	"crypto/sha1"
    27  	"crypto/sha256"
    28  	"crypto/x509"
    29  	"crypto/x509/pkix"
    30  	"encoding/hex"
    31  	"errors"
    32  	"fmt"
    33  	"io"
    34  	"math/big"
    35  	"net"
    36  	"os"
    37  	"time"
    38  	"unsafe"
    39  
    40  	"github.com/golang/glog"
    41  	"github.com/golang/protobuf/proto"
    42  )
    43  
    44  func ComputePcrDigest(alg uint16, in []byte) ([]byte, error) {
    45  	// in should just be a sequence of digest values
    46  	return ComputeHashValue(alg, in)
    47  }
    48  
    49  func GetSerialNumber() *big.Int {
    50  	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 32)
    51  	sn, _ := rand.Int(rand.Reader, serialNumberLimit)
    52  	return sn
    53  }
    54  
    55  type ValidPcrCheck func([]byte, []byte) bool
    56  func ValidPcr(pcrSelect []byte, digest []byte) bool {
    57  	return true
    58  }
    59  
    60  //
    61  //	TPM functions
    62  //
    63  
    64  // OpenTPM opens a channel to the TPM at the given path. If the file is a
    65  // device, then it treats it like a normal TPM device, and if the file is a
    66  // Unix domain socket, then it opens a connection to the socket.
    67  func OpenTPM(path string) (io.ReadWriteCloser, error) {
    68  	// If it's a regular file, then open it
    69  	var rwc io.ReadWriteCloser
    70  	fi, err := os.Stat(path)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	if fi.Mode()&os.ModeDevice != 0 {
    76  		var f *os.File
    77  		f, err = os.OpenFile(path, os.O_RDWR, 0600)
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  		rwc = io.ReadWriteCloser(f)
    82  	} else if fi.Mode()&os.ModeSocket != 0 {
    83  		uc, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: path, Net: "unix"})
    84  		if err != nil {
    85  			return nil, err
    86  		}
    87  		rwc = io.ReadWriteCloser(uc)
    88  	} else {
    89  		return nil, fmt.Errorf("unsupported TPM file mode %s", fi.Mode().String())
    90  	}
    91  
    92  	return rwc, nil
    93  }
    94  
    95  func reportCommand(name string, cmd []byte, resp []byte,
    96  	status TpmError, errOnly bool) {
    97  	if errOnly && status == ErrSuccess {
    98  		return
    99  	}
   100  	glog.Infof("reportCommand, %s, cmd: %x,\n\terr code: %x, resp: %x\n", name, cmd, status, resp)
   101  	// TODO: remove?
   102  	fmt.Printf("%s, cmd: %x,\n\terr code: %x, resp: %x\n", name, cmd, status, resp)
   103  }
   104  
   105  func PrintAttestData(parms *AttestParams) {
   106  	fmt.Printf("Magic_number: %x\n", parms.Magic_number)
   107  	fmt.Printf("Attest_type : %x\n", parms.Attest_type)
   108  	fmt.Printf("Name        : %x\n", parms.Name)
   109  	fmt.Printf("Data        : %x\n", parms.Data)
   110  	fmt.Printf("Clock       : %x\n", parms.Clock)
   111  	fmt.Printf("ResetCount  : %x\n", parms.ResetCount)
   112  	fmt.Printf("RestartCount: %x\n", parms.RestartCount)
   113  	fmt.Printf("Safe        : %x\n", parms.Safe)
   114  	fmt.Printf("FirmwareVersion: %x\n", parms.FirmwareVersion)
   115  	fmt.Printf("PcrSelect   : %x\n", parms.PcrSelect)
   116  	fmt.Printf("PcrDigest   : %x\n", parms.PcrDigest)
   117  }
   118  
   119  func PrintKeyedHashParams(parms *KeyedHashParams) {
   120  	fmt.Printf("Type_alg   : %x\n", parms.Type_alg)
   121  	fmt.Printf("Hash_alg   : %x\n", parms.Hash_alg)
   122  	fmt.Printf("Attributes : %x\n", parms.Attributes)
   123  	fmt.Printf("Auth_policy: %x\n", parms.Auth_policy)
   124  	fmt.Printf("Symalg     : %x\n", parms.Symalg)
   125  	fmt.Printf("Sym_sz     : %x\n", parms.Sym_sz)
   126  	fmt.Printf("Mode       : %x\n", parms.Mode)
   127  	fmt.Printf("Scheme     : %x\n", parms.Scheme)
   128  	fmt.Printf("Unique     : %x\n", parms.Unique)
   129  }
   130  
   131  func PrintRsaParams(parms *RsaParams) {
   132  	fmt.Printf("Enc_alg     : %x\n", parms.Enc_alg)
   133  	fmt.Printf("Hash_alg    : %x\n", parms.Hash_alg)
   134  	fmt.Printf("Attributes  : %x\n", parms.Attributes)
   135  	fmt.Printf("Auth_policy : %x\n", parms.Auth_policy)
   136  	fmt.Printf("Symalg      : %x\n", parms.Symalg)
   137  	fmt.Printf("Sym_sz      : %x\n", parms.Sym_sz)
   138  	fmt.Printf("Mode        : %x\n", parms.Mode)
   139  	fmt.Printf("Scheme      : %x\n", parms.Scheme)
   140  	fmt.Printf("Scheme_hash : %x\n", parms.Scheme_hash)
   141  	fmt.Printf("Modulus size: %x\n", parms.Mod_sz)
   142  	fmt.Printf("Exp         : %x\n", parms.Exp)
   143  	fmt.Printf("Modulus     : %x\n", parms.Modulus)
   144  }
   145  
   146  func SetShortPcrs(pcr_nums []int) ([]byte, error) {
   147  	pcr := []byte{3, 0, 0, 0}
   148  	var byte_num int
   149  	var byte_pos byte
   150  	for _, e := range pcr_nums {
   151  		byte_num = 1 + e/8
   152  		byte_pos = 1 << uint16(e%8)
   153  		pcr[byte_num] |= byte_pos
   154  	}
   155  	return pcr, nil
   156  }
   157  
   158  // nil is error
   159  func SetHandle(handle Handle) []byte {
   160  	uint32_handle := uint32(handle)
   161  	str, _ := pack([]interface{}{&uint32_handle})
   162  	return str
   163  }
   164  
   165  // nil return is an error
   166  func SetPasswordData(password string) []byte {
   167  	// len password
   168  	pw, err := hex.DecodeString(password)
   169  	if err != nil {
   170  		return nil
   171  	}
   172  	ret, _ := pack([]interface{}{&pw})
   173  	return ret
   174  }
   175  
   176  // nil return is an error
   177  // 	returns: len0 TPM_RS_PW 0000 01 password data as []byte
   178  func CreatePasswordAuthArea(password string, owner Handle) []byte {
   179  	owner_str := SetHandle(owner)
   180  	suffix := []byte{0, 0, 1}
   181  	pw := SetPasswordData(password)
   182  	final_buf := append(owner_str, suffix...)
   183  	final_buf = append(final_buf, pw...)
   184  	out := []interface{}{&final_buf}
   185  	ret, _ := pack(out)
   186  	return ret
   187  }
   188  
   189  // nil is error
   190  func CreateSensitiveArea(in1 []byte, in2 []byte) []byte {
   191  	//   password (SENSITIVE CREATE)
   192  	//   0008 0004 01020304
   193  	//        0000
   194  	t1, err := pack([]interface{}{&in1})
   195  	if err != nil {
   196  		return nil
   197  	}
   198  	t2, err := pack([]interface{}{&in2})
   199  	if err != nil {
   200  		return nil
   201  	}
   202  
   203  	t := append(t1, t2...)
   204  	ret, err := pack([]interface{}{&t})
   205  	if err != nil {
   206  		return nil
   207  	}
   208  
   209  	return ret
   210  }
   211  
   212  func DecodeRsaBuf(rsa_buf []byte) (*RsaParams, error) {
   213  	parms := new(RsaParams)
   214  	current := int(0)
   215  	template := []interface{}{&parms.Enc_alg, &parms.Hash_alg,
   216  		&parms.Attributes, &parms.Auth_policy}
   217  	err := unpack(rsa_buf[current:], template)
   218  	if err != nil {
   219  		return nil, errors.New("Can't unpack Rsa buffer 2")
   220  	}
   221  	current += 10 + len(parms.Auth_policy)
   222  	template = []interface{}{&parms.Symalg}
   223  	err = unpack(rsa_buf[current:], template)
   224  	if err != nil {
   225  		return nil, errors.New("Can't unpack Rsa buffer 3")
   226  	}
   227  	current += 2
   228  	if parms.Symalg != uint16(AlgTPM_ALG_NULL) {
   229  		template = []interface{}{&parms.Sym_sz, &parms.Mode}
   230  		err = unpack(rsa_buf[current:], template)
   231  		if err != nil {
   232  			return nil, errors.New("Can't unpack Rsa buffer 4")
   233  		}
   234  		current += 4
   235  	} else {
   236  		parms.Sym_sz = 0
   237  		parms.Mode = 0
   238  		parms.Scheme = 0
   239  	}
   240  	template = []interface{}{&parms.Scheme}
   241  	err = unpack(rsa_buf[current:], template)
   242  	if err != nil {
   243  		return nil, errors.New("Can't unpack Rsa buffer 5")
   244  	}
   245  	current += 2
   246  	if parms.Scheme == uint16(AlgTPM_ALG_RSASSA) {
   247  		template = []interface{}{&parms.Scheme_hash}
   248  		err = unpack(rsa_buf[current:], template)
   249  		if err != nil {
   250  			return nil, errors.New("Can't unpack Rsa buffer 6")
   251  		}
   252  		current += 2
   253  	}
   254  
   255  	template = []interface{}{&parms.Mod_sz, &parms.Exp, &parms.Modulus}
   256  	err = unpack(rsa_buf[current:], template)
   257  	if err != nil {
   258  		return nil, errors.New("Can't unpack Rsa buffer 7")
   259  	}
   260  	return parms, nil
   261  }
   262  
   263  // nil is error
   264  func DecodeRsaArea(in []byte) (*RsaParams, error) {
   265  	var rsa_buf []byte
   266  
   267  	template := []interface{}{&rsa_buf}
   268  	err := unpack(in, template)
   269  	if err != nil {
   270  		return nil, errors.New("Can't unpack Rsa buffer 1")
   271  	}
   272  	return DecodeRsaBuf(rsa_buf)
   273  }
   274  
   275  // nil is error
   276  func CreateKeyedHashParams(parms KeyedHashParams) []byte {
   277  	// 0 (uint16), type, attributes, auth, scheme, 0 (unique)
   278  	template := []interface{}{&parms.Type_alg, &parms.Hash_alg,
   279  		&parms.Attributes, &parms.Auth_policy, &parms.Scheme,
   280  		&parms.Unique}
   281  	t1, err := pack(template)
   282  	if err != nil {
   283  		return nil
   284  	}
   285  	return t1
   286  }
   287  
   288  // nil return is error
   289  func CreateRsaParams(parms RsaParams) []byte {
   290  	template := []interface{}{&parms.Enc_alg, &parms.Hash_alg,
   291  		&parms.Attributes, &parms.Auth_policy}
   292  	t1, err := pack(template)
   293  	if err != nil {
   294  		return nil
   295  	}
   296  
   297  	if parms.Symalg != uint16(AlgTPM_ALG_NULL) {
   298  		template = []interface{}{&parms.Symalg, &parms.Sym_sz,
   299  			&parms.Mode, &parms.Scheme}
   300  	} else {
   301  		template = []interface{}{&parms.Symalg, &parms.Scheme}
   302  	}
   303  	t2, err := pack(template)
   304  	if err != nil {
   305  		return nil
   306  	}
   307  	if parms.Scheme == uint16(AlgTPM_ALG_RSASSA) {
   308  		template3 := []interface{}{&parms.Scheme_hash}
   309  		t3, err := pack(template3)
   310  		if err != nil {
   311  			return nil
   312  		}
   313  		t2 = append(t2, t3...)
   314  	}
   315  
   316  	template4 := []interface{}{&parms.Mod_sz, &parms.Exp, parms.Modulus}
   317  	t4, err := pack(template4)
   318  	if err != nil {
   319  		return nil
   320  	}
   321  
   322  	t5 := append(t1, t2...)
   323  	t5 = append(t5, t4...)
   324  	template5 := []interface{}{&t5}
   325  	buf, err := pack(template5)
   326  	if err != nil {
   327  		return nil
   328  	}
   329  	return buf
   330  }
   331  
   332  // nil return is error
   333  func CreateLongPcr(count uint32, pcr_nums []int) []byte {
   334  	if count == 0 {
   335  		b1, err := pack([]interface{}{&count})
   336  		if err != nil {
   337  			return nil
   338  		}
   339  		return b1
   340  	}
   341  	b1, err := SetShortPcrs(pcr_nums)
   342  	if err != nil {
   343  		return nil
   344  	}
   345  	template := []interface{}{&count, &b1}
   346  	b2, err := pack(template)
   347  	if err != nil {
   348  		return nil
   349  	}
   350  	return b2
   351  }
   352  
   353  // ConstructGetRandom constructs a GetRandom command.
   354  func ConstructGetRandom(size uint32) ([]byte, error) {
   355  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdGetRandom)
   356  	if err != nil {
   357  		return nil, errors.New("ConstructGetRandom failed")
   358  	}
   359  	num_bytes := []interface{}{uint16(size)}
   360  	cmd, _ := packWithHeader(cmdHdr, num_bytes)
   361  	return cmd, nil
   362  }
   363  
   364  // DecodeGetRandom decodes a GetRandom response.
   365  func DecodeGetRandom(in []byte) ([]byte, error) {
   366  	var rand_bytes []byte
   367  
   368  	out := []interface{}{&rand_bytes}
   369  	err := unpack(in, out)
   370  	if err != nil {
   371  		return nil, errors.New("Can't decode GetRandom response")
   372  	}
   373  	return rand_bytes, nil
   374  }
   375  
   376  // GetRandom gets random bytes from the TPM.
   377  func GetRandom(rw io.ReadWriteCloser, size uint32) ([]byte, error) {
   378  	// Construct command
   379  	cmd, err := ConstructGetRandom(size)
   380  	if err != nil {
   381  		return nil, err
   382  	}
   383  
   384  	// Send command
   385  	_, err = rw.Write(cmd)
   386  	if err != nil {
   387  		return nil, errors.New("Write Tpm fails")
   388  	}
   389  
   390  	// Get response
   391  	resp := make([]byte, 1024, 1024)
   392  	read, err := rw.Read(resp)
   393  	if err != nil {
   394  		return nil, errors.New("Read Tpm fails")
   395  	}
   396  
   397  	// Decode Response
   398  	if read < 10 {
   399  		return nil, errors.New("Read buffer too small")
   400  	}
   401  	_, size, status, err := DecodeCommandResponse(resp[0:10])
   402  	if err != nil {
   403  		return nil, err
   404  	}
   405  	reportCommand("GetRandom", cmd, resp[0:size], status, true)
   406  	if status != ErrSuccess {
   407  		return nil, errors.New("Can't decode response")
   408  	}
   409  	rand, err := DecodeGetRandom(resp[10:read])
   410  	if err != nil {
   411  		return nil, err
   412  	}
   413  	return rand, nil
   414  }
   415  
   416  // ConstructFlushContext constructs a FlushContext command.
   417  func ConstructFlushContext(handle Handle) ([]byte, error) {
   418  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdFlushContext)
   419  	if err != nil {
   420  		return nil, errors.New("ConstructFlushContext failed")
   421  	}
   422  	cmd_text := []interface{}{uint32(handle)}
   423  	x, _ := packWithHeader(cmdHdr, cmd_text)
   424  	return x, nil
   425  }
   426  
   427  // FlushContext
   428  func FlushContext(rw io.ReadWriter, handle Handle) error {
   429  	// Construct command
   430  	cmd, err := ConstructFlushContext(handle)
   431  	if err != nil {
   432  		return errors.New("ConstructFlushContext fails")
   433  	}
   434  
   435  	// Send command
   436  	_, err = rw.Write(cmd)
   437  	if err != nil {
   438  		return errors.New("Write Tpm fails")
   439  	}
   440  
   441  	// Get response
   442  	var resp []byte
   443  	resp = make([]byte, 1024, 1024)
   444  	read, err := rw.Read(resp)
   445  	if err != nil {
   446  		return errors.New("Read Tpm fails")
   447  	}
   448  
   449  	// Decode Response
   450  	if read < 10 {
   451  		return errors.New("Read buffer too small")
   452  	}
   453  	_, _, status, err := DecodeCommandResponse(resp[0:10])
   454  	if err != nil {
   455  		return errors.New("DecodeCommandResponse fails")
   456  	}
   457  	if status != ErrSuccess {
   458  		return errors.New("FlushContext unsuccessful")
   459  	}
   460  	return nil
   461  }
   462  
   463  // ConstructReadPcrs constructs a ReadPcr command.
   464  func ConstructReadPcrs(num_spec int, num_pcr byte, pcrs []byte) ([]byte, error) {
   465  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPCR_Read)
   466  	if err != nil {
   467  		return nil, errors.New("ConstructReadPcrs failed")
   468  	}
   469  	num := uint32(num_spec)
   470  	template := []interface{}{&num, &pcrs}
   471  	cmd, _ := packWithHeader(cmdHdr, template)
   472  	return cmd, nil
   473  }
   474  
   475  // DecodeReadPcrs decodes a ReadPcr response.
   476  func DecodeReadPcrs(in []byte) (uint32, []byte, uint16, []byte, error) {
   477  	var pcr []byte
   478  	var digest []byte
   479  	var updateCounter uint32
   480  	var t uint32
   481  	var s uint32
   482  
   483  	out := []interface{}{&t, &updateCounter, &pcr, &s, &digest}
   484  	err := unpack(in, out)
   485  	if err != nil {
   486  		return 1, nil, 0, nil, errors.New("Can't decode ReadPcrs response")
   487  	}
   488  	return updateCounter, pcr, uint16(t), digest, nil
   489  }
   490  
   491  // ReadPcr reads a PCR value from the TPM.
   492  //	Output: updatecounter, selectout, digest
   493  func ReadPcrs(rw io.ReadWriter, num_byte byte, pcrSelect []byte) (uint32, []byte, uint16, []byte, error) {
   494  	// Construct command
   495  	x, err := ConstructReadPcrs(1, 4, pcrSelect)
   496  	if err != nil {
   497  		return 1, nil, 0, nil, errors.New("MakeCommandHeader failed")
   498  	}
   499  
   500  	// Send command
   501  	_, err = rw.Write(x)
   502  	if err != nil {
   503  		return 0, nil, 0, nil, errors.New("Write Tpm fails")
   504  	}
   505  
   506  	// Get response
   507  	var resp []byte
   508  	resp = make([]byte, 1024, 1024)
   509  	read, err := rw.Read(resp)
   510  	if err != nil {
   511  		return 0, nil, 0, nil, errors.New("Read Tpm fails")
   512  	}
   513  
   514  	// Decode Response
   515  	if read < 10 {
   516  		return 0, nil, 0, nil, errors.New("Read buffer too small")
   517  	}
   518  	_, _, status, err := DecodeCommandResponse(resp[0:10])
   519  	if err != nil {
   520  		return 0, nil, 0, nil, errors.New("DecodeCommandResponse fails")
   521  	}
   522  	if status != ErrSuccess {
   523  		return 0, nil, 0, nil, errors.New("ReadPcr command failed")
   524  	}
   525  	counter, pcr, alg, digest, err := DecodeReadPcrs(resp[10:])
   526  	if err != nil {
   527  		return 0, nil, 0, nil, errors.New("DecodeReadPcrsfails")
   528  	}
   529  	return counter, pcr, alg, digest, err
   530  }
   531  
   532  // ConstructReadClock constructs a ReadClock command.
   533  func ConstructReadClock() ([]byte, error) {
   534  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdReadClock)
   535  	if err != nil {
   536  		return nil, errors.New("ConstructGetRandom failed")
   537  	}
   538  	cmd := packWithBytes(cmdHdr, nil)
   539  	return cmd, nil
   540  }
   541  
   542  // DecodeReadClock decodes a ReadClock response.
   543  func DecodeReadClock(in []byte) (uint64, uint64, error) {
   544  	var current_time, current_clock uint64
   545  
   546  	template := []interface{}{&current_time, &current_clock}
   547  	err := unpack(in, template)
   548  	if err != nil {
   549  		return 0, 0, errors.New("Can't decode DecodeReadClock response")
   550  	}
   551  	return current_time, current_clock, nil
   552  }
   553  
   554  // ReadClock
   555  //	Output: current time, current clock
   556  func ReadClock(rw io.ReadWriter) (uint64, uint64, error) {
   557  	// Construct command
   558  	x, err := ConstructReadClock()
   559  	if err != nil {
   560  		return 0, 0, errors.New("Can't construct ReadClock response")
   561  	}
   562  
   563  	// Send command
   564  	_, err = rw.Write(x)
   565  	if err != nil {
   566  		return 0, 0, errors.New("Write Tpm fails")
   567  	}
   568  
   569  	// Get response
   570  	var resp []byte
   571  	resp = make([]byte, 1024, 1024)
   572  	read, err := rw.Read(resp)
   573  	if err != nil {
   574  		return 0, 0, errors.New("Read Tpm fails")
   575  	}
   576  
   577  	// Decode Response
   578  	if read < 10 {
   579  		return 0, 0, errors.New("Read buffer too small")
   580  	}
   581  	_, _, status, err := DecodeCommandResponse(resp[0:10])
   582  	if err != nil {
   583  		return 0, 0, err
   584  	}
   585  	if status != ErrSuccess {
   586  		return 0, 0, errors.New("Can't decode response")
   587  	}
   588  	current_time, current_clock, err := DecodeReadClock(resp[10:read])
   589  	if err != nil {
   590  		return 0, 0, err
   591  	}
   592  	return current_time, current_clock, nil
   593  }
   594  
   595  // ConstructGetCapabilities constructs a GetCapabilities command.
   596  func ConstructGetCapabilities(cap uint32, count uint32, property uint32) ([]byte, error) {
   597  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdGetCapability)
   598  	if err != nil {
   599  		return nil, errors.New("GetCapability failed")
   600  	}
   601  	cap_bytes := []interface{}{&cap, &property, &count}
   602  	cmd, _ := packWithHeader(cmdHdr, cap_bytes)
   603  	return cmd, nil
   604  }
   605  
   606  // DecodeGetCapabilities decodes a GetCapabilities response.
   607  func DecodeGetCapabilities(in []byte) (uint32, []uint32, error) {
   608  	var num_handles uint32
   609  	var cap_reported uint32
   610  
   611  	out := []interface{}{&cap_reported, &num_handles}
   612  	err := unpack(in[1:9], out)
   613  	if err != nil {
   614  		return 0, nil, errors.New("Can't decode GetCapabilities response")
   615  	}
   616  	// only OrdTPM_CAP_HANDLES handled
   617  	if cap_reported != OrdTPM_CAP_HANDLES {
   618  		return 0, nil, errors.New("Only ordTPM_CAP_HANDLES supported")
   619  	}
   620  	var handles []uint32
   621  	var handle uint32
   622  	handle_out := []interface{}{&handle}
   623  	for i := 0; i < int(num_handles); i++ {
   624  		err := unpack(in[8+4*i:12+4*i], handle_out)
   625  		if err != nil {
   626  			return 0, nil, errors.New("Can't decode GetCapabilities handle")
   627  		}
   628  		handles = append(handles, handle)
   629  	}
   630  
   631  	return cap_reported, handles, nil
   632  }
   633  
   634  // GetCapabilities
   635  //	Output: output buf
   636  func GetCapabilities(rw io.ReadWriter, cap uint32, count uint32, property uint32) ([]uint32, error) {
   637  	// Construct command
   638  	cmd, err := ConstructGetCapabilities(cap, count, property)
   639  	if err != nil {
   640  		return nil, err
   641  	}
   642  
   643  	// Send command
   644  	_, err = rw.Write(cmd)
   645  	if err != nil {
   646  		return nil, errors.New("Write Tpm fails")
   647  	}
   648  
   649  	// Get response
   650  	resp := make([]byte, 4096, 4096)
   651  	read, err := rw.Read(resp)
   652  	if err != nil {
   653  		return nil, errors.New("Read Tpm fails")
   654  	}
   655  
   656  	// Decode Response
   657  	if read < 10 {
   658  		return nil, errors.New("Read buffer too small")
   659  	}
   660  	_, _, status, err := DecodeCommandResponse(resp[0:10])
   661  	if err != nil {
   662  		return nil, err
   663  	}
   664  	if status != ErrSuccess {
   665  	}
   666  	_, handles, err := DecodeGetCapabilities(resp[10:read])
   667  	if err != nil {
   668  		return nil, err
   669  	}
   670  	return handles, nil
   671  }
   672  
   673  // ConstructPcrEvent
   674  func ConstructPcrEvent(pcrnum int, eventData []byte) ([]byte, error) {
   675  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdPcrEvent)
   676  	if err != nil {
   677  		return nil, errors.New("GetCapability failed")
   678  	}
   679  	// pcrnum, empty, emptyauth, eventData size, eventData
   680  	var empty []byte
   681  	pc := uint32(pcrnum)
   682  	b1, _ := pack([]interface{}{&pc, &empty})
   683  	b2 := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW))
   684  	b3, _ := pack([]interface{}{&eventData})
   685  	cmd := packWithBytes(cmdHdr, append(append(b1, b2...), b3...))
   686  	return cmd, nil
   687  }
   688  
   689  // PcrEvent
   690  func PcrEvent(rw io.ReadWriter, pcrnum int, eventData []byte) error {
   691  	// Construct command
   692  	cmd, err := ConstructPcrEvent(pcrnum, eventData)
   693  	if err != nil {
   694  		return err
   695  	}
   696  
   697  	// Send command
   698  	_, err = rw.Write(cmd)
   699  	if err != nil {
   700  		return errors.New("Write Tpm fails")
   701  	}
   702  
   703  	// Get response
   704  	var resp []byte
   705  	resp = make([]byte, 4096, 4096)
   706  	read, err := rw.Read(resp)
   707  	if err != nil {
   708  		return errors.New("Read Tpm fails")
   709  	}
   710  
   711  	// Decode Response
   712  	if read < 10 {
   713  		return errors.New("Read buffer too small")
   714  	}
   715  	_, _, status, err := DecodeCommandResponse(resp[0:10])
   716  	if err != nil {
   717  		return err
   718  	}
   719  	if status != ErrSuccess {
   720  		return errors.New("Command failure")
   721  	}
   722  	return nil
   723  }
   724  
   725  // Flushall
   726  func Flushall(rw io.ReadWriter) error {
   727  	handles, err := GetCapabilities(rw, OrdTPM_CAP_HANDLES, 1, 0x80000000)
   728  	if err != nil {
   729  		return err
   730  	}
   731  	for _, e := range handles {
   732  		_ = FlushContext(rw, Handle(e))
   733  	}
   734  	return nil
   735  }
   736  
   737  // ConstructCreatePrimary constructs a CreatePrimary command.
   738  func ConstructCreatePrimary(owner uint32, pcr_nums []int,
   739  	parent_password string, owner_password string,
   740  	parms RsaParams) ([]byte, error) {
   741  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdCreatePrimary)
   742  	if err != nil {
   743  		return nil, errors.New("ConstructCreatePrimary failed")
   744  	}
   745  	var empty []byte
   746  	b1 := SetHandle(Handle(owner))
   747  	b2, _ := pack([]interface{}{&empty})
   748  	b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW))
   749  	t1 := SetPasswordData(owner_password)
   750  	b4 := CreateSensitiveArea(t1[2:], empty)
   751  	b5 := CreateRsaParams(parms)
   752  	b6, _ := pack([]interface{}{&empty})
   753  	var b7 []byte
   754  	if len(pcr_nums) > 0 {
   755  		b7 = CreateLongPcr(uint32(1), pcr_nums)
   756  	} else {
   757  		b7 = CreateLongPcr(uint32(0), pcr_nums)
   758  	}
   759  	arg_bytes := append(b1, b2...)
   760  	arg_bytes = append(arg_bytes, b3...)
   761  	arg_bytes = append(arg_bytes, b4...)
   762  	arg_bytes = append(arg_bytes, b5...)
   763  	arg_bytes = append(arg_bytes, b6...)
   764  	arg_bytes = append(arg_bytes, b7...)
   765  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
   766  	return cmd_bytes, nil
   767  }
   768  
   769  // DecodeCreatePrimary decodes a CreatePrimary response.
   770  func DecodeCreatePrimary(in []byte) (Handle, []byte, error) {
   771  	var handle uint32
   772  	var auth []byte
   773  
   774  	// handle and auth data
   775  	template := []interface{}{&handle, &auth}
   776  	err := unpack(in, template)
   777  	if err != nil {
   778  		return Handle(0), nil, errors.New("Can't decode response 1")
   779  	}
   780  
   781  	var current int
   782  	current = 6 + 2*len(auth)
   783  	// size, size-public
   784  	var tpm2_public []byte
   785  	template = []interface{}{&tpm2_public}
   786  	err = unpack(in[current:], template)
   787  	if err != nil {
   788  		return Handle(0), nil, errors.New("Can't decode CreatePrimary response 2")
   789  	}
   790  
   791  	var rsa_params_buf []byte
   792  	template = []interface{}{&rsa_params_buf}
   793  	err = unpack(tpm2_public, template)
   794  	if err != nil {
   795  		return Handle(0), nil, errors.New("Can't decode CreatePrimary response 3")
   796  	}
   797  
   798  	// Creation data
   799  	current = 2 + len(rsa_params_buf)
   800  	var creation_data []byte
   801  	template = []interface{}{&creation_data}
   802  	err = unpack(tpm2_public[current:], template)
   803  	if err != nil {
   804  		return Handle(0), nil, errors.New("Can't decode CreatePrimary response 4")
   805  	}
   806  	current += len(creation_data) + 2
   807  
   808  	// Digest
   809  	var digest []byte
   810  	template = []interface{}{&digest}
   811  	err = unpack(tpm2_public[current:], template)
   812  	if err != nil {
   813  		return Handle(0), nil, errors.New("Can't decode CreatePrimary response 5")
   814  	}
   815  	current += len(digest) + 2
   816  
   817  	// TPMT_TK_CREATION
   818  	current += 6
   819  	var crap []byte
   820  	template = []interface{}{&crap}
   821  	err = unpack(tpm2_public[current:], template)
   822  	if err != nil {
   823  		return Handle(0), nil, errors.New("Can't decode CreatePrimary response 5")
   824  	}
   825  	current += len(crap) + 2
   826  
   827  	// Name
   828  	var name []byte
   829  	template = []interface{}{&name}
   830  	err = unpack(tpm2_public[current:], template)
   831  	if err != nil {
   832  		return Handle(0), nil, errors.New("Can't decode CreatePrimary response 5")
   833  	}
   834  
   835  	return Handle(handle), tpm2_public, nil
   836  }
   837  
   838  // CreatePrimary
   839  //	Output: handle, public key blob
   840  func CreatePrimary(rw io.ReadWriter, owner uint32, pcr_nums []int,
   841  	parent_password, owner_password string, parms RsaParams) (Handle, []byte, error) {
   842  
   843  	// Construct command
   844  	cmd, err := ConstructCreatePrimary(uint32(owner), pcr_nums, parent_password,
   845  		owner_password, parms)
   846  	if err != nil {
   847  		return Handle(0), nil, err
   848  	}
   849  
   850  	// Send command
   851  	_, err = rw.Write(cmd)
   852  	if err != nil {
   853  		return Handle(0), nil, errors.New("Write Tpm fails")
   854  	}
   855  
   856  	// Get response
   857  	var resp []byte
   858  	resp = make([]byte, 2048, 2048)
   859  	read, err := rw.Read(resp)
   860  	if err != nil {
   861  		return Handle(0), nil, errors.New("Read Tpm fails")
   862  	}
   863  
   864  	// Decode Response
   865  	if read < 10 {
   866  		return Handle(0), nil, errors.New("Read buffer too small")
   867  	}
   868  	_, size, status, err := DecodeCommandResponse(resp[0:10])
   869  	if err != nil {
   870  		return Handle(0), nil, err
   871  	}
   872  	reportCommand("CreatePrimary", cmd, resp[0:size], status, true)
   873  	if status != ErrSuccess {
   874  	}
   875  	handle, public_blob, err := DecodeCreatePrimary(resp[10:read])
   876  	if err != nil {
   877  		return Handle(0), nil, err
   878  	}
   879  	return Handle(handle), public_blob, nil
   880  }
   881  
   882  // ConstructReadPublic constructs a ReadPublic command.
   883  func ConstructReadPublic(handle Handle) ([]byte, error) {
   884  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdReadPublic)
   885  	if err != nil {
   886  		return nil, errors.New("ConstructReadPublic failed")
   887  	}
   888  	num_bytes := []interface{}{uint32(handle)}
   889  	cmd, _ := packWithHeader(cmdHdr, num_bytes)
   890  	return cmd, nil
   891  }
   892  
   893  // DecodeReadPublic decodes a ReadPublic response.
   894  //	public, name, qualified name
   895  func DecodeReadPublic(in []byte) ([]byte, []byte, []byte, error) {
   896  	var public_blob []byte
   897  	var name []byte
   898  	var qualified_name []byte
   899  
   900  	out := []interface{}{&public_blob, &name, &qualified_name}
   901  	err := unpack(in, out)
   902  	if err != nil {
   903  		return nil, nil, nil, errors.New("Can't decode ReadPublic response")
   904  	}
   905  	return public_blob, name, qualified_name, nil
   906  }
   907  
   908  // ReadPublic
   909  //	Output: key blob, name, qualified name
   910  func ReadPublic(rw io.ReadWriter, handle Handle) ([]byte, []byte, []byte, error) {
   911  
   912  	// Construct command
   913  	cmd, err := ConstructReadPublic(handle)
   914  	if err != nil {
   915  		return nil, nil, nil, err
   916  	}
   917  
   918  	// Send command
   919  	_, err = rw.Write(cmd)
   920  	if err != nil {
   921  		return nil, nil, nil, errors.New("Write Tpm fails")
   922  	}
   923  
   924  	// Get response
   925  	var resp []byte
   926  	resp = make([]byte, 4096, 4096)
   927  	read, err := rw.Read(resp)
   928  	if err != nil {
   929  		return nil, nil, nil, errors.New("Read Tpm fails")
   930  	}
   931  
   932  	// Decode Response
   933  	if read < 10 {
   934  		return nil, nil, nil, errors.New("Read buffer too small")
   935  	}
   936  	_, size, status, err := DecodeCommandResponse(resp[0:10])
   937  	if err != nil {
   938  		return nil, nil, nil, err
   939  	}
   940  	reportCommand("ReadPublic", cmd, resp[0:size], status, true)
   941  	if status != ErrSuccess {
   942  		return nil, nil, nil, err
   943  	}
   944  	public_blob, name, qualified_name, err := DecodeReadPublic(resp[10:read])
   945  	if err != nil {
   946  		return nil, nil, nil, err
   947  	}
   948  	return public_blob, name, qualified_name, nil
   949  }
   950  
   951  // CreateKey
   952  
   953  // ConstructCreateKey constructs a CreateKey command.
   954  func ConstructCreateKey(owner uint32, pcr_nums []int, parent_password string, owner_password string,
   955  	parms RsaParams) ([]byte, error) {
   956  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdCreate)
   957  	if err != nil {
   958  		return nil, errors.New("ConstructCreateKey failed")
   959  	}
   960  	var empty []byte
   961  	b1 := SetHandle(Handle(owner))
   962  	b2, _ := pack([]interface{}{&empty})
   963  	b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW))
   964  	t1 := SetPasswordData(owner_password)
   965  	b4 := CreateSensitiveArea(t1[2:], empty)
   966  	b5 := CreateRsaParams(parms)
   967  	b6, _ := pack([]interface{}{&empty})
   968  	b7 := CreateLongPcr(uint32(1), pcr_nums)
   969  	arg_bytes := append(b1, b2...)
   970  	arg_bytes = append(arg_bytes, b3...)
   971  	arg_bytes = append(arg_bytes, b4...)
   972  	arg_bytes = append(arg_bytes, b5...)
   973  	arg_bytes = append(arg_bytes, b6...)
   974  	arg_bytes = append(arg_bytes, b7...)
   975  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
   976  	return cmd_bytes, nil
   977  }
   978  
   979  // DecodeCreateKey decodes a CreateKey response.
   980  //	Output: private_blob, public_blob
   981  func DecodeCreateKey(in []byte) ([]byte, []byte, error) {
   982  	var tpm2b_private []byte
   983  	var tpm2b_public []byte
   984  
   985  	// auth?
   986  	// tpm2b_private
   987  	// tpm2b_public
   988  	out := []interface{}{&tpm2b_private, &tpm2b_public}
   989  	err := unpack(in[4:], out)
   990  	if err != nil {
   991  		return nil, nil, errors.New("Can't decode CreateKey response")
   992  	}
   993  	// creation data
   994  	// tpmt_tk_creation
   995  	// digest
   996  	return tpm2b_private, tpm2b_public, nil
   997  }
   998  
   999  // Output: public blob, private blob, digest
  1000  func CreateKey(rw io.ReadWriter, owner uint32, pcr_nums []int, parent_password string, owner_password string,
  1001  	parms RsaParams) ([]byte, []byte, error) {
  1002  
  1003  	// Construct command
  1004  	cmd, err := ConstructCreateKey(uint32(owner), pcr_nums, parent_password, owner_password, parms)
  1005  	if err != nil {
  1006  		return nil, nil, err
  1007  	}
  1008  
  1009  	// Send command
  1010  	_, err = rw.Write(cmd)
  1011  	if err != nil {
  1012  		return nil, nil, errors.New("Write Tpm fails")
  1013  	}
  1014  
  1015  	// Get response
  1016  	var resp []byte
  1017  	resp = make([]byte, 4096, 4096)
  1018  	read, err := rw.Read(resp)
  1019  	if err != nil {
  1020  		return nil, nil, errors.New("Read Tpm fails")
  1021  	}
  1022  
  1023  	// Decode Response
  1024  	if read < 10 {
  1025  		return nil, nil, errors.New("Read buffer too small")
  1026  	}
  1027  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1028  	if err != nil {
  1029  		return nil, nil, err
  1030  	}
  1031  	reportCommand("CreateKey", cmd, resp[0:size], status, true)
  1032  	if status != ErrSuccess {
  1033  		return nil, nil, errors.New("Error from command")
  1034  	}
  1035  	private_blob, public_blob, err := DecodeCreateKey(resp[10:read])
  1036  	if err != nil {
  1037  		return nil, nil, err
  1038  	}
  1039  	return private_blob, public_blob, nil
  1040  }
  1041  
  1042  // ConstructLoad constructs a Load command.
  1043  func ConstructLoad(parentHandle Handle, parentAuth string, ownerAuth string,
  1044  	public_blob []byte, private_blob []byte) ([]byte, error) {
  1045  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdLoad)
  1046  	if err != nil {
  1047  		return nil, errors.New("ConstructLoad failed")
  1048  	}
  1049  	b1 := SetHandle(parentHandle)
  1050  	b3 := SetPasswordData(parentAuth)
  1051  	b4 := CreatePasswordAuthArea(ownerAuth, Handle(OrdTPM_RS_PW))
  1052  	// private, public
  1053  	b5, _ := pack([]interface{}{&private_blob, &public_blob})
  1054  	arg_bytes := append(b1, b3...)
  1055  	arg_bytes = append(arg_bytes, b4...)
  1056  	arg_bytes = append(arg_bytes, b5...)
  1057  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
  1058  	return cmd_bytes, nil
  1059  }
  1060  
  1061  // DecodeLoad decodes a Load response.
  1062  //	handle, name
  1063  func DecodeLoad(in []byte) (Handle, []byte, error) {
  1064  	var handle uint32
  1065  	var auth []byte
  1066  	var name []byte
  1067  
  1068  	out := []interface{}{&handle, &auth, &name}
  1069  	err := unpack(in, out)
  1070  	if err != nil {
  1071  		return Handle(0), nil, errors.New("Can't decode Load response")
  1072  	}
  1073  	return Handle(handle), name, nil
  1074  }
  1075  
  1076  // Load
  1077  //	Output: handle
  1078  func Load(rw io.ReadWriter, parentHandle Handle, parentAuth string, ownerAuth string,
  1079  	public_blob []byte, private_blob []byte) (Handle, []byte, error) {
  1080  
  1081  	// Construct command
  1082  	cmd, err := ConstructLoad(parentHandle, parentAuth, ownerAuth, public_blob, private_blob)
  1083  	if err != nil {
  1084  		return Handle(0), nil, err
  1085  	}
  1086  
  1087  	// Send command
  1088  	_, err = rw.Write(cmd)
  1089  	if err != nil {
  1090  		return Handle(0), nil, errors.New("Write Tpm fails")
  1091  	}
  1092  
  1093  	// Get response
  1094  	var resp []byte
  1095  	resp = make([]byte, 4096, 4096)
  1096  	read, err := rw.Read(resp)
  1097  	if err != nil {
  1098  		return Handle(0), nil, errors.New("Read Tpm fails")
  1099  	}
  1100  
  1101  	// Decode Response
  1102  	if read < 10 {
  1103  		return Handle(0), nil, errors.New("Read buffer too small")
  1104  	}
  1105  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1106  	if err != nil {
  1107  		return Handle(0), nil, err
  1108  	}
  1109  	reportCommand("Load", cmd, resp[0:size], status, true)
  1110  	if status != ErrSuccess {
  1111  		return Handle(0), nil, errors.New("Error from command")
  1112  	}
  1113  	handle, name, err := DecodeLoad(resp[10:read])
  1114  	if err != nil {
  1115  		return Handle(0), nil, err
  1116  	}
  1117  	return handle, name, nil
  1118  }
  1119  
  1120  // Construct PolicyPcr command.
  1121  func ConstructPolicyPcr(handle Handle, expected_digest []byte,
  1122  	pcr_nums []int) ([]byte, error) {
  1123  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPolicyPCR)
  1124  	if err != nil {
  1125  		return nil, errors.New("ConstructPcr failed")
  1126  	}
  1127  	u_handle := uint32(handle)
  1128  	template := []interface{}{&u_handle, &expected_digest}
  1129  	b1, err := pack(template)
  1130  	if err != nil {
  1131  		return nil, errors.New("Can't pack pcr buf")
  1132  	}
  1133  	b2 := CreateLongPcr(1, pcr_nums)
  1134  	cmd := packWithBytes(cmdHdr, append(b1, b2...))
  1135  	return cmd, nil
  1136  }
  1137  
  1138  // ConstructPolicyPassword constructs a PolicyPassword command.
  1139  func ConstructPolicyPassword(handle Handle) ([]byte, error) {
  1140  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPolicyPassword)
  1141  	if err != nil {
  1142  		return nil, errors.New("ConstructPassword failed")
  1143  	}
  1144  	u_handle := uint32(handle)
  1145  	template := []interface{}{&u_handle}
  1146  	b1, err := pack(template)
  1147  	if err != nil {
  1148  		return nil, errors.New("Can't pack pcr buf")
  1149  	}
  1150  	cmd := packWithBytes(cmdHdr, b1)
  1151  	return cmd, nil
  1152  }
  1153  
  1154  // PolicyPassword
  1155  func PolicyPassword(rw io.ReadWriter, handle Handle) error {
  1156  	// Construct command
  1157  	cmd, err := ConstructPolicyPassword(handle)
  1158  	if err != nil {
  1159  		return err
  1160  	}
  1161  
  1162  	// Send command
  1163  	_, err = rw.Write(cmd)
  1164  	if err != nil {
  1165  		return errors.New("Write Tpm fails")
  1166  	}
  1167  
  1168  	// Get response
  1169  	var resp []byte
  1170  	resp = make([]byte, 1024, 1024)
  1171  	read, err := rw.Read(resp)
  1172  	if err != nil {
  1173  		return errors.New("Read Tpm fails")
  1174  	}
  1175  
  1176  	// Decode Response
  1177  	if read < 10 {
  1178  		return errors.New("Read buffer too small")
  1179  	}
  1180  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1181  	if err != nil {
  1182  		return err
  1183  	}
  1184  	reportCommand("PolicyPassword", cmd, resp[0:size], status, true)
  1185  	if status != ErrSuccess {
  1186  		return errors.New("Comand failure")
  1187  	}
  1188  	return nil
  1189  }
  1190  
  1191  // PolicyPcr
  1192  func PolicyPcr(rw io.ReadWriter, handle Handle, expected_digest []byte,
  1193  	pcr_nums []int) error {
  1194  	// Construct command
  1195  	cmd, err := ConstructPolicyPcr(handle, expected_digest, pcr_nums)
  1196  	if err != nil {
  1197  		return err
  1198  	}
  1199  
  1200  	// Send command
  1201  	_, err = rw.Write(cmd)
  1202  	if err != nil {
  1203  		return errors.New("Write Tpm fails")
  1204  	}
  1205  
  1206  	// Get response
  1207  	var resp []byte
  1208  	resp = make([]byte, 1024, 1024)
  1209  	read, err := rw.Read(resp)
  1210  	if err != nil {
  1211  		return errors.New("Read Tpm fails")
  1212  	}
  1213  
  1214  	// Decode Response
  1215  	if read < 10 {
  1216  		return errors.New("Read buffer too small")
  1217  	}
  1218  	_, _, status, err := DecodeCommandResponse(resp[0:10])
  1219  	if err != nil {
  1220  		return err
  1221  	}
  1222  	if status != ErrSuccess {
  1223  		return errors.New("Comand failure")
  1224  	}
  1225  	return nil
  1226  }
  1227  
  1228  // ConstructPolicyGetDigest constructs a PolicyGetDigest command.
  1229  func ConstructPolicyGetDigest(handle Handle) ([]byte, error) {
  1230  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPolicyGetDigest)
  1231  	if err != nil {
  1232  		return nil, errors.New("ConstructGetDigest failed")
  1233  	}
  1234  	u_handle := uint32(handle)
  1235  	template := []interface{}{&u_handle}
  1236  	b1, err := pack(template)
  1237  	if err != nil {
  1238  		return nil, errors.New("Can't pack pcr buf")
  1239  	}
  1240  	cmd := packWithBytes(cmdHdr, b1)
  1241  	return cmd, nil
  1242  }
  1243  
  1244  // DecodePolicyGetDigest decodes a PolicyGetDigest response.
  1245  func DecodePolicyGetDigest(in []byte) ([]byte, error) {
  1246  	var digest []byte
  1247  
  1248  	out := []interface{}{&digest}
  1249  	err := unpack(in, out)
  1250  	if err != nil {
  1251  		return nil, errors.New("Can't decode DecodePolicyGetDigest response")
  1252  	}
  1253  	return digest, nil
  1254  }
  1255  
  1256  // PolicyGetDigest
  1257  //	Output: digest
  1258  func PolicyGetDigest(rw io.ReadWriter, handle Handle) ([]byte, error) {
  1259  	// Construct command
  1260  	cmd, err := ConstructPolicyGetDigest(handle)
  1261  	if err != nil {
  1262  		return nil, err
  1263  	}
  1264  
  1265  	// Send command
  1266  	_, err = rw.Write(cmd)
  1267  	if err != nil {
  1268  		return nil, errors.New("Write Tpm fails")
  1269  	}
  1270  
  1271  	// Get response
  1272  	var resp []byte
  1273  	resp = make([]byte, 4096, 4096)
  1274  	read, err := rw.Read(resp)
  1275  	if err != nil {
  1276  		return nil, errors.New("Read Tpm fails")
  1277  	}
  1278  
  1279  	// Decode Response
  1280  	if read < 10 {
  1281  		return nil, errors.New("Read buffer too small")
  1282  	}
  1283  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1284  	if err != nil {
  1285  		return nil, err
  1286  	}
  1287  	reportCommand("PolicyGetDigest", cmd, resp[0:size], status, true)
  1288  	if status != ErrSuccess {
  1289  		return nil, errors.New("Comand failure")
  1290  	}
  1291  	digest, err := DecodePolicyGetDigest(resp[10:])
  1292  	if err != nil {
  1293  		return nil, err
  1294  	}
  1295  	return digest, nil
  1296  }
  1297  
  1298  // ConstructStartAuthSession constructs a StartAuthSession command.
  1299  func ConstructStartAuthSession(tpm_key Handle, bind_key Handle,
  1300  	nonceCaller []byte, secret []byte,
  1301  	se byte, sym uint16, hash_alg uint16) ([]byte, error) {
  1302  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdStartAuthSession)
  1303  	if err != nil {
  1304  		return nil, errors.New("ConstructStartAuthSession failed")
  1305  	}
  1306  	b1 := SetHandle(tpm_key)
  1307  	b2 := SetHandle(bind_key)
  1308  	b3, _ := pack([]interface{}{&nonceCaller, &secret})
  1309  	// secret and se
  1310  	b4 := []byte{se}
  1311  	b5, _ := pack([]interface{}{&sym, &hash_alg})
  1312  	arg_bytes := append(b1, b2...)
  1313  	arg_bytes = append(arg_bytes, b3...)
  1314  	arg_bytes = append(arg_bytes, b4...)
  1315  	arg_bytes = append(arg_bytes, b5...)
  1316  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
  1317  	return cmd_bytes, nil
  1318  }
  1319  
  1320  // DecodeStartAuthSession decodes a StartAuthSession response.
  1321  //	Output: session_handle, nonce
  1322  func DecodeStartAuthSession(in []byte) (Handle, []byte, error) {
  1323  	var handle uint32
  1324  	var nonce []byte
  1325  	template := []interface{}{&handle, &nonce}
  1326  	err := unpack(in, template)
  1327  	if err != nil {
  1328  		return Handle(0), nil, errors.New("Can't decode StartAuthSession response")
  1329  	}
  1330  	return Handle(handle), nonce, nil
  1331  }
  1332  
  1333  // StartAuthSession
  1334  func StartAuthSession(rw io.ReadWriter, tpm_key Handle, bind_key Handle,
  1335  	nonceCaller []byte, secret []byte,
  1336  	se byte, sym uint16, hash_alg uint16) (Handle, []byte, error) {
  1337  
  1338  	// Construct command
  1339  	cmd, err := ConstructStartAuthSession(tpm_key, bind_key, nonceCaller, secret,
  1340  		se, sym, hash_alg)
  1341  	if err != nil {
  1342  		return Handle(0), nil, errors.New("ConstructStartAuthSession fails")
  1343  	}
  1344  
  1345  	// Send command
  1346  	_, err = rw.Write(cmd)
  1347  	if err != nil {
  1348  		return Handle(0), nil, errors.New("Write Tpm fails")
  1349  	}
  1350  
  1351  	// Get response
  1352  	var resp []byte
  1353  	resp = make([]byte, 4096, 4096)
  1354  	read, err := rw.Read(resp)
  1355  	if err != nil {
  1356  		return Handle(0), nil, errors.New("Read Tpm fails")
  1357  	}
  1358  
  1359  	// Decode Response
  1360  	if read < 10 {
  1361  		return Handle(0), nil, errors.New("Read buffer too small")
  1362  	}
  1363  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1364  	if err != nil {
  1365  		return Handle(0), nil, errors.New("DecodeCommandResponse fails")
  1366  	}
  1367  	reportCommand("StartAuthSession", cmd, resp[0:size], status, true)
  1368  	if status != ErrSuccess {
  1369  		return Handle(0), nil, errors.New("StartAuthSession unsuccessful")
  1370  	}
  1371  	handle, nonce, err := DecodeStartAuthSession(resp[10:])
  1372  	if err != nil {
  1373  		return Handle(0), nil, errors.New("DecodeStartAuthSession fails")
  1374  	}
  1375  	return handle, nonce, nil
  1376  }
  1377  
  1378  // ConstructCreateSealed constructs a CreateSealed command.
  1379  func ConstructCreateSealed(parent Handle, policy_digest []byte,
  1380  	parent_password string, owner_password string,
  1381  	to_seal []byte, pcr_nums []int,
  1382  	parms KeyedHashParams) ([]byte, error) {
  1383  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdCreate)
  1384  	if err != nil {
  1385  		return nil, errors.New("ConstructCreateKey failed")
  1386  	}
  1387  	var empty []byte
  1388  	b1 := SetHandle(parent)
  1389  	b2, _ := pack([]interface{}{&empty})
  1390  	b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW))
  1391  	t1 := SetPasswordData(owner_password)
  1392  	b4 := CreateSensitiveArea(t1[2:], to_seal)
  1393  	parms.Auth_policy = policy_digest
  1394  	b5 := CreateKeyedHashParams(parms)
  1395  	b6, _ := pack([]interface{}{&b5})
  1396  	b7, _ := pack([]interface{}{&empty})
  1397  	b8 := CreateLongPcr(uint32(1), pcr_nums)
  1398  	arg_bytes := append(b1, b2...)
  1399  	arg_bytes = append(arg_bytes, b3...)
  1400  	arg_bytes = append(arg_bytes, b4...)
  1401  	arg_bytes = append(arg_bytes, b6...)
  1402  	arg_bytes = append(arg_bytes, b7...)
  1403  	arg_bytes = append(arg_bytes, b8...)
  1404  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
  1405  	return cmd_bytes, nil
  1406  }
  1407  
  1408  // DecodeCreateSealed decodes a CreateSealed response.
  1409  // 	Output: private, public, creation_out, digest_out, creation_ticket
  1410  func DecodeCreateSealed(in []byte) ([]byte, []byte, error) {
  1411  	var tpm2b_private []byte
  1412  	var tpm2b_public []byte
  1413  
  1414  	// auth, tpm2b_private, tpm2b_public
  1415  	template := []interface{}{&tpm2b_private, &tpm2b_public}
  1416  	err := unpack(in[4:], template)
  1417  	if err != nil {
  1418  		return nil, nil, errors.New("Can't decode CreateSealed response")
  1419  	}
  1420  	// creation data
  1421  	// tpmt_tk_creation
  1422  	// digest
  1423  	return tpm2b_private, tpm2b_public, nil
  1424  }
  1425  
  1426  // CreateSealed
  1427  // 	Output: public blob, private blob
  1428  func CreateSealed(rw io.ReadWriter, parent Handle, policy_digest []byte,
  1429  	parent_password string, owner_password string,
  1430  	to_seal []byte, pcr_nums []int, parms KeyedHashParams) ([]byte, []byte, error) {
  1431  	// Construct command
  1432  	cmd, err := ConstructCreateSealed(parent, policy_digest,
  1433  		parent_password, owner_password,
  1434  		to_seal, pcr_nums, parms)
  1435  	if err != nil {
  1436  		return nil, nil, errors.New("ConstructCreateSealed fails")
  1437  	}
  1438  
  1439  	// Send command
  1440  	_, err = rw.Write(cmd)
  1441  	if err != nil {
  1442  		return nil, nil, errors.New("Write Tpm fails")
  1443  	}
  1444  
  1445  	// Get response
  1446  	var resp []byte
  1447  	resp = make([]byte, 4096, 4096)
  1448  	read, err := rw.Read(resp)
  1449  	if err != nil {
  1450  		return nil, nil, errors.New("Read Tpm fails")
  1451  	}
  1452  
  1453  	// Decode Response
  1454  	if read < 10 {
  1455  		return nil, nil, errors.New("Read buffer too small")
  1456  	}
  1457  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1458  	if err != nil {
  1459  		return nil, nil, errors.New("DecodeCommandResponse fails")
  1460  	}
  1461  	reportCommand("CreateSealed", cmd, resp[0:size], status, true)
  1462  	if status != ErrSuccess {
  1463  		return nil, nil, errors.New("CreateSealed unsuccessful")
  1464  	}
  1465  	handle, nonce, err := DecodeCreateSealed(resp[10:])
  1466  	if err != nil {
  1467  		return nil, nil, errors.New("DecodeCreateSealed fails")
  1468  	}
  1469  	return handle, nonce, nil
  1470  }
  1471  
  1472  // ConstructUnseal constructs a Unseal command.
  1473  func ConstructUnseal(item_handle Handle, password string, session_handle Handle) ([]byte, error) {
  1474  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdUnseal)
  1475  	if err != nil {
  1476  		return nil, errors.New("Construct Unseal failed")
  1477  	}
  1478  	// item_handle
  1479  	var empty []byte
  1480  	handle1 := uint32(item_handle)
  1481  	template := []interface{}{&handle1, &empty}
  1482  	b1, err := pack(template)
  1483  	if err != nil {
  1484  		return nil, errors.New("Can't construct Unseal")
  1485  	}
  1486  	session_attributes := uint8(1)
  1487  	b2 := CreatePasswordAuthArea(password, session_handle)
  1488  	template = []interface{}{&empty, &session_attributes} // null hmac
  1489  	cmd_bytes := packWithBytes(cmdHdr, append(b1, b2...))
  1490  	return cmd_bytes, nil
  1491  }
  1492  
  1493  // DecodeUnseal decodes a Unseal response.
  1494  //	Output: sensitive data
  1495  func DecodeUnseal(in []byte) ([]byte, []byte, error) {
  1496  	var unsealed []byte
  1497  	var digest []byte
  1498  
  1499  	template := []interface{}{&unsealed, &digest}
  1500  	err := unpack(in[4:], template)
  1501  	if err != nil {
  1502  		return nil, nil, errors.New("Can't decode Unseal response")
  1503  	}
  1504  	return unsealed, digest, nil
  1505  }
  1506  
  1507  // Unseal
  1508  func Unseal(rw io.ReadWriter, item_handle Handle, password string, session_handle Handle,
  1509  	digest []byte) ([]byte, []byte, error) {
  1510  	// Construct command
  1511  	cmd, err := ConstructUnseal(item_handle, password, session_handle)
  1512  	if err != nil {
  1513  		return nil, nil, errors.New("ConstructUnseal fails")
  1514  	}
  1515  
  1516  	// Send command
  1517  	_, err = rw.Write(cmd)
  1518  	if err != nil {
  1519  		return nil, nil, errors.New("Write Tpm fails")
  1520  	}
  1521  
  1522  	// Get response
  1523  	var resp []byte
  1524  	resp = make([]byte, 4096, 4096)
  1525  	read, err := rw.Read(resp)
  1526  	if err != nil {
  1527  		return nil, nil, errors.New("Read Tpm fails")
  1528  	}
  1529  
  1530  	// Decode Response
  1531  	if read < 10 {
  1532  		return nil, nil, errors.New("Read buffer too small")
  1533  	}
  1534  	_, _, status, err := DecodeCommandResponse(resp[0:10])
  1535  	if err != nil {
  1536  		return nil, nil, errors.New("DecodeCommandResponse fails")
  1537  	}
  1538  	if status != ErrSuccess {
  1539  		return nil, nil, errors.New("Unseal unsuccessful")
  1540  	}
  1541  	unsealed, nonce, err := DecodeUnseal(resp[10:])
  1542  	if err != nil {
  1543  		return nil, nil, errors.New("DecodeStartAuthSession fails")
  1544  	}
  1545  	return unsealed, nonce, nil
  1546  }
  1547  
  1548  // ConstructQuote constructs a Quote command.
  1549  func ConstructQuote(signing_handle Handle, parent_password, owner_password string,
  1550  	to_quote []byte, pcr_nums []int, sig_alg uint16) ([]byte, error) {
  1551  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdQuote)
  1552  	if err != nil {
  1553  		return nil, errors.New("ConstructQuote failed")
  1554  	}
  1555  	// TODO: no scheme or sig_alg?
  1556  	// handle
  1557  	var empty []byte
  1558  	b1 := SetHandle(signing_handle)
  1559  	b2, _ := pack([]interface{}{&empty})
  1560  	b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW))
  1561  	b4, _ := pack([]interface{}{&to_quote, &sig_alg})
  1562  	b5 := CreateLongPcr(uint32(1), pcr_nums)
  1563  	arg_bytes := append(b1, b2...)
  1564  	arg_bytes = append(arg_bytes, b3...)
  1565  	arg_bytes = append(arg_bytes, b4...)
  1566  	// Scheme info?
  1567  	arg_bytes = append(arg_bytes, b5...)
  1568  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
  1569  	return cmd_bytes, nil
  1570  }
  1571  
  1572  // DecodeQuote decodes a Quote response.
  1573  //	Output: attest, signature
  1574  func DecodeQuote(in []byte) ([]byte, uint16, uint16, []byte, error) {
  1575  	var empty []byte
  1576  	var buf []byte
  1577  	var attest []byte
  1578  	var signature []byte
  1579  	var s1 uint16
  1580  	var s2 uint16
  1581  
  1582  	template := []interface{}{&empty, &buf}
  1583  	err := unpack(in, template)
  1584  	if err != nil {
  1585  		return nil, 0, 0, nil, errors.New("Can't decode Quote response")
  1586  	}
  1587  
  1588  	template = []interface{}{&attest, &s1, &s2, &signature}
  1589  	err = unpack(buf, template)
  1590  	if err != nil {
  1591  		return nil, 0, 0, nil, errors.New("Can't decode Quote response")
  1592  	}
  1593  	return attest, s1, s2, signature, nil
  1594  }
  1595  
  1596  // Quote
  1597  // 	Output: attest, sig
  1598  func Quote(rw io.ReadWriter, signing_handle Handle, parent_password string, owner_password string,
  1599  	to_quote []byte, pcr_nums []int, sig_alg uint16) ([]byte, []byte, error) {
  1600  	// Construct command
  1601  	cmd, err := ConstructQuote(signing_handle, parent_password, owner_password,
  1602  		to_quote, pcr_nums, sig_alg)
  1603  	if err != nil {
  1604  		return nil, nil, errors.New("ConstructQuote fails")
  1605  	}
  1606  
  1607  	// Send command
  1608  	_, err = rw.Write(cmd)
  1609  	if err != nil {
  1610  		return nil, nil, errors.New("Write Tpm fails")
  1611  	}
  1612  
  1613  	// Get response
  1614  	var resp []byte
  1615  	resp = make([]byte, 4096, 4096)
  1616  	read, err := rw.Read(resp)
  1617  	if err != nil {
  1618  		return nil, nil, errors.New("Read Tpm fails")
  1619  	}
  1620  
  1621  	// Decode Response
  1622  	if read < 10 {
  1623  		return nil, nil, errors.New("Read buffer too small")
  1624  	}
  1625  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1626  	if err != nil {
  1627  		return nil, nil, errors.New("DecodeCommandResponse fails")
  1628  	}
  1629  	reportCommand("Quote", cmd, resp[0:size], status, true)
  1630  	if status != ErrSuccess {
  1631  		return nil, nil, errors.New("Quote unsuccessful")
  1632  	}
  1633  	attest, _, _, sig, err := DecodeQuote(resp[10:size])
  1634  	if err != nil {
  1635  		return nil, nil, errors.New("DecodeQuote fails")
  1636  	}
  1637  	return attest, sig, nil
  1638  }
  1639  
  1640  // ConstructActivateCredential constructs a ActivateCredential command.
  1641  func ConstructActivateCredential(active_handle Handle, key_handle Handle,
  1642  	activePassword string, protectorPassword string,
  1643  	credBlob []byte, secret []byte) ([]byte, error) {
  1644  	var empty []byte
  1645  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdActivateCredential)
  1646  	if err != nil {
  1647  		return nil, errors.New("ConstructActivateCredential failed")
  1648  	}
  1649  	b1 := SetHandle(active_handle)
  1650  	b2 := SetHandle(key_handle)
  1651  	b3, _ := pack([]interface{}{&empty})
  1652  	b4a := CreatePasswordAuthArea(activePassword, Handle(OrdTPM_RS_PW))
  1653  	b4b := CreatePasswordAuthArea(protectorPassword, Handle(OrdTPM_RS_PW))
  1654  	b4t := append(b4a[2:], b4b[2:]...)
  1655  	b4, _ := pack([]interface{}{&b4t})
  1656  	b5, _ := pack([]interface{}{&credBlob, &secret})
  1657  	arg_bytes := append(b1, b2...)
  1658  	arg_bytes = append(arg_bytes, b3...)
  1659  	arg_bytes = append(arg_bytes, b4...)
  1660  	arg_bytes = append(arg_bytes, b5...)
  1661  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
  1662  	return cmd_bytes, nil
  1663  }
  1664  
  1665  // DecodeActivateCredential decodes a ActivateCredential response.
  1666  // returns certInfo
  1667  func DecodeActivateCredential(in []byte) ([]byte, error) {
  1668  	var empty []byte
  1669  	var buf []byte
  1670  	var certInfo []byte
  1671  
  1672  	template := []interface{}{&empty, &buf}
  1673  	err := unpack(in, template)
  1674  	if err != nil {
  1675  		return nil, errors.New("Can't decode ActivateCredential response")
  1676  	}
  1677  	template = []interface{}{&certInfo}
  1678  	err = unpack(buf, template)
  1679  	if err != nil {
  1680  		return nil, errors.New("Can't decode ActivateCredential response")
  1681  	}
  1682  	return certInfo, nil
  1683  }
  1684  
  1685  // ActivateCredential
  1686  // 	Output: certinfo
  1687  func ActivateCredential(rw io.ReadWriter, active_handle Handle, key_handle Handle,
  1688  	activePassword string, protectorPassword string,
  1689  	credBlob []byte, secret []byte) ([]byte, error) {
  1690  	// Construct command
  1691  	cmd, err := ConstructActivateCredential(active_handle, key_handle, activePassword,
  1692  		protectorPassword, credBlob, secret)
  1693  	if err != nil {
  1694  		return nil, errors.New("ConstructActivateCredential fails")
  1695  	}
  1696  
  1697  	// Send command
  1698  	_, err = rw.Write(cmd)
  1699  	if err != nil {
  1700  		return nil, errors.New("Write Tpm fails")
  1701  	}
  1702  
  1703  	// Get response
  1704  	var resp []byte
  1705  	resp = make([]byte, 4096, 4096)
  1706  	read, err := rw.Read(resp)
  1707  	if err != nil {
  1708  		return nil, errors.New("Read Tpm fails")
  1709  	}
  1710  
  1711  	// Decode Response
  1712  	if read < 10 {
  1713  		return nil, errors.New("Read buffer too small")
  1714  	}
  1715  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1716  	if err != nil {
  1717  		return nil, errors.New("DecodeCommandResponse fails")
  1718  	}
  1719  	reportCommand("ActivateCredential", cmd, resp[0:size], status, true)
  1720  	if status != ErrSuccess {
  1721  		return nil, errors.New("ActivateCredential unsuccessful")
  1722  	}
  1723  	cred, err := DecodeActivateCredential(resp[10:])
  1724  	if err != nil {
  1725  		return nil, errors.New("DecodeActivateCredential fails")
  1726  	}
  1727  	return cred, nil
  1728  }
  1729  
  1730  // ConstructEvictControl constructs a EvictControl command.
  1731  func ConstructEvictControl(owner Handle, tmp_handle Handle,
  1732  	persistant_handle Handle) ([]byte, error) {
  1733  	var empty []byte
  1734  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdEvictControl)
  1735  	if err != nil {
  1736  		return nil, errors.New("ConstructEvictControl failed")
  1737  	}
  1738  	b1 := SetHandle(owner)
  1739  	b2 := SetHandle(tmp_handle)
  1740  	b3, err := pack([]interface{}{&empty})
  1741  	if err != nil {
  1742  		return nil, errors.New("can't encode empty")
  1743  	}
  1744  	b4 := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW))
  1745  	b5 := SetHandle(persistant_handle)
  1746  	arg_bytes := append(b1, b2...)
  1747  	arg_bytes = append(arg_bytes, b3...)
  1748  	arg_bytes = append(arg_bytes, b4...)
  1749  	arg_bytes = append(arg_bytes, b5...)
  1750  	cmd_bytes := packWithBytes(cmdHdr, arg_bytes)
  1751  	return cmd_bytes, nil
  1752  }
  1753  
  1754  // DecodeEvictControl decodes a EvictControl response.
  1755  func DecodeEvictControl(in []byte) error {
  1756  	return nil
  1757  }
  1758  
  1759  // EvictControl
  1760  func EvictControl(rw io.ReadWriter, owner Handle, tmp_handle Handle, persistant_handle Handle) error {
  1761  	// Construct command
  1762  	cmd, err := ConstructEvictControl(owner, tmp_handle, persistant_handle)
  1763  	if err != nil {
  1764  		return errors.New("ConstructEvictControl fails")
  1765  	}
  1766  
  1767  	// Send command
  1768  	_, err = rw.Write(cmd)
  1769  	if err != nil {
  1770  		return errors.New("Write Tpm fails")
  1771  	}
  1772  
  1773  	// Get response
  1774  	var resp []byte
  1775  	resp = make([]byte, 1024, 1024)
  1776  	read, err := rw.Read(resp)
  1777  	if err != nil {
  1778  		return errors.New("Read Tpm fails")
  1779  	}
  1780  
  1781  	// Decode Response
  1782  	if read < 10 {
  1783  		return errors.New("Read buffer too small")
  1784  	}
  1785  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1786  	if err != nil {
  1787  		return errors.New("DecodeCommandResponse fails")
  1788  	}
  1789  	reportCommand("EvictControl", cmd, resp[0:size], status, true)
  1790  	if status != ErrSuccess {
  1791  		return errors.New("EvictControl unsuccessful")
  1792  	}
  1793  	err = DecodeEvictControl(resp[10:])
  1794  	if err != nil {
  1795  		return errors.New("DecodeEvictControl fails")
  1796  	}
  1797  	return nil
  1798  }
  1799  
  1800  // ConstructSaveContext constructs a SaveContext command.
  1801  func ConstructSaveContext(handle Handle) ([]byte, error) {
  1802  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdContextSave)
  1803  	if err != nil {
  1804  		return nil, errors.New("ConstructSaveContext failed")
  1805  	}
  1806  	b1 := SetHandle(handle)
  1807  	cmd_bytes := packWithBytes(cmdHdr, b1)
  1808  	return cmd_bytes, nil
  1809  }
  1810  
  1811  // DecodeSaveContext constructs a SaveContext command.
  1812  func DecodeSaveContext(save_area []byte) ([]byte, error) {
  1813  	return save_area, nil
  1814  }
  1815  
  1816  func SaveContext(rw io.ReadWriter, handle Handle) ([]byte, error) {
  1817  	// Construct command
  1818  	cmd, err := ConstructSaveContext(handle)
  1819  	if err != nil {
  1820  		return nil, errors.New("ConstructSaveContext fails")
  1821  	}
  1822  
  1823  	// Send command
  1824  	_, err = rw.Write(cmd)
  1825  	if err != nil {
  1826  		return nil, errors.New("Write Tpm fails")
  1827  	}
  1828  
  1829  	// Get response
  1830  	var resp []byte
  1831  	resp = make([]byte, 4096, 4096)
  1832  	read, err := rw.Read(resp)
  1833  	if err != nil {
  1834  		return nil, errors.New("Read Tpm fails")
  1835  	}
  1836  
  1837  	// Decode Response
  1838  	if read < 10 {
  1839  		return nil, errors.New("Read buffer too small")
  1840  	}
  1841  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1842  	if err != nil {
  1843  		return nil, errors.New("DecodeCommandResponse fails")
  1844  	}
  1845  	reportCommand("SaveContext", cmd, resp[0:size], status, true)
  1846  	if status != ErrSuccess {
  1847  		return nil, errors.New("SaveContext unsuccessful")
  1848  	}
  1849  	save_area, err := DecodeSaveContext(resp[10:size])
  1850  	if err != nil {
  1851  		return nil, errors.New("DecodeSaveContext fails")
  1852  	}
  1853  	return save_area, nil
  1854  }
  1855  
  1856  // LoadContext
  1857  
  1858  // ConstructLoadContext constructs a LoadContext command.
  1859  func ConstructLoadContext(save_area []byte) ([]byte, error) {
  1860  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdContextLoad)
  1861  	if err != nil {
  1862  		return nil, errors.New("ConstructLoadContext failed")
  1863  	}
  1864  	cmd_bytes := packWithBytes(cmdHdr, save_area[0:len(save_area)])
  1865  	return cmd_bytes, nil
  1866  }
  1867  
  1868  // DecodeLoadContext decodes a LoadContext response.
  1869  func DecodeLoadContext(in []byte) (Handle, error) {
  1870  	var handle uint32
  1871  	template := []interface{}{&handle}
  1872  	err := unpack(in, template)
  1873  	if err != nil {
  1874  		return Handle(0), errors.New("Can't decode LoadContext response")
  1875  	}
  1876  	return Handle(handle), nil
  1877  }
  1878  
  1879  // LoadContext
  1880  func LoadContext(rw io.ReadWriter, save_area []byte) (Handle, error) {
  1881  	// Construct command
  1882  	cmd, err := ConstructLoadContext(save_area)
  1883  	if err != nil {
  1884  		return Handle(0), errors.New("ConstructLoadContext fails")
  1885  	}
  1886  
  1887  	// Send command
  1888  	_, err = rw.Write(cmd)
  1889  	if err != nil {
  1890  		return Handle(0), errors.New("Write Tpm fails")
  1891  	}
  1892  
  1893  	// Get response
  1894  	var resp []byte
  1895  	resp = make([]byte, 2048, 2048)
  1896  	read, err := rw.Read(resp)
  1897  	if err != nil {
  1898  		return Handle(0), errors.New("Read Tpm fails")
  1899  	}
  1900  
  1901  	// Decode Response
  1902  	if read < 10 {
  1903  		return Handle(0), errors.New("Read buffer too small")
  1904  	}
  1905  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  1906  	if err != nil {
  1907  		return Handle(0), errors.New("DecodeCommandResponse fails")
  1908  	}
  1909  	reportCommand("LoadContext", cmd, resp[0:size], status, true)
  1910  	if status != ErrSuccess {
  1911  		return Handle(0), errors.New("LoadContext unsuccessful")
  1912  	}
  1913  	handle, err := DecodeLoadContext(resp[10:size])
  1914  	if err != nil {
  1915  		return Handle(0), errors.New("DecodeLoadContext fails")
  1916  	}
  1917  	return handle, nil
  1918  }
  1919  
  1920  func UnmarshalCertifyInfo(in []byte) (*AttestParams, error) {
  1921  	attest := new(AttestParams)
  1922  	var count uint32
  1923  	template := []interface{}{&attest.Magic_number, &attest.Attest_type,
  1924  		&attest.Name, &attest.Data, &attest.Clock,
  1925  		&attest.ResetCount, &attest.RestartCount,
  1926  		&attest.Safe, &attest.FirmwareVersion, &count}
  1927  	err := unpack(in, template)
  1928  	if err != nil {
  1929  		return nil, err
  1930  	}
  1931  	i := 4 + 2 + 2 + 2 + 8 + 4 + 4 + 1 + 8 + 4 + len(attest.Name) + len(attest.Data)
  1932  	attest.PcrSelect = in[i : i+4]
  1933  	template = []interface{}{&attest.PcrDigest}
  1934  	err = unpack(in[i+6:], template)
  1935  	if err != nil {
  1936  		return nil, err
  1937  	}
  1938  	return attest, nil
  1939  }
  1940  
  1941  //	1. Generate Seed
  1942  //	2. encrypted_secret= E(protector_key, seed || "IDENTITY")
  1943  //	3. symKey ≔ KDFa (ekNameAlg, seed, “STORAGE”, name, NULL , bits)
  1944  //	4. encIdentity ≔ AesCFB(symKey, 0, credential)
  1945  //	5. HMACkey ≔ KDFa (ekNameAlg, seed, “INTEGRITY”, NULL, NULL, bits)
  1946  //	6. outerHMAC ≔ HMAC(HMACkey, encIdentity || Name)
  1947  //
  1948  //	Return (all []byte)
  1949  //		encrypted_secret
  1950  //		encIdentity
  1951  //		integrityHmac
  1952  func MakeCredential(protectorPublic *rsa.PublicKey, hash_alg_id uint16,
  1953  	unmarshaled_credential []byte,
  1954  	unmarshaled_name []byte) ([]byte, []byte, []byte, error) {
  1955  	var a [9]byte
  1956  	copy(a[0:9], "IDENTITY")
  1957  
  1958  	// Seed.
  1959  	var seed [16]byte
  1960  	rand.Read(seed[0:16])
  1961  
  1962  	// encrypt secret
  1963  	var encrypted_secret []byte
  1964  	var err error
  1965  	if hash_alg_id == uint16(AlgTPM_ALG_SHA1) {
  1966  		encrypted_secret, err = rsa.EncryptOAEP(sha1.New(),
  1967  			rand.Reader, protectorPublic, seed[0:16], a[0:9])
  1968  	} else if hash_alg_id == uint16(AlgTPM_ALG_SHA256) {
  1969  		encrypted_secret, err = rsa.EncryptOAEP(sha256.New(),
  1970  			rand.Reader, protectorPublic, seed[0:16], a[0:9])
  1971  	} else {
  1972  		return nil, nil, nil, errors.New("Unsupported hash")
  1973  	}
  1974  	if err != nil {
  1975  		return nil, nil, nil, errors.New("Can't encrypt secret")
  1976  	}
  1977  
  1978  	var symKey []byte
  1979  	iv := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  1980  	if hash_alg_id == uint16(AlgTPM_ALG_SHA1) {
  1981  		symKey, err = KDFA(hash_alg_id, seed[0:16], "STORAGE",
  1982  			unmarshaled_name, nil, 128)
  1983  		if err != nil {
  1984  			return nil, nil, nil, err
  1985  		}
  1986  	} else if hash_alg_id == uint16(AlgTPM_ALG_SHA256) {
  1987  		symKey, err = KDFA(hash_alg_id, seed[0:16], "STORAGE",
  1988  			unmarshaled_name, nil, 256)
  1989  		if err != nil {
  1990  			return nil, nil, nil, err
  1991  		}
  1992  	} else {
  1993  		return nil, nil, nil, errors.New("Unsupported hash alg")
  1994  	}
  1995  	block, err := aes.NewCipher(symKey[0:16])
  1996  	if err != nil {
  1997  		return nil, nil, nil, err
  1998  	}
  1999  
  2000  	// encIdentity is encrypted(size || byte-stream), size in big endian
  2001  	marshaled_credential := make([]byte, 2+len(unmarshaled_credential))
  2002  	encIdentity := make([]byte, 2+len(unmarshaled_credential))
  2003  	l := uint16(len(unmarshaled_credential))
  2004  	marshaled_credential[0] = byte(l >> 8)
  2005  	marshaled_credential[1] = byte(l & 0xff)
  2006  	copy(marshaled_credential[2:], unmarshaled_credential)
  2007  	cfb := cipher.NewCFBEncrypter(block, iv)
  2008  	cfb.XORKeyStream(encIdentity, marshaled_credential)
  2009  	cfbdec := cipher.NewCFBDecrypter(block, iv)
  2010  	decrypted_credential := make([]byte, 2+len(unmarshaled_credential))
  2011  	cfbdec.XORKeyStream(decrypted_credential, encIdentity)
  2012  	if bytes.Compare(marshaled_credential, decrypted_credential) != 0 {
  2013  		return nil, nil, nil, errors.New("decrypted cred mismatch")
  2014  	}
  2015  
  2016  	hmacKey, err := KDFA(hash_alg_id, seed[0:16], "INTEGRITY",
  2017  		nil, nil, 8*SizeHash(hash_alg_id))
  2018  	if err != nil {
  2019  		return nil, nil, nil, err
  2020  	}
  2021  
  2022  	var hmac_bytes []byte
  2023  	if hash_alg_id == uint16(AlgTPM_ALG_SHA1) {
  2024  		mac := hmac.New(sha1.New, hmacKey[0:20])
  2025  		mac.Write(append(encIdentity, unmarshaled_name...))
  2026  		hmac_bytes = mac.Sum(nil)
  2027  	} else if hash_alg_id == uint16(AlgTPM_ALG_SHA256) {
  2028  		mac := hmac.New(sha256.New, hmacKey[0:32])
  2029  		mac.Write(append(encIdentity, unmarshaled_name...))
  2030  		hmac_bytes = mac.Sum(nil)
  2031  	} else {
  2032  		return nil, nil, nil, errors.New("Unsupported has alg")
  2033  	}
  2034  	marshalled_hmac, _ := pack([]interface{}{&hmac_bytes})
  2035  	return encrypted_secret, encIdentity, marshalled_hmac, nil
  2036  }
  2037  
  2038  func VerifyRsaQuote(to_quote []byte, rsaQuoteKey *rsa.PublicKey,
  2039  	hash_alg_id uint16, quote_struct_blob []byte,
  2040  	signature []byte, checkPcrFunc ValidPcrCheck) bool {
  2041  	// Decode attest
  2042  	attest, err := UnmarshalCertifyInfo(quote_struct_blob)
  2043  	if err != nil {
  2044  		return false
  2045  	}
  2046  	PrintAttestData(attest)
  2047  
  2048  	if attest.Magic_number != ordTpmMagic {
  2049  		glog.Infof("VerifyRsaQuote: Bad magic number")
  2050  		return false
  2051  	}
  2052  
  2053  	// PCR's valid?
  2054  	if !checkPcrFunc(attest.PcrSelect, attest.PcrDigest) {
  2055  		return false
  2056  	}
  2057  
  2058  	// Compute quote
  2059  	quote_hash, err := ComputeHashValue(hash_alg_id, quote_struct_blob)
  2060  	if err != nil {
  2061  		glog.Infof("VerifyRsaQuote: ComputeHashValue fails")
  2062  		return false
  2063  	}
  2064  
  2065  	// Verify quote
  2066  	e := new(big.Int)
  2067  	e.SetUint64(uint64(rsaQuoteKey.E))
  2068  	x := new(big.Int)
  2069  	x.SetBytes(signature)
  2070  	z := new(big.Int)
  2071  	z = z.Exp(x, e, rsaQuoteKey.N)
  2072  	decrypted_quote := z.Bytes()
  2073  	start_quote_blob := len(decrypted_quote) - SizeHash(hash_alg_id)
  2074  	if bytes.Compare(decrypted_quote[start_quote_blob:], quote_hash) != 0 {
  2075  		glog.Infof("VerifyRsaQuote: Compare fails.  %x %x\n", quote_hash, decrypted_quote[start_quote_blob:])
  2076  		return false
  2077  	}
  2078  	return true
  2079  }
  2080  
  2081  func VerifyQuote(to_quote []byte, quote_key_info QuoteKeyInfoMessage,
  2082  	hash_alg_id uint16, quote_struct_blob []byte,
  2083  	signature []byte, checkPcrFunc ValidPcrCheck) bool {
  2084  	// Decode attest
  2085  	attest, err := UnmarshalCertifyInfo(quote_struct_blob)
  2086  	if err != nil {
  2087  		return false
  2088  	}
  2089  	PrintAttestData(attest)
  2090  
  2091  	if attest.Magic_number != ordTpmMagic {
  2092  		glog.Infof("VerifyQuote: Bad magic number")
  2093  		return false
  2094  	}
  2095  
  2096  	// PCR's valid?
  2097  	if !checkPcrFunc(attest.PcrSelect, attest.PcrDigest) {
  2098  		return false
  2099  	}
  2100  
  2101  	// Compute quote
  2102  	quote_hash, err := ComputeHashValue(hash_alg_id, quote_struct_blob)
  2103  	if err != nil {
  2104  		glog.Infof("VerifyQuote: ComputeHashValue fails")
  2105  		return false
  2106  	}
  2107  
  2108  	// Get quote key from quote_key_info
  2109  	if *quote_key_info.PublicKey.KeyType != "rsa" {
  2110  		glog.Infof("VerifyQuote: Bad key type %s\n", quote_key_info.PublicKey.KeyType)
  2111  		return false
  2112  	}
  2113  
  2114  	// Verify quote
  2115  	var N *big.Int
  2116  	var E *big.Int
  2117  	N = new(big.Int)
  2118  	N.SetBytes(quote_key_info.PublicKey.RsaKey.Modulus)
  2119  	E = new(big.Int)
  2120  	E.SetBytes([]byte{0, 1, 0, 1})
  2121  	x := new(big.Int)
  2122  	x.SetBytes(signature)
  2123  	z := new(big.Int)
  2124  	z = z.Exp(x, E, N)
  2125  	decrypted_quote := z.Bytes()
  2126  	start_quote_blob := len(decrypted_quote) - SizeHash(hash_alg_id)
  2127  	if bytes.Compare(decrypted_quote[start_quote_blob:], quote_hash) != 0 {
  2128  		glog.Infof("VerifyQuote: Compare fails.  %x %x\n", quote_hash, decrypted_quote[start_quote_blob:])
  2129  		return false
  2130  	}
  2131  	return true
  2132  }
  2133  
  2134  // ConstructInternalMakeCredential constructs a InternalMakeCredential command.
  2135  func ConstructInternalMakeCredential(protectorHandle Handle, credential []byte,
  2136  	activeName []byte) ([]byte, error) {
  2137  	cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdMakeCredential)
  2138  	if err != nil {
  2139  		return nil, errors.New("ConstructInternalMakeCredential failed")
  2140  	}
  2141  	b1 := SetHandle(protectorHandle)
  2142  	b2, _ := pack([]interface{}{&credential, activeName})
  2143  	cmd_bytes := packWithBytes(cmdHdr, append(b1, b2...))
  2144  	return cmd_bytes, nil
  2145  }
  2146  
  2147  // DecodeInternalMakeCredential decodes a InternalMakeCredential response.
  2148  // returns blob, encrypted_secret
  2149  func DecodeInternalMakeCredential(in []byte) ([]byte, []byte, error) {
  2150  	var credBlob []byte
  2151  	var encrypted_secret []byte
  2152  
  2153  	template := []interface{}{&credBlob, &encrypted_secret}
  2154  	err := unpack(in, template)
  2155  	if err != nil {
  2156  		return nil, nil, errors.New("Can't decode InternalMakeCredential response")
  2157  	}
  2158  	return credBlob, encrypted_secret, nil
  2159  }
  2160  
  2161  // InternalMakeCredential
  2162  // 	Output: blob, secret
  2163  func InternalMakeCredential(rw io.ReadWriter, protectorHandle Handle, credential []byte,
  2164  	activeName []byte) ([]byte, []byte, error) {
  2165  	// Construct command
  2166  	cmd, err := ConstructInternalMakeCredential(protectorHandle, credential, activeName)
  2167  	if err != nil {
  2168  		return nil, nil, errors.New("ConstructInternalMakeCredential fails")
  2169  	}
  2170  
  2171  	// Send command
  2172  	_, err = rw.Write(cmd)
  2173  	if err != nil {
  2174  		return nil, nil, errors.New("Write Tpm fails")
  2175  	}
  2176  
  2177  	// Get response
  2178  	var resp []byte
  2179  	resp = make([]byte, 2048, 2048)
  2180  	read, err := rw.Read(resp)
  2181  	if err != nil {
  2182  		return nil, nil, errors.New("Read Tpm fails")
  2183  	}
  2184  
  2185  	// Decode Response
  2186  	if read < 10 {
  2187  		return nil, nil, errors.New("Read buffer too small")
  2188  	}
  2189  	_, _, status, err := DecodeCommandResponse(resp[0:10])
  2190  	if err != nil {
  2191  		return nil, nil, errors.New("DecodeCommandResponse fails")
  2192  	}
  2193  	if status != ErrSuccess {
  2194  		return nil, nil, errors.New("InternalMakeCredential unsuccessful")
  2195  	}
  2196  	credBlob, encrypted_secret, err := DecodeInternalMakeCredential(resp[10:])
  2197  	if err != nil {
  2198  		return nil, nil, errors.New("DecodeInternalMakeCredential fails")
  2199  	}
  2200  	return credBlob, encrypted_secret, nil
  2201  }
  2202  
  2203  /*
  2204   *  	TPM Activate Credential interface
  2205   */
  2206  
  2207  // Input: Der encoded endorsement cert and handles
  2208  // Returns program private key protobuf, CertRequestMessage
  2209  func ConstructClientRequest(rw io.ReadWriter, der_endorsement_cert []byte,
  2210  	quote_handle Handle, parent_pw string, owner_pw string,
  2211  	program_name string) (*RsaPrivateKeyMessage,
  2212  	*ProgramCertRequestMessage, error) {
  2213  
  2214  	// Generate Program Key.
  2215  	programPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)
  2216  	if err != nil {
  2217  		return nil, nil, err
  2218  	}
  2219  	// TODO(jlm): replace with helper
  2220  	privateKeyMsg, err := MarshalRsaPrivateToProto(programPrivateKey)
  2221  	if err != nil {
  2222  		return nil, nil, err
  2223  	}
  2224  	programPublicKey := programPrivateKey.PublicKey
  2225  
  2226  	// Generate Request
  2227  	request := new(ProgramCertRequestMessage)
  2228  	request.ProgramKey = new(ProgramKeyParameters)
  2229  	request.EndorsementCertBlob = der_endorsement_cert
  2230  	req_id := "001"
  2231  	request.RequestId = &req_id
  2232  	modulus_bits := int32(2048)
  2233  	key_type := "rsa"
  2234  	request.ProgramKey.ProgramName = &program_name
  2235  	request.ProgramKey.ProgramKeyType = &key_type
  2236  	request.ProgramKey.ProgramBitModulusSize = &modulus_bits
  2237  
  2238  	request.ProgramKey.ProgramKeyExponent = []byte{0, 1, 0, 1}
  2239  	request.ProgramKey.ProgramKeyModulus = programPublicKey.N.Bytes()
  2240  	serialized_program_key := proto.CompactTextString(request.ProgramKey)
  2241  	sha1Hash := sha1.New()
  2242  	sha1Hash.Write([]byte(serialized_program_key))
  2243  	hashed_program_key := sha1Hash.Sum(nil)
  2244  
  2245  	// Quote key
  2246  	key_blob, quote_key_name, _, err := ReadPublic(rw, quote_handle)
  2247  	if err != nil {
  2248  		return nil, nil, err
  2249  	}
  2250  	rsaQuoteParams, err := DecodeRsaBuf(key_blob)
  2251  	if err != nil {
  2252  		return nil, nil, err
  2253  	}
  2254  
  2255  	sig_alg := uint16(AlgTPM_ALG_NULL)
  2256  	attest, sig, err := Quote(rw, quote_handle, owner_pw, owner_pw,
  2257  		hashed_program_key, []int{7}, sig_alg)
  2258  	if err != nil {
  2259  		return nil, nil, err
  2260  	}
  2261  
  2262  	// Quote key info.
  2263  	request.QuoteKeyInfo = new(QuoteKeyInfoMessage)
  2264  	request.QuoteKeyInfo.Name = quote_key_name
  2265  	tmp_name := "Quote-Key"
  2266  	request.QuoteKeyInfo.PublicKey = new(PublicKeyMessage)
  2267  	request.QuoteKeyInfo.PublicKey.RsaKey = new(RsaPublicKeyMessage)
  2268  	request.QuoteKeyInfo.PublicKey.RsaKey.KeyName = &tmp_name
  2269  	var enc_alg string
  2270  	var hash_alg string
  2271  	if rsaQuoteParams.Enc_alg == AlgTPM_ALG_RSA {
  2272  		enc_alg = "rsa"
  2273  	} else {
  2274  		return nil, nil, err
  2275  	}
  2276  	if rsaQuoteParams.Hash_alg == AlgTPM_ALG_SHA1 {
  2277  		hash_alg = "sha1"
  2278  	} else if rsaQuoteParams.Hash_alg == AlgTPM_ALG_SHA256 {
  2279  		hash_alg = "sha256"
  2280  	} else {
  2281  		return nil, nil, err
  2282  	}
  2283  	request.QuoteKeyInfo.PublicKey.KeyType = &enc_alg
  2284  	size := int32(rsaQuoteParams.Mod_sz)
  2285  	request.QuoteKeyInfo.PublicKey.RsaKey.BitModulusSize = &size
  2286  	request.QuoteKeyInfo.PublicKey.RsaKey.Modulus = rsaQuoteParams.Modulus
  2287  	request.QuoteSignAlg = &enc_alg
  2288  	request.QuoteSignHashAlg = &hash_alg
  2289  
  2290  	request.ProgramKey = new(ProgramKeyParameters)
  2291  	request.ProgramKey.ProgramName = &program_name
  2292  	request.ProgramKey.ProgramKeyType = &enc_alg
  2293  	request.ProgramKey.ProgramBitModulusSize = &modulus_bits
  2294  	request.ProgramKey.ProgramKeyModulus = programPublicKey.N.Bytes()
  2295  
  2296  	request.QuotedBlob = attest
  2297  	request.QuoteSignature = sig
  2298  	return privateKeyMsg, request, nil
  2299  }
  2300  
  2301  // Input: policy private key
  2302  func ConstructServerResponse(policy_private_key *rsa.PrivateKey, der_policy_cert []byte,
  2303  	signing_instructions_message SigningInstructionsMessage,
  2304  	request ProgramCertRequestMessage) (*ProgramCertResponseMessage, error) {
  2305  
  2306  	if request.ProgramKey == nil {
  2307  		glog.Infof("ConstructServerResponse: program key is nil")
  2308  	}
  2309  	// hash program key
  2310  	serialized_program_key := proto.CompactTextString(request.ProgramKey)
  2311  	sha256Hash := sha256.New()
  2312  	sha256Hash.Write([]byte(serialized_program_key))
  2313  	hashed_program_key := sha256Hash.Sum(nil)
  2314  
  2315  	var hash_alg_id uint16
  2316  	if *request.QuoteSignHashAlg == "sha256" {
  2317  		hash_alg_id = uint16(AlgTPM_ALG_SHA256)
  2318  	} else {
  2319  		hash_alg_id = uint16(AlgTPM_ALG_SHA1)
  2320  	}
  2321  	if !VerifyQuote(hashed_program_key, *request.QuoteKeyInfo, hash_alg_id,
  2322  		request.QuotedBlob, request.QuoteSignature, ValidPcr) {
  2323  		return nil, errors.New("Can't verify quote")
  2324  	}
  2325  
  2326  	// Create Program Key Certificate
  2327  	progName := request.ProgramKey.ProgramName
  2328  	var notBefore time.Time
  2329  	notBefore = time.Now()
  2330  	validFor := 365 * 24 * time.Hour
  2331  	notAfter := notBefore.Add(validFor)
  2332  	template := x509.Certificate{
  2333  		SerialNumber: GetSerialNumber(),
  2334  		Subject: pkix.Name{
  2335  			Organization: []string{"CloudProxyAuthority"},
  2336  			CommonName:   *progName,
  2337  		},
  2338  		NotBefore:             notBefore,
  2339  		NotAfter:              notAfter,
  2340  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  2341  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  2342  		BasicConstraintsValid: true,
  2343  	}
  2344  	pub := new(rsa.PublicKey)
  2345  	m := new(big.Int)
  2346  	m.SetBytes(request.ProgramKey.ProgramKeyModulus)
  2347  	pub.N = m
  2348  	pub.E = 0x00010001
  2349  	der_program_cert, err := x509.CreateCertificate(rand.Reader, &template, &template,
  2350  		pub, policy_private_key)
  2351  	if err != nil {
  2352  		return nil, err
  2353  	}
  2354  
  2355  	// Get Endorsement blob
  2356  	endorsement_cert, err := x509.ParseCertificate(request.EndorsementCertBlob)
  2357  	if err != nil {
  2358  		return nil, err
  2359  	}
  2360  
  2361  	// Verify Endorsement Cert
  2362  	ok, err := VerifyDerCert(request.EndorsementCertBlob, der_policy_cert)
  2363  	if !ok {
  2364  		return nil, errors.New("Bad endorsement cert")
  2365  	}
  2366  
  2367  	var protectorPublic *rsa.PublicKey
  2368  	switch k := endorsement_cert.PublicKey.(type) {
  2369  	case *rsa.PublicKey:
  2370  		protectorPublic = k
  2371  	case *rsa.PrivateKey:
  2372  		protectorPublic = &k.PublicKey
  2373  	default:
  2374  		return nil, errors.New("endorsement cert not an rsa key")
  2375  	}
  2376  
  2377  	// Generate credential
  2378  	var credential [16]byte
  2379  	rand.Read(credential[0:16])
  2380  	// fmt.Printf("Credential: %x, hashid: %x\n", credential, hash_alg_id)
  2381  	// fmt.Printf("Name: %x\n", request.QuoteKeyInfo.Name)
  2382  	encrypted_secret, encIdentity, integrityHmac, err := MakeCredential(
  2383  		protectorPublic, hash_alg_id,
  2384  		credential[0:16], request.QuoteKeyInfo.Name)
  2385  	if err != nil {
  2386  		return nil, err
  2387  	}
  2388  
  2389  	// Response
  2390  	response := new(ProgramCertResponseMessage)
  2391  	response.RequestId = request.RequestId
  2392  	response.ProgramName = progName
  2393  	integrity_alg := *request.QuoteSignHashAlg
  2394  	response.Secret = encrypted_secret
  2395  	response.IntegrityAlg = &integrity_alg
  2396  	response.IntegrityHMAC = integrityHmac
  2397  	response.EncIdentity = encIdentity
  2398  
  2399  	// Encrypt cert with credential
  2400  	cert_hmac, cert_out, err := EncryptDataWithCredential(true, hash_alg_id,
  2401  		credential[0:16], der_program_cert, nil)
  2402  	if err != nil {
  2403  		return nil, err
  2404  	}
  2405  	response.EncryptedCert = cert_out
  2406  	response.EncryptedCertHmac = cert_hmac
  2407  	return response, nil
  2408  }
  2409  
  2410  // Output is der encoded Program Cert
  2411  func ClientDecodeServerResponse(rw io.ReadWriter, protectorHandle Handle,
  2412  	quoteHandle Handle, password string,
  2413  	response ProgramCertResponseMessage) ([]byte, error) {
  2414  	certBlob := append(response.IntegrityHMAC, response.EncIdentity...)
  2415  	certInfo, err := ActivateCredential(rw, quoteHandle, protectorHandle,
  2416  		password, "", certBlob, response.Secret)
  2417  	if err != nil {
  2418  		return nil, err
  2419  	}
  2420  	// fmt.Printf("certInfo: %x\n", certInfo)
  2421  
  2422  	// Decrypt cert.
  2423  	_, out, err := EncryptDataWithCredential(false, uint16(AlgTPM_ALG_SHA1),
  2424  		certInfo, response.EncryptedCert, response.EncryptedCertHmac)
  2425  	if err != nil {
  2426  		return nil, err
  2427  	}
  2428  	return out, nil
  2429  }
  2430  
  2431  // Make an NvHandle
  2432  func GetNvHandle(slot uint32) (Handle, error) {
  2433  	return Handle((OrdTPM_HT_NV_INDEX << OrdHR_SHIFT) + slot), nil
  2434  }
  2435  
  2436  // UndefineSpace command: 80020000001f0000012240000001010003e800000009400000090000010000
  2437  // UndefineSpace response, cap: 8002, size: 00000013, error code: 00000000
  2438  // 80020000001300000000000000000000010000
  2439  
  2440  func ConstructUndefineSpace(owner Handle, handle Handle) ([]byte, error) {
  2441  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdUndefineSpace)
  2442  	if err != nil {
  2443  		return nil, errors.New("ConstructUndefineSpace failed")
  2444  	}
  2445  	auth := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW))
  2446  	zero := uint16(0)
  2447  	num_bytes := []interface{}{uint32(owner), uint32(handle), zero}
  2448  	out, err := pack(num_bytes)
  2449  	if err != nil {
  2450  		return nil, err
  2451  	}
  2452  	out = append(out, auth...)
  2453  	cmd := packWithBytes(cmdHdr, out)
  2454  	return cmd, nil
  2455  }
  2456  
  2457  // UndefineSpace
  2458  func UndefineSpace(rw io.ReadWriter, owner Handle, handle Handle) (error) {
  2459  	cmd, err := ConstructUndefineSpace(owner, handle)
  2460  	if err != nil {
  2461  		return errors.New("UndefineSpace: Can't construct UndefineSpace command")
  2462  	}
  2463  	// Send command
  2464  	_, err = rw.Write(cmd)
  2465  	if err != nil {
  2466  		return errors.New("UndefineSpace: Write Tpm fails")
  2467  	}
  2468  	// Get response
  2469  	var resp []byte
  2470  	resp = make([]byte, 1024, 1024)
  2471  	read, err := rw.Read(resp)
  2472  	if err != nil {
  2473  		return errors.New("UndefineSpace: Read Tpm fails")
  2474  	}
  2475  	// Decode Response
  2476  	if read < 10 {
  2477  		return errors.New("Read buffer too small")
  2478  	}
  2479  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  2480  	if err != nil {
  2481  		return errors.New("UndefineSpace: DecodeCommandResponse fails")
  2482  	}
  2483  	reportCommand("UndefineSpace", cmd, resp[0:size], status, true)
  2484  	if status != ErrSuccess {
  2485  		return errors.New("UndefineSpace: error")
  2486  	}
  2487  	return nil
  2488  }
  2489  
  2490  // DefineSpace command: 8002000000310000012a4000000100000009400000090000010000000401020304000e010003e800040004001400000008
  2491  // Definespace response, cap: 8002, size: 00000013, error code: 00000000
  2492  // 80020000001300000000000000000000010000
  2493  
  2494  func ConstructDefineSpace(owner Handle, handle Handle, authString string,
  2495  		attributes uint32, policy []byte, dataSize uint16) ([]byte, error) {
  2496  	pw := SetPasswordData(authString)
  2497  	auth := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW))
  2498  	var empty []byte
  2499  	num_bytes := []interface{}{uint32(owner), empty}
  2500  	out1, err := pack(num_bytes)
  2501  	if err != nil {
  2502  		return nil, errors.New("DefineSpace: pack error")
  2503  	}
  2504  	hashAlg := uint16(AlgTPM_ALG_SHA1)
  2505  	sizeNvArea := uint16(2 * int(unsafe.Sizeof(owner)) + 3 * int(unsafe.Sizeof(dataSize)) + len(policy))
  2506  	out1 = append(append(out1, auth...), pw...)
  2507  	num_bytes2 := []interface{}{sizeNvArea, uint32(handle), hashAlg, attributes, policy, dataSize}
  2508  	out2, err := pack(num_bytes2)
  2509  	if err != nil {
  2510  		return nil, errors.New("DefineSpace: pack error")
  2511  	}
  2512  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdDefineSpace)
  2513  	if err != nil {
  2514  		return nil, errors.New("DefineSpace: MakeCommandHeader error")
  2515  	}
  2516  	cmd := packWithBytes(cmdHdr, append(out1, out2...))
  2517  	return cmd, nil
  2518  }
  2519  
  2520  // DefineSpace
  2521  func DefineSpace(rw io.ReadWriter, owner Handle, handle Handle,
  2522  		authString string, policy []byte,
  2523  		attributes uint32, dataSize uint16) (error) {
  2524  	cmd, err := ConstructDefineSpace(owner, handle, authString, attributes, policy, dataSize)
  2525  	if err != nil {
  2526  		return errors.New("DefineSpace: Can't construct DefineSpace command")
  2527  	}
  2528  	// Send command
  2529  	_, err = rw.Write(cmd)
  2530  	if err != nil {
  2531  		return errors.New("DefineSpace: Write Tpm fails")
  2532  	}
  2533  	// Get response
  2534  	var resp []byte
  2535  	resp = make([]byte, 1024, 1024)
  2536  	read, err := rw.Read(resp)
  2537  	if err != nil {
  2538  		return errors.New("DefineSpace: Read Tpm fails")
  2539  	}
  2540  	// Decode Response
  2541  	if read < 10 {
  2542  		return errors.New("Read buffer too small")
  2543  	}
  2544  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  2545  	if err != nil {
  2546  		return errors.New("DefineSpace: DecodeCommandResponse fails")
  2547  	}
  2548  	reportCommand("DefineSpace", cmd, resp[0:size], status, true)
  2549  	if status != ErrSuccess {
  2550  		return errors.New("DefineSpace: Can't decode response")
  2551  	}
  2552  	return nil
  2553  }
  2554  
  2555  // IncrementNv command: 80020000002300000134010003e8010003e80000000d40000009000001000401020304
  2556  // IncrementNv response, cap: 8002, size: 00000013, error code: 00000000
  2557  // 80020000001300000000000000000000010000
  2558  
  2559  func ConstructIncrementNv(handle Handle, authString string) ([]byte, error) {
  2560  	// handle, handle, 0(16), autharea
  2561  	auth := CreatePasswordAuthArea(authString, Handle(OrdTPM_RS_PW))
  2562  	var empty []byte
  2563  	num_bytes := []interface{}{uint32(handle), int32(handle), empty}
  2564  	out, err := pack(num_bytes)
  2565  	if err != nil {
  2566  		return nil, errors.New("ConstructIncrementNv: pack failed")
  2567  	}
  2568  	out = append(out, auth...)
  2569  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdIncrementNvCounter)
  2570  	if err != nil {
  2571  		return nil, errors.New("ConstructIncrementNv: MakeCommandHeader failed")
  2572  	}
  2573  	cmd := packWithBytes(cmdHdr, out)
  2574  	return cmd, nil
  2575  }
  2576  
  2577  // IncrementNv
  2578  func IncrementNv(rw io.ReadWriter, handle Handle, authString string) (error) {
  2579  	cmd, err := ConstructIncrementNv(handle, authString)
  2580  	if err != nil {
  2581  		return errors.New("IncrementNv: Can't construct UndefineSpace command")
  2582  	}
  2583  	// Send command
  2584  	_, err = rw.Write(cmd)
  2585  	if err != nil {
  2586  		return errors.New("IncrementNv: Write Tpm fails")
  2587  	}
  2588  	// Get response
  2589  	var resp []byte
  2590  	resp = make([]byte, 1024, 1024)
  2591  	read, err := rw.Read(resp)
  2592  	if err != nil {
  2593  		return errors.New("IncrementNv: Read Tpm fails")
  2594  	}
  2595  	// Decode Response
  2596  	if read < 10 {
  2597  		return errors.New("Read buffer too small")
  2598  	}
  2599  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  2600  	if err != nil {
  2601  		return errors.New("IncrementNv: DecodeCommandResponse fails")
  2602  	}
  2603  	reportCommand("IncrementNv", cmd, resp[0:size], status, true)
  2604  	if status != ErrSuccess {
  2605  		return errors.New("IncrementNv: Can't decode response")
  2606  	}
  2607  	return nil
  2608  }
  2609  
  2610  // ReadNv command: 8002000000270000014e010003e8010003e80000000d4000000900000100040102030400080000
  2611  // ReadNv response, cap: 8002, size: 0000001d, error code: 00000000
  2612  // 80020000001d000000000000000a000800000000000000cf0000010000
  2613  // Tpm2_ReadNv succeeds
  2614  // Counter value: 00000000000000cf
  2615  
  2616  func DecodeReadNv(in []byte) (uint64, error) {
  2617  	var respSize uint32
  2618  	var byteCounter []byte
  2619  	err :=  unpack(in, []interface{}{&respSize, &byteCounter})
  2620  	if err != nil {
  2621  		return uint64(0), errors.New("ReadNv: unpack failed")
  2622  	}
  2623  	c := uint64(0)
  2624  	for i := 0; i < len(byteCounter); i++ {
  2625  		c = c * 256 +  uint64(byteCounter[i])
  2626  	}
  2627  	return c, nil
  2628  }
  2629  
  2630  func ConstructReadNv(handle Handle, authString string, offset uint16, dataSize uint16) ([]byte, error) {
  2631  	// handle, handle, 0(16), pw-autharea, size(16), offset(16)
  2632  	auth := CreatePasswordAuthArea(authString, Handle(OrdTPM_RS_PW))
  2633  	var empty []byte
  2634  	num_bytes := []interface{}{uint32(handle), int32(handle), empty}
  2635  	out, err := pack(num_bytes)
  2636  	if err != nil {
  2637  		return nil, errors.New("ReadNv: pack failed")
  2638  	}
  2639  	out = append(out, auth...)
  2640  	num_bytes2 := []interface{}{dataSize, offset}
  2641  	out2, err := pack(num_bytes2)
  2642  	if err != nil {
  2643  		return nil, errors.New("ReadNv: pack failed")
  2644  	}
  2645  	cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdReadNv)
  2646  	if err != nil {
  2647  		return nil, errors.New("ReadNv: MakeCommandHeader failed")
  2648  	}
  2649  	cmd := packWithBytes(cmdHdr, append(out, out2...))
  2650  	return cmd, nil
  2651  }
  2652  
  2653  // ReadNv
  2654  func ReadNv(rw io.ReadWriter, handle Handle, authString string,
  2655  		offset uint16, dataSize uint16) (uint64, error) {
  2656  	cmd, err := ConstructReadNv(handle, authString, offset, dataSize)
  2657  	if err != nil {
  2658  		return uint64(0), errors.New("ReadNv: Can't construct ReadNv command")
  2659  	}
  2660  	// Send command
  2661  	_, err = rw.Write(cmd)
  2662  	if err != nil {
  2663  		return uint64(0), errors.New("ReadNv: Write Tpm fails")
  2664  	}
  2665  	// Get response
  2666  	var resp []byte
  2667  	resp = make([]byte, 1024, 1024)
  2668  	read, err := rw.Read(resp)
  2669  	if err != nil {
  2670  		return uint64(0), errors.New("ReadNv: Read Tpm fails")
  2671  	}
  2672  	// Decode Response
  2673  	if read < 10 {
  2674  		return uint64(0), errors.New("Read buffer too small")
  2675  	}
  2676  	_, size, status, err := DecodeCommandResponse(resp[0:10])
  2677  	if err != nil {
  2678  		return uint64(0), errors.New("ReadNv: DecodeCommandResponse fails")
  2679  	}
  2680  	reportCommand("ReadNv", cmd, resp[0:size], status, true)
  2681  	if status != ErrSuccess {
  2682  		return uint64(0), errors.New("ReadNv: error from command")
  2683  	}
  2684  	return DecodeReadNv(resp[10:])
  2685  }
  2686  
  2687  // See note in tpm2_tao.go about counter values for Rollback support.
  2688  
  2689  // Tpm2 GetCounter
  2690  func GetCounter(rw io.ReadWriter, nvHandle Handle, authString string) (int64, error) {
  2691  	c, err := ReadNv(rw, nvHandle, authString, uint16(0), uint16(8))
  2692  	if err != nil {
  2693  		return int64(0), errors.New("Can't read tpm2 counter")
  2694  	}
  2695  	return int64(c), nil
  2696  }
  2697  
  2698  // Tpm2 InitCounter
  2699  func InitCounter(rw io.ReadWriter, nvHandle Handle, authString string) (error) {
  2700  	owner := Handle(OrdTPM_RH_OWNER)
  2701  	dataSize := uint16(8)
  2702  	var tpmPolicy []byte // empty
  2703  	attributes := OrdNV_COUNTER | OrdNV_AUTHWRITE | OrdNV_AUTHREAD
  2704  	err := UndefineSpace(rw, owner, nvHandle)
  2705  	if err != nil {
  2706  		fmt.Printf("UndefineSpace failed (ok) %s\n", err)
  2707  	} else {
  2708  		fmt.Printf("UndefineSpace succeeded\n")
  2709  	}
  2710  	err = DefineSpace(rw, owner, nvHandle, authString,
  2711  		tpmPolicy, attributes, dataSize)
  2712  	if err != nil {
  2713  		fmt.Printf("Space already defined?\n")
  2714  	}
  2715  	err =  IncrementNv(rw, nvHandle, authString)
  2716  	return err
  2717  }
  2718