Open SergiiDmytruk opened 1 year ago
Merging #833 (bccb707) into master (1b3aab9) will decrease coverage by
0.01%
. The diff coverage is70.00%
.
@@ Coverage Diff @@
## master #833 +/- ##
==========================================
- Coverage 72.43% 72.43% -0.01%
==========================================
Files 34 34
Lines 9773 9783 +10
==========================================
+ Hits 7079 7086 +7
- Misses 2694 2697 +3
Impacted Files | Coverage Δ | |
---|---|---|
src/lib/attrs.c | 72.00% <ø> (ø) |
|
src/lib/tpm.c | 71.41% <ø> (ø) |
|
src/lib/sign.c | 76.55% <70.00%> (-0.21%) |
:arrow_down: |
:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more
I'd like to see some examples on how to use this, to for example lock a key to only be usable when a set of pcr's has a certain value.
@glance-, we ended up not needing the changes (at least not yet), so haven't touched this stuff for awhile, but some example based on notes is provided below.
tpm-policy.json
)Policies are described in JSON format (specification), the case of a PCR policy is quite simple:
{
"description": "PCR7 policy",
"policy": [{
"type": "pcr",
"pcrs": [{
"pcr": 7,
"hashAlg": "sha256",
"digest": "0000000000000000000000000000000000000000000000000000000000000000"
}]
}]
}
The description
field is merely informational and is optional in the specification, but implementation in tpm2-tss
requires it to be present.
Current value of a PCR can be obtained via:
tpm2_pcrread sha256:7
# initialize pkcs#11
tpm2_ptool init
# create token
tpm2_ptool addtoken --pid 1 --sopin mysopin --userpin myuserpin --label tpm20
# create a key protected by the policy
tpm2_ptool addkey --label=tpm20 --key-label=mykey --userpin=myuserpin \
--algorithm=rsa2048 --policy="$(cat tpm-policy.json)"
I think I'm missing something here. I've built a tpm2-pkcs11 with this pull-request merged ontop of master, tpm2-tss 4.0.1 and tpm2-pytss 2.2.0-rc0 which all where the latest when I started playing around with this.
When I create a key with a policy just as you've described, only changed policy from pcr 7 to pcr 8 for my tests to be simpler.
To create a simple self signed certificate with that key I've used openssl with -provider tpm as shown in https://github.com/tpm2-software/tpm2-pkcs11/issues/766#issuecomment-1119360906 to create such a certificate:
yaml_rsa0=$(tpm2_ptool export --label=tpm20 --key-label=mykey --userpin=myuserpin)
auth_rsa0=$(echo "$yaml_rsa0" | grep "object-auth" | cut -d' ' -f2-)
openssl req -new -x509 -provider tpm2 -provider base -key "mykey".pem -passin "pass:$auth_rsa0" -subj "/CN=$HOSTNAME" -out "$HOSTNAME.pem" -days 3650 -nodes -sha256 -addext 'basicConstraints=critical,CA:FALSE' -addext 'keyUsage=digitalSignature'
All goes fine while:
# tpm2_pcrread sha256:8
sha256:
8 : 0x0000000000000000000000000000000000000000000000000000000000000000
I can even use it via libtpm2_pkcs11.so with ex sbsign:
sbsign --engine pkcs11 --key 'pkcs11:token=tpm20;pin-value=myuserpin' --cert "$HOSTNAME.pem" --output test-signed.efi /boot/vmlinuz-6.1.0-17-amd64
If I now "break" things by tpm2_pcrextend 8:sha256=f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2
I can't run above sbsign command via the pkcs11 module, but above openssl -provider tpm2 runs just fine.
How can the tpm still allow the openssl tpm provider to access to the key?
Not sure, but it might be related to the fact that policy is processed only for signing here.
But the whole idea is that the tpm should refuse to do anything with the key unless it knows the policy is satisfied. That means that even if I dig up the handles to the key some other way it should know that there's a policy on this key, and refuse to do anything unless it's satisfied.
I just tried the following dirty hack:
diff --git i/src/lib/sign.c w/src/lib/sign.c
index bd91a88..47a07f7 100644
--- i/src/lib/sign.c
+++ w/src/lib/sign.c
@@ -255,7 +255,8 @@ static CK_RV common_init(operation op, session_ctx *ctx, CK_MECHANISM_PTR mechan
if (op == operation_sign) {
rv = policy_is_satisfied(tok->tctx, tobj, tok->pobject.handle);
if (rv != CKR_OK) {
- return rv;
+ LOGE("policy_is_satisfied failed, continuing anyway");
+ rv = CKR_OK;
}
}
And now I get the libtpm2_pkcs11.so to ignore any policies and just sign things anyway, so something is definitely not the way it should be.
You might want to look into something like this key creation and its usage with a policy. This one is enforced by TPM.
I was just expecting the key to be setup in a way requiring the policy to be fulfilled for usage, when it was created with tpm2_ptool addkey ... --policy
I'd guess any other user also would expect that to.
But this concludes, that this part of this feature isn't implemented in this PR, which I'd guess would be a blocker for actually merging this.
But this concludes, that this part of this feature isn't implemented in this PR, which I'd guess would be a blocker for actually merging this.
The implementation follows this comment. There is always a chance of misunderstanding, so maybe you're right and the implementation isn't correct.
Hi.
As was mentioned in #301 about a month ago, we want to have the ability to bind use of a private key to an expected value of a PCR.
Currently the changes include a new attribute and related modifications to
tpm2_ptool
. Sending the PR just in case you can see an issue with the changes right away.I've added
--policy
parameter toaddkey
,import
andlink
subcommands. There is also a new subcommand calledobjpol
, which is similar toobjmod
but deals only with the policy.objpol
can be dropped if you don't see much value in it, but then it would be nice to add--raw
toobjmod
for printing value as is rather than as a YAML.Update. Fixed a bug in
tpm2_ptool
and added code for executing a policy during signing if it's present on a private key. The only callback set is "get PCR" which is enough for handling of PCR policies and their templates.I've noticed that there seems to be an effort to maintain compatibility with
tpm2-tss
v2.0, so handling of policies is optional and is disabled iftpm2-policy
isn't present or--without-policy
is passed toconfigure
.There are also a couple of trivial changes in separate commits.