maxieds/ChameleonMiniDESFireStack

Help and suggestions wanted: DES and 3DES encryption from AVRCryptoLibrary is slow!

Closed this issue · 9 comments

The 3DES encryption scheme implemented in the current firmware is too slow to be useful. The AuthenticateISO (0x1A) command times out every time with my reader using this code. Is there a plausible solution?

Note that to fix the AuthenticateLegacy (0x0A) support (see this testing code), I had to move several structures from PROGMEM to a .data section buffer. This definitely improves the access time noticeably! The 3DES variants based on this same DES encryption code still fail with timeouts. See the -DDESFIRE_QUICK_DES_CRYPTO option in the Makefile (extra free space is at a premium already).

I have read about AVR XMega crypto boosters. I don't think this functionality is standard though. Seems to indicate at the general problem being noticed here.

@dev-zzo
Do you remember how you were handling the 3DES encryption in your fork? I know the TDEA / CBC / MAC routines eventually were added. Was there support for the actual DES encryption?

i'm not sure i understand the question. routines that do DES/3DES were implemented in Firmware/Chameleon-Mini/Application/CryptoTDEA.S and use hardware support. the AVRCryptoLib code implements DES in software so of course it will be slow as a snail.

@dev-zzo

Right. Slow as *uck! (pardon, and noted)

I'm working from this file. Is the function CryptoEncrypt2KTDEA plain old DES. So if I want 3DES, I can build on it?

judging by your question and to make sure you understand what you're doing, i strongly suggest you read on what 3DES (or TDEA -- same thing, different name) is and how it works, on the high level. will save you a lot of time later on.

@dev-zzo
Ok. I was differentiating the AuthenticateLegacy (0x0A), which I was interpreting to use ordinary DES, and AuthenticateISO (0x1A) which I was assuming used 3DES. Does that sound correct to you?

If I have basic DES encryption then I was intending to code 3DES as:

void tdes_enc(void *out, const void *in, const uint8_t *key){
    des_enc(out,  in, (uint8_t*) (key + 0));
    des_dec(out, out, (uint8_t*) (key + 8));
    des_enc(out, out, (uint8_t*) (key + 16));
}
void tdes_dec(void *out, const void *in, const uint8_t *key){
    des_dec(out,  in, (uint8_t*) (key + 16));
    des_enc(out, out, (uint8_t*) (key + 8));
    des_dec(out, out, (uint8_t*) (key + 0));
}

I think I've got the basic idea.

Maybe I'm missing something with the 2KTDEA?

I guess my question, or a request for clarification looking through my code, is the difference between 3DES (3KTDEA) and 2KTDEA?

Nevermind, I think I figured it out.

Thanks @dev-zzo for the suggestions. I think this is now handled, so I'm closing the issue.