After authentication, the IV is reset to all-zeros. As you use AES authentication, you then have to calculate the CMAC for every follow-up command (even if CMAC is not actually appended to the command). So the CMAC calculation for your command will lead to correct IV initialization for decoding the response. I.e. the CMAC for the command is equal to the IV for decrypting the response. Similarly, for all further commands, the IV is the last cipher block from the previous encryption/CMAC.
UPDATE:
How to calculate CMAC pad XOR value
- Encrypt one block of zeros (
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
) with session key (using IV of zeros). ->x[0..15]
- Rotate
x[0..15]
one bit to the left. ->rx[0..15]
- If the last bit (bit 0 in
rx[15]
) is one: xorrx[15]
with0x86
. - Store
rx[0..15]
ascrc_k1[0..15]
. - Rotate
rx[0..15]
one bit to the left. ->rrx[0..15]
- If the last bit (bit 0 in
rrx[15]
) is one: xorrrx[15]
with0x86
. - Store
rrx[0..15]
ascrc_k2[0..15]
.
How to calculate CMAC
- You pad the command using
0x80 0x00 0x00 ...
to the block size of the cipher (16 bytes for AES). If the command length matches a multiple of the block size, no padding is added. - For your command (
0x51
) this would look like:0x51 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- If padding was added, xor the last 16 bytes of the padded command with
crc_k2[0..15]
. - If no padding was added, xor the last 16 bytes of the command with
crc_k1[0..15]
. - Encrypt (in send mode, i.e.
enc(IV xor datablock)
, cipher text of previous block is new IV) the result with the session key. - The ciphertext of the last block is the CMAC and the new IV.
UPDATE 2:
How to rotate a bit vector to the left for one bit
public void rotateLeft(byte[] data) {
byte t = (byte)((data[0] >>> 7) & 0x001);
for (int i = 0; i < (data.length - 1); ++i) {
data[i] = (byte)(((data[i] << 1) & 0x0FE) | ((data[i + 1] >>> 7) & 0x001));
}
data[data.length - 1] = (byte)(((data[data.length - 1] << 1) & 0x0FE) | t);
}