github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+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 }