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: Sand in BloomIPv4You 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 HERE
EXAMPLE 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 | |