des_cmac.c 3.1 KB

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