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 }