github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/tss/tss.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 provides TPM 1.2/2.0 core functionality and 6 // abstraction layer for high-level functions 7 package tss 8 9 import ( 10 "crypto" 11 "crypto/sha1" 12 "crypto/sha256" 13 "errors" 14 "fmt" 15 16 "github.com/google/go-tpm/tpm2" 17 tpmutil "github.com/google/go-tpm/tpmutil" 18 ) 19 20 // NewTPM initializes access to the TPM based on the 21 // config provided. 22 func NewTPM() (*TPM, error) { 23 candidateTPMs, err := probeSystemTPMs() 24 if err != nil { 25 return nil, err 26 } 27 28 for _, tpm := range candidateTPMs { 29 tss, err := newTPM(tpm) 30 if err != nil { 31 continue 32 } 33 return tss, nil 34 } 35 36 return nil, errors.New("TPM device not available") 37 } 38 39 // Info returns information about the TPM. 40 func (t *TPM) Info() (*TPMInfo, error) { 41 var info TPMInfo 42 var err error 43 switch t.Version { 44 case TPMVersion12: 45 info, err = readTPM12Information(t.RWC) 46 case TPMVersion20: 47 info, err = readTPM20Information(t.RWC) 48 default: 49 return nil, fmt.Errorf("unsupported TPM version: %x", t.Version) 50 } 51 if err != nil { 52 return nil, err 53 } 54 55 return &info, nil 56 } 57 58 // GetVersion returns the TPM version 59 func (t *TPM) GetVersion() TPMVersion { 60 return t.Version 61 } 62 63 // Close closes the TPM socket and wipe locked buffers 64 func (t *TPM) Close() error { 65 return t.RWC.Close() 66 } 67 68 // ReadPCRs reads all PCRs into the PCR structure 69 func (t *TPM) ReadPCRs() ([]PCR, error) { 70 var PCRs map[uint32][]byte 71 var err error 72 var alg crypto.Hash 73 74 switch t.Version { 75 case TPMVersion12: 76 PCRs, err = readAllPCRs12(t.RWC) 77 if err != nil { 78 return nil, fmt.Errorf("failed to read PCRs: %v", err) 79 } 80 alg = crypto.SHA1 81 82 case TPMVersion20: 83 PCRs, err = readAllPCRs20(t.RWC, tpm2.AlgSHA256) 84 if err != nil { 85 return nil, fmt.Errorf("failed to read PCRs: %v", err) 86 } 87 alg = crypto.SHA1 88 89 default: 90 return nil, fmt.Errorf("unsupported TPM version: %x", t.Version) 91 } 92 93 out := make([]PCR, len(PCRs)) 94 for index, digest := range PCRs { 95 out[int(index)] = PCR{ 96 Index: int(index), 97 Digest: digest, 98 DigestAlg: alg, 99 } 100 } 101 102 return out, nil 103 } 104 105 // Extend extends a hash into a pcrIndex with a specific hash algorithm 106 func (t *TPM) Extend(hash []byte, pcrIndex uint32) error { 107 switch t.Version { 108 case TPMVersion12: 109 var thash [20]byte 110 hashlen := len(hash) 111 if hashlen != 20 { 112 return fmt.Errorf("hash length invalid - need 20, got: %v", hashlen) 113 } 114 copy(thash[:], hash[:20]) 115 err := extendPCR12(t.RWC, pcrIndex, thash) 116 if err != nil { 117 return err 118 } 119 case TPMVersion20: 120 err := extendPCR20(t.RWC, pcrIndex, hash) 121 if err != nil { 122 return err 123 } 124 default: 125 return fmt.Errorf("unsupported TPM version: %x", t.Version) 126 } 127 128 return nil 129 } 130 131 // Measure measures data with a specific hash algorithm and extends it into the pcrIndex 132 func (t *TPM) Measure(data []byte, pcrIndex uint32) error { 133 switch t.Version { 134 case TPMVersion12: 135 hash := sha1.Sum(data) 136 err := extendPCR12(t.RWC, pcrIndex, hash) 137 if err != nil { 138 return err 139 } 140 case TPMVersion20: 141 hash := sha256.Sum256(data) 142 err := extendPCR20(t.RWC, pcrIndex, hash[:]) 143 if err != nil { 144 return err 145 } 146 default: 147 return fmt.Errorf("unsupported TPM version: %x", t.Version) 148 } 149 150 return nil 151 } 152 153 // ReadPCR reads a single PCR value by defining the pcrIndex 154 func (t *TPM) ReadPCR(pcrIndex uint32) ([]byte, error) { 155 switch t.Version { 156 case TPMVersion12: 157 return readPCR12(t.RWC, pcrIndex) 158 case TPMVersion20: 159 return readPCR20(t.RWC, pcrIndex) 160 default: 161 return nil, fmt.Errorf("unsupported TPM version: %x", t.Version) 162 } 163 } 164 165 // TakeOwnership owns the TPM with an owner/srk password 166 func (t *TPM) TakeOwnership(newAuth, newSRKAuth string) error { 167 switch t.Version { 168 case TPMVersion12: 169 return takeOwnership12(t.RWC, newAuth, newSRKAuth) 170 case TPMVersion20: 171 return takeOwnership20(t.RWC, newAuth, newSRKAuth) 172 } 173 return fmt.Errorf("unsupported TPM version: %x", t.Version) 174 } 175 176 // ClearOwnership tries to clear all credentials on a TPM 177 func (t *TPM) ClearOwnership(ownerAuth string) error { 178 switch t.Version { 179 case TPMVersion12: 180 return clearOwnership12(t.RWC, ownerAuth) 181 case TPMVersion20: 182 return clearOwnership20(t.RWC, ownerAuth) 183 } 184 return fmt.Errorf("unsupported TPM version: %x", t.Version) 185 } 186 187 // ReadPubEK reads the Endorsement public key 188 func (t *TPM) ReadPubEK(ownerPW string) ([]byte, error) { 189 switch t.Version { 190 case TPMVersion12: 191 return readPubEK12(t.RWC, ownerPW) 192 case TPMVersion20: 193 return readPubEK20(t.RWC, ownerPW) 194 } 195 return nil, fmt.Errorf("unsupported TPM version: %x", t.Version) 196 } 197 198 // ResetLockValue resets the password counter to zero 199 func (t *TPM) ResetLockValue(ownerPW string) (bool, error) { 200 switch t.Version { 201 case TPMVersion12: 202 return resetLockValue12(t.RWC, ownerPW) 203 case TPMVersion20: 204 return resetLockValue20(t.RWC, ownerPW) 205 } 206 return false, fmt.Errorf("unsupported TPM version: %x", t.Version) 207 } 208 209 // NVReadValue reads a value from a given NVRAM index 210 // Type and byte order for TPM1.2 interface: 211 // (offset uint32) 212 // Type and byte oder for TPM2.0 interface: 213 // (authhandle uint32) 214 func (t *TPM) NVReadValue(index uint32, ownerPassword string, size, offhandle uint32) ([]byte, error) { 215 switch t.Version { 216 case TPMVersion12: 217 return nvRead12(t.RWC, index, offhandle, size, ownerPassword) 218 case TPMVersion20: 219 return nvRead20(t.RWC, tpmutil.Handle(index), tpmutil.Handle(offhandle), ownerPassword, int(size)) 220 } 221 return nil, fmt.Errorf("unsupported TPM version: %x", t.Version) 222 }