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