I have been reading and reading about NAND and NOR flash.I am wantina (Usualy 512 bytes) to access some stored information in a nand.bin file but cannot for the life of me figure out what I need to do in order to decrypt it. I am aware it takes a key which I have, just dont know how to use it. Here is what I do know. Any advice is greatly appreciatted, I am getting overwhelmed.

The NAND uses a proprietary format.

The format is used to store device specific data (Config blocks, etc) and system data (Bootloaders, Kernel etc).

The files are stored using a format which is designed to be transctional (Each change can be reverted).

The nand uses a series of pages to combine into blocks, which are snippets of data (Usually 512 bytes) which each have an EDC tag at the end (an extra 16 bytes)

These pages are each part of a specific block (which can be ID'd with the EDC) which is usually made with 16 pages.

All (non-eMMC) NANDs have specific Spare-/Metadata for each page inside the NAND. Sometimes it will not be dumped with the NAND, so it has to either be added back or redumped. The Metadata contains the pages block number, a series of flags and a checksum. Those differ slightly, depending on the blocksize.

The ECC/EDC checksum uses a custom algorithm - here is C code for that (Will be converted to vb.net)

int checkEcc(u8* datc, u8* spare)
unsigned int i=0, val=0;
unsigned char edc[4] = {0,0,0,0};
unsigned long * data = (unsigned long*) datc;

unsigned int v=0;
 // printf("original ECC  : %02x %02x %02x %02x ", (spare[0xC] & 0xC0),       spare[0xD],spare[0xE],spare[0xF]);

for (i = 0; i < 0x1066; i++)
if (!(i & 31))
    if (i == 0x1000)
    data = (unsigned long*)spare;
    v = ~*data++; // byte order: LE 
   val ^= v & 1;
   if (val & 1)
       val ^= 0x6954559;
val >>= 1;

val = ~val;

edc[0] = (val << 6) & 0xC0;
edc[1] = (val >> 2) & 0xFF;
edc[2] = (val >> 10) & 0xFF;
edc[3] = (val >> 18) & 0xFF;

if(((spare[0xC] & 0xC0) != edc[0])||(spare[0xD] != edc[1])||(spare[0xE] != edc[2])||(spare[0xF] != edc[3]))
return ECC_FAILED;


At 0x2 in the NAND the version of the flash is stored (2bytes). Further on at 0x8 the offset of the CB is stored, followed by the CF1 offset (4bytes each).

At 0x78 the length of the SMC and offset to the SMC are stored (4bytes each).

Here is what I was told previously but am still learning and couldnt understand:

Checking the key against the nand is quite simple as there are parts of the nand that is encrypted using your key, as key, there are however different algorithms for each part… most of them use RC4 combined with HMAC-SHA1 (the key for the RC4 cipher is a HMAC-SHA1 hash of your cpukey)

to get the data from the nand you have to read each of the 32 pages one by one discarding the 0x10 bytes of spare that follow the 0x200 bytes of userdata…

Can someone, anyone make more sense of this for me? Please?

1 Answer 1


First, some NAND flash basics: NAND flashes are divided in blocks, and subdivided in pages. The write of pages is atomic (you can program pages partially, up to 4 times for a single page, but it's rarely used), and erase is always done on a whole block. Moreover, due to the lack of reliability, pages come with spare area to put some error correction codes.

Let's try to work with what you've got: A source code with a loop going from 0 to 0x1066, but using data only when (!(i & 31)), with a condition on (i == 0x1000) to switch from data to spare, and data is an unsigned long *, usually a pointer to 4 bytes long integers. So, those are some 512 bytes pages, with spares at least 12 bytes large. With byes 12, 13, 14 and 15 used for EDC, it's 16 spare bytes, which is common for small-pages NANDs. I also expect 32 pages per block.

Now, your EDC is just an EDC, not an ECC, maybe that worked on old NAND technologies.

But that's all we can get. We can confirm what you already know.

You ask about a NAND version, CB SMC and CF1 (whatever those acronyms mean for you). With no data, we can't show you any pattern allowing to tell if your data enclose the spares or not, if your data seem inverted, and so on. What do you expect from us ?

In fact, the easiest way would be to have the filesystem source code, but maybe you don't want to publish potential flaws in your security implementation...

  • That really was a remarkable response for what little I had given. I unfortunately can not vote up, but I do feel this is an acceptable considering. Thats why I came here. Thank you kindly.
    – King96
    Dec 2, 2014 at 2:23
  • Spare is 10 bytes. btw.
    – King96
    Dec 2, 2014 at 2:32
  • No, spare is 0x10 bytes, that's 16 bytes. But maybe you use only 10 bytes in it. As a matter of fact, 4 bytes are used for EDC, and probably 1 for the bad block marker, so there are only 11 bytes remaining for actual data.
    – Jacen
    Dec 2, 2014 at 10:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.