MAC and CMAC calculation for Mifare Desfire

6.7k Views Asked by At

Could anyone help me guide the calculation of MAC(4bytes) and CMAC(8bytes) for Mifare Desfire? I am getting unexpected results.

Deskey      =   0000000000000000
Block1(B1)  =   1122334455667788
Block2(B2)  =   9900112200000000
IV          =   0000000000000000
sessionkey  =   2923be84b1495461


R1 = Enc(B1 xor IV)         f2f13994d24714ca
R2 = Enc(R1 xor B2)         880fe38ab9e8a8d3
MAC   880fe38a

Expected MAC =  c8d70ad2 95a88a36

CMAC results

AESKey          =       00000000000000000000000000000000
Block           =       000102030405060708090a0b0c0d0e0f
Enc(Block)      =       7aca0fd9bcd6ec7c9f97466616e6a282
SubKey1         =       CDD297A9DF1458771099F4B39468565C
SubKey2         =       9BA52F53BE28B0EE2133E96728D0AC3F
CMAC(16bytes)   =       8A57896F795CB6ABF6867DAD41A5FB15

Is it true that CMAC is generated only by DES and TDES like DES encrypt all the blocks except the final block which should be TDES encrypted as in retail MAC calculation?

1

There are 1 best solutions below

4
On

Regarding the MAC calculation, it appears to be 3DES CBC-mode encryption of the data, with zero padding on the plaintext and an all-zero IV. The 3DES key is created by XORing the session key with 24 zero bytes. Here is an example in Java:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.xml.bind.DatatypeConverter;

public class MACTest {

  public static void main(String[] args) throws Exception {

    final byte[] keyBytes = new byte[24];
    final byte[] paddedPlaintext = 
        hexStringToByteArray("11223344556677889900112200000000");
    final byte[] iv = new byte[8];
    final byte[] sessionKeyBytes = hexStringToByteArray("2923be84b1495461");

    final byte[] derivedKeyBytes = new byte[24];
    for (int i = 0; i < sessionKeyBytes.length; i++) {
      derivedKeyBytes[i] = (byte) (keyBytes[i] ^ sessionKeyBytes[i]);
    }

    System.out.println(toHexString(derivedKeyBytes));
    SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
    SecretKey derivedKey = factory.generateSecret(new DESedeKeySpec(
        derivedKeyBytes));

    Cipher c = Cipher.getInstance("DESede/CBC/NoPadding");
    c.init(Cipher.ENCRYPT_MODE, derivedKey, new IvParameterSpec(iv));
    byte[] result = c.doFinal(paddedPlaintext);
    System.out.println(toHexString(result));
  }

  public static String toHexString(byte[] array) {
    return DatatypeConverter.printHexBinary(array);
  }

  public static byte[] hexStringToByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
  }
}

Output:

2923BE84B149546100000000000000000000000000000000
F2F13994D24714CA880FE38AB9E8A8D3

You've not supplied enough information to understand what is required to compute the AES CMAC example, nor what your problem actually is. Presumably you are not getting the expected result?