#include "polarssl/libpcrypto.h"
#include <polarssl/aes.h>
+#include <polarssl/aes_cmac128.h>
+// NIST Special Publication 800-38A \97 Recommendation for block cipher modes of operation: methods and techniques, 2001.
int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){
uint8_t iiv[16] = {0};
if (iv)
aes_free(&aes);
return 0;
-}
\ No newline at end of file
+}
+
+// NIST Special Publication 800-38B \97 Recommendation for block cipher modes of operation: The CMAC mode for authentication.
+// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CMAC.pdf
+int aes_cmac(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, int length) {
+ memset(mac, 0x00, 16);
+ uint8_t iiv[16] = {0};
+ if (iv)
+ memcpy(iiv, iv, 16);
+
+ // padding: ISO/IEC 9797-1 Message Authentication Codes (MACs) - Part 1: Mechanisms using a block cipher
+ uint8_t data[2049] = {0}; // length + 16
+ memcpy(data, input, length);
+ data[length] = 0x80;
+ int datalen = (length & 0xfffffff0) + 0x10;
+
+ // NIST 800-38B
+ aes_cmac128_context ctx;
+ aes_cmac128_starts(&ctx, key);
+ aes_cmac128_update(&ctx, data, datalen);
+ aes_cmac128_final(&ctx, mac);
+
+ return 0;
+}
+
+int aes_cmac8(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, int length) {
+ uint8_t cmac[16] = {0};
+ memset(mac, 0x00, 8);
+
+ int res = aes_cmac(iv, key, input, cmac, length);
+ if (res)
+ return res;
+
+ for(int i = 0; i < 8; i++)
+ mac[i] = cmac[i * 2 + 1];
+
+ return 0;
+}