Table of Contents
Cryptography used for Hi-MD
This page uses the data presented in himddownload as example values.
Session key negotiation
Session key negotiation starts with mutual authentication. The mutual authentication process has the host and the device calculate different MACs over the triplet of (current disc ID, host-chosen nonce, device-chosen nonce). Each side is free to use the root key of any EKB that is readable by the other side, but typically the EKB 00010012 is used. It's root key is f51ecb2a808f15fd542ef5123bcdbca4. Each MAC is accompanied by the key chain (part of an EKB) that allows the remote side to verify the MAC.
$ # general setup $ rootkey1_12=f51ecb2a808f15fd542ef5123bcdbca4 $ devkey=$rootkey1_12 $ hostkey=$rootkey1_12 $ retailmac() > { > keyA=$(echo $1 | cut -c 1-16) > keyB=$(echo $1 | cut -c 17-32) > openssl enc -des-cbc -iv 0 -K $keyA -nopad | tail -c 8 | openssl enc -d -des-ecb -iv 0 -K $keyB -nopad | openssl enc -des-ecb -iv 0 -K $keyA -nopad > } $ $ # session-specific data $ hostnonce=be9ae112ab975bba $ devnonce=8a6e4c993194dfca $ discid=02000000000006122102000000722751 $ # this prints the MAC as sent by the device $ devmac=`echo $discid$hostnonce$devnonce | xxd -r -p | retailmac $devkey | xxd -p` $ echo $devmac 408ed62caf74ec19 $ # this prints the MAC as sent by the host $ hostmac=`echo $discid$devnonce$hostnonce | xxd -r -p | retailmac $hostkey | xxd -p` $ echo $hostmac 90ec3e0ffd4a2037 $ # this determines the session key $ sessionkey=`echo $discid$devmac$hostmac | xxd -r -p | retailmac $hostkey | xxd -p` $ echo $sessionkey 3bf281418cdd98ac
MAC list authentication
The MAC list is protected by an ICV (integrity check value). This ICV is signed by the session key. Let's verify the ICV signature first (session continues from above), and then verify that the ICV matches the MAC list. Can't be done completely, as the dump does not include the MACs from unrelated tracks, but it should give the idea. The root key used here is determined using the EKB specified in the MACLIST file.
$ icv=1d3dd1a65b26d1f2c0e419dbb9ab8c30 $ icvheader=0030001000000010 $ # this prints the ICV MAC $ echo $icvheader$icv | xxd -r -p | openssl enc -des-cbc -iv 0 -K $sessionkey -nopad | tail -c 8 | xxd -p 2e09ec3f3e6a1366 $ # now verify the ICV (only head part) $ generation=00000010 $ maclist10=23ef064115d13ca0522ad85308c9a57b $ maclist60=4f5a127e17433c3c29ae460f6d5b9c84 $ headkey=`echo $maclist10 | xxd -r -p | openssl enc -d -des-ede -iv 0 -K $rootkey1_12 -nopad | xxd -p` $ bodykey=`echo $maclist60 | xxd -r -p | openssl enc -d -des-ede -iv 0 -K $rootkey1_12 -nopad | xxd -p` $ # rebuild MCLIST header (bytes 0x20-0x5F) from dump info $ ekbid=00010012 $ padding1=0000000000000000000000000000000000000000 $ padding2=00000000 $ padding3=000000000000000000000000000000000 $ head=$generation$padding1$ekbid$padding2$discid$padding3 $ echo $head | xxd -r -p | xxd 0000000: 0000 0010 0000 0000 0000 0000 0000 0000 ................ 0000010: 0000 0000 0000 0000 0001 0012 0000 0000 ................ 0000020: 0200 0000 0000 0612 2102 0000 0072 2751 ........!....r'Q 0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ $ # this prints the first half of the ICV $ echo $head | xxd -r -p | retailmac $headkey | xxd -p 1d3dd1a65b26d1f2 $ # the second half of the ICV is the retail MAC over the MCLIST body (bytes 0x70..0x7d6f) $ # using bodykey.
Now, this worked nicely for the MAC list as it was read by the computer in the beginning, now let's try again for the MAC list after update.
$ icv=cffa2939fb138e4979fc74da8b00edd8 $ icvheader=0020001000000011 $ # this prints the ICV MAC $ echo $icvheader$icv | xxd -r -p | openssl enc -des-cbc -iv 0 -K $sessionkey -nopad | tail -c 8 | xxd -p 514fca4815ac89bf $ # now calculate the first half of the ICV (second half again impossible because of missing data) $ generation=00000011 $ maclist10=ed985b757d648c86d809ae0b762304d2 $ maclist60=45ee5957aec495837ac62a388357c0e7 $ headkey=`echo $maclist10 | xxd -r -p | openssl enc -d -des-ede -iv 0 -K $rootkey1_12 -nopad | xxd -p` $ bodykey=`echo $maclist60 | xxd -r -p | openssl enc -d -des-ede -iv 0 -K $rootkey1_12 -nopad | xxd -p` $ head=$generation$padding1$ekbid$padding2$discid$padding3 $ # this prints the first half of the ICV $ echo $head | xxd -r -p | retailmac $headkey | xxd -p cffa2939fb138e49
Track encryption
The track key-encryption-key (KEK) is stored encrypted by the EKB root key
$ rootkey1_12=f51ecb2a808f15fd542ef5123bcdbca4 $ # calculate track key-encryption-key $ enctrackkey=d7c9cadc12b9ad99 $ trackkey=`echo $enctrackkey | xxd -r -p | openssl enc -d -des-ede -iv 0 -K $rootkey1_12 -nopad | xxd -p` $ echo $trackkey 3e8ab6c3c32c35eb $ # calculate MAC $ contentid=010f50000004000000b792f6f9318c20fff1aad8 $ trkentry="0001010000000000 $contentid 0000000000000000 01004400" $ mackey=`echo 0000000000000000 | xxd -r -p | openssl enc -des -iv 0 -K $trackkey -nopad | xxd -p` $ echo $trkentry | xxd -r -p | openssl enc -des-cbc -iv 0 -K $mackey -nopad | tail -c 8 | xxd -p 8f35336c5818d22b