Loading...
If the page contents do not appear, it may mean that JavaScript is disabled in your browser. Please enable JavaScript to view this.
An Article from Aaron's Article ArchiveGeekness Alert: Puzzling Over the iPod Shuffle iEKInfo File Format Photo: Easter EggsIPv4You are not logged in. Click here to log in. | |
Use Google to search aarongifford.com:
Here is one of my web log entries, perhaps from my Yakkity Yak page, What's New page, or one of my Astounding Adventures from my Geocaching section: Geekness Alert: Puzzling Over the iPod Shuffle iEKInfo File Format
Monday, 23 May 2005 7:45 PM MDT
Yakkity Yak
This evening I played around a little bit with my iPod Shuffle. I noticed that one of the files on it, iPod_Control/iTunes/iEKInfo looked a bit interesting. It appeared to contain the key information that my iPod needed to play back encrypted AAC files. But the keys in the file appear to be encrypted with some sort of session key.
I have no idea what encryption methods are used, or what is used as keying material. My interest is too casual to undertake reverse engineering this thing. I was mostly just curious. Now I'm wondering if various open source FairPlay DRM projects like they HYMN project have code that knows how to decrypt the keys in this file. They probably do. Maybe I'll have to download it sometime and take a look. Not tonight, though. This is the structure of the iEKInfo file so far as I could see: An atom (seen below as '<ATOM:"abcd">') consists of: <uint32> - Size of atom, including these 4 size bytes and the below 4 type bytes
So far, ALL atoms in iEKInfo that I've encountered have three uint32
<4-byte-type> - Type of atom ("abcd" in above example), usually 4 ASCII bytes <Zero-or-more bytes of content> fields after the atom type, the first being an ID or number, the next a count of the number of subatoms contained, followed by a third uint32 that has always been zero for all atoms I've seen so far. Update: I played around a bit more with a hex editor, changing a byte here or there to see if it broke playback in my iPod. In so doing, I learned that some of the zero-bytes are ignored—I could change them to anything without affecting playback at all. I don't know how any of the changes would affect the host computer music software, though (and I don't care right now). FILE HEADER: ============ <uint32> - Size of file data (excluding this 64-byte header) <60-zero-bytes> - Padding? FILE DATA BEGINS HERE: ====================== <12-zero-bytes> - Padding? <ATOM:"sean"> <uint32> - ID/number (should be 1) <uint32> - No. of subatoms (should be at least 3) <uint32> - Four zero bytes <ATOM:"sym "> <uint32> - ID/number (should be 1) <uint32> - No. of subatoms ("sess" subatoms) - I expect it should be at least 1 <uint32> - Four zero bytes ONE OR MORE "sess" ATOMS: ========================= <ATOM:"sess"> <uint32> - Session ID - Used to identify which keys are encrypted with this session <uint32> - No. of subatoms - Should be 2 (one "valu" subatom, one "index" subatom) <uint32> - Four zero bytes <ATOM:"valu"> <uint32> - ID/number (should be 1) <uint32> - No. of subatoms (should be zero) <uint32> - Four zero bytes <128 bytes of binary data> - The session key or something??? <128 zero bytes> - I don't know if all sessions are structured this way or not... These last 128 bytes are ignored for playback purposes. --- ("valu") <ATOM:"indx"> <uint32> - ID/number (should be 1) <uint32> - No. of subatoms (should be zero) <uint32> - Four zero bytes <uint32> - Every index I've seen thus far has the value six ('6') here. Changing this broke playback on my iPod, so it's important for playback. --- ("indx") --- ("sess") === --- ("sym ") <ATOM:"user"> <uint32> - User ID (a.k.a. DSID) <uint32> - Number of keys, or no. of "key " subatoms <uint32> - Four zero bytes ONE OR MORE "key " ATOMS: ========================= <ATOM:"key "> <uint32> - Key ID or key number <uint32> - Number of subatoms (should be 1) <uint32> - Four zero bytes <ATOM:"valu"> <uint32> - Session ID used to encrypt this key's contents <uint32> - No. of subatoms (Should be zero) <uint32> - Four zero bytes <16 bytes of binary data> - The key data, encrypted with the specified session? --- ("valu") --- ("key") === --- ("user") THREE "guid" ATOMS: (Are there ever more?) =================== <ATOM:"guid"> <uint32> - GUID ID or number (should be one) <uint32> - Number of subatoms (should be zero) <uint32> - Four zero bytes <GUID Data Bytes> - 256 bytes for the first 'guid' atom... The first 9 bytes, if changed, appear to break playback on my iPod. The next three bytes contained data, but I could change it without breaking playback. Byte number 12 (position 11 if the first byte is at position zero) was 1 for a while on my iPod, but later was 2. I didn't check to see if this changed when I moved the iPod from one host computer to another. This is most likely related to the serial number of the iPod. --- ("guid") <ATOM:"guid"> <uint32> - GUID ID or number (should be two) <uint32> - Number of subatoms (should be zero) <uint32> - Four zero bytes <GUID Data Bytes> - 256 bytes for the second 'guid' atom... This has got to be a global unique identifier based on which host computer installation of iTunes the iPod is associated with. It changed when I moved my iPod from one of my host computers to another. But it didn't change when other playlist and/or authorization changes changed the 'sess' session atom. The last 128 bytes are all zero-bytes, and are ignored during playback. I was able to randomly change the last 128 bytes to anything without affecting playback. --- ("guid") <ATOM:"guid"> <uint32> - GUID ID or number (should be three) <uint32> - Number of subatoms (should be zero) <uint32> - Four zero bytes <GUID Data Bytes> - 4 bytes This is the final 'guid' atom, the last one, and yes, it's only 4 bytes long, containing probably a <uint32> value. It has been value six on my iPod. Changing it broke my iPod's ability to play audio files. I see that the value six shows up here, as well in the above 'indx' atom within the 'sess' atom. I can't help but think these two values may be related somehow. --- ("guid") === --- ("sean") === FILE DATA ENDS HEREEXAMPLE of an iEKInfo FILE (in hex): FILE HEADER: ============ 00 00 04 00 <uint32> - Size of file data (1024 bytes) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 60 zero 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - bytes 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ... 00 00 00 00 00 00 00 00 00 00 00 00 - (padding?) FILE DATA BEGINS HERE: ====================== 00 00 00 00 00 00 00 00 00 00 00 00 - 12 zero bytes (padding?) 00 00 03 F4 <uint32> - Atom size (1012 bytes, 1004 body, 992 contents) 73 65 61 6E <atom type> - ASCII "sean" 00 00 00 01 <uint32> - Atom ID 00 00 00 05 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 01 54 <uint32> - Atom size (340 bytes, 332 body, 320 contents) 73 79 6D 20 <atom type> - ASCII "sym " 00 00 00 01 <uint32> - Atom ID 00 00 00 01 <uint32> - Number of session subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 01 40 <uint32> - Atom size (320 bytes, 312 body, 300 contents) 73 65 73 73 <atom type> - ASCII "sess" 00 00 00 01 <uint32> - Session ID 00 00 00 02 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 01 14 <uint32> - Atom size (276 bytes, 268 body, 256 contents) 76 61 6C 75 <atom type> - ASCII "valu" 00 00 00 01 <uint32> - Atom ID 00 00 00 00 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes A6 7B 6B 16 CA 4E 2F 53 1F C8 76 2F 85 12 63 77 - 128 bytes 52 F1 AE 15 22 FE 3A 8E AB 8F B6 0D A5 68 04 FF - of binary 0D C4 7B C3 84 79 D4 00 10 A8 8F 10 A2 FF 0F 14 - session 73 AC 83 90 39 85 C3 66 F3 63 1E BB 92 DC 1D 23 - data used D8 A6 94 A9 A8 F7 4B 07 0F BC B1 3E FF 3F FA 3A - perhaps 59 3E F0 F2 D2 6F CB C9 44 DC B9 36 7B 8C 4F F9 - to 4D 23 9C 65 22 A1 5A 8D AE 5F C7 57 F4 2D 56 0F - ecrypt 53 7B CA 4E 2B EF 85 AD A9 A5 88 F8 A0 A4 C4 CF - user keys 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 128 zero 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - bytes 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - (these 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - bytes are 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ignored 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - for 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - playback) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ... --- ("valu") 00 00 00 18 <uint32> - Atom size (24 bytes, 16 body, 4 contents) 69 6E 64 78 <atom type> - ASCII "indx" 00 00 00 01 <uint32> - Atom ID 00 00 00 00 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 00 06 <uint32> - Some index value? (I've only seen six here) If I change this, it breaks playback on my iPod. --- ("indx") --- ("sess") --- ("sym ") 00 00 00 4C <uint32> - Atom size (76 bytes, 68 body, 56 contents) 75 73 65 72 <atom type> - ASCII "user" BB 65 A4 32 <uint32> - User ID (a.k.a. DSID) 00 00 00 01 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 00 38 <uint32> - Atom size (56 bytes, 48 body, 36 contents) 6B 65 79 20 <atom type> - ASCII "key " 00 00 00 01 <uint32> - Key ID 00 00 00 01 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 00 24 <uint32> - Atom size (36 bytes, 28 body, 16 contents) 76 61 6C 75 <atom type> - ASCII "valu" 00 00 00 01 <uint32> - Session ID used to encrypt this key 00 00 00 00 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 21 FA A8 00 15 D4 FF B5 29 49 52 EF F9 A5 AB 86 - 16 bytes of encrypted key data --- ("valu") --- ("key ") --- ("user") 00 00 01 14 <uint32> - Atom size (276 bytes, 268 body, 256 contents) 67 75 69 64 <atom type> - ASCII "guid" 00 00 00 01 <uint32> - GUID ID or number 00 00 00 00 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 0A 27 00 10 2D E7 ED 00 00 00 01 00 00 00 00 - 256 bytes 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - of binary 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - data... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Mostly all 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - zeros in 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - this case. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - (For 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - playback 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - purposes, 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - all but 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - the first 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - nine bytes 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - are 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ignored) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ... --- ("guid") 00 00 01 14 <uint32> - Atom size (276 bytes, 268 body, 256 contents) 67 75 69 64 <atom type> - ASCII "guid" 00 00 00 02 <uint32> - GUID ID or number 00 00 00 00 <uint32> - Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 42 F9 BE 6E 07 73 2E 05 35 BB 37 78 9A CE A6 EE - 128 bytes EB C1 56 60 C4 FB 8B 56 84 A6 09 55 76 AC 2B D2 - of binary 7E 50 C9 B8 55 57 C8 F5 D3 54 F7 D4 89 31 2C ED - data 5F EA C5 A3 84 6F C3 3C AE EF E5 CC 2C 43 B2 2C - ... 2E FF 30 D5 16 3E 23 3A 4D A9 01 AA B8 2D 18 7E - ... B6 13 C7 12 C6 A2 07 E3 9E A1 DA 66 C0 03 44 88 - ... 6C 83 B5 99 F9 40 C4 2B 5A DB 6C AD 35 53 91 19 - ... 1B C8 E5 06 15 55 7F 2F 0D 3A B8 E2 9F EA A8 88 - ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 128 zero 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - bytes 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - (ignored 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - for 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - playback 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - by my 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - iPod) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ... --- ("guid") 00 00 00 18 <uint32> - Atom size (24 bytes, 16 body, 4 contents) 67 76 69 64 <atom type> - ASCII "guid" 00 00 00 03 <uint32> - GUID ID or number 00 00 00 00 Number of subatoms 00 00 00 00 <uint32> - Four zero bytes 00 00 00 06 - This is important somehow, changing it breaks my ipod's playback ability. I wonder what it means? It does match the index value in the above 'sess' atom. --- ("guid") --- ("sean") === FILE DATA ENDS HERE | |
Copyright © 1993-2012 - Aaron D. Gifford - All Rights Reserved |