Продолжаем изучать устройство и работу криптомикросхемы 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.
Ссылки по теме
ATSHA204 - Библиотека и примеры
ATSHA204A - Чтение зоны конфигурации 1
ATSHA204A - Чтение зоны конфигурации 2
ATSHA204A - Чтение зоны конфигурации 3
ATSHA204A - Запись конфигурации 1
ATSHA204A - Запись конфигурации 2
ATSHA204A - Запись конфигурации 3
ATSHA204A - Запись конфигурации 4
ATSHA204A - Работа в режиме Config Lock
ATSHA204A - Работа с зонами памяти
ATSHA204A - Чтение Data и OTP зон памяти
ATSHA204A - Аутентификация. Базовый блок
ATSHA204A - Криптография и команды
ATSHA204A - Команда CheckMac
ATSHA204A - nRF24 аутентификация. База
ATSHA204A - nRF24 аутентификация. Датчик