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

Cannot unseal LUKS key #48

Open
miczyg1 opened this issue Jul 5, 2020 · 7 comments
Open

Cannot unseal LUKS key #48

miczyg1 opened this issue Jul 5, 2020 · 7 comments

Comments

@miczyg1
Copy link

miczyg1 commented Jul 5, 2020

I did some experiments with DRTM and tried to seal my LUKS key to DRTM PCRs. Although I have verified that my PCRs do not change after final modifications to initramfs and kernel commandline, I get a policy check failed.

sha256:
  0 : 0x2BDAE483EDEEDF49EB446EE620342655426415B59EC2F8B4D11CFCB28C30332F
  1 : 0x55D6649B11D2401AE333657837BFE79EF5C36D1050AF81D8EFB2EA1DAD66380A
  2 : 0x2DE4E2179EA4576726C4160644D91248B2A162747E9923E47C13777DB9965D39
  3 : 0x9B4409F3631D1025AED62A89CC1140CD8C23F770F6D8A995A2C59149542A4C58
  4 : 0x94855A1DF928211EAB2000178968B4B630B9BAC53B4C34177EE5224E9AAF2304
  5 : 0xAEB5AD1E10B8813ED830E30EB82CF82978B4FFDF5F16A922899BAAF9BF532EE0
  6 : 0xD27CC12614B5F4FF85ED109495E320FB1E5495EB28D507E952D51091E7AE2A72
  7 : 0xD27CC12614B5F4FF85ED109495E320FB1E5495EB28D507E952D51091E7AE2A72
  8 : 0x0000000000000000000000000000000000000000000000000000000000000000
  9 : 0x0000000000000000000000000000000000000000000000000000000000000000
  10: 0x2FF621AB240B4354479E6CE068EE9CB455F79C12E1945A20C2CFF81C9F0D03CE
  11: 0x0000000000000000000000000000000000000000000000000000000000000000
  12: 0x0000000000000000000000000000000000000000000000000000000000000000
  13: 0x0000000000000000000000000000000000000000000000000000000000000000
  14: 0x4CC49932DC91C7021E5CFEE8231A5F2DA3AC1DE6DF7A7AEFF333CC8DFD230F28
  15: 0x0000000000000000000000000000000000000000000000000000000000000000
  16: 0x0000000000000000000000000000000000000000000000000000000000000000
  17: 0x1A3DE45428A078918100BEFA0279BCF94F255F95E975A787D77E06C407AFF965
  18: 0x2EBB9B7C1C4342B4776B9F2B06E73BFE899A708B58BE35A579B73AB0D53529DC
  19: 0x0000000000000000000000000000000000000000000000000000000000000000
  20: 0x0000000000000000000000000000000000000000000000000000000000000000
  21: 0x0000000000000000000000000000000000000000000000000000000000000000
  22: 0x0000000000000000000000000000000000000000000000000000000000000000
  23: 0x0000000000000000000000000000000000000000000000000000000000000000
WARNING:esys:src/tss2-esys/api/Esys_Unseal.c:291:Esys_Unseal_Finish() Received TPM Error 
ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:98:Esys_Unseal() Esys Finish ErrorCode (0x0000099d) 
ERROR: Esys_Unseal(0x99D) - tpm:session(1):a policy check failed
ERROR: Unable to run /usr/bin/tpm2_unseal
Falling back to user pass phrase
WARNING:esys:src/tss2-esys/api/Esys_NV_ReadPublic.c:309:Esys_NV_ReadPublic_Finish() Received TPM Error 
ERROR:esys:src/tss2-esys/esys_tr.c:210:Esys_TR_FromTPMPublic_Finish() Error NV_ReadPublic ErrorCode (0x0000018b) 
ERROR:esys:src/tss2-esys/esys_tr.c:321:Esys_TR_FromTPMPublic() Error TR FromTPMPublic ErrorCode (0x0000018b) 
ERROR in tpm2totp_loadKey_nv (src/libtpm2-totp.c:639): 0x0000018b

ERROR in main (src/tpm2-totp.c:441): 0x0000018b
TPM TOTP FAILED

NOTE: No UEFI here. The kernel is not packaged into EFI file, but is only measured by DRTM

Steps I have performed:

  1. Enable DRTM on the platform and bootloader (custom GRUB).
  2. Add tpm.mode=linux tpm.pcrs=17,18 to the kernel commandline.
  3. Update initramfs so that unseal hooks get installed.
  4. Reboot.
  5. Dump PCRs and save them in separate file.
  6. Run sudo safeboot luks-seal 17,18
  7. Reboot
  8. Check the PCRs 17,18 from unseal script output with previously saved file and ensure they are the same. Encounter the policy check error.

