Firstly, according to the documentation of Cipher.doFinal(...)
:
AES, DES, triple DES and Korean SEED algorithms in CBC mode reset the
initial vector(IV) to 0. The initial vector(IV) can be re-initialized
using the init(Key, byte, byte[], short, short)
method.
It means that if you use AES-CBC with non-zero IV, you have to call init
after each doFinal
, so there is no choice, really.
Let's have a look now at some real-world measurements I did on my J2E145 cards by NXP.
Both ALG_AES_BLOCK_128_CBC_NOPAD
and ALG_AES_BLOCK_128_ECB_NOPAD
require 34 bytes of RAM and 32 bytes of persistent memory per object instance.
Concerning time consumption, there are 4 possible situations:
Situation 1: the same transient key:
key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key1, Cipher.MODE_ENCRYPT);
Result: 11 ms per each init(...)
Situation 2: different transient keys:
key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
KeyBuilder.LENGTH_AES_128, false);
key2 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key2, Cipher.MODE_ENCRYPT);
Result: 18 ms per each init(...)
Situation 3: the same persistent key:
key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key1, Cipher.MODE_ENCRYPT);
Result: 12 ms per each init(...)
Situation 4: different persistent keys:
key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
KeyBuilder.LENGTH_AES_128, false);
key2 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key2, Cipher.MODE_ENCRYPT);
Result: 19 ms per each init(...)
Conclusion: init
is really fast independently of the memory type, because EEPROM is only read and copied into the internal (transient) memory of the Cipher
instance. Although I can imagine some cases with high time consumption requirements, 34 RAM bytes seem to be too many to pay for 20ms. Exact results can be different on your platform, of course, but the trade-off efficiency will remain more or less the same.