logo
+7 (951) 999-89-94
428003, г. Чебоксары, ул. Федора Гладкова, д.9, оф.319

ATSHA204A — Команда CheckMac

Продолжаем изучать устройство и работу криптомикросхемы ATSHA204A и этот урок мы посвятим разбору команды CheckMac. Как вы помните, ранее мы подробно разобрали команду MAC и если вы ещё не знакомы с этой темой, то рекомендуем перед чтением этой статьи ознакомиться с ней.

Команда CheckMac

Цитата из даташита о назначении команды CheckMac:

The CheckMac command calculates a MAC response that had been generated on a CryptoAuthentication device and compares the MAC response with some input value. It returns a Boolean result to indicate the success or failure of the comparison.

Перевод:

Команда CheckMac вычисляет ответ MAC и сравнивает это значение с входными данными, которые были сгенерированы на другом CryptoAuthentication устройстве. Функция CheckMac возвращает логический результат сравнения вычисленных и входных данных (совпадают/не совпадают, 0/1).

Далее:

Prior to running this command, the Nonce and/or GenDig commands may have been optionally run to create and load a key or nonce value in TempKey. The mode parameter determines the source of the “key” (the first 32-bytes of the SHA message) and “challenge/nonce” (the second-32 bytes of the SHA message).

Перевод:

Перед выполнением этой команды, команды Nonce и/или GenDig могут быть дополнительно выполнены для создания и загрузки ключа или nonce в TempKey. Параметр mode определяет источник ключа (первые 32 байта SHA сообщения) и challenge/nonce (вторые 32 байта SHA сообщения).

Другими словами, команда CheckMac вычисляет MAC ключа, хранящегося в одном из слотов Data зоны микросхемы ATSHA204A или в TempKey (первые 32 байта SHA сообщения) и некого «challenge» набора данных или данных, загруженных опять же в TempKey (вторые 32 байта SHA сообщения). Далее команда CheckMac сравнивает результат вычисления MAC с входными данными, полученными от другой системы, оснащённой аналогичным CryptoAuthentication модулем (микросхемой ATSHA204A).

Результатом работы команды CheckMac является логический ответ совпадает/не совпадает (0 или 1) на основании которого микроконтроллер может принять решение, например, об успешности/не успешности аутентификации удалённого устройства.

Вот блок-схема, иллюстрирующая логику работы команды CheckMac.

Это общий смысл и принцип работы команды CheckMac, далее мы подробно разберём её тонкие настройки.

Параметры команды CheckMac

Команда CheckMac имеет несколько входных параметров, вот таблица с описанием этих параметров из даташита.

Первый байт — это код операции CheckMac, который равен 0x28.

Второй байт (Param1) — это режим (Mode) работы команды CheckMac, подробнее:

Bit 0 — определяет 32-байтовый источник для второй части SHA сообщения. Если он равен нулю, то данные берутся от (удалённой) клиентской системы, если равен единице, то данные берутся из TempKey.

Bit 1 — определяет 32-байтовый источник для первой части SHA сообщения. Если он равен нулю, то данные берутся из слотов Data зоны микросхемы ATSHA204A, если равен единице, то из TempKey.

Bit 2 — если используется TempKey, то этот бит должен соответствовать значению TempKey.SourceFlag.

Bits 3-4 — должны быть равны нулю.

Bit 5 — 8 байт SHA сообщения. Если этот бит равен нулю, то эти байты тоже равны нулю, если равен единице, то данные берутся из OTP зоны микросхемы ATSHA204A.

Bits 6-7 — должны быть равны нулю.

Два байта (Param2) SlotID — номер используемого слота в Data зоне микросхемы ATSHA204A (используются биты 0-3).

Data1 — Client Challenge (32 байта). Данные, отсылаемые на удалённую систему.

Data2 — Client Response (32 байта). Данные, получаемые от удалённой системы.

Data3 — Конфигурация команды MAC (13 байт). Байты с настройкой работы команды MAC.

Выходными данными команды CheckMac являются логические значения 0/1. 0 — вычисленный дайджест и ответ клиента совпадают, 1 — не совпадают.

Вот сводная таблица всех данных, участвующих в формировании входного сообщения для команды CheckMac:

Параметр OtherData

Назначение параметра OtherData заключается в формировании SHA-256 сообщения, которое будет совпадать с MAC-сообщением, которое использовалось для получения Client Response. По сути, это набор параметров и настроек команды MAC.

Параметр OtherData состоит из 13-и байтов, назначение которых подробно описано в следующей таблице.

Порядок байтов и логика параметра OtherData соответствуют настройкам команды MAC, рассмотренным нами в предыдущих статьях, поэтому здесь мы не будем подробно останавливаться на них, а сразу перейдём к созданию скетча ATSHA204A CheckMac.

Скетч ATSHA204A CheckMac

