Search code examples
openssllibcryptocmac

How to calculate AES CMAC using OpenSSL's CMAC_xxx functions?


Is there any way to compute AES CMAC with OpenSSL/libcrypto?

Preferably in a way that takes advantage of AES-NI (or any other hardware acceleration).

See also CMAC Key generation with OpenSSL EVP_DigestSign* fails


Solution

  • As stated in my blog post you can use the CMAC_CTX_new, CMAC_Init, CMAC_Update and CMAC_Final from lib crypto to calculate AES-128-CBC CMAC. Here is an example:

    #include <stdio.h>
    #include <openssl/cmac.h>
    
    void printBytes(unsigned char *buf, size_t len) {
      for(int i=0; i<len; i++) {
        printf("%02x ", buf[i]);
      }
      printf("\n");
    }
    
    int main(int argc, char *argv[])
    {
      // https://tools.ietf.org/html/rfc4493
    
      // K, M and T from 
      // http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
      // D.1 AES-128
    
      // K: 2b7e1516 28aed2a6 abf71588 09cf4f3c
      unsigned char key[] = { 0x2b,0x7e,0x15,0x16, 
                              0x28,0xae,0xd2,0xa6,
                              0xab,0xf7,0x15,0x88,
                              0x09,0xcf,0x4f,0x3c};
    
      // M: 6bc1bee2 2e409f96 e93d7e11 7393172a Mlen: 128
      unsigned char message[] = { 0x6b,0xc1,0xbe,0xe2, 
                                  0x2e,0x40,0x9f,0x96, 
                                  0xe9,0x3d,0x7e,0x11, 
                                  0x73,0x93,0x17,0x2a };
    
      unsigned char mact[16] = {0}; 
      size_t mactlen;
    
      CMAC_CTX *ctx = CMAC_CTX_new();
      CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL);
      printf("message length = %lu bytes (%lu bits)\n",sizeof(message), sizeof(message)*8);
    
      CMAC_Update(ctx, message, sizeof(message));
      CMAC_Final(ctx, mact, &mactlen);
    
      printBytes(mact, mactlen);
      /* expected result T = 070a16b4 6b4d4144 f79bdd9d d04a287c */
    
      CMAC_CTX_free(ctx);
      return 0;
    }