github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/tss/tpm_linux.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 "io" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "strings" 13 14 "github.com/google/go-tpm/tpm" 15 "github.com/google/go-tpm/tpm2" 16 ) 17 18 const ( 19 tpmRoot = "/sys/class/tpm" 20 ) 21 22 func probeSystemTPMs() ([]probedTPM, error) { 23 var tpms []probedTPM 24 25 tpmDevs, err := ioutil.ReadDir(tpmRoot) 26 if os.IsNotExist(err) { 27 return nil, nil 28 } else if err != nil { 29 return nil, err 30 } 31 32 // TPM look up is hardcoded. Taken from googles go-attestation. 33 // go-tpm does not support GetCapability with the required subcommand. 34 // Implementation will be updated asap this is fixed in Go-tpm 35 for _, tpmDev := range tpmDevs { 36 if strings.HasPrefix(tpmDev.Name(), "tpm") { 37 tpm := probedTPM{ 38 Path: filepath.Join(tpmRoot, tpmDev.Name()), 39 } 40 41 if _, err := os.Stat(filepath.Join(tpm.Path, "caps")); err != nil { 42 if !os.IsNotExist(err) { 43 return nil, err 44 } 45 tpm.Version = TPMVersion20 46 } else { 47 tpm.Version = TPMVersion12 48 } 49 tpms = append(tpms, tpm) 50 } 51 } 52 53 return tpms, nil 54 } 55 56 func newTPM(pTPM probedTPM) (*TPM, error) { 57 interf := TPMInterfaceDirect 58 var rwc io.ReadWriteCloser 59 var err error 60 61 switch pTPM.Version { 62 case TPMVersion12: 63 devPath := filepath.Join("/dev", filepath.Base(pTPM.Path)) 64 interf = TPMInterfaceKernelManaged 65 66 rwc, err = tpm.OpenTPM(devPath) 67 if err != nil { 68 return nil, err 69 } 70 case TPMVersion20: 71 // If the TPM has a kernel-provided resource manager, we should 72 // use that instead of communicating directly. 73 devPath := filepath.Join("/dev", filepath.Base(pTPM.Path)) 74 f, err := ioutil.ReadDir(filepath.Join(pTPM.Path, "device", "tpmrm")) 75 if err != nil { 76 if !os.IsNotExist(err) { 77 return nil, err 78 } 79 } else if len(f) > 0 { 80 devPath = filepath.Join("/dev", f[0].Name()) 81 interf = TPMInterfaceKernelManaged 82 } 83 84 rwc, err = tpm2.OpenTPM(devPath) 85 if err != nil { 86 return nil, err 87 } 88 } 89 90 return &TPM{ 91 Version: pTPM.Version, 92 Interf: interf, 93 SysPath: pTPM.Path, 94 RWC: rwc, 95 }, nil 96 } 97 98 // MeasurementLog reads the TCPA eventlog in binary format 99 // from the Linux kernel 100 func (t *TPM) MeasurementLog() ([]byte, error) { 101 return ioutil.ReadFile("/sys/kernel/security/tpm0/binary_bios_measurements") 102 }