1

I want to use CBC MAC in C++. First I hope to find some implementation of block cipher which I will use in CBC mode, which I understand is CBC MAC. But I have two questions:

1) If the length of the message to be authenticated is not multiple of block cipher block length, what shall I do?

2) To strengthen CBC MAC one recommended way as mentioned on Wiki is to put the length of the message in the first block. But how should I encode the length, as string? Or in binary? If block length of cipher is say 64 bits, do I encode the number as 64 bit number? e.g. if message length is 230, I should use following value as first block:

00000000 00000000 00000000 00000000 00000000 00000000 00000000 ‭11100110‬

?

  • (Disclaimer: I am not a crapto expert) It is common to use [padding](https://en.wikipedia.org/wiki/Padding_(cryptography)) to make the input block-aligned (you need to pad the "length|message" part). AFAIK the length encoding is up to you, my bet is that it itself should have a constant length and be unambiguous. Have you considered another algorithm which might work better (e.g. [CMAC/OMAC1](https://en.wikipedia.org/wiki/CMAC), HMAC)? IMHO you should DEFINITELY use some crypto library (e.g. [crypto++](https://www.cryptopp.com/)). Good luck! – vlp Dec 03 '15 at 00:36
  • I wonder why your question got so little attention (there are surely people who know the right answer), maybe it should be asked on crypto.stackexchange.com...(I am quite new here to know) – vlp Dec 03 '15 at 00:40

1 Answers1

1
  1. It depends on the 2nd question. You must "pad" the message with something until it is a multiple of the block size. The pad bytes are added to the message before the MAC is calculated but only the original message is transmitted/stored/etc.

    For a MAC, the easiest thing to do is pad with zeros. However this has a vulnerability - if the message part ends in one or more zeros, an attacker could add or remove zeros and not change the MAC. But if you do step 2, this and another attack are both mitigated.

  2. If you prepend the length of the message before the message (e.g. not just in the first block, but the first thing in the first block), it mitigates the ability to sometimes add/remove zeros. It also mitigates an attackers ability to forge a message with an entire arbitrary extra block added. So this is a good thing to do. And it is a good idea for completely practical reasons too - you know how many bytes the message is without relying on any external means.

    It does not matter what the format of the length is - some encoded ASCII version or binary. However as a practical matter it should always be simple binary.

    There is no reason that the number of bits in the length must match the cipher block size. The size of the length field must be large enough to represent the message sizes. For example, if the message size could range from 0 to 1000 bytes long, you could prepend an unsigned 16 bit integer.

    This is done first before the MAC is calculated on both the sender and receiver. In essence the length is verified at the same time as the rest of the message, eliminating the ability for an attacker to forge a longer or shorter message.

There are many open source C implementations of block ciphers like AES that would be easy to find and get working.

Caveat Presumably the purpose of the question is just for learning. Any serious use should consider a stronger MAC such as suggested by other comments and a good crypto library. There are other weaknesses and attacks that can be very subtle so you should never attempt to implement your own crypto. Neither of us are crypto experts and this should be done only for learning.

BTW, I recommend both of the following books by Bruce Schneier:

http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099/ref=asap_bc?ie=UTF8

http://www.amazon.com/Cryptography-Engineering-Principles-Practical-Applications/dp/0470474246/ref=asap_bc?ie=UTF8

Anders
  • 2,270
  • 11
  • 19
  • CBCMAC with length prepending should be pretty secure. PS I meant wiki says you should prepend length as first block of message that is why I represented as 64 bit integer if cipher block length is 64 bits –  Dec 04 '15 at 08:09
  • " open source C implementations of block ciphers like AES" most of libraries are cumbersome to use, but I found AES implementation which is used by a popular software and it seems stable –  Dec 04 '15 at 08:11
  • Yes, but you don't need to use the whole first block. You could have a 16 bit length and use 48bits for the first 6 characters. I doubt you really need a 64 bit length. – Anders Dec 04 '15 at 16:36
  • Have you looked at TomCrypt? It has a lot of implementations? – Anders Dec 04 '15 at 16:36
  • It is fine I can use whole block –  Dec 04 '15 at 16:36
  • I see thanks but I have no need to save on bandwidth... Do you know easy to use library for crypto for windows ?C or C++? –  Dec 04 '15 at 16:38
  • The caveat is this: Yes, with length perpending CBC-MAC should be pretty secure. However, there are a ton of implementation mistakes that could ruin the security. It has happened over and over. Ask yourself two things: before your read that you needed to prepend the length did you know about the vulnerabilities? And second, are you sure that _every_ vulnerability you don't know about was listed in your reference? This is why I would use a better MAC than CBC. HMAC or OMAC from a well vetted library, for instance. Doing it yourself is not a good idea for production. – Anders Dec 04 '15 at 16:42
  • So I mentioned libTomCrypt. I also like Crypto++. https://github.com/libtom/libtomcrypt and https://www.cryptopp.com – Anders Dec 04 '15 at 16:43