Создадим скетч, который при помощи команды CheckMac вычисляет SHA-256 хеш и сравнивает его с заранее известным значением, вычисленным ранее в статье «Команда MAC».

Исходные данные будут храниться в массиве challenge (они же должны отправляться на удалённую систему), а заранее вычисленный ответ будет храниться в массиве response_mac. Для экспериментов мы будем использовать тот экземпляр ATSHA204A, с которым мы работали на предыдущих уроках. Вот скриншот заполнения её Data зоны 16-ю тестовыми ключами:

В данном случае мы будем использовать ключ из нулевого слота, заполненный 32-я значениями 0x00. Вот полный код скетча ATSHA204A CheckMac:

/* 
  ATSHA204A CheckMac
*/

#include <sha204_library.h>

const int sha204Pin = A3;

atsha204Class sha204(sha204Pin);

void setup() {
  Serial.begin(115200);
  Serial.println("ATSHA204 CheckMac start...");
  checkMac();
}

void checkMac() {
  uint8_t command[SHA204_CMD_SIZE_MAX];
  uint8_t response[CHECKMAC_RSP_SIZE];

  const uint8_t challenge[MAC_CHALLENGE_SIZE] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };

  const uint8_t response_mac[CHECKMAC_CLIENT_RESPONSE_SIZE] = {
    0x5C, 0x91, 0xBF, 0xDA, 0x80, 0x1E, 0xEC, 0xC1,
    0x70, 0x5D, 0xDB, 0x33, 0x90, 0x54, 0x25, 0xE8,
    0xE3, 0x37, 0x55, 0x0F, 0x58, 0xAA, 0x3A, 0xF8,
    0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE8
    
    // Test wrong value
    //0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE9 
  };

  const uint8_t other_data[CHECKMAC_OTHER_DATA_SIZE] = {
    0x08,                   // MAC OpCode
    0x00,                   // MAC Mode
    0x00, 0x00,             // SlotID for MAC
    0x00, 0x00, 0x00,       // OTP[8:10] for MAC
    0x00, 0x00, 0x00, 0x00, // SN[4:7] for MAC
    0x00, 0x00              // SN[2:3] for MAC
  };

  byte retCode = sha204.sha204m_execute(SHA204_CHECKMAC,
                                        0, 0,
                                        MAC_CHALLENGE_SIZE,            (uint8_t *) challenge,
                                        CHECKMAC_CLIENT_RESPONSE_SIZE, (uint8_t *) response_mac,
                                        CHECKMAC_OTHER_DATA_SIZE,      (uint8_t *) other_data,
                                        sizeof(command),   &command[0],
                                        sizeof(response), &response[0]);

  Serial.print(F("RetCode: ")); Serial.println(retCode);

  Serial.print(F("CheckMac result: "));

  switch (response[1]) {
    case 0: Serial.println(F("match!"));    break;
    case 1: Serial.println(F("mismatch!")); break;
   default: Serial.println(F("(error)"));
  }

}

void loop() {

}

Теперь подробно разберём его работу. В качестве «Challenge», то есть в качестве входного набора байтов, мы будем использовать 32-х байтовый массив challenge, заполненный тестовыми значениями.

  const uint8_t challenge[MAC_CHALLENGE_SIZE] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };

В массив response_mac мы помещаем заранее известный (из предыдущих уроков) ответ удалённой системы.

    // Test wrong value
  const uint8_t response_mac[CHECKMAC_CLIENT_RESPONSE_SIZE] = {
    0x5C, 0x91, 0xBF, 0xDA, 0x80, 0x1E, 0xEC, 0xC1,
    0x70, 0x5D, 0xDB, 0x33, 0x90, 0x54, 0x25, 0xE8,
    0xE3, 0x37, 0x55, 0x0F, 0x58, 0xAA, 0x3A, 0xF8,
    0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE8
    
    // Test wrong value
    //0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE9 
  };

И тут же добавляем закомментированную строку, которая понадобится нам для тестирования корректности работы нашего скетча, в которой последний байт 0xE8 меняем на заведомо неправильный 0xE9.

    // Test wrong value
    //0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE9 

Также добавляем массив other_data с настройками работы команды MAC.

  const uint8_t other_data[CHECKMAC_OTHER_DATA_SIZE] = {
    0x08,                   // MAC OpCode
    0x00,                   // MAC Mode
    0x00, 0x00,             // SlotID for MAC
    0x00, 0x00, 0x00,       // OTP[8:10] for MAC
    0x00, 0x00, 0x00, 0x00, // SN[4:7] for MAC
    0x00, 0x00              // SN[2:3] for MAC
  };

И объявляем два массива для хранения команды и ответа функции sha204.sha204m_execute(). Размеры массивов определяются заранее объявленными в библиотеке константами SHA204_CMD_SIZE_MAX и CHECKMAC_RSP_SIZE.

  uint8_t command[SHA204_CMD_SIZE_MAX];
  uint8_t response[CHECKMAC_RSP_SIZE];

