github.com/andrewsun2898/u-root@v6.0.1-0.20200616011413-4b2895c1b815+incompatible/pkg/tss/capabilities.go (about)

     1  // Copyright 2020 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tss
     6  
     7  import (
     8  	"crypto/sha1"
     9  	"fmt"
    10  	"io"
    11  	"strings"
    12  
    13  	"github.com/google/go-tpm/tpm"
    14  	"github.com/google/go-tpm/tpm2"
    15  )
    16  
    17  func readTPM12VendorAttributes(rwc io.ReadWriter) (TPMInfo, error) {
    18  	var vendorInfo string
    19  
    20  	_, err := tpm.GetManufacturer(rwc)
    21  	if err != nil {
    22  		return TPMInfo{}, err
    23  	}
    24  
    25  	return TPMInfo{
    26  		VendorInfo:           strings.Trim(vendorInfo, "\x00"), // Stubbed
    27  		Manufacturer:         TCGVendorID(uint32(0)),           // Stubbed
    28  		FirmwareVersionMajor: int(0),                           // Stubbed
    29  		FirmwareVersionMinor: int(0),                           // Stubbed
    30  	}, nil
    31  }
    32  
    33  func readTPM20VendorAttributes(rwc io.ReadWriter) (TPMInfo, error) {
    34  	var vendorInfo string
    35  	// The Vendor String is split up into 4 sections of 4 bytes,
    36  	// for a maximum length of 16 octets of ASCII text. We iterate
    37  	// through the 4 indexes to get all 16 bytes & construct vendorInfo.
    38  	// See: TPM_PT_VENDOR_STRING_1 in TPM 2.0 Structures reference.
    39  	for i := 0; i < 4; i++ {
    40  		caps, _, err := tpm2.GetCapability(rwc, tpm2.CapabilityTPMProperties, 1, uint32(tpm2.VendorString1)+uint32(i))
    41  		if err != nil {
    42  			return TPMInfo{}, fmt.Errorf("tpm2.GetCapability(PT_VENDOR_STRING_%d) failed: %v", i+1, err)
    43  		}
    44  		subset, ok := caps[0].(tpm2.TaggedProperty)
    45  		if !ok {
    46  			return TPMInfo{}, fmt.Errorf("got capability of type %T, want tpm2.TaggedProperty", caps[0])
    47  		}
    48  		// Reconstruct the 4 ASCII octets from the uint32 value.
    49  		vendorInfo += string(subset.Value&0xFF000000) + string(subset.Value&0xFF0000) + string(subset.Value&0xFF00) + string(subset.Value&0xFF)
    50  	}
    51  
    52  	caps, _, err := tpm2.GetCapability(rwc, tpm2.CapabilityTPMProperties, 1, uint32(tpm2.Manufacturer))
    53  	if err != nil {
    54  		return TPMInfo{}, fmt.Errorf("tpm2.GetCapability(PT_MANUFACTURER) failed: %v", err)
    55  	}
    56  	manu, ok := caps[0].(tpm2.TaggedProperty)
    57  	if !ok {
    58  		return TPMInfo{}, fmt.Errorf("got capability of type %T, want tpm2.TaggedProperty", caps[0])
    59  	}
    60  
    61  	caps, _, err = tpm2.GetCapability(rwc, tpm2.CapabilityTPMProperties, 1, uint32(tpm2.FirmwareVersion1))
    62  	if err != nil {
    63  		return TPMInfo{}, fmt.Errorf("tpm2.GetCapability(PT_FIRMWARE_VERSION_1) failed: %v", err)
    64  	}
    65  	fw, ok := caps[0].(tpm2.TaggedProperty)
    66  	if !ok {
    67  		return TPMInfo{}, fmt.Errorf("got capability of type %T, want tpm2.TaggedProperty", caps[0])
    68  	}
    69  
    70  	return TPMInfo{
    71  		VendorInfo:           strings.Trim(vendorInfo, "\x00"),
    72  		Manufacturer:         TCGVendorID(manu.Value),
    73  		FirmwareVersionMajor: int((fw.Value & 0xffff0000) >> 16),
    74  		FirmwareVersionMinor: int(fw.Value & 0x0000ffff),
    75  	}, nil
    76  }
    77  
    78  func takeOwnership12(rwc io.ReadWriteCloser, ownerPW, srkPW string) error {
    79  	var ownerAuth [20]byte
    80  	var srkAuth [20]byte
    81  
    82  	if ownerPW != "" {
    83  		ownerAuth = sha1.Sum([]byte(ownerPW))
    84  	}
    85  
    86  	if srkPW != "" {
    87  		srkAuth = sha1.Sum([]byte(srkPW))
    88  	}
    89  
    90  	pubek, err := tpm.ReadPubEK(rwc)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	if err := tpm.TakeOwnership(rwc, ownerAuth, srkAuth, pubek); err != nil {
    96  		return err
    97  	}
    98  	return nil
    99  }
   100  
   101  func takeOwnership20(rwc io.ReadWriteCloser, ownerPW, srkPW string) error {
   102  	return fmt.Errorf("not supported by go-tpm for TPM2.0")
   103  }
   104  
   105  func clearOwnership12(rwc io.ReadWriteCloser, ownerPW string) error {
   106  	var ownerAuth [20]byte
   107  
   108  	if ownerPW != "" {
   109  		ownerAuth = sha1.Sum([]byte(ownerPW))
   110  	}
   111  
   112  	err := tpm.OwnerClear(rwc, ownerAuth)
   113  	if err != nil {
   114  		err := tpm.ForceClear(rwc)
   115  		if err != nil {
   116  			return fmt.Errorf("couldn't clear TPM 1.2 with ownerauth nor force clear")
   117  		}
   118  	}
   119  
   120  	return nil
   121  }
   122  
   123  func clearOwnership20(rwc io.ReadWriteCloser, ownerPW string) error {
   124  	return fmt.Errorf("not supported by go-tpm for TPM2.0")
   125  }
   126  
   127  func readPubEK12(rwc io.ReadWriteCloser, ownerPW string) ([]byte, error) {
   128  	var ownerAuth [20]byte
   129  	if ownerPW != "" {
   130  		ownerAuth = sha1.Sum([]byte(ownerPW))
   131  	}
   132  
   133  	ek, err := tpm.OwnerReadPubEK(rwc, ownerAuth)
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  
   138  	return ek, nil
   139  }
   140  
   141  func readPubEK20(rwc io.ReadWriteCloser, ownerPW string) ([]byte, error) {
   142  	return nil, fmt.Errorf("not supported by go-tpm for TPM2.0")
   143  }
   144  
   145  func resetLockValue12(rwc io.ReadWriteCloser, ownerPW string) (bool, error) {
   146  	var ownerAuth [20]byte
   147  	if ownerPW != "" {
   148  		ownerAuth = sha1.Sum([]byte(ownerPW))
   149  	}
   150  
   151  	if err := tpm.ResetLockValue(rwc, ownerAuth); err != nil {
   152  		return false, err
   153  	}
   154  	return true, nil
   155  }
   156  
   157  func resetLockValue20(rwc io.ReadWriteCloser, ownerPW string) (bool, error) {
   158  	return false, fmt.Errorf("not yet supported by tss")
   159  }