aes_cmac.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "aes_cmac.h"
  2. #define BLOCK_SIZE 16
  3. #define TAG "AESCMAC"
  4. static uint8_t zeroes[] =
  5. {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  6. static uint8_t Rb[] =
  7. {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
  8. void aes_cmac_padBlock(uint8_t* block, size_t len) {
  9. block[len] = 0x80;
  10. }
  11. bool aes_cmac_aes(uint8_t* key, uint8_t* plain, size_t plain_len, uint8_t* enc) {
  12. uint8_t iv[BLOCK_SIZE];
  13. memset(iv, 0, BLOCK_SIZE);
  14. mbedtls_aes_context ctx;
  15. mbedtls_aes_init(&ctx);
  16. mbedtls_aes_setkey_enc(&ctx, key, BLOCK_SIZE * 8);
  17. int rtn = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, plain_len, iv, plain, enc);
  18. mbedtls_aes_free(&ctx);
  19. return rtn == 0;
  20. }
  21. void aes_cmac_bitShiftLeft(uint8_t* input, uint8_t* output, size_t len) {
  22. size_t last = len - 1;
  23. for(size_t i = 0; i < last; i++) {
  24. output[i] = input[i] << 1;
  25. if(input[i + 1] & 0x80) {
  26. output[i] += 0x01;
  27. }
  28. }
  29. output[last] = input[last] << 1;
  30. }
  31. // x = a ^ b
  32. void aes_cmac_xor(uint8_t* a, uint8_t* b, uint8_t* x, size_t len) {
  33. for(size_t i = 0; i < len; i++) {
  34. x[i] = a[i] ^ b[i];
  35. }
  36. }
  37. bool aes_cmac_generateSubkeys(uint8_t* key, uint8_t* subkey1, uint8_t* subkey2) {
  38. uint8_t l[BLOCK_SIZE] = {0};
  39. aes_cmac_aes(key, zeroes, BLOCK_SIZE, l);
  40. aes_cmac_bitShiftLeft(l, subkey1, BLOCK_SIZE);
  41. if(l[0] & 0x80) {
  42. aes_cmac_xor(subkey1, Rb, subkey1, BLOCK_SIZE);
  43. }
  44. aes_cmac_bitShiftLeft(subkey1, subkey2, BLOCK_SIZE);
  45. if(subkey1[0] & 0x80) {
  46. aes_cmac_xor(subkey2, Rb, subkey2, BLOCK_SIZE);
  47. }
  48. return true;
  49. }
  50. bool aes_cmac(uint8_t* key, size_t key_len, uint8_t* message, size_t message_len, uint8_t* cmac) {
  51. uint8_t subkey1[BLOCK_SIZE] = {0};
  52. uint8_t subkey2[BLOCK_SIZE] = {0};
  53. uint8_t blockCount = (message_len + BLOCK_SIZE - 1) / BLOCK_SIZE;
  54. bool lastBlockCompleteFlag;
  55. uint8_t lastBlockIndex;
  56. uint8_t lastBlock[BLOCK_SIZE] = {0};
  57. // Only support key length of 16 bytes
  58. if(key_len != BLOCK_SIZE) {
  59. return false;
  60. }
  61. aes_cmac_generateSubkeys(key, subkey1, subkey2);
  62. if(blockCount == 0) {
  63. blockCount = 1;
  64. lastBlockCompleteFlag = false;
  65. } else {
  66. lastBlockCompleteFlag = (message_len % BLOCK_SIZE == 0);
  67. }
  68. lastBlockIndex = blockCount - 1;
  69. if(lastBlockCompleteFlag) {
  70. memcpy(lastBlock, message + (lastBlockIndex * BLOCK_SIZE), BLOCK_SIZE);
  71. aes_cmac_xor(lastBlock, subkey1, lastBlock, BLOCK_SIZE);
  72. } else {
  73. memcpy(lastBlock, message + (lastBlockIndex * BLOCK_SIZE), message_len % BLOCK_SIZE);
  74. aes_cmac_padBlock(lastBlock, message_len % BLOCK_SIZE);
  75. aes_cmac_xor(lastBlock, subkey2, lastBlock, BLOCK_SIZE);
  76. }
  77. uint8_t x[BLOCK_SIZE];
  78. uint8_t y[BLOCK_SIZE];
  79. memset(x, 0, sizeof(x));
  80. memset(y, 0, sizeof(y));
  81. for(size_t i = 0; i < lastBlockIndex; i++) {
  82. aes_cmac_xor(x, message + (i * BLOCK_SIZE), y, BLOCK_SIZE);
  83. aes_cmac_aes(key, y, BLOCK_SIZE, x);
  84. }
  85. aes_cmac_xor(x, lastBlock, y, BLOCK_SIZE);
  86. bool success = aes_cmac_aes(key, y, BLOCK_SIZE, cmac);
  87. return success;
  88. }