Далее мы вызываем функцию sha204.sha204m_execute() с соответствующим заполнением её параметров.

  byte retCode = sha204.sha204m_execute(SHA204_CHECKMAC,
                                        0, 0,
                                        MAC_CHALLENGE_SIZE,            (uint8_t *) challenge,
                                        CHECKMAC_CLIENT_RESPONSE_SIZE, (uint8_t *) response_mac,
                                        CHECKMAC_OTHER_DATA_SIZE,      (uint8_t *) other_data,
                                        sizeof(command),   &command[0],
                                        sizeof(response), &response[0]);

В данном случае для нас являются важными параметры

SHA204_CHECKMAC,

это константа, содержащая номер команды CheckMac (0x28),

0, 0,

это режим команды CheckMac (Параметр 1) и номер слота в Data зоне ATSHA204A (Параметр 2).

Далее подаём на вход функции sha204.sha204m_execute() массив challenge с исходными данными

MAC_CHALLENGE_SIZE,            (uint8_t *) challenge,

массив response_mac с ответом удалённой системы

CHECKMAC_CLIENT_RESPONSE_SIZE, (uint8_t *) response_mac,

и массив other_data с настройками команды MAC.

CHECKMAC_OTHER_DATA_SIZE,      (uint8_t *) other_data,

И в завершение в Serial выводится результат работы нашего скетча

  Serial.print(F("RetCode: ")); Serial.println(retCode);

  Serial.print(F("CheckMac result: "));

  switch (response[1]) {
    case 0: Serial.println(F("match!"));    break;
    case 1: Serial.println(F("mismatch!")); break;
   default: Serial.println(F("(error)"));
  }

где сначала выводится результат проведения операции

  Serial.print(F("RetCode: ")); Serial.println(retCode);

а затем выводится результат работы команды CheckMac

  Serial.print(F("CheckMac result: "));

  switch (response[1]) {
    case 0: Serial.println(F("match!"));    break;
    case 1: Serial.println(F("mismatch!")); break;
   default: Serial.println(F("(error)"));
  }

Вот скриншот работы нашего скетча при условии верного значения данных в массиве response_mac — микроконтроллер рапортует о совпадении вычисленных и полученных от удалённой системы хешей.

Теперь проверим работу команды CheckMac в случае получения от удалённой системы неверных данных. Для этого закомментируем последнюю строку массива response_mac и раскомментируем строку с заведомо неверным байтом 0xE9.

  const uint8_t response_mac[CHECKMAC_CLIENT_RESPONSE_SIZE] = {
    0x5C, 0x91, 0xBF, 0xDA, 0x80, 0x1E, 0xEC, 0xC1,
    0x70, 0x5D, 0xDB, 0x33, 0x90, 0x54, 0x25, 0xE8,
    0xE3, 0x37, 0x55, 0x0F, 0x58, 0xAA, 0x3A, 0xF8,
    //0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE8
    
    // Test wrong value
    0x09, 0xB7, 0x7C, 0xF1, 0xA0, 0x40, 0xE2, 0xE9 
  };

Заново компилируем скетч и загружаем его в контроллер — всё правильно, команда CheckMac рапортует о несовпадении хешей.

Заключение

Команда CheckMac имеет ещё множество настроек и вариантов использования, мы рассмотрели самый простой из них — вы можете продолжить знакомство и эксперименты с этой командой при помощи информации из даташита микросхемы ATSHA204A.

 

Ссылки по теме

Работа с SHA-256

ATSHA204 - Обзор

ATSHA204 - Спецификации

ATSHA204 - Библиотека и примеры

ATSHA204A - Чтение зоны конфигурации 1

ATSHA204A - Чтение зоны конфигурации 2

ATSHA204A - Чтение зоны конфигурации 3

ATSHA204A - Запись конфигурации 1

ATSHA204A - Запись конфигурации 2

ATSHA204A - Запись конфигурации 3

ATSHA204A - Запись конфигурации 4

ATSHA204A - Config Lock

ATSHA204A - Работа в режиме Config Lock

ATSHA204A - Работа с зонами памяти

ATSHA204A - Запись зоны OTP

ATSHA204A - Data Lock

ATSHA204A - Чтение Data и OTP зон памяти

ATSHA204A - Команда MAC

ATSHA204A - Аутентификация. Базовый блок

ATSHA204A - Криптография и команды

ATSHA204A - Команда CheckMac

ATSHA204A - Команда Nonce

ATSHA204A - Команда GenDig

ATSHA204A - Команда HMAC

ATSHA204A - Команда DeriveKey

ATSHA204A - Команда DeriveKey

ATSHA204A - nRF24 аутентификация. База

ATSHA204A - nRF24 аутентификация. Датчик

ATSHA204A - LoRa аутентификация. База

ATSHA204A - LoRa аутентификация. Датчик