Could it be that tpm2-tools expect the PCRs to be sorted in ascending order when creating policy? Looking at luks-seal execution, the policy was created with PCRs 17,18,14.

What is more, I have checked with tpm2_nvreadpublic and there is not NV index with handle 0x81000000. Maybe the sealing process failed silently.

@miczyg1
Copy link
Author

miczyg1 commented Jul 6, 2020

It seems I have found the culprit...

The safeboot luks-seal script took the PCRs 17,18,14 to create policy. And in that same exact order the PCRs were dumped to $TMP/pcrs.bin. But what if the tpm2_createpolicy tool assumes that PCRs are in ascending order? That would obviously work in original safeboot case with PCRs 0,2,5,7,14, but not for 17,18,14 sequence. So I sorted the PCRs and the digests when sealing the LUKS key, only then the unsealing worked...

@osresearch
Copy link
Owner

Ah, right. DRTM uses the higher PCRs. 14 was selected to store the boot mode on the Lenovo platform I was developing on since it was a high number and unused. The value is precomputed as part of the safeboot luks-seal sub-command https://github.com/osresearch/safeboot/blob/master/sbin/safeboot#L562

The fix for DRTM is going to be a little tricky, since the pcrs.bin does not encode which PCRs are included. Worst case if you seal on something like 0,1,16,17, in which case the boot mode PCR would have to be inserted in the middle of the file.

@miczyg1
Copy link
Author

miczyg1 commented Jul 15, 2020

No, the worst thing in this issue is that tpm2-tools takes the PCR number as a bitmask, but it doesn't account for the order of PCR digests in the pcrs file when passed to create a policy. If the tpm2 tools could parse the order of passed PCRs, this issue would net even exist You would have to iterate through all pcrs, sort them first, then itegrate again and then inject the calculated digest for PCR14 only. Doable in bash I think.

@osresearch
Copy link
Owner

Yeah, the tpm2-tools handles the PCRs as a bitmask since the TPMS_QUOTE_INFO struct only has a bitmap of the PCRs, so no ordering in the quote is possible:

attested:
  quote:
    pcrSelect:
      pcrSelections:
        0:
          hash: 11 (sha256)
          pcrSelect: 170000
    pcrDigest: b7c7154657a49ddf2f8513bc16a6e1821cc739b5ba15bb0a478f8f8dbb0edc3a
pcrs:
  sha256:
    0 : 0x3FBF10A9DD919CD821C71C71B203F3839233120537798917F53714F1EFF7F036
    1 : 0x6BAD0D93219F5B1E3BA7031BAB290ECA4D973AE6468145847A49D44BCC0905BD
    2 : 0x3D458CFE55CC03EA1F443F1562BEEC8DF51C75E14A9FCF9A7234A13F198E7969
    4 : 0xC28F2726BA0A11B9FBA161419FF95BE3DA6CA9ADDC286D5FA1E1E9EC0B79DC35

(also, note the byte order -- 0,1,2,4 => 0x170000)

The fix would have to merge the parser in pcr_parse_selection(), where the user string is provided, and tpm2_policy_build_pcr(), which has the unordered bitmap and the ordered PCR file. The FAPI tools might be a better fit since they process JSON as input rather than the raw binary data.

In the DRTM case do you ever use lower PCRs? One fix would be to modify sbin/safeboot to put the boot mode before the PCRs if the values are higher, or you could override BOOTMODE_PCR in /etc/safeboot/local.conf to use a higher PCR.

@miczyg1
Copy link
Author

miczyg1 commented Jul 16, 2020

In the DRTM case do you ever use lower PCRs? One fix would be to modify sbin/safeboot to put the boot mode before the PCRs if the values are higher, or you could override BOOTMODE_PCR in /etc/safeboot/local.conf to use a higher PCR.

This is basically what I did. Ignored the SRTM PCRs and just used PCRs 14,17,18. At this point it worked, but care must be taken to not choose the PCRs arbitrarily as the safeboot luks-seal allows to do so.

@osresearch
Copy link
Owner

I'm working on an overhaul of how the TPM PCRs are handled as part of #57, which will involve sorting the PCRs and precomputing the SRTM PCR4 as part of the process. This sorting will hopefully also fix your DRTM issue, although the PCR4 will not be correct for a tboot system, so you shouldn't use that one.

@miczyg1
Copy link
Author

miczyg1 commented Nov 10, 2020

Example how PCRs could be sorted:

$ export PCRS=0,2,4,7,10,12,17,18,14
$ echo $PCRS | sed -e $'s/,/\\\n/g' | sort -n | tr '\n' ',' | sed 's/.$//'
0,2,4,7,10,12,14,17,18

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

2 participants