├── LICENSE ├── README.md ├── aes_import ├── README.md ├── go.mod ├── go.sum └── main.go ├── ak_sign_nv ├── README.md ├── go.mod ├── go.sum └── main.go ├── attest_verify ├── README.md ├── go.mod ├── go.sum └── main.go ├── context_chain ├── README.md ├── go.mod ├── go.sum └── main.go ├── ecc_import ├── README.md ├── go.mod ├── go.sum ├── main.go └── private.pem ├── ek_import_blob ├── README.md ├── go.mod ├── go.sum └── main.go ├── encrypt_decrypt_aes ├── README.md ├── go.mod ├── go.sum └── main.go ├── encrypt_with_tpm_rsa ├── README.md ├── go.mod ├── go.sum └── main.go ├── event_log ├── README.md ├── go.mod ├── go.sum └── main.go ├── evictcontrol ├── README.md ├── go.mod ├── go.sum └── main.go ├── gcp_ek_ak ├── README.md ├── go.mod ├── go.sum └── main.go ├── h2_primary_template ├── README.md ├── go.mod └── main.go ├── hmac_import ├── README.md ├── go.mod ├── go.sum └── hmac.go ├── ima_policy └── README.md ├── kdf ├── README.md ├── go.mod ├── go.sum └── main.go ├── keyfile-go-tpm-tools ├── README.md ├── go.mod ├── go.sum ├── main.go └── private.pem ├── luks └── README.md ├── nv ├── README.md ├── go.mod ├── go.sum ├── nv_basic │ └── main.go └── nv_buffer │ └── main.go ├── password ├── README.md ├── go.mod └── main.go ├── pcr_utils ├── README.md ├── go.mod ├── go.sum └── main.go ├── pkcs11 └── README.md ├── policy ├── README.md ├── authorize │ └── main.go ├── go.mod ├── go.sum ├── password │ └── main.go ├── pcrsession │ └── main.go └── signed │ └── main.go ├── policy_gen ├── README.md ├── go.mod ├── go.sum ├── images │ ├── authsession.png │ ├── command.png │ └── parameters.png ├── policy_authorize_direct │ └── authorizegen.go ├── policy_authorize_util │ └── authorizegen.go ├── policy_pcr_direct │ └── pcrgen.go ├── policy_pcr_util │ └── pcrgen.go ├── policy_secret_util │ └── secretgen.go ├── policy_signed_util │ └── main.go └── trace.cap ├── pytss ├── README.md ├── esapi_auth.py ├── esapi_create_sign.py ├── esapi_encrypt_decrypt.py ├── esapi_hmac_import.py ├── esapi_keyfile.py ├── esapi_pcr.py ├── esapi_session_encryption_auth.py ├── esapi_session_encryption_authvalue_pcr_aes.py ├── esapi_session_encryption_authvalue_pcr_rsa.py ├── esapi_session_encryption_pcr.py ├── esapi_tpm2.py ├── fapi_auth.py ├── fapi_create_sign.py ├── fapi_encrypt_decrypt.py ├── fapi_export_tpm2.py ├── fapi_import_sign.py ├── fapi_import_tpm2.py ├── fapi_pcr.py ├── fapi_seal_unseal.py └── profiles │ ├── P_ECCP256SHA256.json │ └── P_RSA2048SHA256.json ├── quote_verify ├── README.md ├── go.mod ├── go.sum └── main.go ├── resource_manager └── README.md ├── rsa_import ├── README.md ├── go.mod ├── go.sum ├── main.go └── private.pem ├── sign_certify_ak ├── README.md ├── go.mod ├── go.sum └── main.go ├── sign_with_ak ├── README.md ├── go.mod ├── go.sum └── main.go ├── sign_with_ecc ├── README.md ├── go.mod ├── go.sum └── main.go ├── sign_with_rsa ├── README.md ├── go.mod ├── go.sum └── main.go ├── simulator_swtpm_tcpdump ├── README.md ├── go.mod ├── images │ ├── pcr.png │ └── unseal.png ├── pcr.cap ├── pcr.go ├── unseal.cap └── unseal.go ├── srk_seal_unseal ├── README.md ├── go.mod ├── go.sum └── main.go ├── tls └── README.md ├── tpm-key ├── README.md └── rsa_sign │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── private.pem ├── tpm2_duplicate └── README.md ├── tpm2_duplicate_ek └── README.md ├── tpm2_duplicate_go ├── README.md ├── go.mod ├── go.sum ├── vm-a │ └── main.go ├── vm-b-1 │ └── main.go └── vm-b-2 │ └── main.go ├── tpm2_get_name ├── README.md ├── getname.go ├── go.mod └── go.sum ├── tpm2_importblob_ek ├── README.md ├── go.mod ├── go.sum └── main.go ├── tpm_encrypted_session ├── README.md ├── clear.cap ├── encrypted.cap ├── encrypted │ └── main.go ├── go.mod ├── go.sum ├── images │ ├── clear.png │ └── encrypted.png └── plain │ └── main.go ├── tpm_make_activate ├── AttestProv.pdf ├── README.md ├── go.mod ├── go.sum └── main.go ├── tpm_remote_attestation └── README.md └── tpm_services ├── README.md ├── attestation ├── go.mod ├── go.sum └── main.go ├── quote_verify ├── go.mod ├── go.sum └── main.go └── seal ├── go.mod ├── go.sum └── main.go /aes_import/README.md: -------------------------------------------------------------------------------- 1 | ## Importing External AES key and performing encryption/decryption 2 | 3 | https://github.com/tpm2-software/tpm2-tools/blob/master/man/tpm2_import.1.md#import-an-aes-128-key 4 | -------------------------------------------------------------------------------- /aes_import/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.2-0.20240822221117-042b4e4b69dc 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /aes_import/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003 h1:gfGQAIxsEEAuYuFvjCGpDnTwisMJOz+rUfJMkk4yTmc= 4 | github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 6 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 7 | github.com/google/go-tpm v0.9.2-0.20240822221117-042b4e4b69dc h1:5TSqMWAyIRcxsU8R3qOESAXg8eI8fYGDVrFYitK5zlM= 8 | github.com/google/go-tpm v0.9.2-0.20240822221117-042b4e4b69dc/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 10 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 11 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 12 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 13 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 14 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 15 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 16 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 17 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 18 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 19 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 20 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 21 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 22 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 23 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 24 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 25 | -------------------------------------------------------------------------------- /ak_sign_nv/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/google/go-tpm v0.9.0 7 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 8 | ) 9 | 10 | require ( 11 | github.com/google/go-sev-guest v0.6.1 // indirect 12 | github.com/google/logger v1.1.1 // indirect 13 | github.com/google/uuid v1.3.0 // indirect 14 | github.com/pborman/uuid v1.2.0 // indirect 15 | github.com/pkg/errors v0.9.1 // indirect 16 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect 17 | golang.org/x/sys v0.8.0 // indirect 18 | google.golang.org/protobuf v1.28.0 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /ak_sign_nv/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 3 | github.com/google/certificate-transparency-go v1.1.2 h1:4hE0GEId6NAW28dFpC+LrRGwQX5dtmXQGDbg8+/MZOM= 4 | github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888 h1:HURgKPRPJSozDuMHpjdV+iyFVLhB6bi1JanhGgSzI1k= 5 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 6 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 7 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 8 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 9 | github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= 10 | github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= 11 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 12 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 13 | github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= 14 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 15 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 16 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 18 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 20 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 21 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 22 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 23 | go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= 24 | go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= 25 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 26 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 27 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 28 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= 29 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 30 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 31 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 32 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 33 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 34 | -------------------------------------------------------------------------------- /attest_verify/README.md: -------------------------------------------------------------------------------- 1 | # Attest and Verify using go-tpm-tools 2 | 3 | 4 | using [https://pkg.go.dev/github.com/google/go-tpm-tools@v0.3.1/server#VerifyAttestation](https://pkg.go.dev/github.com/google/go-tpm-tools@v0.3.1/server#VerifyAttestation) 5 | 6 | 7 | - `confirmGCESEV` verifies if AMD SEV is enabled on GCE instances only [https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#integrity-monitoring](https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#integrity-monitoring) 8 | 9 | on an ordinary vm you'll see `EV SEVStatus: None` 10 | 11 | ```log 12 | # go run main.go --confirmGCESEV=true 13 | 2023/08/09 14:32:02 Attestation Verified 14 | 2023/08/09 14:32:02 =============== Parsing EventLog =============== 15 | 2023/08/09 14:32:02 secureBoot State enabled true 16 | 2023/08/09 14:32:02 PCR and eventlogs verified, assessing SEV Status for GCE: 17 | 2023/08/09 14:32:02 EV SevStatus: NONE 18 | ``` -------------------------------------------------------------------------------- /attest_verify/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888 7 | github.com/google/go-tpm v0.9.0 8 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 9 | ) 10 | 11 | require ( 12 | github.com/golang/protobuf v1.5.3 // indirect 13 | github.com/google/certificate-transparency-go v1.1.2 // indirect 14 | github.com/google/go-sev-guest v0.6.1 // indirect 15 | github.com/google/go-tspi v0.3.0 // indirect 16 | github.com/google/logger v1.1.1 // indirect 17 | github.com/google/uuid v1.3.0 // indirect 18 | github.com/pborman/uuid v1.2.0 // indirect 19 | github.com/pkg/errors v0.9.1 // indirect 20 | go.uber.org/atomic v1.7.0 // indirect 21 | go.uber.org/multierr v1.8.0 // indirect 22 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect 23 | golang.org/x/sys v0.8.0 // indirect 24 | google.golang.org/protobuf v1.30.0 // indirect 25 | ) 26 | -------------------------------------------------------------------------------- /attest_verify/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "crypto" 6 | "errors" 7 | "flag" 8 | "fmt" 9 | "log" 10 | "os" 11 | 12 | "github.com/google/go-attestation/attest" 13 | "github.com/google/go-tpm-tools/client" 14 | attestpb "github.com/google/go-tpm-tools/proto/attest" 15 | "github.com/google/go-tpm-tools/server" 16 | 17 | //"github.com/google/go-tpm/tpm2" 18 | "github.com/google/go-tpm/legacy/tpm2" 19 | ) 20 | 21 | var ( 22 | tpmPath = flag.String("tpm-path", "/dev/tpm0", "Path to the TPM device (character device or a Unix socket).") 23 | confirmGCESEV = flag.Bool("confirmGCESEV", false, "Confirm if GCE SEV Status is active") 24 | eventLogPath = flag.String("eventLogPath", "/sys/kernel/security/tpm0/binary_bios_measurements", "Path to the eventlog") 25 | ) 26 | 27 | func main() { 28 | flag.Parse() 29 | 30 | var err error 31 | 32 | rwc, err := tpm2.OpenTPM(*tpmPath) 33 | if err != nil { 34 | log.Fatalf("can't open TPM %q: %v", *tpmPath, err) 35 | } 36 | defer func() { 37 | if err := rwc.Close(); err != nil { 38 | log.Fatalf("\ncan't close TPM %q: %v", tpmPath, err) 39 | } 40 | }() 41 | 42 | ekk, err := client.EndorsementKeyRSA(rwc) 43 | if err != nil { 44 | log.Fatalf("ERROR: could not get EndorsementKeyRSA: %v", err) 45 | } 46 | defer ekk.Close() 47 | 48 | ak, err := client.AttestationKeyRSA(rwc) 49 | if err != nil { 50 | log.Fatalf("ERROR: could not get AttestationKeyRSA: %v", err) 51 | } 52 | defer ak.Close() 53 | 54 | nonce := []byte("noncevalue") 55 | 56 | attestation, err := ak.Attest(client.AttestOpts{Nonce: nonce}) 57 | if err != nil { 58 | log.Fatalf("failed to attest: %v", err) 59 | } 60 | 61 | //ims, err := server.VerifyAttestation(attestation, server.VerifyOpts{ 62 | _, err = server.VerifyAttestation(attestation, server.VerifyOpts{ 63 | Nonce: nonce, 64 | TrustedAKs: []crypto.PublicKey{ak.PublicKey()}, 65 | }) 66 | if err != nil { 67 | log.Fatalf("failed to verify: %v", err) 68 | } 69 | log.Printf("Attestation Verified") 70 | //log.Printf("Machine State: %v", ims.RawEvents) 71 | 72 | log.Printf("=============== Parsing EventLog ===============") 73 | 74 | el, err := attest.ParseEventLog(attestation.EventLog) 75 | if err != nil { 76 | log.Printf("Quote Parsing EventLog Failed: %v", err) 77 | os.Exit(1) 78 | } 79 | 80 | sb, err := attest.ParseSecurebootState(el.Events(attest.HashSHA1)) 81 | if err != nil { 82 | log.Printf("Quote Parsing EventLog Failed: %v", err) 83 | os.Exit(1) 84 | } 85 | 86 | log.Printf(" secureBoot State enabled %t", sb.Enabled) 87 | 88 | if *confirmGCESEV { 89 | log.Printf(" PCR and eventlogs verified, assessing SEV Status for GCE:") 90 | for _, e := range el.Events(attest.HashSHA256) { 91 | // eventTypes aren't exported enums https://github.com/google/go-attestation/blob/master/attest/internal/events.go#L70 92 | // so match as string 93 | // review: https://github.com/google/go-attestation/blob/master/docs/event-log-disclosure.md#event-type-and-verification-footguns 94 | // https://trustedcomputinggroup.org/wp-content/uploads/TCG-Guidance-Integrity-Measurements-Event-Log-Processing_v1_r0p118_24feb2022-1.pdf 95 | if e.Index == 0 && e.Type.String() == "EV_NONHOST_INFO" { 96 | sevStatus, err := parseGCENonHostInfo(e.Data) 97 | if err != nil { 98 | log.Printf("Error parsing SEV Status: %v", err) 99 | os.Exit(1) 100 | } 101 | log.Printf(" EV SevStatus: %s\n", sevStatus.String()) 102 | } 103 | } 104 | } 105 | 106 | } 107 | 108 | // from https://github.com/google/go-tpm-tools/blob/master/server/policy_constants.go#L162 109 | func parseGCENonHostInfo(nonHostInfo []byte) (attestpb.GCEConfidentialTechnology, error) { 110 | prefixLen := len(server.GCENonHostInfoSignature) 111 | if len(nonHostInfo) < (prefixLen + 1) { 112 | return attestpb.GCEConfidentialTechnology_NONE, fmt.Errorf("length of GCE Non-Host info (%d) is too short", len(nonHostInfo)) 113 | } 114 | 115 | if !bytes.Equal(nonHostInfo[:prefixLen], server.GCENonHostInfoSignature) { 116 | return attestpb.GCEConfidentialTechnology_NONE, errors.New("prefix for GCE Non-Host info is missing") 117 | } 118 | tech := nonHostInfo[prefixLen] 119 | if tech > byte(attestpb.GCEConfidentialTechnology_AMD_SEV_SNP) || tech == byte(3) { 120 | return attestpb.GCEConfidentialTechnology_NONE, fmt.Errorf("unknown GCE Confidential Technology: %d", tech) 121 | } 122 | return attestpb.GCEConfidentialTechnology(tech), nil 123 | } 124 | -------------------------------------------------------------------------------- /context_chain/README.md: -------------------------------------------------------------------------------- 1 | ## Chained Keys 2 | 3 | Snippet which creates a primary, then a child, then a grandchild. 4 | 5 | Use the leaf key to encrypt/decrypt 6 | 7 | ref [TPM-JS Cryptographic Keys](https://google.github.io/tpm-js/#pg_keys) 8 | 9 | 10 | ```bash 11 | go run main.go --mode=create 12 | 13 | [reboot] 14 | 15 | go run main.go --mode=load 16 | ``` 17 | 18 | 19 | ```bash 20 | # create root 21 | tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx 22 | 23 | # create child 24 | tpm2_create -g sha256 -u key_2.pub -r key_2.priv -C primary.ctx -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt" 25 | tpm2_load -C primary.ctx -u key_2.pub -r key_2.priv -c key_2.ctx 26 | 27 | 28 | # create a grandchild (use key_2 as the immediate parent) 29 | tpm2_create -g sha256 -G aes -u key_3.pub -r key_3.priv -C key_2.ctx -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|decrypt|sign" 30 | tpm2_load -C key_2.ctx -u key_3.pub -r key_3.priv -c key_3.ctx 31 | 32 | 33 | # encrypt/decrypt 34 | echo "foo" > secret.dat 35 | openssl rand -out iv.bin 16 36 | 37 | tpm2_encryptdecrypt --iv iv.bin -c key_3.ctx -o encrypt.out secret.dat 38 | tpm2_encryptdecrypt --iv iv.bin -c key_3.ctx -d encrypt.out 39 | ``` 40 | 41 | 42 | --- 43 | 44 | #### verify chain after reboot 45 | 46 | ```bash 47 | ### attempt to load grandchild directly without loading child 48 | ##### this will give an error as expected 49 | 50 | tpm2_load -C key_2.ctx -u key_3.pub -r key_3.priv -c key_3.ctx 51 | WARNING:esys:src/tss2-esys/api/Esys_ContextLoad.c:279:Esys_ContextLoad_Finish() Received TPM Error 52 | ERROR:esys:src/tss2-esys/api/Esys_ContextLoad.c:93:Esys_ContextLoad() Esys Finish ErrorCode (0x000001df) 53 | ERROR: Esys_ContextLoad(0x1DF) - tpm:parameter(1):integrity check failed 54 | ERROR: Incorrect handle value, got: "key_2.ctx", expected expected [o|p|e|n|l] or a handle number 55 | ERROR: Unable to read PEM from provided BIO/file 56 | ERROR: Unable to fetch public/private portions of TSS PRIVKEY 57 | ERROR: Cannot make sense of object context "key_2.ctx" 58 | 59 | 60 | ### now try to load the child 61 | ##### this will give an error as expected because we haven't loaded the parent context 62 | tpm2_load -C primary.ctx -u key_2.pub -r key_2.priv -c key_2.ctx 63 | WARNING:esys:src/tss2-esys/api/Esys_ContextLoad.c:279:Esys_ContextLoad_Finish() Received TPM Error 64 | ERROR:esys:src/tss2-esys/api/Esys_ContextLoad.c:93:Esys_ContextLoad() Esys Finish ErrorCode (0x000001df) 65 | ERROR: Esys_ContextLoad(0x1DF) - tpm:parameter(1):integrity check failed 66 | ERROR: Incorrect handle value, got: "primary.ctx", expected expected [o|p|e|n|l] or a handle number 67 | ERROR: Unable to read PEM from provided BIO/file 68 | ERROR: Unable to fetch public/private portions of TSS PRIVKEY 69 | ERROR: Cannot make sense of object context "primary.ctx" 70 | ERROR: Unable to run tpm2_load 71 | 72 | ### regenerate the parent 73 | ##### we will actually get the same parent key every time since w'ere deriving from a non null hierarchy 74 | tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx 75 | 76 | ### now load the children 77 | tpm2_load -C primary.ctx -u key_2.pub -r key_2.priv -c key_2.ctx 78 | 79 | tpm2_load -C key_2.ctx -u key_3.pub -r key_3.priv -c key_3.ctx 80 | 81 | ### now decrypt 82 | tpm2_encryptdecrypt --iv iv.bin -c key_3.ctx -d encrypt.out 83 | ``` -------------------------------------------------------------------------------- /context_chain/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | // github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003 8 | require github.com/google/go-tpm-tools v0.4.4 9 | 10 | // require github.com/salrashid123/signer/tpm v0.0.0-20240607164123-b64bf0a3f447 11 | 12 | require github.com/google/go-tpm v0.9.0 13 | 14 | require ( 15 | github.com/golang/protobuf v1.5.4 // indirect 16 | github.com/google/go-configfs-tsm v0.2.2 // indirect 17 | github.com/google/uuid v1.6.0 // indirect 18 | golang.org/x/crypto v0.21.0 // indirect 19 | golang.org/x/sys v0.18.0 // indirect 20 | google.golang.org/protobuf v1.33.0 // indirect 21 | ) 22 | 23 | // replace github.com/google/go-tpm => ./go-tpm 24 | -------------------------------------------------------------------------------- /context_chain/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 2 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 3 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 4 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 5 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 6 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 7 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 8 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 9 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 10 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 11 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 12 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 13 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 14 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 15 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 16 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 17 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 18 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 19 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 20 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 21 | golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= 22 | golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= 23 | golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= 24 | golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 25 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 26 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 27 | -------------------------------------------------------------------------------- /ecc_import/README.md: -------------------------------------------------------------------------------- 1 | # Importing an external key and load it ot the TPM 2 | 3 | 4 | ### create ecc key 5 | 6 | ```bash 7 | openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 \ 8 | -pkeyopt ec_param_enc:named_curve \ 9 | -out private.pem 10 | 11 | ``` 12 | 13 | ## using tpm2_tools 14 | 15 | ```bash 16 | tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx 17 | tpm2_import -C primary.ctx -G rsa -i private.pem -u key.pub -r key.prv 18 | tpm2_load -C primary.ctx -u key.pub -r key.prv -c key.ctx 19 | ``` 20 | 21 | 22 | ### create 23 | 24 | ```bash 25 | $ go run importExternalRSA.go --mode=create --keyPub key.pub --keyPriv=key.priv --pemFile=private.pem --handle=0x81010002 26 | 27 | 28 | ``` 29 | 30 | 31 | 32 | 33 | --- 34 | 35 | ```bash 36 | # more private.pem 37 | -----BEGIN PRIVATE KEY----- 38 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgaAe9jz/XJMwpsgTP 39 | KmmS/0rWvPkInMjhXQoRgvScQuWhRANCAAQcnaAC7weNrICA5jWrH0MLiAgAWpk+ 40 | lzTjE2jX+NJLIhDZSVkGfErt0kBk4k++ckWN8w5HpD8RybW690+IPi9h 41 | -----END PRIVATE KEY----- 42 | ``` -------------------------------------------------------------------------------- /ecc_import/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /ecc_import/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 4 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 16 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 17 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 18 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /ecc_import/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgaAe9jz/XJMwpsgTP 3 | KmmS/0rWvPkInMjhXQoRgvScQuWhRANCAAQcnaAC7weNrICA5jWrH0MLiAgAWpk+ 4 | lzTjE2jX+NJLIhDZSVkGfErt0kBk4k++ckWN8w5HpD8RybW690+IPi9h 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /ek_import_blob/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b 7 | github.com/golang/protobuf v1.5.2 8 | github.com/google/go-tpm v0.3.3 9 | github.com/google/go-tpm-tools v0.3.6 10 | 11 | ) 12 | 13 | require ( 14 | github.com/google/certificate-transparency-go v1.1.2 // indirect 15 | github.com/google/go-attestation v0.4.3 // indirect 16 | github.com/google/go-tspi v0.2.1-0.20190423175329-115dea689aad // indirect 17 | golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b // indirect 18 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect 19 | google.golang.org/protobuf v1.27.1 // indirect 20 | ) 21 | -------------------------------------------------------------------------------- /encrypt_decrypt_aes/README.md: -------------------------------------------------------------------------------- 1 | ### Encrypt/Decrypt with AES key on OWNER handle 2 | 3 | optionally seed the "unique" bit 4 | https://github.com/tpm2-software/tpm2-tools/issues/2378 5 | 6 | 7 | ```bash 8 | echo "foo" > secret.dat 9 | openssl rand -out iv.bin 16 10 | 11 | printf '\x00\x01' > ud.1 12 | dd if=/dev/random bs=256 count=1 of=ud.2 13 | cat ud.1 ud.2 > unique.dat 14 | 15 | tpm2_createprimary -C o -g sha1 -G rsa -c primary.ctx -u unique.dat 16 | 17 | tpm2_create -g sha256 -G aes -u key.pub -r key.priv -C primary.ctx 18 | 19 | tpm2_load -C primary.ctx -u key.pub -r key.priv -n key.name -c decrypt.ctx 20 | 21 | tpm2_encryptdecrypt -Q --iv iv.bin -c decrypt.ctx -o encrypt.out secret.dat 22 | 23 | tpm2_encryptdecrypt -Q --iv iv.bin -c decrypt.ctx -d -o decrypt.out encrypt.out 24 | ``` 25 | 26 | 27 | To use the "Direct" go-tpm api, i used a simulator here: 28 | 29 | 30 | ```bash 31 | go run main.go --handle=0x81008001 --tpm-path="127.0.0.1:2321" 32 | ``` 33 | 34 | TODO: support cbc padding which requires (`--pad`: `tpm2_encryptdecrypt --iv iv.bin -c decrypt.ctx --mode=cbc --pad -o encrypt.out secret.dat`) -------------------------------------------------------------------------------- /encrypt_decrypt_aes/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.5 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.2-0.20240625170440-991b038b62b6 9 | github.com/google/go-tpm-tools v0.4.4 10 | ) 11 | 12 | require ( 13 | github.com/google/go-configfs-tsm v0.3.2 // indirect 14 | golang.org/x/sys v0.15.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /encrypt_decrypt_aes/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 2 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 3 | github.com/google/go-configfs-tsm v0.3.2 h1:ZYmHkdQavfsvVGDtX7RRda0gamelUNUhu0A9fbiuLmE= 4 | github.com/google/go-configfs-tsm v0.3.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 5 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 6 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 7 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 8 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 9 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 10 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 11 | github.com/google/go-tpm v0.9.2-0.20240625170440-991b038b62b6 h1:ZW9jfg37wN+ex/zSdoy3J2PgL+Chsm8lABzA47umtCw= 12 | github.com/google/go-tpm v0.9.2-0.20240625170440-991b038b62b6/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 13 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 14 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 15 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 16 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 17 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 18 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 20 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 21 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 22 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 23 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 24 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 25 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= 26 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 27 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 28 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 29 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 30 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 31 | -------------------------------------------------------------------------------- /encrypt_with_tpm_rsa/README.md: -------------------------------------------------------------------------------- 1 | 2 | # TPM Sign with RSA 3 | 4 | ```bash 5 | echo "my message" > message.dat 6 | 7 | tpm2_createprimary -C o -c primary.ctx -Q 8 | tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx -Q 9 | 10 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 11 | tpm2_readpublic -c key.ctx -o key.pem -f PEM -Q 12 | 13 | cat key.pem 14 | 15 | tpm2_sign -c key.ctx -g sha256 -o sig.rssa message.dat 16 | tpm2_verifysignature -c key.ctx -g sha256 -s sig.rssa -m message.dat 17 | 18 | ### openssl 19 | sha256sum message.dat | awk '{ print "000000 " $1 }' | xxd -r -c 32 > data.in.digest 20 | tpm2_sign -Q -c key.ctx -g sha256 -d -f plain -o data.out.signed data.in.digest 21 | openssl dgst -verify key.pem -keyform pem -sha256 -signature data.out.signed message.dat 22 | 23 | ``` 24 | 25 | 26 | --- 27 | 28 | ```bash 29 | # go run svcaccount/main.go 30 | ======= Key persisted ======== 31 | ======= Sign with new RSA ======== 32 | Signature data: L4LkdyjpqaPWpcZXeHV9bMs0xmGRQpXMHeLuosTLxCaljpdmk9TbDGaHS1zqhUYV85ZnbqsvTgYeP0auierHXOOINBV1kbKuoihZJhsbyfmcIpIdoHItRwPM/sTH3fl4ZxcASSiZSC6F6b38Q6J75xQPqAT93Ua0n7LeWdcP/er8eed6yPISdScF/+B/45LmqT/y+3rVTlhRgBLvTm846ifL/1XzUMdcSRq3OOk0UYDNh3IfbQXTg7lFRtgo6hxy+rsUNwwy0Ip54wZXftalVx9+dfrB9ZlHW1c9KF1WObmu+noPEDlex0AoZ4sB3FtTcJj/glXZovP9KKjSjeSkTA 33 | RSA Signing Key 34 | -----BEGIN PUBLIC KEY----- 35 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvJamgslhqX9leS7CJGb4 36 | sOuKhvzSYYjKpocEko3EdhrZlw4Y0ufkeCRV4IQtWe74CZvHNeXzjsf3pFDHGXs1 37 | RMCUJ8u+By54OIMCQFBwmmg6/8lfu/WhXDY/PgdwuAocaAAYuqfj29vIxG/8Y9KX 38 | qZJ3S8o0aP+cLX+C7lU5k/1kS5n4w2BnmUXi9jsfCJ3kBMxXduQdy4zd4Tml450x 39 | ypcAQOI8u7qt0Xam6cMMu2wwJGvIewnkQaVY7P4o+qRRsc42wXsQ3gl8xpkjQFmO 40 | dApWjF2olxUTh20iZfjJLyIyIJf61QC02c9evqC6Q1pHZ23+FWXc/5b9M2HvAIVl 41 | qwIDAQAB 42 | -----END PUBLIC KEY----- 43 | 44 | signature Verified 45 | 46 | ``` 47 | 48 | 49 | --- 50 | 51 | for RSA PSS: 52 | 53 | ```golang 54 | rsaTemplate := tpm2.TPMTPublic{ 55 | Type: tpm2.TPMAlgRSA, 56 | NameAlg: tpm2.TPMAlgSHA256, 57 | ObjectAttributes: tpm2.TPMAObject{ 58 | SignEncrypt: true, 59 | FixedTPM: true, 60 | FixedParent: true, 61 | SensitiveDataOrigin: true, 62 | UserWithAuth: true, 63 | }, 64 | AuthPolicy: tpm2.TPM2BDigest{}, 65 | Parameters: tpm2.NewTPMUPublicParms( 66 | tpm2.TPMAlgRSA, 67 | &tpm2.TPMSRSAParms{ 68 | Scheme: tpm2.TPMTRSAScheme{ 69 | Scheme: tpm2.TPMAlgRSAPSS, 70 | Details: tpm2.NewTPMUAsymScheme( 71 | tpm2.TPMAlgRSAPSS, 72 | &tpm2.TPMSSigSchemeRSAPSS{ 73 | HashAlg: tpm2.TPMAlgSHA256, 74 | }, 75 | ), 76 | }, 77 | KeyBits: 2048, 78 | }, 79 | ), 80 | } 81 | 82 | 83 | sign := tpm2.Sign{ 84 | KeyHandle: tpm2.NamedHandle{ 85 | Handle: rsaKeyResponse.ObjectHandle, 86 | Name: rsaKeyResponse.Name, 87 | }, 88 | Digest: tpm2.TPM2BDigest{ 89 | Buffer: digest[:], 90 | }, 91 | InScheme: tpm2.TPMTSigScheme{ 92 | Scheme: tpm2.TPMAlgRSAPSS, 93 | Details: tpm2.NewTPMUSigScheme( 94 | tpm2.TPMAlgRSAPSS, 95 | &tpm2.TPMSSchemeHash{ 96 | HashAlg: tpm2.TPMAlgSHA256, 97 | }, 98 | ), 99 | }, 100 | Validation: tpm2.TPMTTKHashCheck{ 101 | Tag: tpm2.TPMSTHashCheck, 102 | }, 103 | } 104 | 105 | rsassa, err := rspSign.Signature.Signature.RSAPSS() 106 | 107 | log.Printf("PSS signature: %s\n", base64.StdEncoding.EncodeToString(rsassa.Sig.Buffer)) 108 | 109 | err = rsa.VerifyPSS(rsaPub, crypto.SHA256, digest[:], rsassa.Sig.Buffer, &rsa.PSSOptions{ 110 | Hash: crypto.SHA256, 111 | SaltLength: rsa.PSSSaltLengthAuto, 112 | }) 113 | 114 | 115 | ``` 116 | -------------------------------------------------------------------------------- /encrypt_with_tpm_rsa/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require golang.org/x/sys v0.15.0 // indirect 13 | -------------------------------------------------------------------------------- /encrypt_with_tpm_rsa/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 h1:LGYp08nFCGgxM/pRoE4etWElLB2WsrhJiBG4jK04MPE= 4 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 16 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 17 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 18 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /event_log/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b 7 | github.com/google/go-tpm v0.3.3-0.20210409082102-d3310770bfec 8 | github.com/google/go-tpm-tools v0.3.0-alpha7.0.20210712215558-1689caf35bff 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /evictcontrol/README.md: -------------------------------------------------------------------------------- 1 | EvictControl a handle to nv 2 | 3 | pg 15 4 | 5 | https://trustedcomputinggroup.org/wp-content/uploads/RegistryOfReservedTPM2HandlesAndLocalities_v1p1_pub.pdf -------------------------------------------------------------------------------- /evictcontrol/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.4 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | 11 | ) 12 | 13 | require golang.org/x/sys v0.8.0 // indirect 14 | -------------------------------------------------------------------------------- /gcp_ek_ak/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.4 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | github.com/google/go-sev-guest v0.6.1 // indirect 14 | github.com/google/logger v1.1.1 // indirect 15 | github.com/google/uuid v1.3.0 // indirect 16 | github.com/pborman/uuid v1.2.0 // indirect 17 | github.com/pkg/errors v0.9.1 // indirect 18 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect 19 | golang.org/x/sys v0.8.0 // indirect 20 | google.golang.org/protobuf v1.28.0 // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /gcp_ek_ak/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 3 | github.com/google/certificate-transparency-go v1.1.2 h1:4hE0GEId6NAW28dFpC+LrRGwQX5dtmXQGDbg8+/MZOM= 4 | github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888 h1:HURgKPRPJSozDuMHpjdV+iyFVLhB6bi1JanhGgSzI1k= 5 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 6 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 7 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 8 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 9 | github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= 10 | github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= 11 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9 h1:+M1aX55KSWVy78gdUsxsqlApZ+p8j/ubS5EmNVFcyWM= 12 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 13 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 14 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 15 | github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= 16 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 17 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 18 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 20 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 21 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 22 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 23 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 24 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 25 | go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= 26 | go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= 27 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 28 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 29 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 30 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= 31 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 32 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 33 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 34 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 35 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 36 | -------------------------------------------------------------------------------- /h2_primary_template/README.md: -------------------------------------------------------------------------------- 1 | Generate a primary using the specified format described in [ASN.1 Specification for TPM 2.0 Key Files](https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html#name-parent) where the template h-2 is described in pg 43 [TCG EK Credential Profile](https://trustedcomputinggroup.org/wp-content/uploads/TCG_IWG_EKCredentialProfile_v2p4_r2_10feb2021.pdf) 2 | 3 | the priamry is formatted for use with openssl 4 | 5 | 6 | ```bash 7 | ## create the primary 8 | 9 | printf '\x00\x00' > unique.dat 10 | tpm2_createprimary -C o -G ecc -g sha256 -c primary.ctx -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u unique.dat 11 | 12 | # create parent 13 | tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx 14 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 15 | 16 | ## sign some data 17 | echo -n "foo" > data.txt 18 | tpm2_sign -c key.ctx -g sha256 -o sig.rssa -f plain data.txt 19 | 20 | xxd -p sig.rssa 21 | 16a4a291d764c318f38ff647f9438ce2f57a49b34a11a608daaf2c6c3341 22 | 6f657ff025dca825b01ec6b3347984e4ba86760f3e4b987f84bbcd43c1e2 23 | c68ba83fcf5bb5ef9e8e379204ac0ccdfd5ed26281bab5b6d12e9e460929 24 | 284a5b1632822e4987833679663538208d83b20d0783b7a2d812c369e271 25 | 0209ffed3b6456b295950eeee1c33f2a0cea2a31c9a05184b461fe70f7bd 26 | 27 | ## generate the PEM representation 28 | tpm2tss-genkey -u key.pub -r key.priv private.pem 29 | 30 | $ cat private.pem 31 | -----BEGIN TSS2 PRIVATE KEY----- 32 | MIICFAYGZ4EFCgEDoAMBAf8CBEAAAAEEggEaARgAAQALAAQAcgAAABAAFAALCAAA 33 | AAAAAQDNmPPx25bcaW/9iWROnkG6GRDk4pZ3ijdhAReacawCEEWfeVQ/3P/FBnl5 34 | bzv0eAZBoyVcAwn+mPyBtTseiLT7Kwr9K/ycy2OccdgVXBEzC7fVHkJ383BO+1eB 35 | BIVnuK5LrnAPUzvqZmT4DrTZSqMvBB1o3YwrMOs7BV7TIwNL7oh/7mXby6J3oIJu 36 | iN012zu5/LeT51rTjcgzx9iSLYiSLCGRyYnGuvQvnzthOVhMaUoAxe9QgsIlVRip 37 | +uDuJpdOUgJZC94exzhnfx5hc4d4csxn+/W4kXpdZ9ix0CEEu4WGku4h1RbS0mqe 38 | fNNMkpIRK1nBgB7j/uRIN3N0gfUtBIHgAN4AINr/5le1aGDuMwzMiuhK4SQrQ5Ww 39 | Bk6oQg7ehZnC545UABBwx6xkUVFRLh7rbVQrw2CDtPDeXY08T4VWWpFbtJzsGrWU 40 | qiXBMVrlAwyCMb1hS126A9s92fAwCR/1nojsbYH/cs3EbJsdYuOo7vMjB5SMkOaB 41 | MxvI96A5WJSmqRgOKbesbn2eRElUTAgL9aLUkJ+AdrVdCCocg6WT2GwHwBckI8Y8 42 | rYp+bAhb97JurBfcp7u4ZRC5nWv5S51BWZ1Kp+lLcFGx+I78EEugZYrijiUqrTeh 43 | EBqFFpOTT9Y= 44 | -----END TSS2 PRIVATE KEY----- 45 | 46 | 47 | $ openssl asn1parse -inform PEM -in private.pem 48 | 0:d=0 hl=4 l= 532 cons: SEQUENCE 49 | 4:d=1 hl=2 l= 6 prim: OBJECT :2.23.133.10.1.3 50 | 12:d=1 hl=2 l= 3 cons: cont [ 0 ] 51 | 14:d=2 hl=2 l= 1 prim: BOOLEAN :255 52 | 17:d=1 hl=2 l= 4 prim: INTEGER :40000001 53 | 23:d=1 hl=4 l= 282 prim: OCTET STRING [HEX DUMP]:01180001000B00040072000000100014000B0800000000000100CD98F3F1DB96DC696FFD89644E9E41BA1910E4E296778A376101179A71AC0210459F79543FDCFFC50679796F3BF4780641A3255C0309FE98FC81B53B1E88B4FB2B0AFD2BFC9CCB639C71D8155C11330BB7D51E4277F3704EFB5781048567B8AE4BAE700F533BEA6664F80EB4D94AA32F041D68DD8C2B30EB3B055ED323034BEE887FEE65DBCBA277A0826E88DD35DB3BB9FCB793E75AD38DC833C7D8922D88922C2191C989C6BAF42F9F3B6139584C694A00C5EF5082C2255518A9FAE0EE26974E5202590BDE1EC738677F1E6173877872CC67FBF5B8917A5D67D8B1D02104BB858692EE21D516D2D26A9E7CD34C9292112B59C1801EE3FEE44837737481F52D 54 | 309:d=1 hl=3 l= 224 prim: OCTET STRING [HEX DUMP]:00DE0020DAFFE657B56860EE330CCC8AE84AE1242B4395B0064EA8420EDE8599C2E78E54001070C7AC645151512E1EEB6D542BC36083B4F0DE5D8D3C4F85565A915BB49CEC1AB594AA25C1315AE5030C8231BD614B5DBA03DB3DD9F030091FF59E88EC6D81FF72CDC46C9B1D62E3A8EEF32307948C90E681331BC8F7A0395894A6A9180E29B7AC6E7D9E4449544C080BF5A2D4909F8076B55D082A1C83A593D86C07C0172423C63CAD8A7E6C085BF7B26EAC17DCA7BBB86510B99D6BF94B9D41599D4AA7E94B7051B1F88EFC104BA0658AE28E252AAD37A1101A851693934FD6 55 | ``` 56 | 57 | 58 | Now load the key using go-tpm and keyfile 59 | 60 | ```bash 61 | 62 | 63 | $ go run main.go 64 | 65 | 2024/05/31 22:06:27 ======= Init ======== 66 | 2024/05/31 22:06:27 signature from go-tpm-tools key : 16a4a291d764c318f38ff647f9438ce2f57a49b34a11a608daaf2c6c33416f657ff025dca825b01ec6b3347984e4ba86760f3e4b987f84bbcd43c1e2c68ba83fcf5bb5ef9e8e379204ac0ccdfd5ed26281bab5b6d12e9e460929284a5b1632822e4987833679663538208d83b20d0783b7a2d812c369e2710209ffed3b6456b295950eeee1c33f2a0cea2a31c9a05184b461fe70f7bd0b333c3d78ff22844c1f9b9543259eec5c6183b3019fcc23ca5002097dcafe38a620023fca79499af7ce15b86c87d644ddc2b3313e52cd2a5b711d7836cfc39f7417e61414d019d5a300e4fcf8ccd9399ddc3137a4c5dd379065e573a1fc0478a8bc407db49f60092613 67 | ``` -------------------------------------------------------------------------------- /h2_primary_template/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240525122353-0883da4eb332 7 | github.com/google/go-tpm v0.9.0 8 | ) 9 | 10 | require ( 11 | golang.org/x/crypto v0.19.0 // indirect 12 | golang.org/x/sys v0.17.0 // indirect 13 | ) -------------------------------------------------------------------------------- /hmac_import/README.md: -------------------------------------------------------------------------------- 1 | ## Importing External HMAC and performing HMAC Signatures 2 | 3 | Simple procedure to import an HMAC key into a TPM and signing some data with it. 4 | 5 | https://github.com/google/go-tpm/issues/249 6 | 7 | 8 | ### Openssl 9 | 10 | ```bash 11 | echo -n "change this password to a secret" | xxd -p -c 100 12 | 6368616e676520746869732070617373776f726420746f206120736563726574 13 | 14 | echo -n foo > data.in 15 | 16 | # openssl dgst -sha256 -mac hmac -macopt hexkey:6368616e676520746869732070617373776f726420746f206120736563726574 data.in 17 | HMAC-SHA256(data.in)= 7c50506d993b4a10e5ae6b33ca951bf2b8c8ac399e0a34026bb0ac469bea3de2 18 | ``` 19 | 20 | ### tpm2_tools 21 | 22 | ```bash 23 | export secret="change this password to a secret" 24 | export plain="foo" 25 | 26 | echo -n $secret > hmac.key 27 | hexkey=$(xxd -p -c 256 < hmac.key) 28 | echo $hexkey 29 | 30 | echo -n $plain > data.in 31 | 32 | openssl dgst -sha256 -mac hmac -macopt hexkey:$hexkey data.in 33 | 34 | 35 | tpm2 createprimary -Q -G rsa -g sha256 -C e -c primary.ctx 36 | tpm2_flushcontext -t 37 | tpm2 import -C primary.ctx -G hmac -i hmac.key -u hmac.pub -r hmac.priv 38 | tpm2_flushcontext -t 39 | tpm2 load -C primary.ctx -u hmac.pub -r hmac.priv -c hmac.ctx 40 | tpm2_flushcontext -t 41 | echo -n $plain | tpm2_hmac -g sha256 -c hmac.ctx | xxd -p -c 256 42 | 7c50506d993b4a10e5ae6b33ca951bf2b8c8ac399e0a34026bb0ac469bea3de2 43 | ``` 44 | -------------------------------------------------------------------------------- /hmac_import/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /hmac_import/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003 h1:gfGQAIxsEEAuYuFvjCGpDnTwisMJOz+rUfJMkk4yTmc= 4 | github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 6 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 7 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 8 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 9 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 10 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 11 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 12 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 13 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 14 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 15 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 16 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 17 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 18 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 19 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 20 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 21 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 22 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 23 | -------------------------------------------------------------------------------- /kdf/README.md: -------------------------------------------------------------------------------- 1 | Snippet which uses `NIST SP 800-108` KDF with Countermode 2 | basically, this is an adaptation of [github.com/hashicorp/vault/sdk/helper/kdf#CounterMode](https://pkg.go.dev/github.com/hashicorp/vault/sdk/helper/kdf#CounterMode). 3 | 4 | but with the HMAC operation using the TPM. 5 | 6 | --- 7 | 8 | the sample below uses a `swtpm` where the hmac key is saved as a PEM encoded file. 9 | 10 | First embed the key: 11 | 12 | ```bash 13 | sudo swtpm_setup --tpmstate myvtpm --tpm2 --create-ek-cert 14 | sudo swtpm socket --tpmstate dir=myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=5 15 | 16 | export TPM2TOOLS_TCTI="swtpm:port=2321" 17 | export TPM2OPENSSL_TCTI="swtpm:port=2321" 18 | 19 | export secret="my_api_key" 20 | echo -n $secret > hmac.key 21 | hexkey=$(xxd -p -c 256 < hmac.key) 22 | echo $hexkey 23 | 24 | printf '\x00\x00' > unique.dat 25 | tpm2_createprimary -C o -G ecc -g sha256 -c primary.ctx -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u unique.dat 26 | 27 | tpm2 import -C primary.ctx -G hmac -i hmac.key -u hmac.pub -r hmac.priv 28 | tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 29 | tpm2 load -C primary.ctx -u hmac.pub -r hmac.priv -c hmac.ctx 30 | tpm2_encodeobject -C primary.ctx -u hmac.pub -r hmac.priv -o tpm-key.pem 31 | ``` 32 | 33 | then if you run, a new key is derived by both the TPM and the default vault library of the same. 34 | 35 | the expected result is the same 36 | 37 | ```bash 38 | $ go run main.go 39 | 2025/04/23 15:52:39 TPM KDF 8ee68b83a24249fd9dcd162921c3f5486f591620a871bedf9efce044d5e74734 40 | 2025/04/23 15:52:39 Vault KDF 8ee68b83a24249fd9dcd162921c3f5486f591620a871bedf9efce044d5e74734 41 | ``` 42 | 43 | -------------------------------------------------------------------------------- /kdf/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.24.0 4 | 5 | require ( 6 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20250323135004-b31fac66206e 7 | github.com/google/go-tpm v0.9.3 8 | github.com/google/go-tpm-tools v0.4.5 9 | github.com/hashicorp/vault/sdk v0.15.2 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.32.0 // indirect 14 | golang.org/x/sys v0.29.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /kdf/go.sum: -------------------------------------------------------------------------------- 1 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20250323135004-b31fac66206e h1:2jjYsGgM13xId2Ku+UGDQTO5It50LhT6lljiVJvBj1Y= 2 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20250323135004-b31fac66206e/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= 3 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= 4 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= 5 | github.com/google/go-configfs-tsm v0.3.3-0.20240919001351-b4b5b84fdcbc h1:SG12DWUUM5igxm+//YX5Yq4vhdoRnOG9HkCodkOn+YU= 6 | github.com/google/go-configfs-tsm v0.3.3-0.20240919001351-b4b5b84fdcbc/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 7 | github.com/google/go-sev-guest v0.12.1 h1:H4rFYnPIn8HtqEsNTmh56Zxcf9BI9n48ZSYCnpYLYvc= 8 | github.com/google/go-sev-guest v0.12.1/go.mod h1:SK9vW+uyfuzYdVN0m8BShL3OQCtXZe/JPF7ZkpD3760= 9 | github.com/google/go-tdx-guest v0.3.2-0.20241009005452-097ee70d0843 h1:+MoPobRN9HrDhGyn6HnF5NYo4uMBKaiFqAtf/D/OB4A= 10 | github.com/google/go-tdx-guest v0.3.2-0.20241009005452-097ee70d0843/go.mod h1:g/n8sKITIT9xRivBUbizo34DTsUm2nN2uU3A662h09g= 11 | github.com/google/go-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc= 12 | github.com/google/go-tpm v0.9.3/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 13 | github.com/google/go-tpm-tools v0.4.5 h1:3fhthtyMDbIZFR5/0y1hvUoZ1Kf4i1eZ7C73R4Pvd+k= 14 | github.com/google/go-tpm-tools v0.4.5/go.mod h1:ktjTNq8yZFD6TzdBFefUfen96rF3NpYwpSb2d8bc+Y8= 15 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 16 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 17 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 18 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 | github.com/hashicorp/vault/sdk v0.15.2 h1:Rp5Yp4lyBhlWgq24ZVb2n/YN47RKOAvmx/jlMfS9ku4= 20 | github.com/hashicorp/vault/sdk v0.15.2/go.mod h1:2Wj2tHIgfz0gNWgEPWBbCXFIiPrq96E8FTjPNV9J1Bc= 21 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 22 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 23 | golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= 24 | golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= 25 | golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= 26 | golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 27 | google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= 28 | google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 29 | -------------------------------------------------------------------------------- /keyfile-go-tpm-tools/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## go-tpm-tools.client.Key compatibility with go-keyfile 4 | 5 | the following will 6 | 7 | 0. create a primary key with password 8 | 1. create a key using `go-tpm` password 9 | 2. use save it to disk as `TSS PRIVATE KEY` using `go-keyfile` 10 | 3. generate a test signature using `go-tpm` 11 | 4. close tpm 12 | 5. reload the key from file using `go-keyfile` 13 | 6. construct a `go-tpm-tools.client.Key` 14 | 7. skip generate a test signature using `go-tpm-tools` (because go-tpm singers expects null password) 15 | 8. convert `go-tpm-tools.client.Key` values for use with `go-tpm` 16 | 9. generate a test signature using `go-tpm` with transport encryption 17 | 18 | 19 | -------------------------------------------------------------------------------- /keyfile-go-tpm-tools/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240805214234-f870d6f1ff68 9 | github.com/google/go-tpm v0.9.1-0.20240514145214-58e3e47cd434 10 | github.com/google/go-tpm-tools v0.4.4 11 | ) 12 | 13 | require ( 14 | github.com/golang/protobuf v1.5.4 // indirect 15 | github.com/google/go-configfs-tsm v0.2.2 // indirect 16 | github.com/google/go-sev-guest v0.9.3 // indirect 17 | github.com/google/go-tdx-guest v0.3.1 // indirect 18 | github.com/google/logger v1.1.1 // indirect 19 | github.com/google/uuid v1.6.0 // indirect 20 | github.com/pborman/uuid v1.2.1 // indirect 21 | github.com/pkg/errors v0.9.1 // indirect 22 | go.uber.org/multierr v1.11.0 // indirect 23 | golang.org/x/crypto v0.23.0 // indirect 24 | golang.org/x/sys v0.21.0 // indirect 25 | google.golang.org/protobuf v1.34.1 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /keyfile-go-tpm-tools/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240805214234-f870d6f1ff68 h1:u1Lbb2hWuU302IAaCccDkzPWLgpMBfvva/EMDutEUXk= 4 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240805214234-f870d6f1ff68/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= 5 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= 6 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= 7 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 8 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 9 | github.com/google/certificate-transparency-go v1.1.2 h1:4hE0GEId6NAW28dFpC+LrRGwQX5dtmXQGDbg8+/MZOM= 10 | github.com/google/certificate-transparency-go v1.1.2/go.mod h1:3OL+HKDqHPUfdKrHVQxO6T8nDLO0HF7LRTlkIWXaWvQ= 11 | github.com/google/go-attestation v0.5.0 h1:jXtAWT2sw2Yu8mYU0BC7FDidR+ngxFPSE+pl6IUu3/0= 12 | github.com/google/go-attestation v0.5.0/go.mod h1:0Tik9y3rzV649Jcr7evbljQHQAsIlJucyqQjYDBqktU= 13 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 14 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 15 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 16 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 17 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 18 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 19 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 20 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 21 | github.com/google/go-tpm v0.9.1-0.20240514145214-58e3e47cd434 h1:uPadaCeI0VnloLvthGLalr0Io0IDoI1VEQ95APzVAiw= 22 | github.com/google/go-tpm v0.9.1-0.20240514145214-58e3e47cd434/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 23 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 24 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 25 | github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= 26 | github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= 27 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 28 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 29 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 30 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 31 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 32 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 33 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 34 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 35 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 36 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 37 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 38 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= 39 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 40 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 41 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 42 | golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= 43 | golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= 44 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 45 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 46 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 47 | google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 48 | google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 49 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 50 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 51 | -------------------------------------------------------------------------------- /keyfile-go-tpm-tools/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN TSS2 PRIVATE KEY----- 2 | MIIEEQYGZ4EFCgEDAgUAgAAAAASCARoBGAABAAsABAByAAAAEAAUAAsIAAAAAAAB 3 | ANl/BpkIr701w5bCVwKuZ0AWG3Qy5SrgJExufmJR+XROqT5MAvVhcDPdivq5DZl3 4 | Ns14829rXch/fcBLepwxEN54EIX2MiyiyrSXYGYLcsO2ppZEeYa88TxdTqB2g82W 5 | 38O4xZ5PwsW7HhaEszUFX4Bcrah1B0nFrjfK/+TsHMNoLWy5uLhxczrT8IRIuOJO 6 | MI8AoU8QuRGhny7OZFuQzrXVDG73MTkuMQWzMXLtXvnkr5lT52OMS39zwtXV0BR6 7 | Z5s2OfIWg+5lIZ6wtVj8rjQA49/Av+moZBY81NsJHYhfdysMxM3fKATLIcuTEH7z 8 | jNdcU8e4KLIpyT/t32HsP9UEggLgAt4AIC7hhSwGt5h2aOTv3EUI1IJkkPef1zL1 9 | 9uk5VqEiADSXABAdtorXLCZNUDHuccbfYyDUr65ya9HrLJL3FoKhBLxVV+fZ4C6D 10 | DcpKIqaiAXgfqSZ9eNevbrMPyUUq9O77SJGyE1L0nMovaarhZZFKrEZf8UdwH+R0 11 | D2j1m2ogP0LXPC+eV1Bq3jFlyqvRd2Uo6rZZ7yb/Zk16LlXeDYavErdl0AJc1OfP 12 | wV1nDSmnWrYwQEpLy2J+R8jETfLU0JTFTVS/qen4Q7L4Yep2lSurhQb9OJufMpyO 13 | lnYUe2xCleTSU4VmqhfJdns8cuUeSGr1CwRwHOCsZpG5nukLoi9l1qbGMyJwbPP5 14 | SNtQkuiO5gWwtoVMXMcCJ8M4HiwSiaX3DzHym9gmDaNikd1z8bmzL8T38ZBv7/8j 15 | 659NuVZ4y5pmRcT/qRzCHUrWSMKbRqWByVx+KGUu9XYGvqf+Y6y/N1hTPO7TD/yj 16 | D0BlE3wRIT8vdguo21epTcHNNIPDME2aPn1rgIH6fQKBRTQbY6OLa0GMlQL3TS5i 17 | QdvbCFTXSXOCQ0NtL2/pdhhfdDxuYc6u7slu0fCUUm1oUHMJCeH4fMOM4v2gQULi 18 | v12o41S6AbWk+cOUEa23BD7wfXcZlyMzSFZER44IW/dVrsBUXuBguBeCZXwJe4vS 19 | ctZRjd2es1aBBSyGgYY25x4kRk0NtvMFRL1WmvG0+zGEN3Z06l+uy2Ry4lc4trzq 20 | R8qtvYRhct3KWFmsI4UR57B3TzNCOsC0YBms9zEdg2qFBwiRP9fTGO/JaHKEC9Wp 21 | TFzaGL6SF1k6uY0waWp9nb6wikcZ3o5X7Qxky088mIxbOHQEA+owRR9LhnsqFi47 22 | MPE0+QSmO27QcVYSFSci5+7QRmNXL6qYngrDdzsi2DFXYd9ZOIqET9+ucPH/DkRn 23 | H70Q9G/Ys8RD/u1O9EIQan8NwBsrdERavscYpZiJNrzIJuhB6A== 24 | -----END TSS2 PRIVATE KEY----- 25 | -------------------------------------------------------------------------------- /luks/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Procedure to use the TPM to do LUKS encryption 4 | 5 | really, just see 6 | 7 | - [https://tpm2-software.github.io/2020/04/13/Disk-Encryption.html](https://tpm2-software.github.io/2020/04/13/Disk-Encryption.html) 8 | 9 | 10 | 11 | First mount the luks volume with a known passphrase 12 | 13 | ```bash 14 | $ export luks=137d045fa3897b6fea06d8c9767b7387 15 | $ echo -n $luks | cryptsetup luksOpen /dev/sdb vault_encrypted_volume - 16 | $ mount /dev/mapper/vault_encrypted_volume /mnt/disks/luks/ 17 | 18 | 19 | $ lsblk 20 | NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT 21 | sda 8:0 0 10G 0 disk 22 | ├─sda1 8:1 0 9.9G 0 part / 23 | ├─sda14 8:14 0 4M 0 part 24 | └─sda15 8:15 0 106M 0 part /boot/efi 25 | sdb 8:16 0 10G 0 disk 26 | └─vault_encrypted_volume 253:0 0 10G 0 crypt /mnt/disks/luks 27 | 28 | $ umount /mnt/disks/luks 29 | $ cryptsetup luksClose /dev/mapper/vault_encrypted_volume 30 | ``` 31 | 32 | 33 | Now seal that passphrase to the TPM at the persistent handle `0x81010001` 34 | 35 | ```bash 36 | $ tpm2_createprimary -Q -C o -c prim.ctx 37 | $ echo $luks | tpm2_create -Q -g sha256 -u seal.pub -r seal.priv -i- -C prim.ctx 38 | $ tpm2_load -Q -C prim.ctx -u seal.pub -r seal.priv -n seal.name -c seal.ctx 39 | $ tpm2_evictcontrol -C o -c seal.ctx 0x81010001 40 | 41 | 42 | $ tpm2_unseal -Q -c 0x81010001 | xxd -p 43 | 137d045fa3897b6fea06d8c9767b7387 44 | ``` 45 | 46 | Use that tpm backed key to unseal 47 | 48 | ```bash 49 | $ tpm2_unseal -Q -c 0x81010001 | xxd -p | cryptsetup luksOpen /dev/sdb vault_encrypted_volume 50 | $ mount /dev/mapper/vault_encrypted_volume /mnt/disks/luks/ 51 | ``` 52 | 53 | See the link above to seal to PCR value on boot and then extend the binding PCR value (to prevent a user (root) from subsequently accessing the secret at runtime) 54 | -------------------------------------------------------------------------------- /nv/README.md: -------------------------------------------------------------------------------- 1 | 2 | list persistent handles 3 | 4 | ```bash 5 | # tpm2_getcap handles-persistent 6 | - 0x81008000 7 | ``` 8 | 9 | https://github.com/tpm2-software/tpm2-tools/blob/master/test/integration/tests/nv.sh 10 | 11 | ```bash 12 | 1) BASIC 13 | tpm2_nvundefine -C o 1 14 | tpm2 nvdefine 1 -C o -s 12 -a "ownerread|ownerwrite" 15 | echo -n "please123abc" > nv.test_w 16 | tpm2_nvreadpublic 17 | tpm2 nvwrite -Q 1 -C o -i nv.test_w 18 | tpm2 nvread 1 -C o -s 12 | xxd - 19 | ``` 20 | 21 | 2) Policy written to NV 22 | https://github.com/tpm2-software/tpm2-tools/blob/master/man/tpm2_policyauthorizenv.1.md 23 | 24 | ```bash 25 | tpm2_nvundefine -C o 1 26 | tpm2_nvdefine -C o -a "authread|authwrite" -s 34 1 27 | 28 | tpm2_startauthsession -S session.dat 29 | tpm2_policypcr -S session.dat -l sha256:23 -L policy.dat 30 | tpm2_flushcontext session.dat 31 | 32 | echo "000b" | xxd -p -r | cat - policy.dat | tpm2_nvwrite -C 1 1 -i - 33 | 34 | tpm2_startauthsession -S session.ctx 35 | tpm2_policyauthorizenv -S session.ctx -C 1 -L policyauthorizenv.dat 1 36 | tpm2_flushcontext session.ctx 37 | 38 | tpm2_createprimary -C o -c prim.ctx 39 | echo "secretdata" | tpm2_create -C prim.ctx -u key.pub -r key.priv -a "fixedtpm|fixedparent|adminwithpolicy" -L policyauthorizenv.dat -i - 40 | 41 | tpm2_load -C prim.ctx -u key.pub -r key.priv -c key.ctx 42 | tpm2_pcrread sha256:23 -o pcr23_val.bin 43 | 44 | tpm2_startauthsession -S session.ctx --policy-session 45 | tpm2_policypcr -S session.ctx -l sha256:23 -f pcr23_val.bin 46 | tpm2_policyauthorizenv -S session.ctx -C 1 1 47 | 48 | tpm2_unseal -c key.ctx -p session:session.ctx 49 | tpm2_flushcontext session.ctx 50 | ``` 51 | 52 | 3) NV with PCR policy 53 | 54 | ```bash 55 | tpm2_pcrread -o measured.pcrvalues sha256:23 56 | sha256: 57 | 23: 0xF5A5FD42D16A20302798EF6ED309979B43003D2320D9F0E8EA9831A92759FB4B 58 | 59 | tpm2_createpolicy --policy-pcr -l sha256:23 -f measured.pcrvalues -L measured.policy 60 | 61 | tpm2_nvdefine 0x1500016 -C o -s 32 -L measured.policy -a "policyread|policywrite" 62 | 63 | echo -n "fooo secret" > secret.txt 64 | 65 | tpm2_nvwrite 0x1500016 -C 0x1500016 -P pcr:sha256:23=measured.pcrvalues -i secret.txt 66 | tpm2_nvread 0x1500016 -C 0x1500016 -P pcr:sha256:23=measured.pcrvalues 67 | ``` 68 | 69 | 4) Read EKCert RSA from NV 70 | 71 | from pg 13 of [TCG EK Credential Profile](https://trustedcomputinggroup.org/wp-content/uploads/TCG_IWG_EKCredentialProfile_v2p4_r3.pdf) 72 | 73 | ``` 74 | 2.2.1.4 Low Range 75 | The Low Range is at NV Indices 0x01c00002 - 0x01c0000c. 76 | 0x01c00002 RSA 2048 EK Certificate 77 | 0x01c00003 RSA 2048 EK Nonce 78 | 0x01c00004 RSA 2048 EK Template 79 | 0x01c0000a ECC NIST P256 EK Certificate 80 | 0x01c0000b ECC NIST P256 EK Nonce 81 | 0x01c0000c ECC NIST P256 EK Template 82 | ``` 83 | 84 | Note, omit the `0` prefix 85 | 86 | ```bash 87 | export TPM2_EK_NV_INDEX=0x1c00002 88 | tpm2_nvreadpublic | sed -n -e "/""$TPM2_EK_NV_INDEX""/,\$p" | sed -e '/^[ \r\n\t]*$/,$d' | grep "size" | sed 's/.*size.*://' | sed -e 's/^[[:space:]]*//' | sed -e 's/[[:space:]]$//' 89 | # the ouput data size will be diferent 90 | 91 | 92 | tpm2_nvread -s 1422 -C o $TPM2_EK_NV_INDEX | openssl x509 --inform DER -text -noout -in - 93 | ``` 94 | 95 | 96 | 97 | =============== 98 | 99 | 5) Write and Read from NV 100 | 101 | ```bash 102 | go run nv_basic/main.go 103 | ``` 104 | 105 | 6) Read NV as buffers 106 | 107 | 108 | 109 | ```bash 110 | #### constants at: https://pkg.go.dev/github.com/google/go-tpm-tools/client#pkg-constants 111 | 112 | # gcloud compute instances create instance-1 \ 113 | # --zone=us-central1-a \ 114 | # --machine-type=n2d-standard-2 --min-cpu-platform="AMD Milan" \ 115 | # --shielded-secure-boot --no-service-account --no-scopes \ 116 | # --shielded-vtpm \ 117 | # --shielded-integrity-monitoring \ 118 | # --confidential-compute 119 | 120 | 121 | # $ gcloud compute instances get-shielded-identity instance-1 122 | 123 | 124 | # TPM2_EK_NV_INDEX=0x1c10000 125 | # tpm2_nvreadpublic | sed -n -e "/""$TPM2_EK_NV_INDEX""/,\$p" | sed -e '/^[ \r\n\t]*$/,$d' | grep "size" | sed 's/.*size.*://' | sed -e 's/^[[:space:]]*//' | sed -e 's/[[:space:]]$//' 126 | # 1516 127 | # tpm2_nvread -s 1516 -C o $TPM2_EK_NV_INDEX | openssl x509 --inform DER -text -noout -in - 128 | 129 | 130 | go run nv_buffer/main.go 131 | ``` -------------------------------------------------------------------------------- /nv/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require golang.org/x/sys v0.15.0 // indirect 13 | 14 | // replace ( 15 | // github.com/google/go-tpm => "./go-tpm" 16 | // ) 17 | -------------------------------------------------------------------------------- /nv/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 4 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 16 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 17 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 18 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /nv/nv_basic/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "io" 6 | "log" 7 | "net" 8 | "slices" 9 | 10 | //"github.com/google/go-tpm/tpm2" 11 | 12 | "github.com/google/go-tpm-tools/simulator" 13 | "github.com/google/go-tpm/tpm2" 14 | "github.com/google/go-tpm/tpm2/transport" 15 | "github.com/google/go-tpm/tpmutil" 16 | ) 17 | 18 | const ( 19 | keyPassword = "keypwd" 20 | ) 21 | 22 | var ( 23 | tpmPath = flag.String("tpm-path", "simulator", "Path to the TPM device (character device or a Unix socket).") 24 | nv = flag.Uint("nv", 0x1500000, "nv to use") 25 | nvdata = flag.String("nvdata", "foo", "nv data") 26 | ) 27 | 28 | var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"} 29 | 30 | func OpenTPM(path string) (io.ReadWriteCloser, error) { 31 | if slices.Contains(TPMDEVICES, path) { 32 | return tpmutil.OpenTPM(path) 33 | } else if path == "simulator" { 34 | return simulator.GetWithFixedSeedInsecure(1073741825) 35 | } else { 36 | return net.Dial("tcp", path) 37 | } 38 | } 39 | 40 | func main() { 41 | flag.Parse() 42 | 43 | rwc, err := OpenTPM(*tpmPath) 44 | if err != nil { 45 | log.Fatalf("can't open TPM %q: %v", *tpmPath, err) 46 | } 47 | defer func() { 48 | if err := rwc.Close(); err != nil { 49 | log.Fatalf("can't close TPM %q: %v", *tpmPath, err) 50 | } 51 | }() 52 | 53 | rwr := transport.FromReadWriter(rwc) 54 | 55 | log.Printf("======= createPrimary ========") 56 | 57 | defs := tpm2.NVDefineSpace{ 58 | AuthHandle: tpm2.TPMRHOwner, 59 | // Auth: tpm2.TPM2BAuth{ 60 | // Buffer: []byte("p@ssw0rd"), 61 | // }, 62 | PublicInfo: tpm2.New2B( 63 | tpm2.TPMSNVPublic{ 64 | NVIndex: tpm2.TPMHandle(*nv), 65 | NameAlg: tpm2.TPMAlgSHA256, 66 | Attributes: tpm2.TPMANV{ 67 | OwnerWrite: true, 68 | OwnerRead: true, 69 | AuthWrite: true, 70 | AuthRead: true, 71 | NT: tpm2.TPMNTOrdinary, 72 | NoDA: true, 73 | }, 74 | DataSize: 4, 75 | }), 76 | } 77 | 78 | pub, err := defs.PublicInfo.Contents() 79 | if err != nil { 80 | log.Fatalf("%v", err) 81 | } 82 | nvName, err := tpm2.NVName(pub) 83 | if err != nil { 84 | log.Fatalf("Calculating name of NV index: %v", err) 85 | } 86 | 87 | _, err = defs.Execute(rwr) 88 | if err != nil { 89 | log.Fatalf("error executing PolicyPCR: %v", err) 90 | } 91 | 92 | prewrite := tpm2.NVWrite{ 93 | AuthHandle: tpm2.AuthHandle{ 94 | Handle: pub.NVIndex, 95 | Name: *nvName, 96 | Auth: tpm2.HMAC(tpm2.TPMAlgSHA256, 16, tpm2.Auth([]byte{})), //tpm2.PasswordAuth([]byte("p@ssw0rd")), 97 | }, 98 | NVIndex: tpm2.NamedHandle{ 99 | Handle: pub.NVIndex, 100 | Name: *nvName, 101 | }, 102 | Data: tpm2.TPM2BMaxNVBuffer{ 103 | Buffer: []byte("fooo"), 104 | }, 105 | Offset: 0, 106 | } 107 | if _, err := prewrite.Execute(rwr); err != nil { 108 | log.Fatalf("Calling TPM2_NV_Write: %v", err) 109 | } 110 | 111 | readPubRsp, err := tpm2.NVReadPublic{ 112 | NVIndex: pub.NVIndex, 113 | }.Execute(rwr) 114 | if err != nil { 115 | log.Fatalf("Calling TPM2_NV_ReadPublic: %v", err) 116 | } 117 | log.Printf("Name: %x", readPubRsp.NVName.Buffer) 118 | 119 | readRsp, err := tpm2.NVRead{ 120 | AuthHandle: tpm2.AuthHandle{ 121 | Handle: tpm2.TPMRHOwner, 122 | Auth: tpm2.HMAC(tpm2.TPMAlgSHA256, 16, tpm2.Auth([]byte{})), //tpm2.PasswordAuth([]byte("")), //tpm2.HMAC(tpm2.TPMAlgSHA256, 16, tpm2.Auth([]byte("p@ssw0rd"))), 123 | }, 124 | NVIndex: tpm2.NamedHandle{ 125 | Handle: pub.NVIndex, 126 | Name: readPubRsp.NVName, 127 | }, 128 | Size: 4, 129 | }.Execute(rwr) 130 | if err != nil { 131 | log.Fatalf("Calling Read: %v", err) 132 | } 133 | log.Printf("Name: %s", string(readRsp.Data.Buffer)) 134 | } 135 | -------------------------------------------------------------------------------- /password/README.md: -------------------------------------------------------------------------------- 1 | ### Encrypt/Decrypt with AES and auth passwords 2 | 3 | auth password set on both the parent and key 4 | 5 | 6 | 7 | ```bash 8 | ## using swtpm: 9 | # rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm && sudo swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear 10 | export TPM2TOOLS_TCTI="swtpm:port=2321" 11 | 12 | 13 | echo "foo" > secret.dat 14 | openssl rand -out iv.bin 16 15 | 16 | tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx -p primarypwd 17 | tpm2_flushcontext -t 18 | tpm2_create -g sha256 -G aes -u key.pub -r key.priv -C primary.ctx -p keypwd -P primarypwd 19 | tpm2_flushcontext -t 20 | tpm2_load -C primary.ctx -u key.pub -r key.priv -n key.name -c aes.ctx -P primarypwd 21 | tpm2_flushcontext -t 22 | 23 | tpm2_encryptdecrypt --iv iv.bin -c aes.ctx -o cipher.out -p bar secret.dat -p keypwd 24 | tpm2_encryptdecrypt --iv iv.bin -c aes.ctx -d -o plain.out -p bar cipher.out -p keypwd 25 | ``` 26 | 27 | 28 | note, the go-tpm example uses encryptdecrypt2 which isn't supported as of 6/18/24. i have it working locally and will file a PR against go-tpm shortly -------------------------------------------------------------------------------- /password/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require golang.org/x/sys v0.15.0 // indirect 13 | 14 | // replace github.com/google/go-tpm => ./go-tpm 15 | -------------------------------------------------------------------------------- /pcr_utils/README.md: -------------------------------------------------------------------------------- 1 | 2 | # PCR Read and Extend 3 | 4 | Reads PCR value 5 | 6 | ```bash 7 | $ go run main.go --mode=read --pcr=23 -v 10 -alsologtostderr 8 | 9 | I1006 12:22:28.485244 10509 main.go:66] ======= Print PCR ======== 10 | I1006 12:22:28.487989 10509 main.go:71] PCR(23) 536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c 11 | ``` 12 | 13 | 14 | Increments PCR value 15 | 16 | ```bash 17 | $ go run main.go --mode=extend --pcr=23 -v 10 -alsologtostderr 18 | 19 | I1006 12:22:33.498722 10542 main.go:74] ======= Extend PCR ======== 20 | I1006 12:22:33.501522 10542 main.go:79] Current PCR(23) 536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c 21 | I1006 12:22:33.505490 10542 main.go:92] New PCR(23) 9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30 22 | ``` -------------------------------------------------------------------------------- /pcr_utils/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require golang.org/x/sys v0.15.0 // indirect 13 | -------------------------------------------------------------------------------- /pcr_utils/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 h1:LGYp08nFCGgxM/pRoE4etWElLB2WsrhJiBG4jK04MPE= 4 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 6 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 7 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 8 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 9 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 10 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 11 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 12 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 13 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 14 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 15 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 16 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 17 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 18 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 19 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 20 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 21 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 22 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 23 | -------------------------------------------------------------------------------- /pcr_utils/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // go run main.go --mode=read --pcr=1 -v 10 -alsologtostderr 4 | import ( 5 | "encoding/hex" 6 | "flag" 7 | "io" 8 | "log" 9 | "net" 10 | "slices" 11 | 12 | "github.com/google/go-tpm-tools/simulator" 13 | "github.com/google/go-tpm/tpm2" 14 | "github.com/google/go-tpm/tpm2/transport" 15 | "github.com/google/go-tpm/tpmutil" 16 | ) 17 | 18 | var ( 19 | tpmPath = flag.String("tpm-path", "simulator", "Path to the TPM device (character device or a Unix socket).") 20 | mode = flag.String("mode", "read", "read or extend PCR value") 21 | pcr = flag.Uint("pcr", 23, "PCR Value to read or extend") 22 | ) 23 | 24 | var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"} 25 | 26 | func OpenTPM(path string) (io.ReadWriteCloser, error) { 27 | if slices.Contains(TPMDEVICES, path) { 28 | return tpmutil.OpenTPM(path) 29 | } else if path == "simulator" { 30 | return simulator.GetWithFixedSeedInsecure(1073741825) 31 | } else { 32 | return net.Dial("tcp", path) 33 | } 34 | } 35 | 36 | func main() { 37 | flag.Parse() 38 | 39 | rwc, err := OpenTPM(*tpmPath) 40 | if err != nil { 41 | log.Fatalf("can't open TPM %q: %v", *tpmPath, err) 42 | } 43 | defer func() { 44 | if err := rwc.Close(); err != nil { 45 | log.Fatalf("can't close TPM %q: %v", *tpmPath, err) 46 | } 47 | }() 48 | 49 | rwr := transport.FromReadWriter(rwc) 50 | 51 | if *mode == "read" { 52 | 53 | pcrReadRsp, err := tpm2.PCRRead{ 54 | PCRSelectionIn: tpm2.TPMLPCRSelection{ 55 | PCRSelections: []tpm2.TPMSPCRSelection{ 56 | { 57 | Hash: tpm2.TPMAlgSHA256, 58 | PCRSelect: tpm2.PCClientCompatible.PCRs(*pcr), 59 | }, 60 | }, 61 | }, 62 | }.Execute(rwr) 63 | if err != nil { 64 | panic(err) 65 | } 66 | 67 | for _, d := range pcrReadRsp.PCRValues.Digests { 68 | log.Printf("hex: %s\n", hex.EncodeToString(d.Buffer)) 69 | } 70 | 71 | } else if *mode == "extend" { 72 | log.Printf("======= Extend PCR ========") 73 | pcrReadRsp, err := tpm2.PCRRead{ 74 | PCRSelectionIn: tpm2.TPMLPCRSelection{ 75 | PCRSelections: []tpm2.TPMSPCRSelection{ 76 | { 77 | Hash: tpm2.TPMAlgSHA256, 78 | PCRSelect: tpm2.PCClientCompatible.PCRs(*pcr), 79 | }, 80 | }, 81 | }, 82 | }.Execute(rwr) 83 | if err != nil { 84 | panic(err) 85 | } 86 | for _, d := range pcrReadRsp.PCRValues.Digests { 87 | log.Printf("hex: %s\n", hex.EncodeToString(d.Buffer)) 88 | } 89 | _, err = tpm2.PCRExtend{ 90 | PCRHandle: tpm2.AuthHandle{ 91 | Handle: tpm2.TPMHandle(uint32(*pcr)), 92 | Auth: tpm2.PasswordAuth(nil), 93 | }, 94 | Digests: tpm2.TPMLDigestValues{ 95 | Digests: []tpm2.TPMTHA{ 96 | { 97 | HashAlg: tpm2.TPMAlgSHA256, 98 | Digest: pcrReadRsp.PCRValues.Digests[0].Buffer, 99 | }, 100 | }, 101 | }, 102 | }.Execute(rwr) 103 | if err != nil { 104 | panic(err) 105 | } 106 | 107 | pcrReadRsp, err = tpm2.PCRRead{ 108 | PCRSelectionIn: tpm2.TPMLPCRSelection{ 109 | PCRSelections: []tpm2.TPMSPCRSelection{ 110 | { 111 | Hash: tpm2.TPMAlgSHA256, 112 | PCRSelect: tpm2.PCClientCompatible.PCRs(*pcr), 113 | }, 114 | }, 115 | }, 116 | }.Execute(rwr) 117 | if err != nil { 118 | panic(err) 119 | } 120 | 121 | for _, d := range pcrReadRsp.PCRValues.Digests { 122 | log.Printf("hex: %s\n", hex.EncodeToString(d.Buffer)) 123 | } 124 | 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /policy/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9 9 | github.com/google/go-tpm-tools v0.4.4 10 | ) 11 | 12 | require ( 13 | github.com/google/go-sev-guest v0.11.1 // indirect 14 | github.com/google/logger v1.1.1 // indirect 15 | github.com/google/uuid v1.6.0 // indirect 16 | github.com/pborman/uuid v1.2.1 // indirect 17 | github.com/pkg/errors v0.9.1 // indirect 18 | golang.org/x/crypto v0.28.0 // indirect 19 | golang.org/x/sys v0.26.0 // indirect 20 | google.golang.org/protobuf v1.35.1 // indirect 21 | ) 22 | 23 | // replace ( 24 | // github.com/google/go-tpm => "./go-tpm" 25 | // ) 26 | -------------------------------------------------------------------------------- /policy_gen/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.4 6 | 7 | require ( 8 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20241207144721-04534a2f2feb 9 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9 10 | github.com/google/go-tpm-tools v0.4.4 11 | github.com/salrashid123/tpm2genkey v0.0.66-0.20241220122222-196b340ea185 12 | //github.com/salrashid123/tpm2genkey v0.0.0 13 | ) 14 | 15 | require ( 16 | golang.org/x/crypto v0.19.0 // indirect 17 | golang.org/x/sys v0.21.0 // indirect 18 | ) 19 | 20 | // replace ( 21 | // github.com/salrashid123/tpm2genkey => "./tpm2genkey" 22 | // ) 23 | -------------------------------------------------------------------------------- /policy_gen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20241207144721-04534a2f2feb h1:kwNzot0LHHST1wdN8zP5hSWITzPubfEZlwyRspMAzFg= 2 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20241207144721-04534a2f2feb/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= 3 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= 4 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= 5 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 6 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 7 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 8 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 9 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 10 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 11 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 12 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 13 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9 h1:+M1aX55KSWVy78gdUsxsqlApZ+p8j/ubS5EmNVFcyWM= 14 | github.com/google/go-tpm v0.9.2-0.20240920144513-364d5f2f78b9/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 15 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 16 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 17 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 18 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 19 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 20 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 21 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 22 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 23 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 24 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 25 | github.com/salrashid123/tpm2genkey v0.0.66-0.20241220122222-196b340ea185 h1:kGt7GeSv+X9WE2kAl8Ndk8zVTXcdkn+02UVcRDnPbTc= 26 | github.com/salrashid123/tpm2genkey v0.0.66-0.20241220122222-196b340ea185/go.mod h1:xSfcIVR14h5amG2e5xsULbIyMSS9dWTFaGCTrZ0uwuI= 27 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 28 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 29 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 30 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 31 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 32 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 33 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 34 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 35 | -------------------------------------------------------------------------------- /policy_gen/images/authsession.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/policy_gen/images/authsession.png -------------------------------------------------------------------------------- /policy_gen/images/command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/policy_gen/images/command.png -------------------------------------------------------------------------------- /policy_gen/images/parameters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/policy_gen/images/parameters.png -------------------------------------------------------------------------------- /policy_gen/trace.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/policy_gen/trace.cap -------------------------------------------------------------------------------- /pytss/README.md: -------------------------------------------------------------------------------- 1 | ## Python ESAPI and FAPI examples 2 | 3 | 4 | Ref: 5 | 6 | * [https://tpm2-pytss.readthedocs.io/en/latest/api.html](https://tpm2-pytss.readthedocs.io/en/latest/api.html) 7 | * [/P_RSA2048SHA256.json](https://github.com/tpm2-software/tpm2-tss/blob/master/dist/fapi-profiles/P_RSA2048SHA256.json) 8 | * [fapi-config](https://github.com/tpm2-software/tpm2-tss/blob/master/doc/fapi-config.md) 9 | 10 | * [TSS_FAPI_v0p94_r09_pub.pdf](https://trustedcomputinggroup.org/wp-content/uploads/TSS_FAPI_v0p94_r09_pub.pdf) 11 | * [TSS_JSON_Policy_v0p7_r08_pub](https://trustedcomputinggroup.org/wp-content/uploads/TSS_JSON_Policy_v0p7_r08_pub.pdf) 12 | 13 | #### Install 14 | 15 | ```bash 16 | apt-get install libtss2-dev 17 | python3 -m pip install tpm2-pytss 18 | ``` 19 | 20 | 21 | ### ESAPI 22 | 23 | - `esapi_create_sign.py`: create rsa key and sign/verify 24 | - `esapi_encrypt_decrypt.py`: create aes key and encrypt/decrypt 25 | - `esapi_hmac_import.py`: import and use an hmac key 26 | - `esapi_keyfile.py`: create and use PEM encoded keyfiles 27 | - `esapi_auth.py`: create key with auth password 28 | - `esapi_pcr.py`: create key with pcrpolicy 29 | - `esapi_session_encryption_auth.py`: encrypted sessions with password AES 30 | - `esapi_session_encryption_pcr.py`: encrypted sessions with pcr policy AES 31 | - `esapi_session_encryption_authvalue_pcr_aes.py`: encrypted sessions with pcr and authvalue AES 32 | - `esapi_session_encryption_authvalue_pcr_rsa.py`: encrypted sessions with pcr and authvalue RSA 33 | - `esapi_tpm2.py`: load key created using tpm2_tools 34 | 35 | - `fapi_create_sign.py`: create rsa key and sign/verify 36 | - `fapi_seal_unseal.py`: seal/unseal 37 | - `fapi_import_tpm2.py`: import pub/priv keys generated by tpm2tools into fapi contexts 38 | - `fapi_export_tpm2.py`: export key fapi context to pub/priv blobs readable by tpm2tools 39 | - `fapi_auth.py`: create key and bind to password auth with callback 40 | - `fapi_pcr.py`: create key and bind to pcr policy 41 | 42 | ### Policy JSON 43 | 44 | [JSON Data Types and Policy Language Specification](https://trustedcomputinggroup.org/resource/tcg-tss-json/) 45 | 46 | 47 | ### ESAPI Session Encryption 48 | 49 | From : [TCG_CPU_TPM_Bus_Protection_Guidance_Passive_Attack_Mitigation](https://trustedcomputinggroup.org/wp-content/uploads/TCG_CPU_TPM_Bus_Protection_Guidance_Passive_Attack_Mitigation_8May23-3.pdf) 50 | 51 | ``` 52 | • Application developers typically use the high-level TCG Feature API (FAPI) [3]. A compliant TSS 53 | implementation of FAPI automatically encrypts commands and responses, and no work is required by 54 | application developers. 55 | ``` 56 | 57 | 58 | ```bash 59 | rm -rf ~/.local/share/tpm2-tss/ 60 | rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm 61 | sudo swtpm_setup --tpmstate /tmp/myvtpm --tpm2 --create-ek-cert 62 | sudo swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=5 63 | 64 | export TPM2TOOLS_TCTI="swtpm:port=2321" 65 | export TPM2OPENSSL_TCTI="swtpm:port=2321" 66 | 67 | tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 68 | ``` 69 | -------------------------------------------------------------------------------- /pytss/esapi_auth.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | from cryptography.hazmat.primitives import hashes 4 | from cryptography.hazmat.backends import default_backend 5 | 6 | def sha256(data: bytes) -> bytes: 7 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 8 | digest.update(data) 9 | digest = digest.finalize() 10 | return digest 11 | 12 | ectx = ESAPI(tcti="swtpm:port=2321") 13 | ectx.startup(TPM2_SU.CLEAR) 14 | r = ectx.get_random( 8 ) 15 | print(str(r)) 16 | 17 | 18 | inPublic = TPM2B_PUBLIC( 19 | TPMT_PUBLIC.parse( 20 | alg="rsa2048", 21 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 22 | | TPMA_OBJECT.RESTRICTED 23 | | TPMA_OBJECT.DECRYPT 24 | | TPMA_OBJECT.FIXEDTPM 25 | | TPMA_OBJECT.FIXEDPARENT 26 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 27 | ) 28 | ) 29 | 30 | inPublicRSA = TPM2B_PUBLIC( 31 | TPMT_PUBLIC.parse( 32 | alg="rsa2048:rsassa:null", 33 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 34 | | TPMA_OBJECT.FIXEDPARENT 35 | | TPMA_OBJECT.FIXEDTPM 36 | | TPMA_OBJECT.SENSITIVEDATAORIGIN 37 | | TPMA_OBJECT.SIGN_ENCRYPT, 38 | ) 39 | ) 40 | 41 | inSensitive = TPM2B_SENSITIVE_CREATE( 42 | TPMS_SENSITIVE_CREATE(userAuth=TPM2B_AUTH("password")) 43 | ) 44 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, inPublic) 45 | priv, pub, _, _, _ = ectx.create(primary1, inSensitive, inPublicRSA) 46 | childHandle = ectx.load(primary1, priv, pub) 47 | ectx.flush_context(primary1) 48 | 49 | digest = sha256(b"fff") 50 | scheme = TPMT_SIG_SCHEME(scheme=TPM2_ALG.RSASSA) 51 | scheme.details.any.hashAlg = TPM2_ALG.SHA256 52 | validation = TPMT_TK_HASHCHECK(tag=TPM2_ST.HASHCHECK, hierarchy=TPM2_RH.OWNER) 53 | 54 | digest, ticket = ectx.hash(b"fff", TPM2_ALG.SHA256, ESYS_TR.OWNER) 55 | 56 | ectx.tr_set_auth(childHandle, "password") 57 | signature = ectx.sign(childHandle, TPM2B_DIGEST(digest), scheme, validation) 58 | print(signature.marshal().hex()) 59 | 60 | ectx.tr_set_auth(childHandle, "password") 61 | ectx.verify_signature(childHandle, TPM2B_DIGEST(digest), signature) 62 | ectx.flush_context(childHandle) 63 | 64 | ectx.close() -------------------------------------------------------------------------------- /pytss/esapi_create_sign.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | from cryptography.hazmat.primitives import hashes 4 | from cryptography.hazmat.backends import default_backend 5 | 6 | def sha256(data: bytes) -> bytes: 7 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 8 | digest.update(data) 9 | digest = digest.finalize() 10 | return digest 11 | 12 | ectx = ESAPI(tcti="swtpm:port=2321") 13 | ectx.startup(TPM2_SU.CLEAR) 14 | 15 | inPublic = TPM2B_PUBLIC( 16 | TPMT_PUBLIC.parse( 17 | alg="rsa2048", 18 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 19 | | TPMA_OBJECT.RESTRICTED 20 | | TPMA_OBJECT.DECRYPT 21 | | TPMA_OBJECT.FIXEDTPM 22 | | TPMA_OBJECT.FIXEDPARENT 23 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 24 | ) 25 | ) 26 | 27 | inPublicRSA = TPM2B_PUBLIC( 28 | TPMT_PUBLIC.parse( 29 | alg="rsa2048:rsassa:null", 30 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 31 | | TPMA_OBJECT.FIXEDPARENT 32 | | TPMA_OBJECT.FIXEDTPM 33 | | TPMA_OBJECT.SENSITIVEDATAORIGIN 34 | | TPMA_OBJECT.SIGN_ENCRYPT, 35 | ) 36 | ) 37 | 38 | inSensitive = TPM2B_SENSITIVE_CREATE() 39 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, inPublic) 40 | priv, pub, _, _, _ = ectx.create(primary1, inSensitive, inPublicRSA) 41 | childHandle = ectx.load(primary1, priv, pub) 42 | ectx.flush_context(primary1) 43 | 44 | scheme = TPMT_SIG_SCHEME(scheme=TPM2_ALG.RSASSA) 45 | scheme.details.any.hashAlg = TPM2_ALG.SHA256 46 | validation = TPMT_TK_HASHCHECK(tag=TPM2_ST.HASHCHECK, hierarchy=TPM2_RH.OWNER) 47 | 48 | digest, ticket = ectx.hash(b"fff", TPM2_ALG.SHA256, ESYS_TR.OWNER) 49 | 50 | s = ectx.sign(childHandle, TPM2B_DIGEST(digest), scheme, validation) 51 | 52 | print(s.sigAlg) 53 | print(s.signature.rsassa.hash) 54 | print(s.signature.rsassa.sig) 55 | 56 | ectx.verify_signature(childHandle, TPM2B_DIGEST(digest), s) 57 | ectx.flush_context(childHandle) 58 | 59 | ectx.close() -------------------------------------------------------------------------------- /pytss/esapi_encrypt_decrypt.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | from cryptography.hazmat.primitives import hashes 4 | from cryptography.hazmat.backends import default_backend 5 | 6 | ectx = ESAPI(tcti="swtpm:port=2321") 7 | ectx.startup(TPM2_SU.CLEAR) 8 | 9 | inPublic = TPM2B_PUBLIC( 10 | TPMT_PUBLIC.parse( 11 | alg="rsa2048", 12 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 13 | | TPMA_OBJECT.RESTRICTED 14 | | TPMA_OBJECT.DECRYPT 15 | | TPMA_OBJECT.FIXEDTPM 16 | | TPMA_OBJECT.FIXEDPARENT 17 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 18 | ) 19 | ) 20 | 21 | inPublicAES = TPM2B_PUBLIC( 22 | TPMT_PUBLIC.parse( 23 | alg="aes", 24 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 25 | | TPMA_OBJECT.FIXEDPARENT 26 | | TPMA_OBJECT.FIXEDTPM 27 | | TPMA_OBJECT.SENSITIVEDATAORIGIN 28 | | TPMA_OBJECT.DECRYPT 29 | | TPMA_OBJECT.SIGN_ENCRYPT, 30 | ) 31 | ) 32 | 33 | inSensitive = TPM2B_SENSITIVE_CREATE() 34 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, inPublic) 35 | priv, pub, _, _, _ = ectx.create(primary1, inSensitive, inPublicAES) 36 | aesKeyHandle = ectx.load(primary1, priv, pub) 37 | ectx.flush_context(primary1) 38 | 39 | ivIn = TPM2B_IV(b"thisis16bytes123") 40 | inData = TPM2B_MAX_BUFFER(b"fooo") 41 | 42 | encrpyted, outIV2 = ectx.encrypt_decrypt(aesKeyHandle, False, TPM2_ALG.CFB, ivIn, inData) 43 | 44 | print(encrpyted.buffer.hex()) 45 | print(outIV2.buffer.hex()) 46 | 47 | decrypted, outIV2 = ectx.encrypt_decrypt(aesKeyHandle, True, TPM2_ALG.CFB, ivIn, encrpyted) 48 | 49 | print(decrypted.marshal().decode("ascii")) 50 | 51 | ectx.flush_context(aesKeyHandle) 52 | 53 | -------------------------------------------------------------------------------- /pytss/esapi_hmac_import.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | from cryptography.hazmat.primitives import hashes 4 | from cryptography.hazmat.backends import default_backend 5 | 6 | ectx = ESAPI(tcti="swtpm:port=2321") 7 | ectx.startup(TPM2_SU.CLEAR) 8 | 9 | 10 | # https://github.com/salrashid123/tpm2/tree/master/hmac_import 11 | # echo -n "change this password to a secret" | xxd -p -c 100 12 | # 6368616e676520746869732070617373776f726420746f206120736563726574 13 | # echo -n foo > data.in 14 | # openssl dgst -sha256 -mac hmac -macopt hexkey:6368616e676520746869732070617373776f726420746f206120736563726574 data.in 15 | # HMAC-SHA256(data.in)= 7c50506d993b4a10e5ae6b33ca951bf2b8c8ac399e0a34026bb0ac469bea3de2 16 | 17 | k = 'change this password to a secret' 18 | 19 | inPublic = TPM2B_PUBLIC( 20 | TPMT_PUBLIC.parse( 21 | alg="rsa2048", 22 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 23 | | TPMA_OBJECT.RESTRICTED 24 | | TPMA_OBJECT.DECRYPT 25 | | TPMA_OBJECT.FIXEDTPM 26 | | TPMA_OBJECT.FIXEDPARENT 27 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 28 | ) 29 | ) 30 | 31 | inPublicHMAC = TPM2B_PUBLIC( 32 | TPMT_PUBLIC.parse( 33 | alg="hmac", 34 | nameAlg="sha256", 35 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 36 | | TPMA_OBJECT.FIXEDPARENT 37 | | TPMA_OBJECT.FIXEDTPM 38 | | TPMA_OBJECT.SIGN_ENCRYPT, 39 | ) 40 | ) 41 | 42 | inSensitive = TPM2B_SENSITIVE_CREATE() 43 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, inPublic) 44 | 45 | inSensitiveHMAC = TPM2B_SENSITIVE_CREATE(TPMS_SENSITIVE_CREATE(data=TPM2B_SENSITIVE_DATA(k.encode("utf-8")))) 46 | priv, pub, _, _, _ = ectx.create(primary1, inSensitiveHMAC, inPublicHMAC) 47 | 48 | 49 | 50 | childHandle = ectx.load(primary1, priv, pub) 51 | ectx.flush_context(primary1) 52 | thmac = ectx.hmac(childHandle, b"foo", TPM2_ALG.SHA256) 53 | 54 | print(thmac.buffer.hex()) 55 | 56 | 57 | ectx.flush_context(childHandle) -------------------------------------------------------------------------------- /pytss/esapi_keyfile.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | from tpm2_pytss.tsskey import TSSPrivKey 3 | 4 | from cryptography.hazmat.primitives import hashes 5 | from cryptography.hazmat.backends import default_backend 6 | 7 | ectx = ESAPI(tcti="swtpm:port=2321") 8 | ectx.startup(TPM2_SU.CLEAR) 9 | 10 | 11 | inPublic = TPM2B_PUBLIC( 12 | TPMT_PUBLIC.parse( 13 | alg="rsa2048", 14 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 15 | | TPMA_OBJECT.RESTRICTED 16 | | TPMA_OBJECT.DECRYPT 17 | | TPMA_OBJECT.FIXEDTPM 18 | | TPMA_OBJECT.FIXEDPARENT 19 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 20 | ) 21 | ) 22 | 23 | _parent_ecc_template = TPMT_PUBLIC( 24 | type=TPM2_ALG.ECC, 25 | nameAlg=TPM2_ALG.SHA256, 26 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 27 | | TPMA_OBJECT.RESTRICTED 28 | | TPMA_OBJECT.DECRYPT 29 | | TPMA_OBJECT.NODA 30 | | TPMA_OBJECT.FIXEDTPM 31 | | TPMA_OBJECT.FIXEDPARENT 32 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 33 | authPolicy=b"", 34 | parameters=TPMU_PUBLIC_PARMS( 35 | eccDetail=TPMS_ECC_PARMS( 36 | symmetric=TPMT_SYM_DEF_OBJECT( 37 | algorithm=TPM2_ALG.AES, 38 | keyBits=TPMU_SYM_KEY_BITS(aes=128), 39 | mode=TPMU_SYM_MODE(aes=TPM2_ALG.CFB), 40 | ), 41 | scheme=TPMT_ECC_SCHEME(scheme=TPM2_ALG.NULL), 42 | curveID=TPM2_ECC.NIST_P256, 43 | kdf=TPMT_KDF_SCHEME(scheme=TPM2_ALG.NULL), 44 | ), 45 | ), 46 | ) 47 | 48 | inPublicAES = TPM2B_PUBLIC( 49 | TPMT_PUBLIC.parse( 50 | alg="aes", 51 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 52 | | TPMA_OBJECT.FIXEDPARENT 53 | | TPMA_OBJECT.FIXEDTPM 54 | | TPMA_OBJECT.SENSITIVEDATAORIGIN 55 | | TPMA_OBJECT.DECRYPT 56 | | TPMA_OBJECT.SIGN_ENCRYPT, 57 | ) 58 | ) 59 | 60 | inSensitive = TPM2B_SENSITIVE_CREATE() 61 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, TPM2B_PUBLIC(publicArea=_parent_ecc_template)) 62 | priv, pub, _, _, _ = ectx.create(primary1, inSensitive, inPublicAES) 63 | k1= TSSPrivKey(priv,pub,empty_auth=True,parent=TPM2_RH.OWNER) 64 | 65 | 66 | 67 | p1 = k1.to_pem() 68 | f = open("/tmp/p1.pem", "w") 69 | f.write(p1.decode()) 70 | f.close() 71 | 72 | 73 | ectx.flush_context(primary1) 74 | 75 | 76 | 77 | f = open("/tmp/p1.pem", "r") 78 | k = TSSPrivKey.from_pem(f.read().encode("utf-8")) 79 | 80 | 81 | # see https://github.com/tpm2-software/tpm2-pytss/issues/595 82 | ### its better to load h2 primary and flush manually 83 | # aesKeyHandle = k.load(ectx,password='') 84 | inSensitive = TPM2B_SENSITIVE_CREATE() 85 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, TPM2B_PUBLIC(publicArea=_parent_ecc_template)) 86 | aesKeyHandle = ectx.load(primary1, k.private, k.public) 87 | ectx.flush_context(primary1) 88 | 89 | 90 | ivIn = TPM2B_IV(bytes(bytearray.fromhex("4ca91f6bc6376a33a4ddb8a9c3cf5ea9"))) 91 | inData = TPM2B_MAX_BUFFER(b"foo") 92 | 93 | encrypted, outIV2 = ectx.encrypt_decrypt(aesKeyHandle, False, TPM2_ALG.CFB, ivIn, inData) 94 | print(encrypted) 95 | 96 | decrypted, outIV2 = ectx.encrypt_decrypt(aesKeyHandle, True, TPM2_ALG.CFB, ivIn, encrypted) 97 | print(decrypted.marshal().decode("ascii")) 98 | 99 | ectx.flush_context(aesKeyHandle) 100 | 101 | ectx.close() 102 | 103 | -------------------------------------------------------------------------------- /pytss/esapi_session_encryption_auth.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | from tpm2_pytss.internal.templates import _ek 3 | from tpm2_pytss.tsskey import TSSPrivKey 4 | 5 | ''' 6 | printf '\x00\x00' > /tmp/unique.dat 7 | tpm2_createprimary -C o -G ecc -g sha256 \ 8 | -c primary.ctx \ 9 | -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u /tmp/unique.dat 10 | 11 | tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 12 | tpm2_create -g sha256 -G aes128cfb -u aes.pub -r aes.prv -C primary.ctx -p pass 13 | 14 | tpm2_load -C primary.ctx -u aes.pub -r aes.prv -c aes.ctx 15 | tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 16 | echo "foo" > secret.dat 17 | openssl rand -out iv.bin 16 18 | 19 | tpm2_encryptdecrypt -Q --iv iv.bin -G cfb -c aes.ctx -o encrypt.out secret.dat -p pass 20 | tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 21 | tpm2_encryptdecrypt -Q --iv iv.bin -G cfb -c aes.ctx -d -o decrypt.out encrypt.out -p pass 22 | tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 23 | ''' 24 | 25 | ectx = ESAPI(tcti="swtpm:port=2321") 26 | ectx.startup(TPM2_SU.CLEAR) 27 | 28 | _parent_ecc_template = TPMT_PUBLIC( 29 | type=TPM2_ALG.ECC, 30 | nameAlg=TPM2_ALG.SHA256, 31 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 32 | | TPMA_OBJECT.RESTRICTED 33 | | TPMA_OBJECT.DECRYPT 34 | | TPMA_OBJECT.NODA 35 | | TPMA_OBJECT.FIXEDTPM 36 | | TPMA_OBJECT.FIXEDPARENT 37 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 38 | authPolicy=b"", 39 | parameters=TPMU_PUBLIC_PARMS( 40 | eccDetail=TPMS_ECC_PARMS( 41 | symmetric=TPMT_SYM_DEF_OBJECT( 42 | algorithm=TPM2_ALG.AES, 43 | keyBits=TPMU_SYM_KEY_BITS(aes=128), 44 | mode=TPMU_SYM_MODE(aes=TPM2_ALG.CFB), 45 | ), 46 | scheme=TPMT_ECC_SCHEME(scheme=TPM2_ALG.NULL), 47 | curveID=TPM2_ECC.NIST_P256, 48 | kdf=TPMT_KDF_SCHEME(scheme=TPM2_ALG.NULL), 49 | ), 50 | ), 51 | ) 52 | 53 | inSensitive = TPM2B_SENSITIVE_CREATE() 54 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, TPM2B_PUBLIC(publicArea=_parent_ecc_template)) 55 | 56 | 57 | with open("/tmp/aes.pub", "rb") as file: 58 | pu = file.read() 59 | 60 | with open("/tmp/aes.prv", "rb") as file: 61 | pr = file.read() 62 | 63 | ## if you want, you can write the pub/priv to disk (eg pub.marshal()) 64 | pub, _ = TPM2B_PUBLIC.unmarshal(pu) 65 | priv, _ = TPM2B_PRIVATE.unmarshal(pr) 66 | 67 | aesKeyHandle = ectx.load(primary1, priv,pub) 68 | ectx.flush_context(primary1) 69 | 70 | 71 | nv, tmpl = _ek.EK_RSA2048 72 | 73 | inSensitive = TPM2B_SENSITIVE_CREATE() 74 | handle, outpub, _, _, _ = ectx.create_primary( 75 | inSensitive, tmpl, ESYS_TR.ENDORSEMENT) 76 | 77 | hsess = ectx.start_auth_session( 78 | tpm_key=handle, 79 | bind=ESYS_TR.NONE, 80 | session_type=TPM2_SE.HMAC, 81 | symmetric=TPMT_SYM_DEF( 82 | algorithm=TPM2_ALG.AES, 83 | keyBits=TPMU_SYM_KEY_BITS(sym=128), 84 | mode=TPMU_SYM_MODE(sym=TPM2_ALG.CFB), 85 | ), 86 | auth_hash=TPM2_ALG.SHA256, 87 | ) 88 | ectx.trsess_set_attributes( 89 | hsess, (TPMA_SESSION.DECRYPT | TPMA_SESSION.ENCRYPT ) 90 | ) 91 | 92 | 93 | ivIn = TPM2B_IV(b"thisis16bytes123") 94 | inData = TPM2B_MAX_BUFFER(b"fooo") 95 | 96 | ectx.tr_set_auth(aesKeyHandle, "pass") 97 | 98 | encrypted, outIV2 = ectx.encrypt_decrypt_2(aesKeyHandle, False, TPM2_ALG.CFB, ivIn, inData, session1=hsess) 99 | 100 | print(encrypted.buffer.hex()) 101 | print(outIV2.buffer.hex()) 102 | 103 | 104 | 105 | 106 | hsess = ectx.start_auth_session( 107 | tpm_key=handle, 108 | bind=ESYS_TR.NONE, 109 | session_type=TPM2_SE.HMAC, 110 | symmetric=TPMT_SYM_DEF( 111 | algorithm=TPM2_ALG.AES, 112 | keyBits=TPMU_SYM_KEY_BITS(sym=128), 113 | mode=TPMU_SYM_MODE(sym=TPM2_ALG.CFB), 114 | ), 115 | auth_hash=TPM2_ALG.SHA256, 116 | ) 117 | ectx.trsess_set_attributes( 118 | hsess, (TPMA_SESSION.DECRYPT | TPMA_SESSION.ENCRYPT ) 119 | ) 120 | 121 | 122 | 123 | decrypted, outIV2 = ectx.encrypt_decrypt_2(aesKeyHandle, True, TPM2_ALG.CFB, ivIn, encrypted, session1=hsess) 124 | 125 | print(decrypted.marshal().decode("ascii")) 126 | 127 | ectx.flush_context(handle) 128 | ectx.flush_context(aesKeyHandle) 129 | 130 | 131 | ectx.close() -------------------------------------------------------------------------------- /pytss/esapi_tpm2.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | 4 | from cryptography.hazmat.primitives import hashes 5 | from cryptography.hazmat.backends import default_backend 6 | 7 | from tpm2_pytss.internal.templates import _ek 8 | 9 | 10 | # tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 11 | # printf '\x00\x00' > /tmp/unique.dat 12 | # tpm2_createprimary -C o -G ecc -g sha256 \ 13 | # -c primary.ctx \ 14 | # -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u /tmp/unique.dat 15 | 16 | # tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 17 | # tpm2_create -g sha256 -G aes128cfb -u key.pub -r key.prv -C primary.ctx 18 | 19 | # tpm2_load -C primary.ctx -u key.pub -r key.prv -c key.ctx 20 | # tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 21 | # echo "foo" > secret.dat 22 | # openssl rand -out iv.bin 16 23 | 24 | # tpm2_encryptdecrypt -Q --iv iv.bin -G cfb -c key.ctx -o encrypt.out secret.dat 25 | # tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 26 | # tpm2_encryptdecrypt -Q --iv iv.bin -G cfb -c key.ctx -d -o decrypt.out encrypt.out 27 | # tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l 28 | 29 | 30 | ectx = ESAPI(tcti="swtpm:port=2321") 31 | ectx.startup(TPM2_SU.CLEAR) 32 | 33 | 34 | _parent_ecc_template = TPMT_PUBLIC( 35 | type=TPM2_ALG.ECC, 36 | nameAlg=TPM2_ALG.SHA256, 37 | objectAttributes=TPMA_OBJECT.USERWITHAUTH 38 | | TPMA_OBJECT.RESTRICTED 39 | | TPMA_OBJECT.DECRYPT 40 | | TPMA_OBJECT.NODA 41 | | TPMA_OBJECT.FIXEDTPM 42 | | TPMA_OBJECT.FIXEDPARENT 43 | | TPMA_OBJECT.SENSITIVEDATAORIGIN, 44 | authPolicy=b"", 45 | parameters=TPMU_PUBLIC_PARMS( 46 | eccDetail=TPMS_ECC_PARMS( 47 | symmetric=TPMT_SYM_DEF_OBJECT( 48 | algorithm=TPM2_ALG.AES, 49 | keyBits=TPMU_SYM_KEY_BITS(aes=128), 50 | mode=TPMU_SYM_MODE(aes=TPM2_ALG.CFB), 51 | ), 52 | scheme=TPMT_ECC_SCHEME(scheme=TPM2_ALG.NULL), 53 | curveID=TPM2_ECC.NIST_P256, 54 | kdf=TPMT_KDF_SCHEME(scheme=TPM2_ALG.NULL), 55 | ), 56 | ), 57 | ) 58 | 59 | inSensitive = TPM2B_SENSITIVE_CREATE() 60 | primary1, _, _, _, _ = ectx.create_primary(inSensitive, TPM2B_PUBLIC(publicArea=_parent_ecc_template)) 61 | 62 | 63 | with open("/tmp/key.pub", "rb") as file: 64 | pu = file.read() 65 | 66 | with open("/tmp/key.prv", "rb") as file: 67 | pr = file.read() 68 | 69 | ## if you want, you can write the pub/priv to disk (eg pub.marshal()) 70 | pub, _ = TPM2B_PUBLIC.unmarshal(pu) 71 | priv, _ = TPM2B_PRIVATE.unmarshal(pr) 72 | 73 | aesKeyHandle = ectx.load(primary1, priv,pub) 74 | ectx.flush_context(primary1) 75 | 76 | 77 | ivIn = TPM2B_IV(bytes(bytearray.fromhex("4ca91f6bc6376a33a4ddb8a9c3cf5ea9"))) 78 | inData = TPM2B_MAX_BUFFER(b"foo") 79 | 80 | encrypted, outIV2 = ectx.encrypt_decrypt(aesKeyHandle, False, TPM2_ALG.CFB, ivIn, inData) 81 | print(encrypted) 82 | 83 | decrypted, outIV2 = ectx.encrypt_decrypt(aesKeyHandle, True, TPM2_ALG.CFB, ivIn, encrypted) 84 | print(decrypted.marshal().decode("ascii")) 85 | 86 | ectx.flush_context(aesKeyHandle) 87 | 88 | ectx.close() 89 | 90 | -------------------------------------------------------------------------------- /pytss/fapi_auth.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | from cryptography.hazmat.primitives import hashes 4 | from cryptography.hazmat.backends import default_backend 5 | def sha256(data: bytes) -> bytes: 6 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 7 | digest.update(data) 8 | digest = digest.finalize() 9 | return digest 10 | 11 | 12 | import random, string 13 | def random_uid() -> str: 14 | """Generate a random id which can be used e.g. for unique key names.""" 15 | return "".join(random.choices(string.digits, k=10)) 16 | 17 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 18 | system_dir="~/.local/share/tpm2-tss/system/keystore", 19 | profile_dir="./profiles", 20 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 21 | 22 | fapi_ctx = FAPI() 23 | fapi_ctx.provision() 24 | 25 | 26 | def password_callback(path, descr, user_data): 27 | print(f"Callback: path={path}, descr={descr}, user_data={user_data}") 28 | return user_data 29 | 30 | key_path= f"/HS/SRK/enc{random_uid()}" 31 | fapi_ctx.create_key(path=key_path, type_='sign', exists_ok=True, auth_value="password") 32 | fapi_ctx.set_auth_callback(password_callback, user_data=b"password") 33 | 34 | 35 | digest = sha256(b"fff") 36 | sig, pub,cert = fapi_ctx.sign(path=key_path, digest=digest, padding="rsa_ssa") 37 | print(sig.hex()) 38 | 39 | 40 | key_path= f"/HS/SRK/enc{random_uid()}" 41 | fapi_ctx.create_key(path=key_path, type_='decrypt', exists_ok=True, auth_value="password") 42 | fapi_ctx.set_auth_callback(password_callback, user_data=b"password") 43 | e = fapi_ctx.encrypt(path=key_path, plaintext='foo') 44 | print(e.hex()) 45 | d = fapi_ctx.decrypt(path=key_path, ciphertext=e) 46 | print(d.decode('ascii')) 47 | 48 | -------------------------------------------------------------------------------- /pytss/fapi_create_sign.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | 4 | from cryptography.hazmat.primitives import hashes 5 | from cryptography.hazmat.backends import default_backend 6 | 7 | 8 | import random, string 9 | def random_uid() -> str: 10 | """Generate a random id which can be used e.g. for unique key names.""" 11 | return "".join(random.choices(string.digits, k=10)) 12 | 13 | 14 | def sha256(data: bytes) -> bytes: 15 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 16 | digest.update(data) 17 | digest = digest.finalize() 18 | return digest 19 | 20 | 21 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 22 | system_dir="~/.local/share/tpm2-tss/system/keystore", 23 | profile_dir="/etc/tpm2-tss/fapi-profiles/", 24 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 25 | 26 | fapi_ctx = FAPI() 27 | fapi_ctx.provision() 28 | 29 | key_path= f"/HS/SRK/sign{random_uid()}" 30 | 31 | try: 32 | fapi_ctx.create_key(path=key_path, type_='sign', exists_ok=False) 33 | except Exception as e: 34 | print(e) 35 | pass 36 | 37 | l = fapi_ctx.list(search_path="/HS/") 38 | print(l) 39 | 40 | digest = sha256(b"fff") 41 | 42 | sig, pub,cert = fapi_ctx.sign(path=key_path, digest=digest, padding="rsa_ssa") 43 | print(sig.hex()) 44 | 45 | 46 | fapi_ctx.verify_signature(path=key_path, digest=digest, signature=sig) 47 | 48 | #fapi_ctx.delete("/") 49 | fapi_ctx.close() -------------------------------------------------------------------------------- /pytss/fapi_encrypt_decrypt.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | import random, string 4 | def random_uid() -> str: 5 | """Generate a random id which can be used e.g. for unique key names.""" 6 | return "".join(random.choices(string.digits, k=10)) 7 | 8 | 9 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321",temp_dirs=True, ek_cert_less='yes',profile_dir="./profiles") 10 | fapi_ctx = FAPI() 11 | fapi_ctx.provision() 12 | 13 | print(str(fapi_ctx.get_random(8).hex())) 14 | 15 | fapi_ctx.create_key(path='/HS/SRK/enc1', type_='decrypt', exists_ok=True) 16 | e = fapi_ctx.encrypt(path='/HS/SRK/enc1', plaintext='foo') 17 | 18 | print(e.hex()) 19 | 20 | d = fapi_ctx.decrypt(path='/HS/SRK/enc1', ciphertext=e) 21 | print(d.decode('ascii')) 22 | 23 | 24 | fapi_ctx.delete("/") 25 | fapi_ctx.close() -------------------------------------------------------------------------------- /pytss/fapi_export_tpm2.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | 4 | from cryptography.hazmat.primitives import hashes 5 | from cryptography.hazmat.backends import default_backend 6 | 7 | import random, string 8 | def random_uid() -> str: 9 | """Generate a random id which can be used e.g. for unique key names.""" 10 | return "".join(random.choices(string.digits, k=10)) 11 | 12 | 13 | ## after running fapi_export_tpm2.py, you'll have /tmp/key.pub /tmp/key.priv which you can load with: 14 | 15 | # tpm2_createprimary -C o -c /tmp/primary.ctx -Q 16 | # tpm2_load -C /tmp/primary.ctx -u /tmp/key.pub -r /tmp/key.priv -c /tmp/key.ctx 17 | # tpm2_flushcontext -t 18 | # echo -n "fff" > message.dat 19 | # tpm2_sign -c key.ctx -g sha256 -o sig.rssa message.dat -f plain 20 | # xxd -p sig.rssa 21 | 22 | 23 | def sha256(data: bytes) -> bytes: 24 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 25 | digest.update(data) 26 | digest = digest.finalize() 27 | return digest 28 | 29 | 30 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 31 | system_dir="~/.local/share/tpm2-tss/system/keystore", 32 | profile_dir="/etc/tpm2-tss/fapi-profiles/", 33 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 34 | 35 | fapi_ctx = FAPI() 36 | fapi_ctx.provision() 37 | 38 | key_path= f"/HS/SRK/sign{random_uid()}" 39 | 40 | 41 | try: 42 | fapi_ctx.create_key(path=key_path, type_='sign', exists_ok=False) 43 | except Exception as e: 44 | print(e) 45 | pass 46 | 47 | l = fapi_ctx.list(search_path="/HS/") 48 | print(l) 49 | 50 | digest = sha256(b"fff") 51 | 52 | sig, pub,cert = fapi_ctx.sign(path=key_path, digest=digest, padding="rsa_ssa") 53 | print(sig.hex()) 54 | fapi_ctx.verify_signature(path=key_path, digest=digest, signature=sig) 55 | 56 | pub, priv, pol = fapi_ctx.get_tpm_blobs(path=key_path) 57 | 58 | 59 | with open("/tmp/key.pub", "wb") as binary_file: 60 | binary_file.write(pub.marshal()) 61 | 62 | with open("/tmp/key.priv", "wb") as binary_file: 63 | binary_file.write(priv.marshal()) 64 | 65 | ## if you want, you can write the pub/priv to disk (eg pub.marshal()) 66 | # pub2, _ = TPM2B_PUBLIC.unmarshal(pub.marshal()) 67 | # priv2, _ = TPM2B_PRIVATE.unmarshal(priv.marshal()) 68 | 69 | #fapi_ctx.delete("/") 70 | fapi_ctx.close() 71 | -------------------------------------------------------------------------------- /pytss/fapi_import_sign.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | 4 | from cryptography.hazmat.primitives import hashes 5 | from cryptography.hazmat.backends import default_backend 6 | 7 | import random, string 8 | def random_uid() -> str: 9 | """Generate a random id which can be used e.g. for unique key names.""" 10 | return "".join(random.choices(string.digits, k=10)) 11 | 12 | 13 | def sha256(data: bytes) -> bytes: 14 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 15 | digest.update(data) 16 | digest = digest.finalize() 17 | return digest 18 | 19 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 20 | system_dir="~/.local/share/tpm2-tss/system/keystore", 21 | profile_dir="./profiles", 22 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 23 | 24 | fapi_ctx = FAPI() 25 | fapi_ctx.provision() 26 | 27 | key_path= f"/HS/SRK/key{random_uid()}" 28 | try: 29 | key_private_pem="-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDOHW00xKYNp0xv\ngbUDbedDyGDV6dM54TIBEiVZ0PPldACI6YBt8n+N5EnrrzkxEOEqTBQduhIQaGpe\nAgigU9MZPw1o1974Se7FIjRJA9nrvAkT2uEGAfq8wFgFnTvH7NbROGyaMEiwoAGI\nKAZfyXJ7Np095eLHSBx8xyP/j1OtrWw6M/duPR30X4bXdEZ8xbNbMsaz7+rYhuuU\n5XtUzJ1kcd5B6dlC05nq+k5GxQWYOa8rlCmqLHsUW9LCHABGFY+/srscEEywpFzC\nP7uimEwLsaKSkBPhJG5S0P4D3jDHBEuM8K7BXZXL7Y7hsozd1K/E2MBRrWhlsRZ/\ncgYS8S0zAgMBAAECggEALyun3wA0OoKzqP9HxGmmGCqnEr2pFCF4Fqum9aeu8a+7\nIZpCxKbPT1NUIYaf8Z050rrHjcgUM0IaObqAa+TTNn9qG7jvs+YDqYT670zc1ijZ\n8PvSLNROJF1mp55E3KvUu9wMarsrH5T21MjIMKrDMvScRtqyLEZSErJmiCmujlvt\nRJuUDzL3FFgax/RgS80FUWsmqGvBNL+guJfvYp4NwpSj+9xcV8Gaf8bI6CMIeWQd\nJ/vUGTT31yv2j5P5t1dnMfKdZSt2vFjdfizJKnhpj1sFgldwC+jSVzG9sRb1Xyb4\nZNWWJw27xZtp76xT92gIiU8AR+aO8wXdH5UcVmW56QKBgQD0h/lZttkNEoo4edV4\nelG3SMYEB/1fQ/ukG1EAVpOHfCpcuJEy0FOfsmQf5an4QF8L2EU50Td81HTnTJWK\nfLF9qAiIHa1mdUmtLjSelGgZOagG0BJhZeV6sdi+VayWhCbWmeEikS6zr+xwIv7S\nNuN83Gf3r9GMRvkbF8RI95Xc+wKBgQDXyDLWrWWdSjQEMa8D8U+eUzD6JrRlqa1z\nWptVcRXtQ+dvgPW36iz8lBo4DvTk1SsmEUeUO33YuO/timzCNqS9+2chtzSAJi3g\nJUpfIZoqwEbIpuJB5qr/rcUFHPtk4vGJeA7OLBJUsS3FLVoRCikf1jX9fHTLhzS3\nGSj/07YLKQKBgQCreH39zx488HdESwrKRNvwbnOMeB3QI9fdp9oRJqSlKQh7pGEN\nBNDe9zUGuQGLN3hu0eUZOgBy5HhliWqDhhTgTGhPKqBhbHWRnwj++opUxf1xaY66\nBb35X6ThMyqnEVw6uAULPEtHbWGa8K9HsX2sHNI6+WsztsEPoobds9++6QKBgQCQ\n2sFeIhsT4wtWQXAm6mizdU9srmztzmE1Df829Wpt0+bakKzjYN4AVP/g4BGASKXl\nsTXnCaTqxwOx5/ooynv/WXSbSpyA5qBnV0E86ZbP2jHqYzWCXfIvH50iWJle2Yah\n7SmrOCS6HBMIyfArfjGrQKcP2uug8cvumoJOcvZDOQKBgHoZhEHU/veIResRGF/y\nhPThSWJby8k4Rh7f//7SwZHAdG+zB2I81R92zOMhCwzdFIHQ2vattNpU/tW8dcHK\nXMZwbjhrGtF51NLkjHWTclP7KF2666gCGsFJ5qiJ9qxkgnAuqEwfSriU0xDMshxo\nsD808S+2pl4qks0EnHYC2uPi\n-----END PRIVATE KEY-----\n" 30 | fapi_ctx.import_object(path=key_path, import_data=key_private_pem) 31 | except Exception as e: 32 | print(e) 33 | pass 34 | 35 | l = fapi_ctx.list(search_path="/HS/") 36 | print(l) 37 | 38 | digest = sha256(b"fff") 39 | 40 | sig, pub,cert = fapi_ctx.sign(path=key_path, digest=digest, padding="rsa_ssa") 41 | print(sig.hex()) 42 | 43 | 44 | fapi_ctx.verify_signature(path=key_path, digest=digest, signature=sig) 45 | 46 | 47 | 48 | #fapi_ctx.delete("/") 49 | fapi_ctx.close() 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /pytss/fapi_import_tpm2.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | import base64 4 | import json 5 | from datetime import datetime, timedelta 6 | 7 | import random, string 8 | def random_uid() -> str: 9 | """Generate a random id which can be used e.g. for unique key names.""" 10 | return "".join(random.choices(string.digits, k=10)) 11 | 12 | 13 | from cryptography.hazmat.primitives import hashes 14 | from cryptography.hazmat.backends import default_backend 15 | 16 | key_path= f"/HS/SRK/key{random_uid()}" 17 | 18 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 19 | system_dir="~/.local/share/tpm2-tss/system/keystore", 20 | profile_dir="./profiles", 21 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 22 | 23 | fapi_ctx = FAPI() 24 | fapi_ctx.provision() 25 | 26 | # $ tpm2_createprimary -C o -c primary.ctx 27 | # name-alg: 28 | # value: sha256 29 | # raw: 0xb 30 | # attributes: 31 | # value: fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt 32 | # raw: 0x30072 33 | # type: 34 | # value: rsa 35 | # raw: 0x1 36 | # exponent: 65537 37 | # bits: 2048 38 | # scheme: 39 | # value: null 40 | # raw: 0x10 41 | # scheme-halg: 42 | # value: (null) 43 | # raw: 0x0 44 | # sym-alg: 45 | # value: aes 46 | # raw: 0x6 47 | # sym-mode: 48 | # value: cfb 49 | # raw: 0x43 50 | # sym-keybits: 128 51 | 52 | 53 | # tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx -Q 54 | # tpm2_flushcontext -t 55 | # tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 56 | # tpm2_flushcontext -t 57 | 58 | # $ echo '{"public":"'`xxd -p -c 1000 key.pub`'", "private": "'`xxd -p -c 1000 key.priv`'", "noauth":"YES"}' | jq '.' 59 | # { 60 | # "public": "01180001000b00040072000000100014000b0800000000000100c4e9061e188c90f05a92a7820d91e8dcc3bbd784f738a0acc21dd3249940e001ef926dac486ba429f50d6c76b82013bbcc066cc1f54019182ff33d13da3c9962930dff3a0b55d775a9087b36ab7248a801abb8905097c61718959184c877a24d4aab00196bf2204d8eb5b856418ce78a382611904249c4309798240519dd21495b32450ba91c6dad7e09fd74c560382819cca9f96f8c8cb201ef274147e85d4f680b7ec2e32a54bdc1010cf7188415cd36a7575c7ef6569b1d7f2cd0bd993e2546a1617ffeb1f21015a015f2ebeff39d3da311917b3d6cdc5e8dbdb3e2725e45166cf3f3f93371b99a072d33d2ca0db1ad37cef2159bb83493df6dadaa5c1a4b", 61 | # "private": "00de002085ba735dd632280c670e2731b018e8faf221209e8784bea712b1e5578db076aa0010174bd9ceb675c5dbedb1fbc79533c6a6206d8e7f56a92cfb2a90e350484f25a1a0add8f939d5459d6d5c52c415fa4b1ad16da009abe2102d5a59a1283ab16f195d3bd4a04304a444a16c9eb5d81a80071cbef97ec4182f51ebc049341833432106c9508c1a4244559bc6d94feb1003d89873d24a149e8fe9e828fa4f72f6e64f70d82a3a1eb46b18723064cd884a3866e45e33cfdc1cf100d569baf2f8e99171ec9873cc2a2a7730e501856fce4e0bf251782ddcfcd341e4feac", 62 | # "noauth": "YES" 63 | # } 64 | 65 | ### important: replace with the pub/priv from your tpm 66 | key = """{ 67 | "public": "01180001000b00040072000000100014000b0800000000000100c4e9061e188c90f05a92a7820d91e8dcc3bbd784f738a0acc21dd3249940e001ef926dac486ba429f50d6c76b82013bbcc066cc1f54019182ff33d13da3c9962930dff3a0b55d775a9087b36ab7248a801abb8905097c61718959184c877a24d4aab00196bf2204d8eb5b856418ce78a382611904249c4309798240519dd21495b32450ba91c6dad7e09fd74c560382819cca9f96f8c8cb201ef274147e85d4f680b7ec2e32a54bdc1010cf7188415cd36a7575c7ef6569b1d7f2cd0bd993e2546a1617ffeb1f21015a015f2ebeff39d3da311917b3d6cdc5e8dbdb3e2725e45166cf3f3f93371b99a072d33d2ca0db1ad37cef2159bb83493df6dadaa5c1a4b", 68 | "private": "00de002085ba735dd632280c670e2731b018e8faf221209e8784bea712b1e5578db076aa0010174bd9ceb675c5dbedb1fbc79533c6a6206d8e7f56a92cfb2a90e350484f25a1a0add8f939d5459d6d5c52c415fa4b1ad16da009abe2102d5a59a1283ab16f195d3bd4a04304a444a16c9eb5d81a80071cbef97ec4182f51ebc049341833432106c9508c1a4244559bc6d94feb1003d89873d24a149e8fe9e828fa4f72f6e64f70d82a3a1eb46b18723064cd884a3866e45e33cfdc1cf100d569baf2f8e99171ec9873cc2a2a7730e501856fce4e0bf251782ddcfcd341e4feac", 69 | "noauth": "YES" 70 | } 71 | """ 72 | fapi_ctx.import_object(path=key_path, import_data=key,exists_ok=False) 73 | 74 | def sha256(data: bytes) -> bytes: 75 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 76 | digest.update(data) 77 | digest = digest.finalize() 78 | return digest 79 | 80 | 81 | l = fapi_ctx.list(search_path="/HS/") 82 | print(l) 83 | 84 | digest = sha256(b"fff") 85 | 86 | sig, pub,cert = fapi_ctx.sign(path=key_path, digest=digest, padding="rsa_ssa") 87 | print(sig.hex()) 88 | 89 | fapi_ctx.verify_signature(path=key_path, digest=digest, signature=sig) 90 | 91 | #fapi_ctx.delete("/") 92 | fapi_ctx.close() -------------------------------------------------------------------------------- /pytss/fapi_pcr.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | import random, string 4 | 5 | 6 | from cryptography.hazmat.primitives import hashes 7 | from cryptography.hazmat.backends import default_backend 8 | 9 | 10 | def sha256(data: bytes) -> bytes: 11 | digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) 12 | digest.update(data) 13 | digest = digest.finalize() 14 | return digest 15 | 16 | 17 | def random_uid() -> str: 18 | """Generate a random id which can be used e.g. for unique key names.""" 19 | return "".join(random.choices(string.digits, k=10)) 20 | 21 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 22 | system_dir="~/.local/share/tpm2-tss/system/keystore", 23 | profile_dir="./profiles", 24 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 25 | 26 | fapi_ctx = FAPI() 27 | fapi_ctx.provision() 28 | 29 | 30 | key_path= f"/HS/SRK/sign1111" 31 | 32 | policy_path = f"/policy/pcr-policy" 33 | pcr_policy="""{ 34 | "description":"Policy PCR 0 TPM2_ALG_SHA256", 35 | "policy":[ 36 | { 37 | "type":"POLICYPCR", 38 | "pcrs":[ 39 | { 40 | "pcr":0, 41 | "hashAlg":"TPM2_ALG_SHA256", 42 | "digest":"0000000000000000000000000000000000000000000000000000000000000000" 43 | } 44 | ] 45 | } 46 | ] 47 | } 48 | 49 | """ 50 | fapi_ctx.import_object(path=policy_path, import_data=pcr_policy, exists_ok=True) 51 | fapi_ctx.create_key(path=key_path, type_='sign', exists_ok=True, policy_path=policy_path) 52 | 53 | l = fapi_ctx.list(search_path="/HS/") 54 | print(l) 55 | 56 | digest = sha256(b"fff") 57 | sig, pub,cert = fapi_ctx.sign(path=key_path, digest=digest, padding="rsa_ssa") 58 | print(sig.hex()) 59 | 60 | 61 | fapi_ctx.verify_signature(path=key_path, digest=digest, signature=sig) 62 | 63 | #fapi_ctx.delete("/") 64 | fapi_ctx.close() 65 | -------------------------------------------------------------------------------- /pytss/fapi_seal_unseal.py: -------------------------------------------------------------------------------- 1 | from tpm2_pytss import * 2 | 3 | import random, string 4 | def random_uid() -> str: 5 | """Generate a random id which can be used e.g. for unique key names.""" 6 | return "".join(random.choices(string.digits, k=10)) 7 | 8 | 9 | FAPIConfig(profile_name='P_RSA2048SHA256',tcti="swtpm:port=2321", temp_dirs=False, ek_cert_less='yes', 10 | system_dir="~/.local/share/tpm2-tss/system/keystore", 11 | profile_dir="./profiles", 12 | user_dir="~/.local/share/tpm2-tss/user/keystore/") 13 | 14 | fapi_ctx = FAPI() 15 | fapi_ctx.provision() 16 | 17 | seal_data = "secret".encode() 18 | 19 | policy_path= f"/policy{random_uid()}" 20 | key_path= f"/HS/SRK/key{random_uid()}" 21 | 22 | pcr_policy="""{ 23 | "description":"Policy PCR 0 TPM2_ALG_SHA256", 24 | "policy":[ 25 | { 26 | "type":"POLICYPCR", 27 | "pcrs":[ 28 | { 29 | "pcr":0, 30 | "hashAlg":"TPM2_ALG_SHA256", 31 | "digest":"0000000000000000000000000000000000000000000000000000000000000000" 32 | } 33 | ] 34 | } 35 | ] 36 | } 37 | 38 | """ 39 | fapi_ctx.import_object(path=policy_path, import_data=pcr_policy) 40 | 41 | success = fapi_ctx.create_seal(path=key_path, data=seal_data, policy_path=policy_path) 42 | 43 | print(success) 44 | 45 | # pcr_data = b"abc" 46 | # pcr_digest = sha256(pcr_data) 47 | # fapi_ctx.pcr_extend(index=0,data=pcr_digest) 48 | 49 | unsealed_data = fapi_ctx.unseal(path=key_path) 50 | 51 | print(unsealed_data.decode('ascii')) 52 | 53 | # fapi_ctx.delete("/") 54 | fapi_ctx.close() -------------------------------------------------------------------------------- /pytss/profiles/P_ECCP256SHA256.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "TPM2_ALG_ECC", 3 | "nameAlg":"TPM2_ALG_SHA256", 4 | "srk_template": "system,restricted,decrypt,0x81000001", 5 | "srk_description": "Storage root key SRK", 6 | "srk_persistent": 0, 7 | "ek_template": "system,restricted,decrypt", 8 | "ek_description": "Endorsement key EK", 9 | "ecc_signing_scheme": { 10 | "scheme":"TPM2_ALG_ECDSA", 11 | "details":{ 12 | "hashAlg":"TPM2_ALG_SHA256" 13 | } 14 | }, 15 | "sym_mode":"TPM2_ALG_CFB", 16 | "sym_parameters": { 17 | "algorithm":"TPM2_ALG_AES", 18 | "keyBits":"128", 19 | "mode":"TPM2_ALG_CFB" 20 | }, 21 | "sym_block_size": 16, 22 | "pcr_selection": [ 23 | { "hash": "TPM2_ALG_SHA1", 24 | "pcrSelect": [ ] 25 | }, 26 | { "hash": "TPM2_ALG_SHA256", 27 | "pcrSelect": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ] 28 | } 29 | ], 30 | "curveID": "TPM2_ECC_NIST_P256", 31 | "ek_policy": { 32 | "description": "Endorsement hierarchy used for policy secret.", 33 | "policy":[ 34 | { 35 | "type":"POLICYSECRET", 36 | "objectName": "4000000b" 37 | } 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pytss/profiles/P_RSA2048SHA256.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "TPM2_ALG_RSA", 3 | "nameAlg":"TPM2_ALG_SHA256", 4 | "srk_template": "system,restricted,decrypt,0x81000001", 5 | "srk_description": "Storage root key SRK", 6 | "srk_persistent": 1, 7 | "ek_template": "system,restricted,decrypt", 8 | "ek_description": "Endorsement key EK", 9 | "rsa_signing_scheme": { 10 | "scheme":"TPM2_ALG_RSAPSS", 11 | "details":{ 12 | "hashAlg":"TPM2_ALG_SHA256" 13 | } 14 | }, 15 | "rsa_decrypt_scheme": { 16 | "scheme":"TPM2_ALG_OAEP", 17 | "details":{ 18 | "hashAlg":"TPM2_ALG_SHA256" 19 | } 20 | }, 21 | "sym_mode":"TPM2_ALG_CFB", 22 | "sym_parameters": { 23 | "algorithm":"TPM2_ALG_AES", 24 | "keyBits":"128", 25 | "mode":"TPM2_ALG_CFB" 26 | }, 27 | "sym_block_size": 16, 28 | "pcr_selection": [ 29 | { "hash": "TPM2_ALG_SHA1", 30 | "pcrSelect": [ ] 31 | }, 32 | { "hash": "TPM2_ALG_SHA256", 33 | "pcrSelect": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ] 34 | } 35 | ], 36 | "exponent": 0, 37 | "keyBits": 2048, 38 | "session_symmetric":{ 39 | "algorithm":"TPM2_ALG_AES", 40 | "keyBits":"128", 41 | "mode":"TPM2_ALG_CFB" 42 | }, 43 | "ek_policy": { 44 | "description": "Endorsement hierarchy used for policy secret.", 45 | "policy":[ 46 | { 47 | "type":"POLICYSECRET", 48 | "objectName": "4000000b" 49 | } 50 | ] 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /quote_verify/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require golang.org/x/sys v0.15.0 // indirect 13 | 14 | // replace github.com/google/go-tpm => ./go-tpm 15 | -------------------------------------------------------------------------------- /quote_verify/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 h1:LGYp08nFCGgxM/pRoE4etWElLB2WsrhJiBG4jK04MPE= 4 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 16 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 17 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 18 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /resource_manager/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Resource Manager 3 | 4 | Sample flow using the TPM directly vs the in-kernel Resource Manger 5 | 6 | - [TCG TSS 2.0 TAB and Resource Manager Specification](https://trustedcomputinggroup.org/wp-content/uploads/TSS_2p0_TAB_ResourceManager_v1p0_r18_04082019_pub.pdf) 7 | 8 | ### Direct to TPM 9 | 10 | ```bash 11 | export TPM2TOOLS_TCTI="device:/dev/tpm0" 12 | 13 | tpm2_flushcontext -t -l -s 14 | 15 | ## this should be empty 16 | tpm2_getcap handles-transient 17 | 18 | tpm2_createprimary -Q -C o -g sha1 -G rsa -c primary.ctx 19 | tpm2_getcap -T device:/dev/tpm0 handles-transient 20 | - 0x80000000 21 | 22 | 23 | tpm2_create -g sha256 -Q -G aes -u key.pub -r key.priv -C primary.ctx 24 | tpm2_getcap -T device:/dev/tpm0 handles-transient 25 | - 0x80000000 26 | - 0x80000001 27 | 28 | tpm2_load -Q -C primary.ctx -u key.pub -r key.priv -n key.name -c aes.ctx 29 | WARNING:esys:src/tss2-esys/api/Esys_Load.c:324:Esys_Load_Finish() Received TPM Error 30 | ERROR:esys:src/tss2-esys/api/Esys_Load.c:112:Esys_Load() Esys Finish ErrorCode (0x00000902) 31 | ERROR: Esys_Load(0x902) - tpm:warn(2.0): out of memory for object contexts 32 | ERROR: Unable to run tpm2_load 33 | 34 | ## flush the transient handles to make room 35 | tpm2_flushcontext -t 36 | tpm2_getcap handles-transient 37 | 38 | # now load the chain: 39 | tpm2_load -Q -C primary.ctx -u key.pub -r key.priv -n key.name -c aes.ctx 40 | 41 | echo "foo" > secret.dat 42 | openssl rand -out iv.bin 16 43 | tpm2_encryptdecrypt --iv iv.bin -c aes.ctx -o cipher.out secret.dat 44 | 45 | tpm2_flushcontext -t 46 | tpm2_getcap handles-transient 47 | tpm2_load -Q -C primary.ctx -u key.pub -r key.priv -n key.name -c aes.ctx 48 | tpm2_encryptdecrypt --iv iv.bin -c aes.ctx -d cipher.out 49 | ``` 50 | 51 | 52 | ### With Resource Manager 53 | 54 | ```bash 55 | export TPM2TOOLS_TCTI="device:/dev/tpmrm0" 56 | 57 | tpm2_flushcontext -t -l -s 58 | tpm2_getcap handles-transient 59 | 60 | tpm2_createprimary -Q -C o -g sha1 -G rsa -c primary.ctx 61 | tpm2_create -g sha256 -Q -G aes -u key.pub -r key.priv -C primary.ctx 62 | tpm2_load -Q -C primary.ctx -u key.pub -r key.priv -n key.name -c aes.ctx 63 | 64 | echo "foo" > secret.dat 65 | openssl rand -out iv.bin 16 66 | tpm2_encryptdecrypt --iv iv.bin -c aes.ctx -o cipher.out secret.dat 67 | tpm2_encryptdecrypt --iv iv.bin -c aes.ctx -d cipher.out 68 | ``` -------------------------------------------------------------------------------- /rsa_import/README.md: -------------------------------------------------------------------------------- 1 | # Importing an external key and load it ot the TPM 2 | 3 | 4 | ### create rsa key 5 | 6 | ```bash 7 | 8 | openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -out private.pem 9 | 10 | ``` 11 | 12 | ## using tpm2_tools 13 | 14 | ```bash 15 | tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx 16 | tpm2_import -C primary.ctx -G rsa -i private.pem -u key.pub -r key.prv 17 | tpm2_load -C primary.ctx -u key.pub -r key.prv -c key.ctx 18 | tpm2_evictcontrol -C o -c key.ctx 0x81010002 19 | 20 | 21 | 22 | ### remove prior handles (if any) 23 | tpm2_getcap handles-persistent 24 | - 0x81010002 25 | 26 | # to actually remove 27 | tpm2_evictcontrol -C o -c 0x81010002 28 | 29 | ``` 30 | 31 | 32 | ### create 33 | 34 | ```bash 35 | $ go run importExternalRSA.go --mode=create --keyPub key.pub --keyPriv=key.priv --pemFile=private.pem --handle=0x81010002 36 | 37 | 38 | ``` 39 | 40 | 41 | 42 | 43 | --- 44 | 45 | ```bash 46 | # more private.pem 47 | -----BEGIN RSA PRIVATE KEY----- 48 | MIIEowIBAAKCAQEA6T5pb0vvy8qBI00VnqZDDQt7qfAS4+fTnpLo+xFRwseUhe8D 49 | MD8PFreK54fRU8U7vHRc6fcx3qL0GxikdXU5q524SodNi7xV5peCi2jNNoQS0gHI 50 | 2VVPtmQqHqGiJN1H5SqKhtJAMPJsx5vS4edxzijX/DcbBP5kMbcLqc8iaH3M65jY 51 | yx8entT0U33boceRDhJWUerrNb0OUItOPStQPnj6BjMQim5mWsK/u8DD0eN1stMM 52 | Nc2QV14Nv9gn/dtDpe24El/730oU7JRB1X2NuUNlhU5BLBhdaAbCvA9oJr1yTO+y 53 | v/zVTWNTCQTPk2KG533EWsPy5slWOy7KStfD/QIDAQABAoIBAFxhSNc5B1f689zs 54 | egSlK2duReOP35t+xXVIEJjoSi7QZ4YInYWtZCeGOLDtPT5lnvxMRkSwkILynaZh 55 | wzl2XYoYZNa38kHHLWqwVZcrwiO2edHNvSQ/Qtwlnf0V3aemMQSWLdmqSpxYWDdT 56 | A1pQFeYmjS0rEjuPGlYKfscZ8DHb6AkVdTcJ2pZBPUuKB+lPKnI+i5W+7CeJTw2T 57 | lUqsFAS9rWxQDZxczvXmLk/Jm68LFS4I05tB7PFfUkublMdLUc3ck80meaCOeHcN 58 | HCSm89xecJwwHSL2UnDZ3jxu/O4w9mA4u5Q5M2bJQY/ijrd233tpOMTBATWMZ4UX 59 | mWZUnK0CgYEA980AmrTb/M9WXb7ZAxmbCC9qcYzhAWK6F64eyFZl7g1RjJMtSZHd 60 | plDq8KaT4SC6T/KuJXt2bCiFVDLXmE7V3fkhc8rUm1oM74GGCsZKWmtwgFUcRkNT 61 | ryqOnwvx2+jmlRnbF9dgmQeo9ZkOa6dc299qdEf+zAzd99VFHYhcOtMCgYEA8PYa 62 | utedfF3Z3CIHbTSKHLQ8yfhyXiM89/ePb/6QxTaDKB3ESAbuT+o7fyNMlrSGsNRz 63 | bgU2AudzGGslQ/sKPRlZrZVs9Bohq0vGpq9inTQ3x1QRV452iU2wo/7ifN/DJzw4 64 | z+t4+xdqz5gP44MwLQQakd22WTuuEqZDoqlGI+8CgYBXr+Rx2mQqPthqDfnPHgV9 65 | TQIWsmqAygXeEVB1RhWFupLL8tzItuQ/UU0B4YBc3u7vEYpMWzcZqPEdTWx7ShJm 66 | HR2YUwMPAjunmSbssyRmgLRrxTJfLr3zM1UKtPheADlwM5kTA7T8EfjZB9NRhwTW 67 | DWYnRb7FSBxX8dEmVTWF3wKBgCpgvha6MQJcZyJmAbRdFyUxNbe3sDWKMQDTUzC5 68 | LrDgg3Sct5aLUYJQiaI0jRW8LiwPUTW6SON93SogPe+UyRoxySnUK9NKfT1pGEjc 69 | c5V+R4kQ6fPiJErFlRlijGa129acqsk2epJ+bdSQw8qZmfFw1VNuENHkwxqYjzCe 70 | YK2VAoGBAJJLsLrmFAse7xUVzo4E7gDHIQW42OQRdW7rY5dWT1fWSZWqBlDox2mU 71 | JMohPgZdTlq/7Umb6O0nqRxAJT04381RKw+DxsQzMnKRDkc2gNe5qzBMKbdkSB6g 72 | R/C+mWqI7iiyT1xZSJK5Z1Fm/Hk688nzA1WOXKozwmNU4b3ANekA 73 | -----END RSA PRIVATE KEY----- 74 | ``` -------------------------------------------------------------------------------- /rsa_import/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /rsa_import/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 4 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 16 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 17 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 18 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /rsa_import/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD1fNomIrQYUAv+ 3 | ixnaxN/WWO/iqdyAbpbJJEhtzwi+CY1NaQizB5oJONRAFzxRsuGy3qhKx7ruZScz 4 | uSj4BO0WhxVFJI1kjIQkD60J887kz2X0fdwDsYfwkRmvjCuPwDd6/l7WX5AKgyv/ 5 | obF1k1fnSvqAENHtRI8NyEDmRd3EMwwTLgbpvZ3DSGnkU47gsLHL5fb/9GhicVly 6 | xZCDP/17e79/RxKsTMgjQYnv+Pt3fdMIn0yeJxBHsQhB4nQkkBqZlu4M4G0rKnst 7 | fubZQ1Hn5JHfON32KP7DoiZWBnfxJNGpg4hzNTHM0Wk4/Ke0fEPWPWvZZm48+Tj/ 8 | b6a4kdAlAgMBAAECggEAGREapXI9uY3S67cAeNpJkPWb6SU3ItYoB3nw+2V8mwsW 9 | pqTnAoDwNajb43975UvCyCT8QkaKy/UAP8PUbx7xpq88eMb2uSGwDI6dOLrwkWSs 10 | IH8JjEcAfowSd150xET4ZVK8FF/FsY0bXQsBt+PHwhJh6dnN1dB+WwXrupe/wVzR 11 | 2CQ5i4jR9seE8jhoPsiFf7psbcVDH5xwIPiUTOVsTSg8ob9ZBXLACZGSDPQDLzBY 12 | zllLOb3xorUOep0C/m2pxratPNQ/dTraHFX9D072ZkH4zZh/CO0qp5WsQidSuKCs 13 | 1wHaDqik1HY0H+ck3YH3WGgkELkihQz3qnVj05MpAQKBgQD8j+19ulFP4EtEFtRP 14 | CH/Rdp2gor4aWmLfV9b3aK4g0CM8erC3gDVxFeLrszbpbuDAsAM6s72gJaLxIlcV 15 | Xb/UrSbaJDtHcN2EmOI4/bus1TzSqIl1uPosV/9yqEQjRYTxs6DQsOzit5l4U1N4 16 | HSLe8XrSlYQ7P2u9ST28HTOtFQKBgQD41EXTtugxIm9PW3JNMCWx9X71fvbrwppY 17 | ik1rwPzt3JjdORLOq7elid18K7GxNBa4uie3NmrWyJbX8G8nQJdXqMlKGKLXU2JC 18 | DLpPs5dXI8d1K0/mRZdZgc+K1FX1zQFxzJ7jzwhd4iW1mS36AoHCJOUCgkTs0wh7 19 | lKS+9a/60QKBgQC5HjWQxhP7XAdO7PzIwQ4O1cZLi32Ti1SVJ6kkxtF6s5RgK/2D 20 | QrHpJYWiBUXma6LJGToEuOHwlCWOYQE7Y+/LTu7/TTc18gArxHNsGm6JC/L85RN7 21 | +g1Em2tc+wCWaco77tGcpVG8C56tl0XC8HgyuQSxfW3ij2XE4/4f97d80QKBgQCW 22 | M0yTJ+2w+yBFvuWYQl/+tDoW5rUWSznwCEwDp1MGIgsEPtdjebQ5cKcJtTZlyROO 23 | HpCqv2ZukFa9spzmDM9OUsxutcBWSjcdt6EfS0EnkKltyN9KGOfrV7h4DQR2g3FD 24 | yEiBKw/Z3BD3NafTKoA5ORwkD46bhiewsWFhA91egQKBgBPHkkpr16UYPVpVQlFl 25 | 0Qt3UWc7VO/y9YAApoKKUrG0w00ro9sbKxNONTj2wPiSHTUzO54TrC5UbvGWm4jq 26 | IUoIJP2amVHpu9ryidOU42USBI2uUzgshzzCE0RZfd6cRRN6z36WDZq8uaWLybZT 27 | ughoxNbZ+i2lriM4gMUwZsSi 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /sign_certify_ak/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Certify a Child Key with an AK. 5 | 6 | 1. Generate EK 7 | 2. Generate AK 8 | 3. Generate Child Key (k1) of EK that is unrestricted (`tpm2.FlagRestricted`) 9 | 4. Certify `k1` with AK 10 | 5. Verify Certification (note, [go-tpm/issues/262](https://github.com/google/go-tpm/issues/262)) 11 | 12 | At step 6, since you confirmed AK signed k1 and if you trust AK, you can trust the signature done by `k1` in step 4 13 | 14 | 15 | >> TODO: it would be better if `k1` is a child of AK but i could not figure that part out.... 16 | 17 | 18 | ```bash 19 | $ go run main.go 20 | 21 | 22 | 23 | ``` -------------------------------------------------------------------------------- /sign_certify_ak/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.4.4 10 | ) 11 | 12 | require ( 13 | github.com/google/go-configfs-tsm v0.2.2 // indirect 14 | golang.org/x/sys v0.15.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /sign_certify_ak/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 2 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 3 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 4 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 5 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 6 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 7 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 8 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 9 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 10 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 11 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 12 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 13 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 14 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 15 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 16 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 18 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 19 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 20 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 21 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 22 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 23 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= 24 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 25 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 26 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 27 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 28 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 29 | -------------------------------------------------------------------------------- /sign_with_ak/README.md: -------------------------------------------------------------------------------- 1 | 2 | # TPM Sign with AK 3 | 4 | ```bash 5 | tpm2_createek -c ek.ctx -G rsa -u ek.pub 6 | tpm2_createak -C ek.ctx -c ak.ctx -n ak.name -u ak.pub 7 | 8 | tpm2_readpublic -c ek.ctx -o ek.pem -f PEM 9 | 10 | cat ek.pem 11 | -----BEGIN PUBLIC KEY----- 12 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7U6d8qx3jNYczU/YUOwg 13 | yWgSQSvRRiTV5963lfUFTkbLfmbxCbsjysVMpJTDseO6JTnN7ogmRL8AjgKe3swH 14 | k6sfM1/pVnTLRb6fGANU043y8J3dUyRg6n3b2mUfbfCcH7fWwVMIk6ZpzwQ5l4Ib 15 | wD7g5EWZDTVkyPNC12MZFFozk506gPQJWXzzM7N+Dq0tjkKhBkygewiKh+nY8wmg 16 | bR31x3/kp8sStqLEbWgstpZKEq20AJux/NFdwqXtSRmwbiVDqwIsn5qrmECNW0OZ 17 | 35WYmGVajAOcdlXcWUzeyh4l47ut9GbYsnAX8kkxpfQ4fTHHwmhNSfS4TwQwDBSM 18 | +wIDAQAB 19 | -----END PUBLIC KEY----- 20 | 21 | 22 | echo "meet me at.." > message.txt 23 | 24 | tpm2_hash -C e -g sha256 -o hash.bin -t ticket.bin message.txt 25 | 26 | ## w/o ticket 27 | tpm2_sign -c ak.ctx -g sha256 -o sig.rssa message.txt 28 | ERROR: Eys_Sign(0x3E0) - tpm:parameter(3):invalid ticket 29 | ERROR: Unable to run tpm2_sign 30 | 31 | ## w/ ticket 32 | 33 | tpm2_sign -c ak.ctx -g sha256 -o sig.rssa -t ticket.bin message.txt 34 | 35 | tpm2_verifysignature -c ak.ctx -g sha256 -s sig.rssa -m message.txt 36 | ``` 37 | 38 | 39 | ```bash 40 | $ go run main.go 41 | 42 | 2024/09/30 11:35:43 ======= Init ======== 43 | 2024/09/30 11:35:43 ======= EK ======== 44 | 2024/09/30 11:35:43 Name 000b9a04eaa73cc7ed6556b8874ea2eade41b9f564b024ef98782065192542e1fc33 45 | 2024/09/30 11:35:43 RSA createPrimary public 46 | -----BEGIN PUBLIC KEY----- 47 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7U6d8qx3jNYczU/YUOwg 48 | yWgSQSvRRiTV5963lfUFTkbLfmbxCbsjysVMpJTDseO6JTnN7ogmRL8AjgKe3swH 49 | k6sfM1/pVnTLRb6fGANU043y8J3dUyRg6n3b2mUfbfCcH7fWwVMIk6ZpzwQ5l4Ib 50 | wD7g5EWZDTVkyPNC12MZFFozk506gPQJWXzzM7N+Dq0tjkKhBkygewiKh+nY8wmg 51 | bR31x3/kp8sStqLEbWgstpZKEq20AJux/NFdwqXtSRmwbiVDqwIsn5qrmECNW0OZ 52 | 35WYmGVajAOcdlXcWUzeyh4l47ut9GbYsnAX8kkxpfQ4fTHHwmhNSfS4TwQwDBSM 53 | +wIDAQAB 54 | -----END PUBLIC KEY----- 55 | 56 | 2024/09/30 11:35:44 RSA Attestation Key 57 | -----BEGIN PUBLIC KEY----- 58 | spFymZ7eHkFcEoRzYnM7Jx85w0VXsmt8Mjun3p2q+S5C38VgrUB2Ll3FryvMfjEW 59 | WLEmcltzj7vq23afkLFArkWFVATSOZclOpDUzPXgk33T6+qYhgkYY3GgoQ3zk+pu 60 | 5F3sUZZgEUwbe/26yt9Zj8d3V7KKJ/PcjH3La+TlhhEzT6S2igrZuBWI9sRU8fWG 61 | /uYPMgJSVkAHPJVOTamnENXClZwDkZCgfZov2moQsb31XBNfIWNm5GzQqbzrSG4G 62 | 61JzYdtXIj4xzJ14u/eFYouEk0pRvVmw21CcfZUFjb8svrJRr9z0jbNeXqPff16R 63 | xrKqANCWoQDOen471LGRZw== 64 | -----END PUBLIC KEY----- 65 | 66 | 2024/09/30 11:35:44 ======= generate test signature with RSA key ======== 67 | 2024/09/30 11:35:44 signature: Y/nrXl18MCJ8SIcbilJKt9Ioe/tsQLrqQSYj4YL+doNrGUiRBB4ACtEQ5gpa4IJIBm6/Z+tb4MDL/NJiCEFD6I7XHgzgIj6RZ6KN9nGtyjcTT64m6Rb0FXjBBP3mGVtzRIc0Uy1/DFi67JyfNmaVxTbjpz1UZnwuEjEAGzONXuV7n5rP/OpSXriHIsvja5GCwKVigHprcWz2i68gDoxHKnGbPojAx2tgT7vKwtAndLQvc7o//Hv5yB/Kn7PwY9bOhSS2Ubpdkr8yvXF7CtvSokNuuzThwy6vu7d0r32l9QDh1cVRhYjxEq5kB936tJlR9n5maRLIgvkB5TKwz5htQA== 68 | 69 | ``` -------------------------------------------------------------------------------- /sign_with_ak/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.4.4 10 | ) 11 | 12 | require ( 13 | github.com/google/go-configfs-tsm v0.2.2 // indirect 14 | golang.org/x/sys v0.15.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /sign_with_ak/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 2 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 3 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 4 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 5 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 6 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 7 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 8 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 9 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 10 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 11 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 12 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 13 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 14 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 15 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 16 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 18 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 19 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 20 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 21 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 22 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 23 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= 24 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 25 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 26 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 27 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 28 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 29 | -------------------------------------------------------------------------------- /sign_with_ecc/README.md: -------------------------------------------------------------------------------- 1 | 2 | # TPM Sign with ECC 3 | 4 | ```bash 5 | tpm2_createprimary -C e -c primary.ctx 6 | tpm2_create -G ecc -u key.pub -r key.priv -C primary.ctx 7 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 8 | tpm2_evictcontrol -C o -c key.ctx 0x81008002 9 | 10 | echo "my message" > message.dat 11 | tpm2_sign -c key.ctx -g sha256 -o sig.ecc message.dat 12 | tpm2_verifysignature -c key.ctx -g sha256 -s sig.ecc -m message.dat 13 | ``` 14 | 15 | 16 | --- 17 | 18 | ``` 19 | # go run svcaccount/main.go 20 | ======= Key persisted ======== 21 | ======= Sign with new RSA ======== 22 | Signature data: L4LkdyjpqaPWpcZXeHV9bMs0xmGRQpXMHeLuosTLxCaljpdmk9TbDGaHS1zqhUYV85ZnbqsvTgYeP0auierHXOOINBV1kbKuoihZJhsbyfmcIpIdoHItRwPM/sTH3fl4ZxcASSiZSC6F6b38Q6J75xQPqAT93Ua0n7LeWdcP/er8eed6yPISdScF/+B/45LmqT/y+3rVTlhRgBLvTm846ifL/1XzUMdcSRq3OOk0UYDNh3IfbQXTg7lFRtgo6hxy+rsUNwwy0Ip54wZXftalVx9+dfrB9ZlHW1c9KF1WObmu+noPEDlex0AoZ4sB3FtTcJj/glXZovP9KKjSjeSkTA 23 | RSA Signing Key 24 | -----BEGIN PUBLIC KEY----- 25 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvJamgslhqX9leS7CJGb4 26 | sOuKhvzSYYjKpocEko3EdhrZlw4Y0ufkeCRV4IQtWe74CZvHNeXzjsf3pFDHGXs1 27 | RMCUJ8u+By54OIMCQFBwmmg6/8lfu/WhXDY/PgdwuAocaAAYuqfj29vIxG/8Y9KX 28 | qZJ3S8o0aP+cLX+C7lU5k/1kS5n4w2BnmUXi9jsfCJ3kBMxXduQdy4zd4Tml450x 29 | ypcAQOI8u7qt0Xam6cMMu2wwJGvIewnkQaVY7P4o+qRRsc42wXsQ3gl8xpkjQFmO 30 | dApWjF2olxUTh20iZfjJLyIyIJf61QC02c9evqC6Q1pHZ23+FWXc/5b9M2HvAIVl 31 | qwIDAQAB 32 | -----END PUBLIC KEY----- 33 | 34 | signature Verified 35 | 36 | ``` -------------------------------------------------------------------------------- /sign_with_ecc/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /sign_with_ecc/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 4 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 16 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 17 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 18 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /sign_with_rsa/README.md: -------------------------------------------------------------------------------- 1 | 2 | # TPM Sign with RSA 3 | 4 | ```bash 5 | echo "my message" > message.dat 6 | 7 | tpm2_createprimary -C o -c primary.ctx -Q 8 | tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx -Q 9 | 10 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 11 | tpm2_readpublic -c key.ctx -o key.pem -f PEM -Q 12 | 13 | cat key.pem 14 | 15 | tpm2_sign -c key.ctx -g sha256 -o sig.rssa message.dat 16 | tpm2_verifysignature -c key.ctx -g sha256 -s sig.rssa -m message.dat 17 | 18 | ### openssl 19 | sha256sum message.dat | awk '{ print "000000 " $1 }' | xxd -r -c 32 > data.in.digest 20 | tpm2_sign -Q -c key.ctx -g sha256 -d -f plain -o data.out.signed data.in.digest 21 | openssl dgst -verify key.pem -keyform pem -sha256 -signature data.out.signed message.dat 22 | 23 | ``` 24 | 25 | 26 | --- 27 | 28 | ```bash 29 | # go run svcaccount/main.go 30 | ======= Key persisted ======== 31 | ======= Sign with new RSA ======== 32 | Signature data: L4LkdyjpqaPWpcZXeHV9bMs0xmGRQpXMHeLuosTLxCaljpdmk9TbDGaHS1zqhUYV85ZnbqsvTgYeP0auierHXOOINBV1kbKuoihZJhsbyfmcIpIdoHItRwPM/sTH3fl4ZxcASSiZSC6F6b38Q6J75xQPqAT93Ua0n7LeWdcP/er8eed6yPISdScF/+B/45LmqT/y+3rVTlhRgBLvTm846ifL/1XzUMdcSRq3OOk0UYDNh3IfbQXTg7lFRtgo6hxy+rsUNwwy0Ip54wZXftalVx9+dfrB9ZlHW1c9KF1WObmu+noPEDlex0AoZ4sB3FtTcJj/glXZovP9KKjSjeSkTA 33 | RSA Signing Key 34 | -----BEGIN PUBLIC KEY----- 35 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvJamgslhqX9leS7CJGb4 36 | sOuKhvzSYYjKpocEko3EdhrZlw4Y0ufkeCRV4IQtWe74CZvHNeXzjsf3pFDHGXs1 37 | RMCUJ8u+By54OIMCQFBwmmg6/8lfu/WhXDY/PgdwuAocaAAYuqfj29vIxG/8Y9KX 38 | qZJ3S8o0aP+cLX+C7lU5k/1kS5n4w2BnmUXi9jsfCJ3kBMxXduQdy4zd4Tml450x 39 | ypcAQOI8u7qt0Xam6cMMu2wwJGvIewnkQaVY7P4o+qRRsc42wXsQ3gl8xpkjQFmO 40 | dApWjF2olxUTh20iZfjJLyIyIJf61QC02c9evqC6Q1pHZ23+FWXc/5b9M2HvAIVl 41 | qwIDAQAB 42 | -----END PUBLIC KEY----- 43 | 44 | signature Verified 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /sign_with_rsa/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /sign_with_rsa/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003 h1:gfGQAIxsEEAuYuFvjCGpDnTwisMJOz+rUfJMkk4yTmc= 4 | github.com/google/go-tpm v0.9.1-0.20240510201744-5c2f0887e003/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 6 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 7 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 8 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 9 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 10 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 11 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 12 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 13 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 14 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 15 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 16 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 17 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 18 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 19 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 20 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 21 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 22 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 23 | -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### Using software TPM (swtpm) to trace API calls with TCPDump 3 | 4 | 5 | If you want to capture raw API calls with software TPM, start it first as a socket 6 | 7 | ```bash 8 | mkdir /tmp/myvtpm 9 | sudo swtpm_setup --tpmstate /tmp/myvtpm --tpm2 --create-ek-cert 10 | sudo swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear 11 | 12 | 13 | export TPM2TOOLS_TCTI="swtpm:port=2321" 14 | export TPM2OPENSSL_TCTI="swtpm:port=2321" 15 | export TPM2TSSENGINE_TCTI="swtpm:port=2321" 16 | export OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/ # or wherever tpm2.so sits, eg /usr/lib/x86_64-linux-gnu/ossl-modules/tpm2.so 17 | export TSS2_LOG=esys+debug 18 | ``` 19 | 20 | To verify connectivity with `tpm2_tools`: 21 | 22 | ```bash 23 | export TPM2TOOLS_TCTI="swtpm:port=2321" 24 | tpm2_pcrread sha256:23 25 | sha256: 26 | 23: 0x0000000000000000000000000000000000000000000000000000000000000000 27 | 28 | tpm2_pcrextend 23:sha256=0x0000000000000000000000000000000000000000000000000000000000000000 29 | 30 | tpm2_pcrread sha256:23 31 | sha256: 32 | 23: 0xF5A5FD42D16A20302798EF6ED309979B43003D2320D9F0E8EA9831A92759FB4B 33 | 34 | ## note, tpm2_tools assumes resource manager so we need ot flush manually 35 | 36 | ## RSA 37 | tpm2_createprimary -C e -c primary.ctx 38 | tpm2_create -G rsa2048:rsassa:null -g sha256 -u key.pub -r key.priv -C primary.ctx 39 | tpm2_flushcontext -t 40 | tpm2_getcap handles-transient 41 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 42 | tpm2_evictcontrol -C o -c key.ctx 0x81008001 43 | 44 | ## RSA-PSS 45 | tpm2_createprimary -C e -c primary.ctx 46 | tpm2_create -G rsa2048:rsapss:null -g sha256 -u key.pub -r key.priv -C primary.ctx 47 | tpm2_flushcontext -t 48 | tpm2_getcap handles-transient 49 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 50 | tpm2_evictcontrol -C o -c key.ctx 0x81008001 51 | 52 | ## ECC 53 | tpm2_createprimary -C e -c primary.ctx 54 | tpm2_create -G ecc:ecdsa -g sha256 -u key.pub -r key.priv -C primary.ctx 55 | tpm2_flushcontext -t 56 | tpm2_getcap handles-transient 57 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 58 | tpm2_evictcontrol -C o -c key.ctx 0x81008002 59 | ``` 60 | 61 | For openssl 62 | 63 | ```bash 64 | export TPM2OPENSSL_TCTI="swtpm:port=2321" 65 | tpm2tss-genkey -a rsa -s 2048 private.pem 66 | 67 | ## with https://github.com/tpm2-software/tpm2-openssl 68 | openssl asn1parse -inform PEM -in private.pem 69 | openssl rsa -provider tpm2 -provider default -in private.pem --text 70 | ``` 71 | 72 | 73 | To capture a command trace, run `tcpdump` 74 | 75 | ```bash 76 | sudo tcpdump -s0 -ilo -w trace.cap port 2321 77 | ``` 78 | 79 | In our code, open as a tcp connection: 80 | 81 | ```golang 82 | package main 83 | 84 | import ( 85 | "github.com/google/go-tpm-tools/simulator" 86 | "github.com/google/go-tpm/tpm2" 87 | "github.com/google/go-tpm/tpm2/transport" 88 | "github.com/google/go-tpm/tpmutil" 89 | ) 90 | 91 | var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"} 92 | 93 | func OpenTPM(path string) (io.ReadWriteCloser, error) { 94 | if slices.Contains(TPMDEVICES, path) { 95 | return tpmutil.OpenTPM(path) 96 | } else if path == "simulator" { 97 | return simulator.GetWithFixedSeedInsecure(1073741825) 98 | } else { 99 | return net.Dial("tcp", path) 100 | } 101 | } 102 | 103 | func main() { 104 | rwc, err := OpenTPM("127.0.0.1:2321") 105 | if err != nil { 106 | log.Fatalf("can't open TPM %v", err) 107 | } 108 | defer func() { 109 | rwc.Close() 110 | }() 111 | 112 | rwr := transport.FromReadWriter(rwc) 113 | } 114 | 115 | ``` 116 | 117 | 118 | then open up the trace in wireshark 119 | 120 | ```bash 121 | wireshark trace.cap 122 | ``` 123 | 124 | you can see the command request and responses. It seems the pcrread command dissector doesn't show the responses that cleanly: 125 | 126 | ![images/pcr.png](images/pcr.png) 127 | 128 | compare that with unseal 129 | 130 | ![images/unseal.png](images/unseal.png) 131 | 132 | where the highlighted bit is what i unsealed (`0006736563726574` --> `secret`) 133 | 134 | -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.2 4 | -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/images/pcr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/simulator_swtpm_tcpdump/images/pcr.png -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/images/unseal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/simulator_swtpm_tcpdump/images/unseal.png -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/pcr.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/simulator_swtpm_tcpdump/pcr.cap -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/pcr.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net" 9 | "slices" 10 | 11 | "github.com/google/go-tpm-tools/simulator" 12 | "github.com/google/go-tpm/tpm2" 13 | "github.com/google/go-tpm/tpm2/transport" 14 | "github.com/google/go-tpm/tpmutil" 15 | ) 16 | 17 | const () 18 | 19 | var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"} 20 | 21 | func OpenTPM(path string) (io.ReadWriteCloser, error) { 22 | if slices.Contains(TPMDEVICES, path) { 23 | return tpmutil.OpenTPM(path) 24 | } else if path == "simulator" { 25 | return simulator.GetWithFixedSeedInsecure(1073741825) 26 | } else { 27 | return net.Dial("tcp", path) 28 | } 29 | } 30 | 31 | func main() { 32 | rwc, err := OpenTPM("127.0.0.1:2321") 33 | if err != nil { 34 | log.Fatalf("can't open TPM %v", err) 35 | } 36 | defer func() { 37 | rwc.Close() 38 | }() 39 | 40 | rwr := transport.FromReadWriter(rwc) 41 | 42 | pcrRead := tpm2.PCRRead{ 43 | PCRSelectionIn: tpm2.TPMLPCRSelection{ 44 | PCRSelections: []tpm2.TPMSPCRSelection{ 45 | { 46 | Hash: tpm2.TPMAlgSHA256, 47 | PCRSelect: tpm2.PCClientCompatible.PCRs(23), 48 | }, 49 | }, 50 | }, 51 | } 52 | 53 | pcrReadRsp, err := pcrRead.Execute(rwr) 54 | if err != nil { 55 | panic(err) 56 | } 57 | 58 | for _, d := range pcrReadRsp.PCRValues.Digests { 59 | fmt.Printf("hex: %s\n", hex.EncodeToString(d.Buffer)) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/unseal.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/simulator_swtpm_tcpdump/unseal.cap -------------------------------------------------------------------------------- /simulator_swtpm_tcpdump/unseal.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "io" 6 | "log" 7 | "net" 8 | "slices" 9 | 10 | "github.com/google/go-tpm-tools/simulator" 11 | "github.com/google/go-tpm/tpm2" 12 | "github.com/google/go-tpm/tpm2/transport" 13 | "github.com/google/go-tpm/tpmutil" 14 | ) 15 | 16 | const () 17 | 18 | var ( 19 | tpmPath = flag.String("tpm-path", "/dev/tpm0", "Path to the TPM device (character device or a Unix socket).") 20 | dataToSeal = flag.String("datatoseal", "secret", "data to sign") 21 | ) 22 | 23 | var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"} 24 | 25 | func OpenTPM(path string) (io.ReadWriteCloser, error) { 26 | if slices.Contains(TPMDEVICES, path) { 27 | return tpmutil.OpenTPM(path) 28 | } else if path == "simulator" { 29 | return simulator.GetWithFixedSeedInsecure(1073741825) 30 | } else { 31 | return net.Dial("tcp", path) 32 | } 33 | } 34 | func main() { 35 | flag.Parse() 36 | 37 | log.Println("======= Init ========") 38 | 39 | //rwc, err := tpmutil.OpenTPM(*tpmPath) 40 | //rwc, err := simulator.GetWithFixedSeedInsecure(1073741825) 41 | 42 | rwc, err := OpenTPM("127.0.0.1:2321") 43 | if err != nil { 44 | log.Fatalf("can't open TPM %q: %v", *tpmPath, err) 45 | } 46 | defer func() { 47 | rwc.Close() 48 | }() 49 | 50 | rwr := transport.FromReadWriter(rwc) 51 | 52 | log.Printf("======= createPrimary ========") 53 | 54 | // create a primary with auth with a session that is encrypted using the EK 55 | 56 | srkAuth := []byte("mySRK") 57 | primaryKey, err := tpm2.CreatePrimary{ 58 | PrimaryHandle: tpm2.TPMRHOwner, 59 | InPublic: tpm2.New2B(tpm2.RSASRKTemplate), 60 | InSensitive: tpm2.TPM2BSensitiveCreate{ 61 | Sensitive: &tpm2.TPMSSensitiveCreate{ 62 | UserAuth: tpm2.TPM2BAuth{ 63 | Buffer: srkAuth, 64 | }, 65 | }, 66 | }, 67 | }.Execute(rwr) 68 | if err != nil { 69 | log.Fatalf("can't create primary %v", err) 70 | } 71 | 72 | defer func() { 73 | flushContextCmd := tpm2.FlushContext{ 74 | FlushHandle: primaryKey.ObjectHandle, 75 | } 76 | _, _ = flushContextCmd.Execute(rwr) 77 | }() 78 | 79 | // rsa 80 | 81 | log.Printf("======= create key ========") 82 | 83 | // create a Key with auth with a password and some data to seal 84 | // // Use HMAC auth to authorize the rest of the Create commands 85 | // use the newprimary key 86 | 87 | data := []byte(*dataToSeal) 88 | auth := []byte("passw0rd") 89 | 90 | createBlobRsp, err := tpm2.Create{ 91 | ParentHandle: tpm2.AuthHandle{ 92 | Handle: primaryKey.ObjectHandle, 93 | Name: primaryKey.Name, 94 | Auth: tpm2.PasswordAuth(srkAuth), 95 | }, 96 | InPublic: tpm2.New2B(tpm2.TPMTPublic{ 97 | Type: tpm2.TPMAlgKeyedHash, 98 | NameAlg: tpm2.TPMAlgSHA256, 99 | ObjectAttributes: tpm2.TPMAObject{ 100 | FixedTPM: true, 101 | FixedParent: true, 102 | UserWithAuth: true, 103 | NoDA: true, 104 | }, 105 | }), 106 | InSensitive: tpm2.TPM2BSensitiveCreate{ 107 | Sensitive: &tpm2.TPMSSensitiveCreate{ 108 | UserAuth: tpm2.TPM2BAuth{ 109 | Buffer: auth, 110 | }, 111 | Data: tpm2.NewTPMUSensitiveCreate(&tpm2.TPM2BSensitiveData{ 112 | Buffer: data, 113 | }), 114 | }, 115 | }, 116 | }.Execute(rwr) 117 | if err != nil { 118 | log.Fatalf("can't create blob %v", err) 119 | } 120 | 121 | // Load the sealed blob 122 | loadBlobCmd := tpm2.Load{ 123 | ParentHandle: tpm2.AuthHandle{ 124 | Handle: primaryKey.ObjectHandle, 125 | Name: primaryKey.Name, 126 | Auth: tpm2.PasswordAuth(srkAuth), 127 | }, 128 | InPrivate: createBlobRsp.OutPrivate, 129 | InPublic: createBlobRsp.OutPublic, 130 | } 131 | loadBlobRsp, err := loadBlobCmd.Execute(rwr) 132 | if err != nil { 133 | log.Fatalf("can't create blob %v", err) 134 | } 135 | 136 | defer func() { 137 | flushBlobCmd := tpm2.FlushContext{FlushHandle: loadBlobRsp.ObjectHandle} 138 | if _, err := flushBlobCmd.Execute(rwr); err != nil { 139 | log.Fatalf("can't close flush blob %v", err) 140 | } 141 | }() 142 | 143 | log.Println("Created blob") 144 | 145 | // unseal with standalone session 146 | log.Println("======= unsealing ========") 147 | //defer cleanup() 148 | 149 | unsealRsp, err := tpm2.Unseal{ 150 | ItemHandle: tpm2.AuthHandle{ 151 | Handle: loadBlobRsp.ObjectHandle, 152 | Name: loadBlobRsp.Name, 153 | Auth: tpm2.PasswordAuth(auth), 154 | }, 155 | }.Execute(rwr) 156 | 157 | if err != nil { 158 | log.Fatalf("can't unseal %v", err) 159 | } 160 | 161 | log.Printf("Unsealed %s\n", string(unsealRsp.OutData.Buffer)) 162 | } 163 | -------------------------------------------------------------------------------- /srk_seal_unseal/README.md: -------------------------------------------------------------------------------- 1 | # SEAL DATA TO TPM using PCR value at back 23 2 | 3 | 4 | 5 | - Define policy file: 6 | ```bash 7 | tpm2_pcrread sha256:23 -o pcr23_val.bin 8 | tpm2_createpolicy --policy-pcr -l sha256:23 -L policy.file -f pcr23_val.bin 9 | 10 | echo "foo" > secret.dat 11 | 12 | # optionally seed the "unique" bit 13 | # https://github.com/tpm2-software/tpm2-tools/issues/2378 14 | printf '\x00\x01' > ud.1 15 | dd if=/dev/random bs=256 count=1 of=ud.2 16 | cat ud.1 ud.2 > unique.dat 17 | 18 | tpm2_createprimary -C o -c primary.ctx -u unique.dat 19 | echo "my sealed data" > seal.dat 20 | tpm2_create -C primary.ctx -i seal.dat -u key.pub -r key.priv -L policy.file 21 | tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx 22 | 23 | tpm2_unseal -o unseal.dat -c key.ctx -p"pcr:sha256:23=pcr23_val.bin" 24 | 25 | cat unseal.dat 26 | ``` 27 | 28 | otherwise, with a pcrextend, you can't unseal 29 | 30 | ``` 31 | $ tpm2_pcrextend 23:sha256=0xC78009FDF07FC56A11F122370658A353AAA542ED63E44C4BC15FF4CD105AB33C 32 | $ tpm2_pcrread sha256:23 33 | sha256: 34 | 23: 0x536D98837F2DD165A55D5EEAE91485954472D56F246DF256BF3CAE19352A123C 35 | ``` 36 | 37 | ```bash 38 | tpm2_unseal -o unseal.dat -c key.ctx -p"pcr:sha256:23=pcr23_val.bin" 39 | WARNING:esys:src/tss2-esys/api/Esys_Unseal.c:291:Esys_Unseal_Finish() Received TPM Error 40 | ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:98:Esys_Unseal() Esys Finish ErrorCode (0x0000099d) 41 | ERROR: Esys_Unseal(0x99D) - tpm:session(1):a policy check failed 42 | ERROR: Unable to run tpm2_unseal 43 | ``` 44 | 45 | --- 46 | -------------------------------------------------------------------------------- /srk_seal_unseal/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require golang.org/x/sys v0.15.0 // indirect 13 | 14 | // replace ( 15 | // github.com/google/go-tpm => "./go-tpm" 16 | // ) 17 | -------------------------------------------------------------------------------- /srk_seal_unseal/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 h1:LGYp08nFCGgxM/pRoE4etWElLB2WsrhJiBG4jK04MPE= 4 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 16 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 17 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 18 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /tpm-key/rsa_sign/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240805214234-f870d6f1ff68 9 | github.com/google/go-tpm v0.9.1-0.20240514145214-58e3e47cd434 10 | github.com/google/go-tpm-tools v0.4.4 11 | ) 12 | 13 | require ( 14 | golang.org/x/crypto v0.19.0 // indirect 15 | golang.org/x/sys v0.21.0 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /tpm-key/rsa_sign/go.sum: -------------------------------------------------------------------------------- 1 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240805214234-f870d6f1ff68 h1:u1Lbb2hWuU302IAaCccDkzPWLgpMBfvva/EMDutEUXk= 2 | github.com/foxboron/go-tpm-keyfiles v0.0.0-20240805214234-f870d6f1ff68/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= 3 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= 4 | github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= 5 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 6 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 7 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 8 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 9 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 10 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 11 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 12 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 13 | github.com/google/go-tpm v0.9.1-0.20240514145214-58e3e47cd434 h1:uPadaCeI0VnloLvthGLalr0Io0IDoI1VEQ95APzVAiw= 14 | github.com/google/go-tpm v0.9.1-0.20240514145214-58e3e47cd434/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 15 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 16 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 17 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 18 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 19 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 20 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 21 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 22 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 23 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 24 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 25 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 26 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 27 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 28 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 29 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 30 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 31 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 32 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 33 | -------------------------------------------------------------------------------- /tpm-key/rsa_sign/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN TSS2 PRIVATE KEY----- 2 | MIIELwYGZ4EFCgEDAgUAgAAAAQSCATgBNgABAAsABgRyACA8h6Sz+4Xr7qWMX7Nq 3 | wi0/KAzsJ6n23Q+iO+nOVg3uyAAQABAIAAAAAAABAKVYjm6TVp5J4yfPT/vxJfQd 4 | iVP72I8cOSG7VHif+CHpafbQP0nmBoOSoC9a3NGhHSCjjXs397Wk7CyMliCUm1vF 5 | UGP8JlzHEctnWAj/yFXBIaVHHU4XfiI4yUBxRfEB6XqT02AFgeD+Iqj40rmtxwms 6 | Gne19X9dVQnfN+MrNJozJaNsj3XP9OIAaVHuXF15LSw/7ecIpipo853KHUcDS55h 7 | VYZc3Op9VZGZqcWGA3j4hJSaHLm+rTNNYHGHmwN+P8qxqg/x8tJVcS1wYlvpBYrN 8 | xlwWnuuPBKFarcHNknfwLxeVnO6bqEXMHGcMm+A/vNLoqk3yy4x6Q3ICVKiMGMcE 9 | ggLgAt4AIMGTdl7pxrHEGHsoTm5tb90LCkXp5IxNKSe+g/B9OAmZABALUNwTiY8C 10 | HV6kIlnVsPipBzwZjAzN3Y5g44A2DtQslnZ5v2WynN9GyUpQ42w9Y1pn5St8RWXx 11 | 73dYb7FuE8DG5aEJBnBjooBP65IT8U8Tj+gQJkfWriR3ovxHfcR8adNgoU5P/F3v 12 | A5fkkG235SaJi8uACZrYTwH16q2bRSjeyOByHUa5yyxwbn9pnmto40eXDS7iCaz5 13 | ukPmeOqWDI2XvAVV5aDmsm+OsJojCgp6SgKyPcL0RYP5LV5a7hyBpEcotXLf7jn5 14 | QlxSya/Y0qVhBGhRhb+L010UuEE3DAbZCoVJoW6goK0q+CsTWOC4TBgS0erzFIvh 15 | 0LHsLaHxP+IqK2MbDiiIou63YNaOTKVlWB2es7qLd2cS5GRyR/vgpBByxv8G+D1f 16 | zX5uEEGKRF/oEdHWu093DofaN5BjooY2Lp80obHY3+hxzM/YfwF6py4tZK3HM7fi 17 | rLhh/1ZT5RSgcF2gB90mkt91QIFQUAGcYnIahPv7+EYSGhbrZTiWUfDRqoMltkJo 18 | g/OfOLVpKJ0+ofBxwgfQB7u+Vl63XI4AKFoCySq40z50fBWJLtJ7Ob+Qqy53T/Lo 19 | WFjIVb7jUWlIm2SMtcOGy/bPzlHF/hu6u518Do4W8xcYONcPSYWaj/6sDuCgCeNG 20 | 2sANN8woUZOMJlJBqtbAzto5RUoztv6W3EwS2icIeoodVFcBgzxwzR91y5161LO6 21 | X0v0cQtaAJoWT/OtIU+NeFFpwD46+n/LGPiyr0ukbnPzYufQncCCIAY23ffVRJ01 22 | e/wE//1juxMe9i/V8k8SMZbeWwlNp1y0Uzgdh13tNdQTj4690ncyIFpRmYvChyY9 23 | 9DF1okUEpiXqrifH53odtKDloJ9IK0bEMvjNv93EhFpr0BOhJTIXY+NgbVfFRZd9 24 | MyqePdvdNRigGtJo2infNwyYsw== 25 | -----END TSS2 PRIVATE KEY----- 26 | -------------------------------------------------------------------------------- /tpm2_duplicate_go/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 9 | github.com/google/go-tpm-tools v0.4.4 10 | google.golang.org/protobuf v1.31.0 11 | ) 12 | 13 | require ( 14 | github.com/golang/protobuf v1.5.3 // indirect 15 | github.com/google/go-configfs-tsm v0.2.2 // indirect 16 | github.com/google/go-sev-guest v0.9.3 // indirect 17 | github.com/google/go-tdx-guest v0.3.1 // indirect 18 | github.com/google/logger v1.1.1 // indirect 19 | github.com/google/uuid v1.3.1 // indirect 20 | github.com/pborman/uuid v1.2.1 // indirect 21 | github.com/pkg/errors v0.9.1 // indirect 22 | go.uber.org/multierr v1.11.0 // indirect 23 | golang.org/x/crypto v0.17.0 // indirect 24 | golang.org/x/sys v0.15.0 // indirect 25 | ) 26 | -------------------------------------------------------------------------------- /tpm2_duplicate_go/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 4 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 5 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 6 | github.com/google/certificate-transparency-go v1.1.2 h1:4hE0GEId6NAW28dFpC+LrRGwQX5dtmXQGDbg8+/MZOM= 7 | github.com/google/certificate-transparency-go v1.1.2/go.mod h1:3OL+HKDqHPUfdKrHVQxO6T8nDLO0HF7LRTlkIWXaWvQ= 8 | github.com/google/go-attestation v0.5.0 h1:jXtAWT2sw2Yu8mYU0BC7FDidR+ngxFPSE+pl6IUu3/0= 9 | github.com/google/go-attestation v0.5.0/go.mod h1:0Tik9y3rzV649Jcr7evbljQHQAsIlJucyqQjYDBqktU= 10 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 11 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 12 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 13 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 14 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 15 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 16 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 17 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 18 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 19 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623 h1:LGYp08nFCGgxM/pRoE4etWElLB2WsrhJiBG4jK04MPE= 20 | github.com/google/go-tpm v0.9.1-0.20240411180339-1fb84445f623/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 21 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 22 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 23 | github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= 24 | github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= 25 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 26 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 27 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 28 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 29 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 30 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 31 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 32 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 33 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 34 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 35 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 36 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= 37 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 38 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 39 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 40 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= 41 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 42 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 43 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 44 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 45 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 46 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 47 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 48 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 49 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 50 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 51 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 52 | -------------------------------------------------------------------------------- /tpm2_get_name/README.md: -------------------------------------------------------------------------------- 1 | # Get EK "Name" 2 | 3 | Sample program that uses the PEM format of a Key to get its "name" from the RSA Public key 4 | 5 | 6 | ```bash 7 | $ go run main.go 8 | Name 000b7d5ae2283593ce63281bd4a5b681b50ceff54a49e17ee6e40bc8e82f47967d55 9 | PEM 10 | -----BEGIN PUBLIC KEY----- 11 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnMDg8UTDAfb8+wdYQFbz 12 | M3XkvBDBY30G77JlIuYH4FElqNUFruIrdGCW21jqCwauFJC/He+fjYJE7giy7TGi 13 | fr6yLn+f7fIeVYKB5bZofaO/8uRdRD4GsG8+Y3ywQdEsQuZ23bmAZHBZjfHdWGi8 14 | DYWTjIWfSaSRkKKLovaaV0vdLR+3AbVcswiTFYtxMjkHn/ss4CkBPGIzqyqFchFV 15 | I/DAhXn/xTtKPZYxLNelbvLH1hYoHEIyHfvw5nf+2CxINdVBWx5S2V6nFuzLXPYC 16 | WGtoAkVO7oM+So41pIy/C8iOix6NtfiNyOy7LfXzkvajiEX/Gn6c6wXiHNhayFLv 17 | 2QIDAQAB 18 | -----END PUBLIC KEY----- 19 | 20 | Name 000b7d5ae2283593ce63281bd4a5b681b50ceff54a49e17ee6e40bc8e82f47967d55 21 | ``` 22 | 23 | if using swtpm: 24 | 25 | ```bash 26 | $ rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm 27 | sudo swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear 28 | 29 | export TPM2TOOLS_TCTI="swtpm:port=2321" 30 | 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /tpm2_get_name/getname.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | //"context" 5 | 6 | "crypto/x509" 7 | "encoding/hex" 8 | "encoding/pem" 9 | "flag" 10 | "fmt" 11 | "io" 12 | "log" 13 | "net" 14 | "os" 15 | "slices" 16 | 17 | "github.com/google/go-tpm-tools/simulator" 18 | "github.com/google/go-tpm/tpm2" 19 | "github.com/google/go-tpm/tpm2/transport" 20 | "github.com/google/go-tpm/tpmutil" 21 | ) 22 | 23 | var ( 24 | tpmPath = flag.String("tpm-path", "127.0.0.1:2321", "Path to the TPM device (character device or a Unix socket).") 25 | ekpubFile = flag.String("ekpubFile", "output.dat", "Path to the ekPublicKey.") 26 | ) 27 | 28 | /* 29 | recreates the "name" from an ek rsa key 30 | 31 | $ go run main.go 32 | Name 000b7d5ae2283593ce63281bd4a5b681b50ceff54a49e17ee6e40bc8e82f47967d55 33 | PEM 34 | -----BEGIN PUBLIC KEY----- 35 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnMDg8UTDAfb8+wdYQFbz 36 | M3XkvBDBY30G77JlIuYH4FElqNUFruIrdGCW21jqCwauFJC/He+fjYJE7giy7TGi 37 | fr6yLn+f7fIeVYKB5bZofaO/8uRdRD4GsG8+Y3ywQdEsQuZ23bmAZHBZjfHdWGi8 38 | DYWTjIWfSaSRkKKLovaaV0vdLR+3AbVcswiTFYtxMjkHn/ss4CkBPGIzqyqFchFV 39 | I/DAhXn/xTtKPZYxLNelbvLH1hYoHEIyHfvw5nf+2CxINdVBWx5S2V6nFuzLXPYC 40 | WGtoAkVO7oM+So41pIy/C8iOix6NtfiNyOy7LfXzkvajiEX/Gn6c6wXiHNhayFLv 41 | 2QIDAQAB 42 | -----END PUBLIC KEY----- 43 | 44 | Name 000b7d5ae2283593ce63281bd4a5b681b50ceff54a49e17ee6e40bc8e82f47967d55 45 | */ 46 | const () 47 | 48 | var TPMDEVICES = []string{"/dev/tpm0", "/dev/tpmrm0"} 49 | 50 | func OpenTPM(path string) (io.ReadWriteCloser, error) { 51 | if slices.Contains(TPMDEVICES, path) { 52 | return tpmutil.OpenTPM(path) 53 | } else if path == "simulator" { 54 | return simulator.GetWithFixedSeedInsecure(1073741825) 55 | } else { 56 | return net.Dial("tcp", path) 57 | } 58 | } 59 | 60 | func main() { 61 | 62 | flag.Parse() 63 | //ctx := context.Background() 64 | 65 | rwc, err := OpenTPM(*tpmPath) 66 | if err != nil { 67 | fmt.Fprintf(os.Stderr, "can't open TPM %s: %v", *tpmPath, err) 68 | os.Exit(1) 69 | } 70 | defer func() { 71 | if err := rwc.Close(); err != nil { 72 | fmt.Fprintf(os.Stderr, "can't close TPM %q: %v", *tpmPath, err) 73 | os.Exit(1) 74 | } 75 | }() 76 | 77 | rwr := transport.FromReadWriter(rwc) 78 | 79 | createEKRsp, err := tpm2.CreatePrimary{ 80 | PrimaryHandle: tpm2.TPMRHEndorsement, 81 | InPublic: tpm2.New2B(tpm2.RSAEKTemplate), 82 | }.Execute(rwr) 83 | if err != nil { 84 | log.Fatalf("error reading rsa public %v", err) 85 | } 86 | defer func() { 87 | flushContextCmd := tpm2.FlushContext{ 88 | FlushHandle: createEKRsp.ObjectHandle, 89 | } 90 | _, _ = flushContextCmd.Execute(rwr) 91 | }() 92 | 93 | fmt.Printf("Name %s\n", hex.EncodeToString(createEKRsp.Name.Buffer)) 94 | 95 | // to write the public to bytes and back 96 | // bt := createEKRsp.OutPublic.Bytes() 97 | // cc := tpm2.BytesAs2B[tpm2.TPMTPublic](bt) 98 | 99 | // print the rsa key and recreate the "name" using key details 100 | 101 | c, err := createEKRsp.OutPublic.Contents() 102 | if err != nil { 103 | log.Fatalf("error reading rsa public %v", err) 104 | } 105 | 106 | rsaDetail, err := c.Parameters.RSADetail() 107 | if err != nil { 108 | log.Fatalf("error reading rsa public %v", err) 109 | } 110 | rsaUnique, err := c.Unique.RSA() 111 | if err != nil { 112 | log.Fatalf("error reading rsa unique %v", err) 113 | } 114 | 115 | rsaPub, err := tpm2.RSAPub(rsaDetail, rsaUnique) 116 | if err != nil { 117 | log.Fatalf("Failed to get rsa public key: %v", err) 118 | } 119 | 120 | b, err := x509.MarshalPKIXPublicKey(rsaPub) 121 | if err != nil { 122 | log.Fatalf("Failed to get rsa public key: %v", err) 123 | } 124 | 125 | publicKeyPEM := pem.EncodeToMemory(&pem.Block{ 126 | Type: "PUBLIC KEY", 127 | Bytes: b, 128 | }) 129 | 130 | fmt.Printf("PEM \n%s\n", string(publicKeyPEM)) 131 | 132 | // recreate the "name" using just the RSA Public Key modulus 133 | // https://github.com/google/go-tpm-tools/blob/6a70865538a8e7e85b95164bba3ae855f4bc4f68/server/key_conversion.go#L30 134 | 135 | u := tpm2.NewTPMUPublicID( 136 | tpm2.TPMAlgRSA, 137 | &tpm2.TPM2BPublicKeyRSA{ 138 | Buffer: rsaPub.N.Bytes(), 139 | }, 140 | ) 141 | 142 | ekPububFromPEMTemplate := tpm2.RSAEKTemplate 143 | 144 | ekPububFromPEMTemplate.Unique = u 145 | 146 | n, err := tpm2.ObjectName(&ekPububFromPEMTemplate) 147 | if err != nil { 148 | log.Fatalf("Failed to get name key: %v", err) 149 | } 150 | 151 | fmt.Printf("Name %s\n", hex.EncodeToString(n.Buffer)) 152 | 153 | } 154 | -------------------------------------------------------------------------------- /tpm2_get_name/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | github.com/google/go-tpm v0.9.0 7 | github.com/google/go-tpm-tools v0.4.4 8 | ) 9 | 10 | require ( 11 | github.com/google/go-configfs-tsm v0.2.2 // indirect 12 | golang.org/x/sys v0.15.0 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /tpm2_get_name/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 2 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 3 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 4 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 5 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 6 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 7 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 8 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 9 | github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= 10 | github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= 11 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 12 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 13 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 14 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 15 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 16 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 18 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 19 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 20 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 21 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 22 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 23 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= 24 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 25 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 26 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 27 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 28 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 29 | -------------------------------------------------------------------------------- /tpm2_importblob_ek/README.md: -------------------------------------------------------------------------------- 1 | #### Sealed Asymmetric Key with persistent files 2 | 3 | Using ek public key to import an external RSA key and seal it into a TPM 4 | 5 | basically [https://github.com/salrashid123/gcp_tpm_sealed_keys/tree/main#sealed-asymmetric-key](https://github.com/salrashid123/gcp_tpm_sealed_keys/tree/main#sealed-asymmetric-key) except that the public and private keys are saved externally (meaning it will survive a reboot). 6 | 7 | fixes [https://github.com/google/go-tpm-tools/issues/349](https://github.com/google/go-tpm-tools/issues/349) 8 | 9 | >> note this is a copy of : [https://github.com/salrashid123/gcp_tpm_sealed_keys/tree/main#sealed-asymmetric-key-with-persistent-files](https://github.com/salrashid123/gcp_tpm_sealed_keys/tree/main#sealed-asymmetric-key-with-persistent-files) 10 | 11 | 12 | 13 | ### Get EK Public key 14 | 15 | either from the TPM directly 16 | 17 | ```bash 18 | tpm2_createek -c primary.ctx -G rsa -u ek.pub -Q 19 | tpm2_readpublic -c primary.ctx -o ek.pem -f PEM -Q 20 | ``` 21 | 22 | or if you're on GCP, you can use an api remotely 23 | 24 | ```bash 25 | gcloud compute instances get-shielded-identity instance-1 --format="value(encryptionKey.ekPub)" > /tmp/ek.pem 26 | ``` 27 | 28 | either way, transfer `ek.pem` to the system where you want to seal a candidate rsa key 29 | 30 | ##### on laptop 31 | 32 | The following program will seal and unseal an RSA key but critically, the imported RSA key on the tpm has the public/private key saved to files. 33 | 34 | THis means the key can be reused after reboots easily. 35 | 36 | ```bash 37 | openssl genrsa -out /tmp/key.pem 2048 38 | openssl rsa -in /tmp/key.pem -out /tmp/key_rsa.pem -traditional 39 | ``` 40 | 41 | ##### Without PCR Policy 42 | 43 | use the `ek.pem` file to seal the rsa key 44 | 45 | ```bash 46 | git clone https://github.com/salrashid123/gcp_tpm_sealed_keys.git 47 | 48 | go run asymmetric/seal/main.go \ 49 | --rsaKeyFile=/tmp/key_rsa.pem \ 50 | --sealedOutput=sealsealed_no_pcred.dat \ 51 | --ekPubFile=/tmp/ek.pem \ 52 | --v=10 -alsologtostderr 53 | 54 | gcloud compute scp sealed_no_pcr.dat instance-1:/tmp/sealed_no_pcr.dat 55 | ``` 56 | 57 | ##### on instance-1 58 | 59 | ```bash 60 | sudo /usr/local/go/bin/go run asymmetric/persistent/main.go --mode=import --pub pub.dat -priv priv.dat --importSigningKeyFile=sealed_no_pcr.dat --flush=all 61 | ## by default the public/private references are saved to pub.dat and priv.dat 62 | 63 | sudo /usr/local/go/bin/go run asymmetric/persistent/main.go --mode=sign --pub pub.dat -priv priv.dat --flush=all 64 | 65 | ## reboot and read the pub.dat and priv.dat to sign data 66 | sudo /usr/local/go/bin/go run asymmetric/persistent/main.go --mode=sign --pub pub.dat -priv priv.dat --flush=all 67 | ``` 68 | 69 | 70 | ##### With PCR Policy 71 | 72 | first alter the tpm's pcr value so we can test: 73 | 74 | ```bash 75 | $ tpm2_pcrread sha256:23 76 | $ tpm2_pcrextend 23:sha256=0x0000000000000000000000000000000000000000000000000000000000000000 77 | $ tpm2_pcrread sha256:23 78 | sha256: 79 | 23: 0xF5A5FD42D16A20302798EF6ED309979B43003D2320D9F0E8EA9831A92759FB4B 80 | ``` 81 | 82 | on laptop 83 | 84 | then seal to that pcr value 85 | 86 | ```bash 87 | git clone https://github.com/salrashid123/gcp_tpm_sealed_keys.git 88 | go run asymmetric/seal/main.go \ 89 | --rsaKeyFile=/tmp/key_rsa.pem \ 90 | --sealedOutput=sealed_pcr.dat --pcrValues=23=f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b \ 91 | --ekPubFile=/tmp/ek.pem \ 92 | --v=10 -alsologtostderr 93 | 94 | gcloud compute scp sealed_pcr instance-1:sealed_pcr.dat 95 | ``` 96 | 97 | ##### on instance-1 98 | 99 | ```bash 100 | sudo /usr/local/go/bin/go run asymmetric/persistent/main.go --mode=import --pub pub.dat -priv priv.dat --importSigningKeyFile=sealed_pcr.dat --flush=all --bindPCRValues=23 101 | ## remember to set the pcr23 value forward 102 | sudo /usr/local/go/bin/go run asymmetric/persistent/main.go --mode=sign --flush=all --pub pub.dat -priv priv.dat --bindPCRValues=23 103 | ## reboot, remember to reset the pcr23 value forward 104 | sudo /usr/local/go/bin/go run asymmetric/persistent/main.go --mode=sign --flush=all --pub pub.dat -priv priv.dat --bindPCRValues=23 105 | ``` 106 | -------------------------------------------------------------------------------- /tpm2_importblob_ek/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.21.0 4 | 5 | require ( 6 | github.com/golang/protobuf v1.5.3 7 | github.com/google/go-tpm v0.9.0 8 | github.com/google/go-tpm-tools v0.4.1 9 | ) 10 | 11 | require ( 12 | github.com/google/go-sev-guest v0.7.0 // indirect 13 | github.com/google/go-tdx-guest v0.2.1-0.20230907045450-944015509c84 // indirect 14 | github.com/google/logger v1.1.1 // indirect 15 | github.com/google/uuid v1.3.0 // indirect 16 | github.com/pborman/uuid v1.2.0 // indirect 17 | github.com/pkg/errors v0.9.1 // indirect 18 | golang.org/x/crypto v0.11.0 // indirect 19 | golang.org/x/sys v0.10.0 // indirect 20 | google.golang.org/protobuf v1.31.0 // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /tpm2_importblob_ek/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 3 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 4 | github.com/google/certificate-transparency-go v1.1.2 h1:4hE0GEId6NAW28dFpC+LrRGwQX5dtmXQGDbg8+/MZOM= 5 | github.com/google/certificate-transparency-go v1.1.2/go.mod h1:3OL+HKDqHPUfdKrHVQxO6T8nDLO0HF7LRTlkIWXaWvQ= 6 | github.com/google/go-attestation v0.5.0 h1:jXtAWT2sw2Yu8mYU0BC7FDidR+ngxFPSE+pl6IUu3/0= 7 | github.com/google/go-attestation v0.5.0/go.mod h1:0Tik9y3rzV649Jcr7evbljQHQAsIlJucyqQjYDBqktU= 8 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 9 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 10 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 11 | github.com/google/go-sev-guest v0.7.0 h1:DBCABhTo7WicP27ZH/hwcCdjcmxFkxxMOQXm5hFcfp4= 12 | github.com/google/go-sev-guest v0.7.0/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 13 | github.com/google/go-tdx-guest v0.2.1-0.20230907045450-944015509c84 h1:XqVJa7fVU8b+Hlhcvw49qfg0+LYcRI+V+jYUrSek848= 14 | github.com/google/go-tdx-guest v0.2.1-0.20230907045450-944015509c84/go.mod h1:a8EIh1l5x7jmIrrOuH//xWn6y4Sk4yupwmMcJE006RI= 15 | github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= 16 | github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= 17 | github.com/google/go-tpm-tools v0.4.1 h1:gYU6iwRo0tY3V6NDnS6m+XYog+b3g6YFhHQl3sYaUL4= 18 | github.com/google/go-tpm-tools v0.4.1/go.mod h1:w03m0jynhTo7puXTYoyfpNOMqyQ9SB7sixnKWsS/1L0= 19 | github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= 20 | github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= 21 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 22 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 23 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 24 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 25 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 26 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 27 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 28 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 29 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 30 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 31 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 32 | golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= 33 | golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= 34 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 35 | golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= 36 | golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 37 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 38 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 39 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 40 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 41 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 42 | -------------------------------------------------------------------------------- /tpm_encrypted_session/README.md: -------------------------------------------------------------------------------- 1 | ### Session Encryption 2 | 3 | Sample demonstrates how to setup session encryption. 4 | 5 | Basically this encrypts the data in transit in a way that sniffing low level bus traffic does not show the secrets (like end-to-end encryption). 6 | 7 | See: 8 | 9 | - [CPU to TPM Bus Protection Guidance](https://trustedcomputinggroup.org/wp-content/uploads/TCG_CPU_TPM_Bus_Protection_Guidance_Passive_Attack_Mitigation_8May23-3.pdf) 10 | - [Protecting Secrets At Tpm Interface](https://tpm2-software.github.io/2021/02/17/Protecting-secrets-at-TPM-interface.html) 11 | 12 | 13 | 14 | The two snippets below this section uses seal/unseal to encode and read back a secret. 15 | 16 | This uses a swtpm simulator running on a tcp port. It also uses `tcpdump` to capture the application->TPM traffic which we can decode with wireshark. 17 | 18 | 19 | First one run in clear text without encryption and you can see the 'unseal' data in clear text 20 | 21 | The second one we run with session encryption set so the data is still encrypted in transit 22 | 23 | 24 | To use, run the simulator 25 | 26 | ```bash 27 | mkdir /tmp/myvtpm 28 | swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear 29 | ``` 30 | 31 | In a new window, test 32 | 33 | ```bash 34 | export TPM2TOOLS_TCTI="swtpm:port=2321" 35 | tpm2_pcrread 36 | 37 | sudo tcpdump -s0 -ilo -w trace.cap port 2321 38 | ``` 39 | 40 | Now 41 | 42 | #### Seal/Unseal without session encryption 43 | 44 | You'll see the raw data 45 | 46 | ![images/clear.png](images/clear.png) 47 | 48 | 49 | ### Seal/Unseal with session encryption 50 | 51 | you'll see the encrypted data 52 | 53 | ![images/encrypted.png](images/encrypted.png) 54 | 55 | -------------------------------------------------------------------------------- /tpm_encrypted_session/clear.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/tpm_encrypted_session/clear.cap -------------------------------------------------------------------------------- /tpm_encrypted_session/encrypted.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/tpm_encrypted_session/encrypted.cap -------------------------------------------------------------------------------- /tpm_encrypted_session/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | github.com/google/go-tpm v0.9.0 7 | github.com/google/go-tpm-tools v0.4.4 8 | ) 9 | 10 | require ( 11 | github.com/google/go-configfs-tsm v0.2.2 // indirect 12 | golang.org/x/crypto v0.19.0 // indirect 13 | golang.org/x/sys v0.17.0 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /tpm_encrypted_session/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 2 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 3 | github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98= 4 | github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= 5 | github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU= 6 | github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs= 7 | github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw= 8 | github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE= 9 | github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= 10 | github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= 11 | github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= 12 | github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= 13 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 14 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 15 | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 16 | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 | github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= 18 | github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 19 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 20 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 21 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 22 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 23 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 24 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 25 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 26 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 27 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 28 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 29 | -------------------------------------------------------------------------------- /tpm_encrypted_session/images/clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/tpm_encrypted_session/images/clear.png -------------------------------------------------------------------------------- /tpm_encrypted_session/images/encrypted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/tpm_encrypted_session/images/encrypted.png -------------------------------------------------------------------------------- /tpm_make_activate/AttestProv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salrashid123/tpm2/c912acc8133e681cf168f26770f7d5c6a4725347/tpm_make_activate/AttestProv.pdf -------------------------------------------------------------------------------- /tpm_make_activate/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.2 6 | 7 | require ( 8 | github.com/google/go-tpm v0.9.1 9 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 10 | ) 11 | 12 | require ( 13 | golang.org/x/crypto v0.19.0 // indirect 14 | golang.org/x/sys v0.17.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /tpm_make_activate/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 2 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 3 | github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= 4 | github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= 5 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 6 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 7 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 8 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 9 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 10 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 12 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 13 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= 16 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 17 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= 18 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 19 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 20 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 21 | -------------------------------------------------------------------------------- /tpm_services/README.md: -------------------------------------------------------------------------------- 1 | ## TPM samples for go-attestation and go-tpm-tools 2 | 3 | 4 | samples that use updated [go-tpm-tools](https://pkg.go.dev/github.com/google/go-tpm-tools), and [https://github.com/google/go-attestation](https://github.com/google/go-attestation) 5 | 6 | to do the following 7 | 8 | 1. remote attestation 9 | 2. quote_verify 10 | 3. seal_unseal 11 | 12 | 13 | for import, see [https://github.com/salrashid123/gcp_tpm_sealed_keys](https://github.com/salrashid123/gcp_tpm_sealed_keys) 14 | 15 | 16 | the following repo uses a lower level go-tpm library set and some go-tpm-tools 17 | - [https://github.com/salrashid123/go_tpm_remote_attestation](https://github.com/salrashid123/go_tpm_remote_attestation) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tpm_services/attestation/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888 7 | github.com/google/go-tpm v0.9.0 8 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 9 | ) 10 | 11 | require ( 12 | github.com/google/certificate-transparency-go v1.1.2 // indirect 13 | github.com/google/go-sev-guest v0.6.1 // indirect 14 | github.com/google/go-tspi v0.3.0 // indirect 15 | github.com/google/logger v1.1.1 // indirect 16 | github.com/google/uuid v1.3.0 // indirect 17 | github.com/pborman/uuid v1.2.0 // indirect 18 | github.com/pkg/errors v0.9.1 // indirect 19 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect 20 | golang.org/x/sys v0.8.0 // indirect 21 | google.golang.org/protobuf v1.28.0 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /tpm_services/quote_verify/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888 7 | github.com/google/go-tpm v0.9.0 8 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 9 | ) 10 | 11 | require ( 12 | github.com/google/certificate-transparency-go v1.1.2 // indirect 13 | github.com/google/go-sev-guest v0.6.1 // indirect 14 | github.com/google/go-tspi v0.3.0 // indirect 15 | github.com/google/logger v1.1.1 // indirect 16 | github.com/google/uuid v1.3.0 // indirect 17 | github.com/pborman/uuid v1.2.0 // indirect 18 | github.com/pkg/errors v0.9.1 // indirect 19 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect 20 | golang.org/x/sys v0.8.0 // indirect 21 | google.golang.org/protobuf v1.28.0 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /tpm_services/seal/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/google/go-tpm v0.9.0 7 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba 8 | ) 9 | 10 | require ( 11 | github.com/google/go-sev-guest v0.6.1 // indirect 12 | github.com/google/logger v1.1.1 // indirect 13 | github.com/google/uuid v1.3.0 // indirect 14 | github.com/pborman/uuid v1.2.0 // indirect 15 | github.com/pkg/errors v0.9.1 // indirect 16 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect 17 | golang.org/x/sys v0.8.0 // indirect 18 | google.golang.org/protobuf v1.28.0 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /tpm_services/seal/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 3 | github.com/google/certificate-transparency-go v1.1.2 h1:4hE0GEId6NAW28dFpC+LrRGwQX5dtmXQGDbg8+/MZOM= 4 | github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888 h1:HURgKPRPJSozDuMHpjdV+iyFVLhB6bi1JanhGgSzI1k= 5 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 6 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 7 | github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0= 8 | github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q= 9 | github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= 10 | github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= 11 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc= 12 | github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc= 13 | github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= 14 | github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= 15 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 16 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 18 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 | github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 20 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 21 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 22 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 23 | go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= 24 | go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= 25 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= 26 | golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 27 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 28 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= 29 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 30 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 31 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 32 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 33 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 34 | -------------------------------------------------------------------------------- /tpm_services/seal/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha1" 5 | "crypto/sha256" 6 | "encoding/hex" 7 | "flag" 8 | "fmt" 9 | "hash" 10 | "log" 11 | "strconv" 12 | "strings" 13 | 14 | "github.com/google/go-tpm-tools/client" 15 | 16 | //"github.com/google/go-tpm-tools/proto/attest" 17 | "github.com/google/go-tpm-tools/proto/tpm" 18 | tpmpb "github.com/google/go-tpm-tools/proto/tpm" 19 | "github.com/google/go-tpm/legacy/tpm2" 20 | ) 21 | 22 | var ( 23 | expectedPCRMapSHA256 = flag.String("expectedPCRMapSHA256", "0:24af52a4f429b71a3184a6d64cddad17e54ea030e2aa6576bf3a5a3d8bd3328f", "Sealing and Quote PCRMap (as comma separated key:value). pcr#:sha256,pcr#sha256. Default value uses pcr0:sha256") 24 | 25 | handleNames = map[string][]tpm2.HandleType{ 26 | "all": []tpm2.HandleType{tpm2.HandleTypeLoadedSession, tpm2.HandleTypeSavedSession, tpm2.HandleTypeTransient}, 27 | "loaded": []tpm2.HandleType{tpm2.HandleTypeLoadedSession}, 28 | "saved": []tpm2.HandleType{tpm2.HandleTypeSavedSession}, 29 | "transient": []tpm2.HandleType{tpm2.HandleTypeTransient}, 30 | } 31 | ) 32 | 33 | func main() { 34 | flag.Parse() 35 | 36 | // on client create SKR cert 37 | rwc, err := tpm2.OpenTPM("/dev/tpm0") 38 | if err != nil { 39 | log.Fatalf("failed to initialize simulator: %v", err) 40 | } 41 | defer rwc.Close() 42 | 43 | totalHandles := 0 44 | for _, handleType := range handleNames["all"] { 45 | handles, err := client.Handles(rwc, handleType) 46 | if err != nil { 47 | log.Fatalf("getting handles: %v", err) 48 | } 49 | for _, handle := range handles { 50 | if err = tpm2.FlushContext(rwc, handle); err != nil { 51 | log.Fatalf("flushing handle 0x%x: %v", handle, err) 52 | } 53 | log.Printf("Handle 0x%x flushed\n", handle) 54 | totalHandles++ 55 | } 56 | } 57 | 58 | // ek, err := client.EndorsementKeyRSA(rwc) 59 | // if err != nil { 60 | // log.Fatalf("failed to create storage root key: %v", err) 61 | // } 62 | 63 | // seal to endorsement not supported yet 64 | //srk, err := client.EndorsementKeyECC(rwc) 65 | srk, err := client.StorageRootKeyRSA(rwc) 66 | if err != nil { 67 | log.Fatalf("failed to create storage root key: %v", err) 68 | } 69 | 70 | // send srk to server 71 | // on server use SRK to seal secret to tpm value and pcr value 72 | 73 | sealedSecret := []byte("secret password") 74 | sel := tpm2.PCRSelection{Hash: tpm2.AlgSHA256, PCRs: []int{7}} 75 | 76 | // seal on server 77 | pcrMap, _, err := getPCRMap(tpm.HashAlgo_SHA256) 78 | if err != nil { 79 | log.Fatalf("failed to create storage root key: %v", err) 80 | } 81 | pcrs := &tpmpb.PCRs{Hash: tpmpb.HashAlgo_SHA256, Pcrs: pcrMap} 82 | sealedBlob, err := srk.Seal([]byte(sealedSecret), client.SealOpts{Target: pcrs}) 83 | if err != nil { 84 | log.Fatalf("failed to seal to SRK: %v", err) 85 | } 86 | 87 | // send sealedBlob to client 88 | // unseal on client 89 | output, err := srk.Unseal(sealedBlob, client.UnsealOpts{CertifyCurrent: sel}) 90 | if err != nil { 91 | log.Fatalf("failed to unseal blob: %v", err) 92 | } 93 | // TODO: use unseal output. 94 | fmt.Println(string(output)) 95 | } 96 | 97 | func getPCRMap(algo tpm.HashAlgo) (map[uint32][]byte, []byte, error) { 98 | 99 | pcrMap := make(map[uint32][]byte) 100 | var hsh hash.Hash 101 | // https://github.com/tpm2-software/tpm2-tools/blob/83f6f8ac5de5a989d447d8791525eb6b6472e6ac/lib/tpm2_openssl.c#L206 102 | if algo == tpm.HashAlgo_SHA1 { 103 | hsh = sha1.New() 104 | } 105 | if algo == tpm.HashAlgo_SHA256 { 106 | hsh = sha256.New() 107 | } 108 | if algo == tpm.HashAlgo_SHA1 || algo == tpm.HashAlgo_SHA256 { 109 | for _, v := range strings.Split(*expectedPCRMapSHA256, ",") { 110 | entry := strings.Split(v, ":") 111 | if len(entry) == 2 { 112 | uv, err := strconv.ParseUint(entry[0], 10, 32) 113 | if err != nil { 114 | return nil, nil, fmt.Errorf(" PCR key:value is invalid in parsing %s", v) 115 | } 116 | hexEncodedPCR, err := hex.DecodeString(entry[1]) 117 | if err != nil { 118 | return nil, nil, fmt.Errorf(" PCR key:value is invalid in encoding %s", v) 119 | } 120 | pcrMap[uint32(uv)] = hexEncodedPCR 121 | hsh.Write(hexEncodedPCR) 122 | } else { 123 | return nil, nil, fmt.Errorf(" PCR key:value is invalid %s", v) 124 | } 125 | } 126 | } else { 127 | return nil, nil, fmt.Errorf("Unknown Hash Algorithm for TPM PCRs %v", algo) 128 | } 129 | if len(pcrMap) == 0 { 130 | return nil, nil, fmt.Errorf(" PCRMap is null") 131 | } 132 | return pcrMap, hsh.Sum(nil), nil 133 | } 134 | --------------------------------------------------------------------------------