Open glimchb opened 4 months ago
need to add how to generate and save into tpm iDEVID (private and public keys) of the devices
See as reference tls config using tpm
useful TPM constants: https://github.com/lf-edge/eve/blob/12be0c21435e09a9d396bb9795398d43c2b8ba4f/pkg/pillar/evetpm/tpm.go#L29-L72
const (
//TpmPasswdHdl is the well known TPM NVIndex for TPM Credentials
TpmPasswdHdl tpmutil.Handle = 0x1600000
//TpmEKHdl is the well known TPM permanent handle for Endorsement key
TpmEKHdl tpmutil.Handle = 0x81000001
//TpmSRKHdl is the well known TPM permanent handle for Storage key
TpmSRKHdl tpmutil.Handle = 0x81000002
//TpmAKHdl is the well known TPM permanent handle for AIK key
TpmAKHdl tpmutil.Handle = 0x81000003
//TpmQuoteKeyHdl is the well known TPM permanent handle for PCR Quote signing key
TpmQuoteKeyHdl tpmutil.Handle = 0x81000004
//TpmEcdhKeyHdl is the well known TPM permanent handle for ECDH key
TpmEcdhKeyHdl tpmutil.Handle = 0x81000005
//TpmDeviceKeyHdl is the well known TPM permanent handle for device key
TpmDeviceKeyHdl tpmutil.Handle = 0x817FFFFF
//TpmCredentialsFileName is the file that holds the dynamically created TPM credentials
TpmCredentialsFileName = types.IdentityDirname + "/tpm_credential"
//MaxPasswdLength is the max length allowed for a TPM password
MaxPasswdLength = 7 //limit TPM password to this length
//TpmDiskKeyHdl is the handle for constructing disk encryption key
TpmDiskKeyHdl tpmutil.Handle = 0x1700000
//TpmDeviceCertHdl is the well known TPM NVIndex for device cert
TpmDeviceCertHdl tpmutil.Handle = 0x1500000
//TpmSealedDiskPrivHdl is the handle for constructing disk encryption key
TpmSealedDiskPrivHdl tpmutil.Handle = 0x1800000
//TpmSealedDiskPubHdl is the handle for constructing disk encryption key
TpmSealedDiskPubHdl tpmutil.Handle = 0x1900000
//EmptyPassword is an empty string
EmptyPassword = ""
vaultKeyLength = 32 //Bytes
)
will try without QEMU like this https://github.com/opiproject/sztp/blob/main/doc/swtpm.md
sudo apt-get install swtpm tpm2-tools -y
mkdir /tmp/emulated_tpm
mkdir /tmp/emulated_tpm
swtpm socket --tpm2 \
--server type=unixio,path=/tmp/emulated_tpm/swtpm.sock \
--ctrl type=unixio,path=/tmp/emulated_tpm/swtpm.sock.ctrl \
--tpmstate dir=/tmp/emulated_tpm \
--log file="swtpm.log" \
--log level=20 \
--flags not-need-init,startup-clear &
export TPM2TOOLS_TCTI="swtpm:path=/tmp/emulated_tpm/swtpm.sock" tpm2 clear
or
docker run --rm -it -v sztp_tpm-data:/swtpm -e TPM2TOOLS_TCTI="swtpm:path=/swtpm/swtpm.sock" docker.io/strongx509/tpm:5.9.13 tpm2 clear
and then in golang:
package main
import (
"io/ioutil"
"log"
"net"
"github.com/google/go-tpm/legacy/tpm2"
"github.com/google/go-tpm/tpmutil"
)
var (
tpmSrkHandle = 0x81000001
tpmPcrSelection = tpm2.PCRSelection{Hash: tpm2.AlgSHA256, PCRs: []int{}}
tpmDefaultKeyParams = tpm2.Public{
Type: tpm2.AlgRSA,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagDecrypt | tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagSensitiveDataOrigin | tpm2.FlagNoDA,
AuthPolicy: []byte{},
RSAParameters: &tpm2.RSAParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgNull,
Mode: tpm2.AlgUnknown,
},
KeyBits: 2048,
},
}
)
func main() {
rwc, tpmerr := net.Dial("unix", "/tmp/emulated_tpm/swtpm.sock")
//rwc, tpmerr := tpm2.OpenTPM("/tmp/emulated_tpm/swtpm.sock")
if tpmerr != nil {
log.Fatalf("[ERROR] %s", tpmerr.Error())
return
}
defer rwc.Close()
if _, err := tpm2.GetManufacturer(rwc); err != nil {
log.Fatalf("device is not a TPM 2.0")
return
}
handle := tpmutil.Handle(tpmSrkHandle)
privKey, pubKey, _, _, _, err := tpm2.CreateKey(rwc, handle, tpmPcrSelection, "", "", tpmDefaultKeyParams)
if err != nil {
log.Fatalf("[ERROR] %s", err.Error())
return
}
tpmKeyHandle, _, err := tpm2.Load(rwc, handle, "", pubKey, privKey)
if err != nil {
log.Fatalf("[ERROR] %s", err.Error())
return
}
defer tpm2.FlushContext(rwc, tpmKeyHandle)
ekhBytes, err := tpm2.ContextSave(rwc, tpmKeyHandle)
err = ioutil.WriteFile("key.ctx", ekhBytes, 0644)
log.Fatalf("[ERROR] %s", err.Error())
}
and run like
docker run --rm -it -v `pwd`:/app -w /app golang:alpine go mod init github.com/opiproject/sztp/sztp-agent
docker run --rm -it -e GO111MODULE=on -v `pwd`:/app -w /app golang:alpine go get -u github.com/google/go-tpm/tpmutil
docker run --rm -it -v /tmp/emulated_tpm:/tmp/emulated_tpm -v `pwd`:/app -w /app golang:alpine go run tpm.go
log
SWTPM_IO_Read: length 22
80 01 00 00 00 16 00 00 01 7A 00 00 00 06 00 00
01 05 00 00 00 01
SWTPM_IO_Write: length 27
80 01 00 00 00 1B 00 00 00 00 01 00 00 00 06 00
00 00 01 00 00 01 05 49 42 4D 00
SWTPM_IO_Read: length 63
80 02 00 00 00 3F 00 00 01 53 81 00 00 01 00 00
00 09 40 00 00 09 00 00 01 00 00 00 04 00 00 00
00 00 16 00 01 00 0B 00 02 04 32 00 00 00 10 00
10 08 00 00 00 00 00 00 00 00 00 00 00 00 00
SWTPM_IO_Write: length 10
80 01 00 00 00 0A 00 00 01 8B
Data client disconnected
go: downloading github.com/google/go-tpm v0.9.1
go: downloading golang.org/x/sys v0.22.0
2024/07/15 21:13:05 [ERROR] handle 1, error code 0xb : the handle is not correct for the use
exit status 1