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

Fail to extract volume key for capi:authenc(hmac(sha256),xts(aes))-plain64 #10

Closed
pPanda-beta opened this issue Jan 23, 2023 · 4 comments

Comments

@pPanda-beta
Copy link

The volume key of luks2 with integrity is slightly different from regular luks2 volume key.

It is normally 96bytes. The first 64 bytes are the two parts of aes-xts key. The next 32bytes are the integrity key which is used for validation.

There are primarily two problems I've identified:

  1. Reading the anti-forensic key
    Here this code is reading equivalent size of keyslot.KeySize but it should read the anti forensic area size (keyslot.Area.KeySize) only.

    afKey, err := deriveLuks2AfKey(keyslot.Kdf, keyslotIdx, passphrase, keyslot.KeySize)

    When using aes-xts-plain64 without integrity, both the values are 64bytes.

  2. Separation of aes-xts key and integrity key. As I've mentioned above, the 96 bytes need to be split into 64bytes and 32bytes. This should be done near

    finalKey, err := d.decryptLuks2VolumeKey(keyslotIdx, keyslot, afKey)

Command to prepare the test data:

dd if=/dev/random of=/tmp/partitionKey.txt  bs=1 count=32
cryptsetup luksFormat -q --type luks2 /tmp/exp1/test_disk.img --cipher aes-xts-plain64 --key-file /tmp/partitionKey.txt \
    --integrity hmac-sha256 --integrity-no-wipe --sector-size 4096

# Extract volume key and verify with our code's output
cryptsetup luksDump /tmp/exp1/test_disk.img -q -v  --key-file /tmp/partitionKey.txt --dump-volume-key --volume-key-file /tmp/exp1/vk.key
@anatol
Copy link
Owner

anatol commented Jan 24, 2023

Adding support for keys with integrity sounds reasonable. There are a few places in luks.go that assume keyslot.KeySize and keyslot.Area.KeySize are the same. And this needs to be fixed.

Would you be able to provide a patch for the changes you mentioned? And I can add an integration test for this change.

@pPanda-beta
Copy link
Author

I've identified only two places which are harmful.

afKey, err := deriveLuks2AfKey(keyslot.Kdf, keyslotIdx, passphrase, keyslot.KeySize)

and
return afMerge(keyData, int(keyslot.KeySize), int(af.Stripes), h())

For the patch I tried modifying these, but it was giving checksum error. The 2nd part is also crucial. I tried taking only first 64bytes of the volume key. It didnt work. Tried looking over internet to see if any algorithm or pseudocode is present for this. Unfortunately I couldn’t find any good resource.
This doc is too much theoretical and actual algorithm / steps are not clear from it.

I'm planning to go through the latest cryptsetup luksOpen codebase. (Too challenging, since its a c code with low readability)

If you know any good documentation please let me know.

@anatol anatol closed this as completed in ada2562 Jan 25, 2023
@anatol
Copy link
Owner

anatol commented Jan 25, 2023

There is no good documentation about the implementation algorithm, unfortunately.

I've been using luks2_keyslot_get_key() code from cryptsetup project to understand the logic.

I think I was able to figure out what was wrong with the function. Please try luks.go from master branch and let me know if you still see the problem.

@pPanda-beta
Copy link
Author

@anatol
Thanks for that PR. I think this part is solved for now. But I'm still struggling to read encrypted data at certain offset. I believe the problem lies in the devmapper.go codebase and not here.
To discuss that I have opened anatol/devmapper.go#1

Anyway, it would be nice if we can somehow pass on the information to the CryptTable struct that this key contains both cipher key and integrity key.

Somewhere near here:

Key: v.key,

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