| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #include "des_cmac.h"
- #define BLOCK_SIZE 8
- #define TAG "DESCMAC"
- static uint8_t zeroes[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- static uint8_t Rb[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b};
- void des_cmac_padBlock(uint8_t* block, size_t len) {
- block[len] = 0x80;
- }
- bool des_cmac_des3(uint8_t* key, uint8_t* plain, size_t plain_len, uint8_t* enc) {
- uint8_t iv[BLOCK_SIZE];
- memset(iv, 0, BLOCK_SIZE);
- mbedtls_des3_context ctx;
- mbedtls_des3_init(&ctx);
- mbedtls_des3_set2key_enc(&ctx, key);
- int rtn = mbedtls_des3_crypt_cbc(&ctx, MBEDTLS_DES_ENCRYPT, plain_len, iv, plain, enc);
- mbedtls_des3_free(&ctx);
- return rtn == 0;
- }
- void des_cmac_bitShiftLeft(uint8_t* input, uint8_t* output, size_t len) {
- size_t last = len - 1;
- for(size_t i = 0; i < last; i++) {
- output[i] = input[i] << 1;
- if(input[i + 1] & 0x80) {
- output[i] += 0x01;
- }
- }
- output[last] = input[last] << 1;
- }
- // x = a ^ b
- void des_cmac_xor(uint8_t* a, uint8_t* b, uint8_t* x, size_t len) {
- for(size_t i = 0; i < len; i++) {
- x[i] = a[i] ^ b[i];
- }
- }
- bool des_cmac_generateSubkeys(uint8_t* key, uint8_t* subkey1, uint8_t* subkey2) {
- uint8_t l[BLOCK_SIZE] = {0};
- des_cmac_des3(key, zeroes, BLOCK_SIZE, l);
- des_cmac_bitShiftLeft(l, subkey1, BLOCK_SIZE);
- if(l[0] & 0x80) {
- des_cmac_xor(subkey1, Rb, subkey1, BLOCK_SIZE);
- }
- des_cmac_bitShiftLeft(subkey1, subkey2, BLOCK_SIZE);
- if(subkey1[0] & 0x80) {
- des_cmac_xor(subkey2, Rb, subkey2, BLOCK_SIZE);
- }
- return true;
- }
- bool des_cmac(uint8_t* key, size_t key_len, uint8_t* message, size_t message_len, uint8_t* cmac) {
- uint8_t subkey1[BLOCK_SIZE] = {0};
- uint8_t subkey2[BLOCK_SIZE] = {0};
- uint8_t blockCount = (message_len + BLOCK_SIZE - 1) / BLOCK_SIZE;
- bool lastBlockCompleteFlag;
- uint8_t lastBlockIndex;
- uint8_t lastBlock[BLOCK_SIZE] = {0};
- // Only support key length of 16 bytes
- if(key_len != 16) {
- return false;
- }
- des_cmac_generateSubkeys(key, subkey1, subkey2);
- if(blockCount == 0) {
- blockCount = 1;
- lastBlockCompleteFlag = false;
- } else {
- lastBlockCompleteFlag = (message_len % BLOCK_SIZE == 0);
- }
- lastBlockIndex = blockCount - 1;
- if(lastBlockCompleteFlag) {
- memcpy(lastBlock, message + (lastBlockIndex * BLOCK_SIZE), BLOCK_SIZE);
- des_cmac_xor(lastBlock, subkey1, lastBlock, BLOCK_SIZE);
- } else {
- memcpy(lastBlock, message + (lastBlockIndex * BLOCK_SIZE), message_len % BLOCK_SIZE);
- des_cmac_padBlock(lastBlock, message_len % BLOCK_SIZE);
- des_cmac_xor(lastBlock, subkey2, lastBlock, BLOCK_SIZE);
- }
- uint8_t x[BLOCK_SIZE];
- uint8_t y[BLOCK_SIZE];
- memset(x, 0, sizeof(x));
- memset(y, 0, sizeof(y));
- for(size_t i = 0; i < lastBlockIndex; i++) {
- des_cmac_xor(x, message + (i * BLOCK_SIZE), y, BLOCK_SIZE);
- des_cmac_des3(key, y, BLOCK_SIZE, x);
- }
- des_cmac_xor(x, lastBlock, y, BLOCK_SIZE);
- bool success = des_cmac_des3(key, y, BLOCK_SIZE, cmac);
- return success;
- }
|