google / go-attestation Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Currently the server generates a challenge but doesn't actually verify that ActivationParameters.Public matches what's passed in ActivationParameters.AK.CreateAttestation.
go-attestation/attest/activation.go
Line 236 in 355135f
I can take this tomorrow.
[signal SIGSEGV: segmentation violation code=0x1 addr=0x2 pc=0x56251519dc69]
<redacted>/attest.ParseAKPublic(0x2, 0xc0029c44e0, 0x1a, 0x20, 0xc002a13980, 0x1, 0x1)
<redacted>/attest/attest.go:244 +0x449 fp=0xc002a63090 sp=0xc002a62fa8 pc=0x56251519dc69
Appears to be a deref somewhere in .RSAParameters.Sign.Hash
.
This input can cause it: [0 1 0 4 0 1 0 0 0 0 0 6 0 128 0 67 0 16 8 0 0 1 0 1 0 0]
Hello. I am trying to understand the TPM credential activation flow. I have been trying to run a simple test that does:
---client produces EK, AK data, sends to server---
ak := tpm.NewAK()
ap := ak.AttestationParameters()
---server generates encrypted challenge for EK,AK---
activation := attest.ActivationParameters{ //deserialized data from client }
secret1, challenge := activation.Generate()
---client receives challenge blob---
ak := tpm.LoadAK()
secret2 := attest.ActivateCredential(challenge)
---server receives decrypted challenge---
validate(secret1, secret2)
In my testing, client and server are running on the same machine. My test fails at activation.Generate() complaining that the AK in ActivationParameters is not an RSA key. Is it wrong to use AttestationParameters.Public from Tpm.NewAK().AttestationParameters() here? It looks like the template used by Tpm.NewAK() is an RSA key as prescribed. I looked at a hex dump of the data and if I'm parsing the fields correctly, the AK produced is RSA/SHA1. Any hints?
Derek
attest-tool isn't able to list EKs on a shielded Windows VM. Figure out if this is an issue with attest-tool or the attest package.
I'm working on implementing TPM credential activation using this library. I've got EC and AIK creation working, but I'm getting a strange error when I try to actually activate the credential:
failed to activate credential: write /dev/tpmrm0: invalid argument"
Here's the relevant code:
func CalculateResponse(ec *attest.EncryptedCredential, aik *attest.AIK, path string) (*ChallengeResponse, error) {
tpm, err := attest.OpenTPM(&attest.OpenConfig{
TPMVersion: attest.TPMVersion20,
})
if err != nil {
return nil, fmt.Errorf("failed to connect to tpm: %v", err)
}
defer tpm.Close()
log.Println(*ec)
secret, err := aik.ActivateCredential(tpm, *ec)
if err != nil {
return nil, fmt.Errorf("failed to activate credential: %v", err)
}
return &ChallengeResponse{
Secret: secret,
}, nil
}
Any idea what might be wrong here? I am running as root FWIW. Thanks!
Otherwise, I wrote an incomplete parser:
https://github.com/systemboot/tpmtool/blob/master/pkg/tpm/tcpa_log.go
Hi! Really appreciate your hard work on this project guys. I have a question regarding post-activation steps
the server records the AK and EK association and allows the client to use its AK as a credential (e.g. by issuing it a client certificate).
My understanding is that client should also send a CSR for server to issue certificate. I've spent some time trying to find information on how to create CSR using generated AK, but did not succeed. Can you please give me any links/instructions to point me in the right direction?
We currently test TPM 1.2 and 2.0 quotes for Linux and Windows, but both of them are SHA1.
Hey Guys
I am running a test and I am seeing
# github.com/google/go-tspi/tspi
/go/pkg/mod/github.com/google/[email protected]/tspi/context.go:17:27: fatal error: trousers/tss.h: No such file or directory
// #include <trousers/tss.h>
^
compilation terminated.
I am assuming this is the related issue of not installing the libtspi-dev since I am running it on centos. May I know if I dont want TPM12 support what I should run to build?
I check the relate issues here #163 but not pretty clear how I should use any flag to make it build.
Thanks!
Found this when migrating to GitHub actions
E.g. setupSimulatedTPM is only defined on Linux but is referenced in other files
attest/certification_test.go: sim, tpm := setupSimulatedTPM(t)
attest/certification_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go:func setupSimulatedTPM(t *testing.T) (*simulator.Simulator, *TPM) {
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/attest_simulated_tpm20_test.go: sim, tpm := setupSimulatedTPM(t)
attest/application_key_test.go: sim, tpm := setupSimulatedTPM(t)
attest/application_key_test.go: sim, tpm := setupSimulatedTPM(t)
attest/application_key_test.go: sim, tpm := setupSimulatedTPM(t)
Running go test ./... on MacOS or Windows should both build and pass, skipping anything that requires Linux dependencies.
Found by oss-fuzz + ASAN.
| Bot: oss-fuzz-linux-zone3-host-7gp2-4
| Time ran: 0.310926914215
|
| INFO: Seed: 1399422185
| INFO: 65536 Extra Counters
| /mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_go-attestation_6af98b8fbc8e1eba35c78858068206247723399f/revisions/parse_ek_certificate_fuzzer: Running 1 inputs 100 time(s) each.
| Running: /crash-dbfcf248daa33db6546c2cd1ab0de0a4fcfcf534
| panic: runtime error: slice bounds out of range [5:4]
|
| goroutine 17 [running, locked to thread]:
| github.com/google/go-attestation/attest.ParseEKCertificate(0x6020000000b0, 0x6, 0x6, 0x559843, 0x10c00006a058, 0x10c00006a058)
| /root/go/src/github.com/google/go-attestation/attest/tpm.go:165 +0x753
| github.com/google/go-attestation/attest.FuzzParseEKCertificate(0x6020000000b0, 0x6, 0x6, 0x7ffe955cfe28)
| /root/go/src/github.com/google/go-attestation/attest/attest_fuzz.go:44 +0x5d
| main.LLVMFuzzerTestOneInput(0x6020000000b0, 0x6, 0x9c3f58)
| github.com/google/go-attestation/attest/go.fuzz.main/main.go:35 +0x66
| main._cgoexpwrap_120fe4414799_LLVMFuzzerTestOneInput(0x6020000000b0, 0x6, 0xacf800)
| _cgo_gotypes.go:64 +0x37
| AddressSanitizer:DEADLYSIGNAL
| =================================================================
| ==1==ERROR: AddressSanitizer: ABRT on unknown address 0x000000000001 (pc 0x0000005aad51 bp 0x10c000046b60 sp 0x10c000046b48 T0)
| SCARINESS: 10 (signal)
| #0 0x5aad51 in runtime.raise runtime/sys_linux_amd64.s:150
|
| AddressSanitizer can not provide additional info.
| SUMMARY: AddressSanitizer: ABRT (/mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_go-attestation_6af98b8fbc8e1eba35c78858068206247723399f/revisions/parse_ek_certificate_fuzzer+0x5aad51)
| ==1==ABORTING
|
|
| +----------------------------------------Release Build Unsymbolized Stacktrace (diff)----------------------------------------+
|
| ==1==ERROR: AddressSanitizer: ABRT on unknown address 0x000000000001 (pc 0x0000005aad51 bp 0x10c000046b60 sp 0x10c000046b48 T0)
| SCARINESS: 10 (signal)
| #0 0x5aad51 (/mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_go-attestation_6af98b8fbc8e1eba35c78858068206247723399f/revisions/parse_ek_certificate_fuzzer+0x5aad51)
|
| AddressSanitizer can not provide additional info.
Replicating input: 1001 00ff ff20
Analysis ongoing, but I have a failing unit test:
--- FAIL: TestSecureBootBugThing (0.00s)
secureboot_test.go:58: failed parsing secureboot state: failed parsing EFI variable authority at event 12: asn1: structure error: tags don't match (16 vs {class:2 tag:25 length:65 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false lax:true name:} certificate @2
secureboot_test.go:60: <nil>
I have some TPM1.2 machines that do not seem to come with an EK certificate. They have an Intel discrete TPM but Intel's HTTP interface returns just 404 and attempts to write a dummy EK certificate to the NVRAM also fail. Would you be interested in a pull request that makes the self-test work on such machines? I understood that TPM1.2 support was in maintenance-only mode now so I thought I'd ask before spending too much time polishing a PR.
I got this to work by modifying eks() in tpm12_linux.go to read the EK directly from the TPM if reading the EK certificate from NVRAM fails. This required also adding two functions to go-tspi to read the EK from the TPM.
This is a super-set of #72
It's currently unclear when a user needs to provide SHA1 or SHA256, or when we can infer it from other data. There are several places where we need a hash:
For now, I propose we modify the MeasurementLog signature to return the hash:
func (t *TPM) MeasurementLog() ([]byte, HashAlg, error)
And the PCRs call to take a hash:
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error)
Users would then do something like
rawLog, alg, err := tpm.MeasurementLog()
if err != nil {
// ...
}
pcrs, err := tpm.PCRs(alg)
I'm using the latest published version (v0.3.2
) of this library with a TPM 2.0.
With the following code (copied from the examples):
func main() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
}
defer tpm.Close()
log.Printf("+ Opened TPM!\n")
// Create a new AK.
ak, err := tpm.NewAK(nil)
if err != nil {
log.Fatalf("Failed to create AK: %v", err)
}
defer ak.Close(tpm)
log.Printf("+ Created new AK\n")
// Read the EK.
ek, err := tpm.EKs()
if err != nil {
log.Fatalf("Failed to enumerate EKs: %v", err)
}
log.Printf("+ Got EKs len=%d ==> %+v\n", len(ek), ek)
// Read parameters necessary to generate a challenge.
ap := ak.AttestationParameters()
// Generate a credential activation challenge (usually done on the server).
activation := attest.ActivationParameters{
TPMVersion: tpm.Version(),
EK: ek[0].Public,
AK: ap,
}
secret, challenge, err := activation.Generate()
if err != nil {
log.Fatalf("Failed to generate activation challenge: %v", err)
}
// Challenge the AK & EK properties to recieve the decrypted secret.
decrypted, err := ak.ActivateCredential(tpm, *challenge)
if err != nil {
log.Fatalf("Failed to activate credential: %v", err)
}
// Check that the AK completed the challenge (usually done on the server).
if subtle.ConstantTimeCompare(secret, decrypted) == 0 {
log.Fatal("Activation response did not match secret")
}
}
It seems that, if I execute the program, it never finishes after calling tpm.EKs()
.
After a little debugging it came clear that the tpm2.NVReadEx(…)
tries to determine the block size if the blockSize
parameter is zero by reading the capability NVMaxBufferSize
.
But it seems that my TPM does not have this capability:
~$ tpm2_getcap properties-variable
TPM2_PT_PERSISTENT:
ownerAuthSet: 0
endorsementAuthSet: 0
lockoutAuthSet: 0
reserved1: 0
disableClear: 0
inLockout: 0
tpmGeneratedEPS: 0
reserved2: 0
TPM2_PT_STARTUP_CLEAR:
phEnable: 1
shEnable: 1
ehEnable: 1
phEnableNV: 1
reserved1: 0
orderly: 0
TPM2_PT_HR_NV_INDEX: 0x4
TPM2_PT_HR_LOADED: 0x0
TPM2_PT_HR_LOADED_AVAIL: 0x3
TPM2_PT_HR_ACTIVE: 0x0
TPM2_PT_HR_ACTIVE_AVAIL: 0x40
TPM2_PT_HR_TRANSIENT_AVAIL: 0x3
TPM2_PT_HR_PERSISTENT: 0x2
TPM2_PT_HR_PERSISTENT_AVAIL: 0x8
TPM2_PT_NV_COUNTERS: 0x0
TPM2_PT_NV_COUNTERS_AVAIL: 0xC
TPM2_PT_ALGORITHM_SET: 0x0
TPM2_PT_LOADED_CURVES: 0x0
TPM2_PT_LOCKOUT_COUNTER: 0x0
TPM2_PT_MAX_AUTH_FAIL: 0x20
TPM2_PT_LOCKOUT_INTERVAL: 0x1C20
TPM2_PT_LOCKOUT_RECOVERY: 0x15180
TPM2_PT_AUDIT_COUNTER_0: 0x0
TPM2_PT_AUDIT_COUNTER_1: 0x0
~$ tpm2_getcap properties-fixed
TPM2_PT_FAMILY_INDICATOR:
raw: 0x322E3000
value: "2.0"
TPM2_PT_LEVEL:
raw: 0
TPM2_PT_REVISION:
raw: 0x63
value: 0.99
TPM2_PT_DAY_OF_YEAR:
raw: 0xCE
TPM2_PT_YEAR:
raw: 0x7DD
TPM2_PT_MANUFACTURER:
raw: 0x49465800
value: "IFX"
TPM2_PT_VENDOR_STRING_1:
raw: 0x534C4239
value: "SLB9"
TPM2_PT_VENDOR_STRING_2:
raw: 0x36363500
value: "665"
TPM2_PT_VENDOR_STRING_3:
raw: 0x0
value: ""
TPM2_PT_VENDOR_STRING_4:
raw: 0x0
value: ""
TPM2_PT_VENDOR_TPM_TYPE:
raw: 0x1
TPM2_PT_FIRMWARE_VERSION_1:
raw: 0x50000
TPM2_PT_FIRMWARE_VERSION_2:
raw: 0x44102
TPM2_PT_INPUT_BUFFER:
raw: 0x400
TPM2_PT_HR_TRANSIENT_MIN:
raw: 0x3
TPM2_PT_HR_PERSISTENT_MIN:
raw: 0x7
TPM2_PT_HR_LOADED_MIN:
raw: 0x3
TPM2_PT_ACTIVE_SESSIONS_MAX:
raw: 0x40
TPM2_PT_PCR_COUNT:
raw: 0x18
TPM2_PT_PCR_SELECT_MIN:
raw: 0x3
TPM2_PT_CONTEXT_GAP_MAX:
raw: 0xFFFFFFFF
TPM2_PT_NV_COUNTERS_MAX:
raw: 0x0
TPM2_PT_NV_INDEX_MAX:
raw: 0x680
TPM2_PT_MEMORY:
raw: 0x6
TPM2_PT_CLOCK_UPDATE:
raw: 0x1000
TPM2_PT_CONTEXT_HASH:
raw: 0xB
TPM2_PT_CONTEXT_SYM:
raw: 0x6
TPM2_PT_CONTEXT_SYM_SIZE:
raw: 0x80
TPM2_PT_ORDERLY_COUNT:
raw: 0xFF
TPM2_PT_MAX_COMMAND_SIZE:
raw: 0x500
TPM2_PT_MAX_RESPONSE_SIZE:
raw: 0x500
TPM2_PT_MAX_DIGEST:
raw: 0x20
TPM2_PT_MAX_OBJECT_CONTEXT:
raw: 0x26A
TPM2_PT_MAX_SESSION_CONTEXT:
raw: 0xE9
TPM2_PT_PS_FAMILY_INDICATOR:
raw: 0x1
TPM2_PT_PS_LEVEL:
raw: 0x2
TPM2_PT_PS_REVISION:
raw: 0x100
TPM2_PT_PS_DAY_OF_YEAR:
raw: 0x0
TPM2_PT_PS_YEAR:
raw: 0x0
TPM2_PT_SPLIT_MAX:
raw: 0x0
TPM2_PT_TOTAL_COMMANDS:
raw: 0x55
TPM2_PT_LIBRARY_COMMANDS:
raw: 0x54
TPM2_PT_VENDOR_COMMANDS:
raw: 0x1
algs := make([]specAlgSize, header.NumAlgs)
if err := binary.Read(r, binary.LittleEndian, &algs); err != nil {
return nil, fmt.Errorf("reading algorithms: %v", err)
}
Reproduction:
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
RyXs7SdTSQ==
Produces:
header{
Signature: [16]uint8{0x53, 0x70, 0x65, 0x63, 0x20, 0x49, 0x44, 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x33, 0x0},
PlatformClass: 0x0,
VersionMinor: 0x0,
VersionMajor: 0x2,
Errata: 0x0,
UintnSize: 0x2,
NumAlgs: 0xffff0001,
}
0xffff0001 = 4.295 GB
Hello,
great library you have created so far! I would like to use the created Keys to provision certificates that are bound to a TPM. Eventually, I would like to have a virtual SmartCard interface that I can use in a browser, as it is possible, e.g. with the TPM2-TSS tools (https://github.com/tpm2-software/tpm2-pkcs11). Are you aware of an implementation in GO where this SmartCard object is created? Do you plan on extending the code for using it in combination with certificates?
Currently TPM2 clients generate an AK and then self-certify using TPM2_Certify.
But I don't think the self-certification is currently serving any purpose:
As far as I can tell, if att.AttestedCreationInfo.Name.Digest
in generateChallengeTPM20
was replaced with tpm2.DecodePublic(p.AIK.Public).Name().Digest
, then p.AIK.CreateData
and p.AIK.CreateAttestation
can be removed entirely without losing any security properties.
But maybe I'm missing something, or there are plans to eventually utilize more of the attestation data. E.g., maybe firmwareVersion is useful to log in case it's discovered that some TPM firmware versions had key generation vulnerabilities (e.g., ROCA for RSA keys, or Yubikey's FIPS RNG goofup affecting both RSA and ECC keys); though in that case, you probably need to re-generate (and re-certify) the EK too, so I'm not sure the AK is your biggest concern.
I'm trying a simple test program on my Pi and i run into this issue during building:
# github.com/google/go-tspi/tspi
../go/pkg/mod/github.com/google/[email protected]/tspi/tpm.go:92:13: type [1073741824]_Ctype_struct_tdTSS_PCR_EVENT larger than address space
../go/pkg/mod/github.com/google/[email protected]/tspi/tpm.go:92:13: type [1073741824]_Ctype_struct_tdTSS_PCR_EVENT too large
if i understood this error correctly this is linked to
in attest/tpm.go. Is there a common or known workaround for this issue?
Specs:
Pi4 (raspdebian 10.9)
go1.16.5 linux/arm
Hello guys
When trying to OpenTPM() to perform attestation, I always get the following error: "Open /dev/tpm0: device or resource busy".
When I run the same piece of code in a real HW TPM, everything works fine, but when running in a virtualized environment (VMs instantiated through qemu and vTPM by means of SWTPM, TSS, ABRMD) I get this error.
Has anyone been through this before?
Any help is appreciated.
There's no reason you shouldn't be able to run the platform independent code on Mac, or on a Linux server without cgo.
$ GOOS=darwin go test -v -c github.com/google/go-attestation/attest
# github.com/google/go-attestation/attest [github.com/google/go-attestation/attest.test]
./attest.go:88:9: undefined: platformTPM
./attest.go:90:26: undefined: platformTPM
./attest.go:91:11: undefined: platformTPM
./tpm.go:274:7: undefined: platformTPM
$ GOOS=linux CGO_ENABLED=0 go test -c github.com/google/go-attestation/attest
build github.com/google/go-tspi/tspi: cannot load github.com/google/go-tspi/tspi: no Go source files
Its set on SHA256 for some SHA1 PCRs ive had coming from the simulator. Need to investigate.
Tried running attest-tool "self-test" in RHEL 8.4 systems.
Getting the following error :
Error: NewAK() failed: failed to get SRK handle: CreatePrimary failed: session 1, error code 0x22 : authorization failure without DA implications
Does any permissions need to be enabled ? Please share the commands for that.
Hello, I downloaded the library and tried to import it locally from my pc, but it returns me many errors when executing, any reason for that?
Here's a screenshot of the errors: https://imgur.com/a/WsvStLC
Users may choose to use Quote() to challenge the presence of an AIK, by quoting over PCRs and providing a nonce. In this case, there is no event log (and there may be none present), but we still want to be able to verify the quote.
Currently, the API for verifying a quote is coupled into event log verification (users must call EventLog{}.Validate()
, which will fail if they do not provide an event log).
Proposal 1: Add a Verify(aik, nonce, pcrs)
method directly on Quote
Proposal 2: Make it legal to call Validate
on EventLog
where no event log is present.
WDYT @ericchiang ?
Hello,
While running the code from the project's README (also attached with the post: tpm_attest .go.txt), I am getting the following error:
ActivateCredential: parameter 2, error code 0x4 : value is out of range or is not correct for the context
The TPM equipped on the device is a Nuvoton TPM 2.0. Following is the output from running Intel's TPM TSS tpm2_tools' (version: 2.1.0) tpm2_dump_capability:
TPM_PT_FAMILY_INDICATOR:
as UINT32: 0x08322e3000
as string: "2.0"
TPM_PT_LEVEL: 0
TPM_PT_REVISION: 1.00
TPM_PT_DAY_OF_YEAR: 0x0000002f
TPM_PT_YEAR: 0x000007df
TPM_PT_MANUFACTURER: 0x4e544300
TPM_PT_VENDOR_STRING_1:
as UINT32: 0x726c7300
as string: "rls"
TPM_PT_VENDOR_STRING_2:
as UINT32: 0x4e504354
as string: "NPCT"
TPM_PT_VENDOR_STRING_3:
as UINT32: 0x20000000
as string: " "
TPM_PT_VENDOR_STRING_4:
as UINT32: 0x20000000
as string: " "
TPM_PT_VENDOR_TPM_TYPE: 0x00000001
TPM_PT_FIRMWARE_VERSION_1: 0x00010003
TPM_PT_FIRMWARE_VERSION_2: 0x00000001
My guess is that the problem lies in ActivateCredential is called for this particular device. Using a test from Intel's tpm2-tools (Attached: tpm2_clear_and_test_activation-221.sh.txt) I get the following error on the same host:
ERROR: ActivateCredential failed. TPM Error:0x80012
On performing a tpm2_rc_decode on the error code, I get:
tpm2_rc_decode 0x80012
error layer
hex: 0x80000
identifier: TSS2_SYS_ERROR_LEVEL
description: Error from the SAPI
base error code
identifier: TSS2_BASE_RC_INSUFFICIENT_CONTEXT
description: Context not large enough
When I execute the same two attached files on another host with a different TPM, they run as expected.
Any help in this regard is greatly appreciated.
Thanks!
Best regards,
I'm working on a TPM implementation and would love to see the last section (marked TODO) if and when you have time!
In issue #98 it was mentioned that some of the AK activation was done to match how the windows Platform Crypto Provider performs things.
Would it be possible to document this as an example (even if in a rough way) somewhere?
I've made a client that successfully performs the AIK activation using raw TPM commands, but I've been trying to convert that to use the PCP and have found progress hard (not due to this project, but lack of windows documentation) and any information would be useful.
Hello, I do like to know how/if can I retrieve the values of the PCRs from the Quote, because I didn't see any method related to that.
var h rawEventHeader
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
return event, err
}
data := make([]byte, int(h.EventSize))
In this code path an attacker can control the number of allocated bytes. This can lead to a DoS attack by OOMing the process.
Example:
Mzk0MDIwMDYxOTYzOTQ0NzkyMTIyNzkwNDAxbUfvv70AMDAxNDM2MTM4MDUwNzk3MzkyNzA0NjU0
NDY2Njc5NDgyOTM0MDQyNDU3MjE3NzE0OTY4NzAzMjkwNDcyNjYwODgyNTg5MzgwMDE4NjE2MDY5
NzMxMTIzMTk=
Produces:
rawEventHeader{
PCRIndex:0x30343933,
Type:0x36303032,
Digest:[20]uint8{0x31, 0x39, 0x36, 0x33, 0x39, 0x34, 0x34, 0x37, 0x39, 0x32, 0x31, 0x32, 0x32, 0x37, 0x39, 0x30, 0x34, 0x30, 0x31, 0x6d},
EventSize:0xbdbfef47,
}
0xbdbfef47
being 3.183 GB.
It doesn't appear that the TCG EFI Protocol Specification defines a maximum size for an event. So it seems our options are either choosing an arbitrary maximum or reporting this to the TCG as undefined behavior.
Running this sample , which is based on the official example, ActivateCredential
, and especially the call to nCryptGetProperty
fails on 2 of my Windows 10 machines with the following error code : 0X80090030 (NTE_DEVICE_NOT_READY)
.
Running the same sample but using an admin cmd, everything works as expected.
I'm sorry I'm not quite yet familiar with how PCP
handles all this TPM 2.0
stuff, but is this a normal behaviour ? or is there something I should be doing beforehand ?
Thanks.
Tried to run 'self-test' , 'tpm-info' , getting the following error :
FAIL
Error: credential activation failed: failed to generate activate credential: NCryptGetProperty returned 80090030 (The operation completed successfully.) for key activation
I am able to run the same binary and get expected output output in some systems while in some other systems, I am getting the error mentioned.
It will be very useful if someone can point out a way to solve this error. Many Thanks.
Use-case: Verifying an EK certificate chains up to a set of known root CA's and intermediates.
We could leave this to implementers to hack something up using x509.CertPool
, but there are a few complexities that make that suboptimal:
Proposal:
Make an EKCertVerifier
structure, that consumes a slice of intermediate & root x509 certificates.
Users call .Verify(der)
and recieve the validated certificate chain, or an error.
WDYT?
We should run windows tests on a shielded VM GCP instance.
This can lead to errors when trying to parse it: invalid log: event data size is 0
.
Given an empty event log defeats the point of platform attestation, a call to AttestPlatform()
should return an error if the platform does not have a valid event log.
The error: parameter 2, error code 0x4 : value is out of range or is not correct for the context
(one of the) causes: 2.2.1.2.3 specifies that the EK template can have a nonce. We never accounted for that logic when creating the EK primary key. This feature is a footgun and was only used on old TPMs, hence why I never encountered it before.
The fix is to correctly interrogate the NV indices for the nonce and template when creating the EK if its not already persisted.
Thanks for @chrisfenner for debugging this with me.
Looking at the exported API the package is a little cluttered. https://godoc.org/github.com/google/go-attestation/attest
Some thoughts for cleaning up the API, these are mostly just nits:
certificate-transparency-go/x509
relaxes the golang cert parsing and error checking in dangerous ways that should not be used apart from certificate observation use cases.
Hello, a couple days ago I came here to talk about a question of retrieving the PCRs values from the Quote and I got Verify method as answer, I've studied about this method and as I see, it compares all 24 PCRs values, I would like to know if I could select which PCRs I want to be compared. For example, In my problem I only need PCRs 2, 4, 5, 6 and 9.
I am contributing to a downstream project, spire-tpm-plugin, and would like to be able to test using the TPM simulator like this project does:
go-attestation/attest/attest_simulated_tpm20_test.go
Lines 30 to 42 in 25ce564
The issue I'm running into is that platformTPM
is a private struct, so I am unable to "fake" the TPM in downstream testing
Right now, a user of go-attestation must download and install libtspi-dev even if they only wish to use TPM2 (such as with GCE). This can be problematic as this library is not distributed with all Linux distros.
Go supports build constraints to allow for conditional compilation. Similar to how we don't require tspi on Windows builds, we could use a notspi
build constraint to allow:
go build -notspi windows ./attest/attest-tool
to build without tspi.
We could also invert the semantics, having the tspi
build flag enable support for TPM 1.2 on Linux, depending on what we want to be the default.
Use case:
Proposal:
Event
is verified by the digest or not.The PR pending here: google/go-tpm#143
Will export a method to get a crypto.Hash
from a tpm2.Algorithm
. We should use it once it lands so we have a smaller integration surface to maintain.
This should be its own call or take a context. When packages make requests, users MUST be able to provide a custom http.Client
for scenarios like transport proxies.
Can we expand the PlatformEK so uses can handle these cases?
type EK struct {
// Public key of the EK.
Public crypto.PublicKey
// Certificate is the EK certificate. This may be nil, depending on the provider.
Certificate *x509.Certificate
// For Intel TPMs, Intel hosts certificates at a public URL derived from the
// Public key. Clients or servers can perform an HTTP GET to this URL, and
// use ParseEKCertificate on the response body.
CertificateURL string
}
func ParseEKCertificate(b []byte) (*x509.Certificate, error)
Hello, I'm working with your lib and I wonder if you plan to make a function to make the quote using a set of pcrs. Because I've studied your lib and I saw you only give me a way to make a quote using all pcrs.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.