Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Sealing and Unsealing #246

Open
tobuh opened this issue Apr 28, 2021 · 4 comments
Open

Basic Sealing and Unsealing #246

tobuh opened this issue Apr 28, 2021 · 4 comments

Comments

@tobuh
Copy link

tobuh commented Apr 28, 2021

I know the example for complete seal and unsealing workflow, including policies. However, just simple tpm2.Seal() und tpm2.Unseal() does not work. For example, I would expect the following to work:

rwc, err := tpm2.OpenTPM("/dev/tpm0")
if err != nil {
  log.Fatal(err)
}
defer rwc.Close()

secret := []byte("test")

srkHandle := tpmutil.Handle(0x81000001)

privSeal, pubSeal, err := tpm2.Seal(rwc, srkHandle, "", "", nil, secret)
if err != nil {
  log.Fatal(err.Error())
}

sealHandle, _, err := tpm2.Load(rwc, srkHandle, "", pubSeal, privSeal)
if err != nil {
  log.Fatal(err.Error())
}
unsealed, err := tpm2.Unseal(rwc, sealHandle, "")
if err != nil {
  log.Fatal(err.Error())
}

log.Print(string(unsealed))

But I receive this error:
error code 0x2f : authValue or authPolicy is not available for selected entity

I would expect something similar (and compatible) to this:

echo test | tpm2_create -u test.pub -r test.priv -i- -C 0x81000001
tpm2_load -C 0x81000001 -u test.pub -r test.priv -c test.ctx
tpm2_unseal -c test.ctx

Is there something I do wrong?

@chrisfenner
Copy link
Member

I don't think the current implementation of Seal supports unsealing without policy:

go-tpm/tpm2/tpm2.go

Lines 575 to 580 in d331077

inPublic := Public{
Type: AlgKeyedHash,
NameAlg: AlgSHA256,
Attributes: FlagFixedTPM | FlagFixedParent,
AuthPolicy: objectAuthPolicy,
}

Since userWithAuth is not set, the sealed data blob can only be authorized by policy (which is unsatisfiable if nil was passed)

I propose that we improve Seal by adding userWithAuth if a nil policy was provided, as there is otherwise no way to unseal the data. However, opaquely relaxing the security properties of the API is something we should be careful about. What say ye, @twitchy-jsonp / @josephlr ?

@chrisfenner
Copy link
Member

Alternative: deprecate go-tpm's Seal entirely because there is no TPM2_Seal command. Instead, we should expose a flexible enough TPM2_Create to allow the creation of sealed data blobs.

(Why is there no TPM2_Seal command? Because a sealed blob is just another type of TPM object, which can always be created either by the TPM itself with TPM2_Create or off-box, encrypted and imported under a Storage key with TPM2_Import.)

@tobuh
Copy link
Author

tobuh commented Apr 29, 2021

@chrisfenner Thanks for the reply and the explanations.

I don't think there are any security issues added, as currently it would be possible to unseal by:

tpm2_load -C 0x81000001 -u test.pub -r test.priv -c test.ctx
tpm2_startauthsession --policy-session -S session.dat
tpm2_policypassword -S session.dat
tpm2_unseal -c test.ctx -p session:session.dat+""

So there is no security difference from my perspective. It is also a question of usability. And I think it is always a good idea to be as compatible as possible to tpm2-tools.

Remark: I manually added FlagUserWithAuth, but it does not seem to work that simple.

@josephlr
Copy link
Member

@chrisfenner I think deprecating Seal in this library would be the best bet. It has issues that we can't likely fix in a backwards compatible way. In go-tpm-tools, we had to use CreateKeyWithSensitive rather than Seal to get things to work correctly. We should just recommend users use that method instead. Something like:

inPublic := tpm2.Public{
	Type:       tpm2.AlgKeyedHash,
	NameAlg:    sessionHashAlgTpm,
	Attributes: tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagUserWithAuth,
	AuthPolicy: nil,
}
private, public, _, _, _, err := tpm2.CreateKeyWithSensitive(rw, parentHandle, PCRSelection{}, "", "", inPublic, sensitive)
// Check err
// Store private/public

And I think it is always a good idea to be as compatible as possible to tpm2-tools.

@tobuh I would say that this library seeks to (eventually) have parity with the TCG's ESAPI which is part of tpm2-tss (which is in turn used by tpm2-tools).

If you want a higher-level API that makes this sealing stuff easier, we have go-tpm-tools which tries to provide a smaller, easier to use API (but with reduced functionality). Would go-tpm-tools/client.Seal work for your use case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants