github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/tss/capabilities.go (about)

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