title: AES 128 with CBC-MAC in C
body: <p>The code showing below is AES with CBC mode implementation. I am very new to the network security aspect. I am wondering how I can add the mac generation function upon the block and makes it as cbc-mac</p>
  
  <pre><code> static void GenerateDecryptionKey(uint8_t *key)
  {
  CRYCONLbits.CRYON = 0b1;        //Turn module on
  CRYCONHbits.KEYSRC = 0b000;    //Select the key source (CRYKEY)
  CRYCONLbits.OPMOD = 0b0010;     //Select the operational mode (AES Decryption Key Expansion)
  CRYCONLbits.CPHRSEL = 0b1;      //Select the cipher (AES)
  //(AES decryption key generation)
  CRYCONHbits.KEYMOD = 0b00;      //Set the key strength (128-bit key)
  memcpy((void *)&amp;CRYKEY0, key, 16); //Load the key into CRYKEY
  //(128-bit key in this example)
  CRYCONLbits.CRYGO = 0b1;        //Start the encryption
  while (CRYCONLbits.CRYGO == 0b1)
      ;
    }
  
   // For 128-bit key and 128-bit block size
   void EncryptBlocks(
      CIPHER_MODE mode,
      uint8_t *key,
      uint8_t *iv,
      uint8_t *plaintext,
      uint8_t *ciphertext,
      int numblocks)
   {
  CRYCONLbits.CRYON   = 1; //Turn module on
  CRYCONHbits.KEYSRC  = 0b0000;     //Select the key source (CRYKEY)
  CRYCONLbits.OPMOD   = 0b0000;     //Select operational mode (Encryption)
  CRYCONLbits.CPHRSEL = 1;          //Select cipher engine (AES)
  CRYCONLbits.CPHRMOD = 0b001 ;       //Select encryption mode
  CRYCONHbits.KEYMOD  = 0;          //Set key strength to 128-bit
  
  memcpy((void*)&amp;CRYKEY0, key, 16); //Load the 128-bit key into CRYKEY
  
  memcpy((void*)&amp;CRYTXTB0, iv, 16); //Load the 128-bit initial vector (IV)
  
  
  int i;
  for (i = 0; i &lt; numblocks; i += 16) {
  
      //Load the next plaintext block into CRYTXTA
      memcpy((void*)&amp;CRYTXTA0, plaintext+ i, 16);
  
      //Start the encryption
      CRYCONLbits.CRYGO = 0b1;
  
      // Wait for completion
      while (CRYCONLbits.CRYGO == 0b1)
          ;
  
      //Read the results out of CRYTXTB
      memcpy(ciphertext+i, (void*)&amp;CRYTXTB0, 16);
   }
   }
  
  // For 128-bit key and 128-bit block size
  void DecryptBlocks(
      CIPHER_MODE mode,
      uint8_t *key,
      uint8_t *ciphertext,
      uint8_t *plaintext,
      int numblocks)
   {
  
  GenerateDecryptionKey(key);
  CRYCONLbits.CRYON   = 1; //Turn module on
  CRYCONHbits.KEYSRC  = 0b0000;     //Select the key source (CRYKEY)
  CRYCONLbits.OPMOD   = 0b0001;     //Select operational mode (Decryption)
  CRYCONLbits.CPHRSEL = 1;          //Select cipher engine (AES)
  CRYCONLbits.CPHRMOD = 0b001;          //Select decryption mode (CBC)
  
  CRYCONHbits.KEYMOD  = 0;          //Set key strength to 128-bit
  
  int i;
  for (i = 0; i &lt; numblocks; i+= 16) {
  
      //Load the next plaintext block into CRYTXTA
      memcpy((void*)&amp;CRYTXTA0, plaintext+i, 16);
  
      //Start the encryption
      CRYCONLbits.CRYGO = 0b1;
  
      // Wait for completion
      while (CRYCONLbits.CRYGO == 0b1)
          ;
  
      //Read the results out of CRYTXTB
      memcpy(ciphertext+i, (void*)&amp;CRYTXTB0, 16);
  }
  }
  </code></pre>
  
  <p>part of the test code is showing below</p>
  
  <pre><code> EncryptBlocks(mode, AES_KEY, 0, plaintext, ciphertext, numblocks);
   //EncryptBlocks(mode, AES_KEY, 0, plaintext, ciphertext, numblocks);//iv=0;  for ECB mode
  //LED1 = 0;
  printf("Encrypted block:");
  for (i = 0; i &lt; numblocks; i++) {
      base = i*16;
      printf("\n");
      for (j = base; j &lt; base+16; j++) {
          printf(" %02X", ciphertext[j]);
          last[0] = ciphertext[j];
      }
  }
  printf("\n\n");
  
  
  for (i = 0; i &lt; 16; i++) {
      iv[i] = 0;
  }
  for(i=0;i&lt;sizeof(plaintext);i++)
      plaintext[i] = 0;
  DecryptBlocks(mode, AES_KEY, ciphertext, plaintext, numblocks);
  printf("Decrypted block: ");
  
  
  for (i = 0; i &lt; numblocks; i++)
  {
      base = i*16;
      printf("\n");
      for (j = base; j &lt; base+16; j++) {
          printf(" %02X", plaintext[j]);
      }
  }
  printf("\n");
  }
  </code></pre>