1

Can anyone share a sample code on how to implement CBCBlockCipherMac in objective C. here is how far I got and its giving a different result from the java implementation.

const unsigned char key[16] = "\x1\x2\x3\x4\x5\x6\x7\x8\x9\x0\x1\x2\x3\x4\x5\x6";
const unsigned char data[14] = "\x54\x68\x69\x73\x69\x73\x6d\x79\x73\x74\x72\x69\x6e\x67";

CMAC_CTX *ctx = CMAC_CTX_new();
ret = CMAC_Init(ctx, key, sizeof(key), EVP_des_ede3(), 0);


printf("CMAC_Init = %d\n", ret);

ret = CMAC_Update(ctx, data, sizeof(data));

printf("CMAC_Update = %d\n", ret);

size_t size;
//unsigned int size;
unsigned char tag[4];
ret = CMAC_Final(ctx, tag, &size);


printf("CMAC_Final = %d, size = %u\n", ret, size);

CMAC_CTX_free(ctx);

printf("expected: 391d1520\n"
       "got:      ");
size_t index;
for (index = 0; index < sizeof(tag) - 1; ++index) {
    printf("%02x", tag[index]);
    if ((index + 1) % 4 == 0) {
        printf(" ");
    }
}
printf("%02x\n", tag[sizeof(tag) - 1]);

And my java code looks like this

String *data = "Thisismystring";
String *keyString = "1234567890123456";


bytes[]mac = new byte[4];
CBCBlockCipherMac macCipher = new CBCBlockCipherMac(DESedeEngine);
DESedeParameters keyParameter = new DESedeParameters(keyString.getBytes());
DESedeEngine engine = new DESedeEngine();
engine,init(true, keyParameter);
byte[] dataBytes = data.getBytes();
macCipher.update(dataBytes,0,data.length());
macCipher.doFinal(mac,0);
byte[] macBytesEncoded = Hex.encode(mac);
String macString = new String(macBytesEncoded);

This gives me "391d1520". But the objective c gives me "01000000"

Mayoor
  • 131
  • 1
  • 3
  • 8
  • Could you show the outputs you are getting, also a few more lines of Java code would not hurt, just to compare with the C code? – Maarten Bodewes May 09 '14 at 21:15
  • @owlstead...edited my question with more java code. Thanks – Mayoor May 09 '14 at 21:31
  • I don't know what `01000000` is but there is a very small chance that it can be the actual output of a MAC function, the output of a MAC function should be indistinguishable from random. Now any value can be generated by a random, but a single 1 bit and 63 bits set to zero, nah... – Maarten Bodewes May 09 '14 at 21:48

1 Answers1

0

CMAC is not the same as CBC MAC. CMAC has an an additional step at the beginning and the end of the calculation. If possible I would suggest you upgrade your Java code to use CMAC, as CBC is not as secure, e.g. using org.bouncycastle.crypto.macs.CMac.

OpenSSL does not seem to implement CBC MAC directly (at least, I cannot find any reference to it). So if you need it, you need to implement it yourself.

You can use CBC mode encryption with a zero IV and take the last 16 bytes of the encryption. Of course, this means you need to store the rest of the ciphertext in a buffer somewhere, or you need to use the update functions smartly (reusing the same buffer over and over again for the ciphertext).

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • @rmaddy If you are missing anything from the answer, don't hesitate to comment. I'll try and dig up some Java code in the mean time. – Maarten Bodewes May 09 '14 at 21:23
  • @owlstead the java implementation is not up to me. can't change it – Mayoor May 09 '14 at 21:34
  • Yeah, I was afraid of that, having looked at your previous question, so I have already added some more info at the end of the answer. – Maarten Bodewes May 09 '14 at 21:36
  • Could you try and implement this yourself, and comment here if you fail? I detest programming in C/C++, as I always get compiler/linker errors and suchlike that take my mind of programming the actual solution. – Maarten Bodewes May 09 '14 at 21:41