Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!


Click here to return to the 'Recover/repair a corrupt encrypted sparse image' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Recover/repair a corrupt encrypted sparse image
Authored by: ptone on Apr 27, '07 08:55:33AM
I'm not a fan of having the entire hint posted at a site that may or may not exist in the future. The OP should update in the macosxhints.com comments. I've copied and pasted the original posters hint here so that it is preserved in this sites archive.

Recover a corrupt AES-128 encrypted sparse image (using an older backup - without it, you're almost lost)

Version 1.3, April 2007

General considerations

An important, encrypted sparse image (like file vault), got corrupted after a system freeze.
I only had an older backup (I should have had a newer one, I know...)

trying to mount the image (by finder or hdiutil) yielded...:

[host:~] user% hdiutil attach -nomount -noverify -noautofsck -stdinpass MyImage.sparseimage
hdiutil: attach failed - corrupt image

using the -debug option in hdiutil showed some more (taken the most informative lines):

[host:~] user% hdiutil attach -nomount -noverify -noautofsck -stdinpass -debug MyImage.sparseimage
...
WARNING flushing header and index nodes failed.
DIResolveBackingStoreToDiskImage: unable to resolve to any disk image class. 103.
...

It was then clear that some sort of header was broken.
Just because a little bit is gone all my data gone??! Without even the possibility to repair it somehow!?

Yes. Why? Because AES encryption is not just your passphrase molded into your data. Your passphrase gets thru a method called pbkdf2. This function generates the 128-bit key needed using your passphrase, a salt, and a certain number of iterations.

The Key, the salt, the information needed for the iv and other info are stored into the image header, a 4kb block, which is in turn encrypted using 3DES-EDE. Without this header, you're basically LOST.

Last but NOT least, Apple has (by now) 2 formats for the header and 2 places for them: the old one, version 1, (concerning my case and all FileVault/encrypted images created before Mac OS X 10.4.7), was stored at the END of the image.

With version 1 of the header, at every sync, it has to be attached at the end of the file. If the computer freezes, or you have a power interruption, mac os x fails to write this down and you lose the most importan piece of information.

The new format (version 2) introduced with Mac OS X 10.4.7 stores the header at the BEGINNING of the image, which is a much safer idea. But this actually happens only for new images. So my advice is: If you have older encrypted sparse images, make new ones immediately and copy the files onto them!

Fortunately, I had an old copy of that same, corrupt image, from which I could recover the lost header.

I copied the last 4kb of the old image to the end of the broken one, and then I was able to attach the device. I used the tool referenced as vfdecrypt below to decrypt it first into an unencrypted sparse image, but that should not be usually necessary, hdiutil should attach the image device if it finds a valid header.
The filesystem was broken, but with the help of Disk Warrior 4 I was able to rebuild the filesystem (fsck was not enough in this case).

Step-by-step description of what I did (given an older backup)

If You still have an old backup of the broken image, you can try the following, (on a copy of the broken image of course):

[host:~] user% dd if=WorkingBackup.sparseimage bs=1 skip=`ls -al WorkingBackup.sparseimage  | awk '{ print $5 -4096 }'` of=Broken.sparseimage seek=`ls -al Broken.sparseimage  | awk '{ print $5 }'`

then you can try to attach it, without mounting, as the filesystem will need to be probably checked:

[host:~] user% hdiutil attach -nomount -noverify -ignorebadchecksums Broken.sparseimage

if it attaches, You can try to repair it with fsck (change X and Y accordingly):

[host:~] user% fsck_hfs -f /dev/diskXsY

if it is not enough, like in my case, You can still try with DiskWarrior (having the image attached but not mounted).

What helped a lot the understanding:

Read http://crypto.nsa.org/vilefault/23C3-VileFault.pdf - THANKS to You guys at nsa.org!!!

Useful decryption tool (included in http://crypto.nsa.org/vilefault/vilefault-23c3.tar.gz):
I used the source of vfdecrypt, vfdecrypt.c/.h, to better understand what's happening and the binary to obtain an unencrypted version of the image, which I then mounted with hdiutil. Might be useful for You, too:

[host:~] user% curl -O 'http://crypto.nsa.org/vilefault/vilefault-23c3.tar.gz'
[host:~] user% tar xzf vilefault-23c3.tar.gz
[host:~] user% cd vilefault/vfdecrypt
[host:~] user% gcc -lcrypto util.c vfdecrypt.c -o vfdecrypt
[host:~] user% ./vfdecrypt -v -i MyBrokenImage.sparseimage -o MyBrokenImage_decrypted.sparseimage -p 'mypassphrase'
Image headers: how to find out which header version you have.

If You made a new filevault before 10.4.7, it is highly advisable to make a fresh one. This will reduce the risk of corruption drammatically. There is an easy way to check if Your image has the header at the beginning or at the end:

[host:~] user% dd if=/Users/path_to.sparseimage bs=1 count=8 2>/dev/null | grep -c encrcdsa

If the result is "1" then you have a version 2 header, which is at the beginning. That's good :)
If it is 0, then you have the old format, version 1, which places it at the end. You can counter-Check it with the following:

[host:~] user% dd if=/Users/path_to.sparseimage bs=1 skip=`ls -al /Users/path_to.sparseimage  | awk '{ print $5 -8 }'` 2>/dev/null | grep -c cdsaencr

If you  have a version 1 header (bad! risky!), the latter line will output 1.

How to possibly find a lost image header (if you have no backup)

As You can see from the above, both headers have a string to recognize them: version 1 headers END with the string "cdsaencr" , while version 2 headers BEGIN with the string "encrcdsa". If you have no backup image from which to restore the header, there is some chance to find these on the free space of your hard disk. To do this, the best thing is to write a script in perl, php, or a program in C, which reads your hard drive partition device (the one containing the broken image, e.g. /dev/disk0s3), searching for one of those strings (presumably "cdsaencr", as version 1 headers are the ones that break more often). If you find it, try to copy that block back to a file (best on another device, to avoid overwriting it). Be sure to seek to the position where you found the string, minus 4088. The inverse is true for "encrcdsa", version 2, i.e., position of the "e" + 4095.

Good Luck!

©2007 Lorenzo Perone (email)



[ Reply to This | # ]
Recover/repair a corrupt encrypted sparse image
Authored by: lpzlpz on May 07, '07 03:26:46AM

Hi, I'm the original author of the hint. Please apologize for not posting it completely on Macosxhints. It is completely OK for me (@admins!) to edit this hint to contain the whole story. I added a note on the original page for confirmation, also, upon a visitor request, the binaries for the linked tool vfdecrypt by nsa.org.
Please leave the link to the page, however. If I'll find any news on the subject I'll update the page (ok, and maybe I'll also post a comment).
Glad to hear it helped others too.

Lorenzo



[ Reply to This | # ]