When entering the AES 256 key for decryption I set the mode to LTC0_MD = (LTC_MD_ALG_AES | LTC_MD_AAI_CBC | LTC_MD_AAI_DK); // AES key for decryption [0x00101100]

This is accepted - but the decryption fails.

If I then remove the LTC_MD_ALG_AES flag (0x00100000) and set the key the LTC sets its error interrupt (with error saying that there is an AES mode error). The only way to clear this error is to reset the LTC.However now the AES256 decryption of the block works.

In fact previously I was just setting the DK bit (which I think is what the SDK examples do) when setting the key for decryption and it had worked. Only when I realised that it was causing the error interrupt to be set, and stopped this by presumably setting the algorithm correctly, did the decryption start failing.

Can anyone explain this?

Regards

Mark

P.S. I am posting a second question about AES CBC across multiple block so data in a second post, which is related to this too.

I think the best way is to use SDK demo and driver directly. I guess there is some sequence issue. For example, the driver set DK at the beginning of LTC_AES_DecryptCbc(). But when it set all control bit in MD

DK must be set "before" (or while) the key is entered otherwise the module will think it is an encrypt key and so it will fail when decrypting.

At the moment I can't get the SDK working because MCUXpresso fails to import the project. I'll be doing a complete MCUXpresso update / reinstall shortly to see whether I can resolve it and test the SDK code directly.

I know that SDK does

base->MD |= (1U << kLTC_ModeRegBitShiftDK);

before entering the key but in my experience this causes the error interrupt flag to be set (when DK is set and the other algorithm bits are not appropriate). The fact that the interrupt error is set doesn't cause operational failure but seems strange to me....

I finally managed to run the SDK tests (I woudln't get MCUXpressor to work with the FRDM board so I had to first had to spend some time porting it to IAR). Only after stepping the code did I realise that the reference never actually sets the DK.

Also I re-read the description for about the 6th time and finally it starts to make sense:

Basically, if DK is set it means one is passing the decrypt key (and not the encrypt key). The LTC can work with the encrypt key by doing a decrypt conversion when needed (takes longer than if the decrypt key is supplied directly).

Interestingly in another post I was finding that the second decrypted block was successful when using the DK setting (setting encryption key and informing that it were the decrypt key) which suggest that after the first block decryption (failed) it was internally converting the key to a decrypt key (presumably as a part of the normal decrypt operation...).....

The remaining problem is that decrypting a stream of data in a number of block call (rather than one large block) is failing after the first block. See LTC AES-256 CBC across multiple blocks

The KDS reference only tests a single block so I am wondering whether it can handle a stream or not?

The decryption key is derived from the encryption key and needs to be performed as a step before usage. For example in the embedTLS library it is performed by calling aes_setkey_dec().The LTC does this step as an integral part of its decryption function (if DK is 0) and the derived decryption key can be seen in the module's key registers after the step.When DK is set to 1 it essentially tells the module that it should skip this step because the decryption key (and not the encrypt key) is (already) in place.

I don't think that the decrpt key is usually of general interest (that is, how it looks) but I suspect that in both cases it could be read back and saved. Then it could be directly loaded (in case of the LTC to its key registers and in the case of the SW implementation to its key buffer in its instance) and thus the conversion step be saved when it is used again -> speed improvement against need to backup the values. Whether there is great interest in this (slight) optimisation is another question. I will measure the LTC decryption speed with a primed decrypt key against its speed when it needs to do the conversion at some point and let you know....

As predicted, the second block decryption is faster than the first which suggests that the LTC requires about 3us to derive the decrypt key from the encrypt key as a part of the first block decryption.

Apart from the speed advantage of the LTC the code size is up to 10k Bytes smaller than a SW implementation too!