logo
+7 (495) 997-37-74
Москва, ул.Международная, 15

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

Итак, после всех тестов и манипуляций с микросхемой ATSHA204A, описанных в предыдущих статьях, мы имеем чип с заблокированной конфигурационной зоной и разблокированными зонами данных (Data Zone) и зоной OTP.

В этой статье мы исследуем работу ATSHA204A в этом режиме и подробно разберём её поведение и открывшиеся, в связи с блокировкой, возможности. Это довольно нетривиальная информация и хорошее понимание всех описанных в этой статье вопросов необходимо вам для грамотной и осмысленной работы с ATSHA204A.

Начнём мы с генератора случайных чисел.

Генератор случайных чисел (RNG)

Микросхема ATSHA204A содержит высококачественный генератор случайных 32-байтных чисел (RNG), который используется в работе с криптографическими функциями, а также может быть использован вами в ваших проектах. Но в работе этого генератора есть некоторые неочевидные нюансы.

Как уже было отмечено выше, свойства и функции микросхемы ATSHA204A зависят от состояния блокировки её зон памяти. Работа генератора случайных чисел также зависит от этих блокировок, в частности, генератор начинает работать только после блокировки конфигурационной зоны микросхемы ATSHA204A.

Об этом будет рассказано чуть ниже, а пока код скетча генератора случайных чисел на ATSHA204A:

/* 
  ATSHA204 Random (RNG)

*/

#include <sha204_library.h>

#define ATSHA204_PIN A3

atsha204Class sha204(ATSHA204_PIN);

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

void printArray(byte arr[], byte len) {
  for (byte i = 0; i < len; i++) {
    if (arr[i] < 16) {Serial.print('0');}
    Serial.print(arr[i], HEX); Serial.print(' ');
  }
}

void randomExample() {
  uint8_t response[RANDOM_RSP_SIZE];
  uint8_t tx_buffer[12] = {0};
  
  byte res = sha204.sha204m_random(tx_buffer, response, RANDOM_NO_SEED_UPDATE);

  printArray(response, RANDOM_RSP_SIZE);
  Serial.println();
  
}

void loop() {
  randomExample();
  delay(1000);
}

Работа по получению случайных чисел от микросхемы ATSHA204A выполняется библиотечной функцией sha204.sha204m_random()

byte res = sha204.sha204m_random(tx_buffer, response, RANDOM_NO_SEED_UPDATE);

и далее случайные 32-байтные числа, полученные от ATSHA204A, в бесконечном цикле выводятся в Serial

void loop() {
  randomExample();
  delay(1000);
}

Если запустить этот скетч на микросхеме с незаблокированной конфигурационной зоной (её изначальное состояние), то вместо случайных чисел генерируется специальная тестовая последовательность (которую, естественно, нельзя использовать в реальной работе).

При запуске скетча на ATSHA204A с заблокированной конфигурационной зоной, тот же скетч выдаёт уже полноценные случайные 32-битные числа, которые вы можете использовать в своих проектах для любых целей.

Запись в заблокированную зону

Теперь давайте проверим функцию записи в заблокированную зону и попытаемся изменить байт I2C Address в конфигурационной зоне нашей микросхемы. Для этого воспользуемся несколько модернизированным скетчем из наших предыдущих статей.

/* 
  ATSHA204 Write Config I2C Address
*/

#include <sha204_library.h>

#define ATSHA204_PIN A3

byte bufTx[SHA204_CMD_SIZE_MAX];
byte bufRx[SHA204_RSP_SIZE_MAX];

byte slot = 4;
byte shift = 0;

byte addrDefault = 0xC8;
byte addrNew = 0x55;

#define SLOT_LEN 4
byte bufRead[SLOT_LEN];
byte bufWrite[SLOT_LEN];

atsha204Class sha204(ATSHA204_PIN);


void setup() {
  Serial.begin(115200);
  Serial.println(F("ATSHA204 Write Config I2C Address start..."));

  Serial.print(F("Slot #"));  Serial.println(slot);

  readSlot();

  seti2cAddress(addrNew);
  writeConfig();
  
  readSlot();
}

// Print

void printBuffer(byte* data, byte len) {
  for (size_t i = 0; i < len; i++) {
    if (data[i] < 10) {Serial.print('0');}
    Serial.print(data[i], HEX);
    if (i < len - 1) {Serial.print(' ');}
  }
}

// Read

void copyReadToWrite() {
  bufWrite[0] = bufRead[0];
  bufWrite[1] = bufRead[1];
  bufWrite[2] = bufRead[2];
  bufWrite[3] = bufRead[3];
}

byte addr(byte slot) {
  return slot * 4;
}

void readConf() {
  byte retCode = sha204.sha204m_read(bufTx, bufRx, SHA204_ZONE_CONFIG, addr(slot));
  bufRead[0] = bufRx[SHA204_BUFFER_POS_DATA + 0];
  bufRead[1] = bufRx[SHA204_BUFFER_POS_DATA + 1];
  bufRead[2] = bufRx[SHA204_BUFFER_POS_DATA + 2];
  bufRead[3] = bufRx[SHA204_BUFFER_POS_DATA + 3];
  
}

void readSlot() {
  readConf();
  copyReadToWrite();
  
  Serial.print(F("Read: "));
  printBuffer(bufRead, SLOT_LEN);
  Serial.println();
}

// Write

void seti2cAddress(byte b) {
  bufWrite[shift] = b;
}

void writeConfig() {
  byte retCode = sha204.sha204m_execute(SHA204_WRITE,
                                        SHA204_ZONE_CONFIG, slot,
                                        4, bufWrite,
                                        0, NULL,
                                        0, NULL,
                                        WRITE_COUNT_SHORT, bufTx,
                                        WRITE_RSP_SIZE,    bufRx);
  if (retCode == 0) {Serial.println(F("Write Ok"));}
               else {Serial.println(F("Write Error"));}
}

void loop() {

}

Запускаем скетч и видим ожидаемую реакцию системы — тот код, который отлично работает на новой микросхеме ATSHA204A, выдаёт ошибку при попытке изменить байт I2C Address в заблокированной конфигурационной зоне ATSHA204A.

Запись ключа в Data Zone

Теперь давайте перейдём ближе к практической плоскости и попробуем решить задачу записи ключа шифрования в зону данных (Data Zone) нашей микросхемы ATSHA204A. Это один из важных этапов работы потому, что в реальных проектах вам придётся сохранять ключи шифрования в памяти ATSHA204A.

Для примера мы выберем максимально упрощённую задачу: нам нужно будет сохранить 32-битный ключ hmacKey в нулевом слоте Data зоны микросхемы ATSHA204A. Поскольку это тестовый пример, байты ключа выбраны произвольным образом и равны 0x01.

uint8_t hmacKey[] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
Полный код скетча ATSHA204 Data Zone Write Key:
 
/* 
  ATSHA204 Data Zone Write Key
*/

#include <sha204_library.h>

#define ATSHA204_PIN A3

byte bufTx[SHA204_CMD_SIZE_MAX];
byte bufRx[SHA204_RSP_SIZE_MAX];

byte retCode = 0;

uint8_t hmacKey[] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};

atsha204Class sha204(ATSHA204_PIN);

void setup() {
  Serial.begin(115200);
  Serial.println(F("ATSHA204 Data Zone Write Key..."));

  Serial.print(F("Key: "));
  printBuffer(hmacKey, 32);
  Serial.println();

  storeHmacKey(hmacKey);
}

void printBuffer(byte* data, byte len) {
  for (size_t i = 0; i < len; i++) {
    if (data[i] < 16) {Serial.print('0');}
    Serial.print(data[i], HEX);
    if (i < len - 1) {Serial.print(' ');}
  }
}

void storeHmacKey(uint8_t* key) {
  retCode = sha204.sha204m_execute(SHA204_WRITE,
                                   SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 0,
                                   SHA204_ZONE_ACCESS_32, key,
                                   0, NULL,
                                   0, NULL,
                                   WRITE_COUNT_LONG, bufTx,
                                   WRITE_RSP_SIZE,   bufRx);
                                   
  if (retCode == 0) {Serial.println(F("Write Ok"));}
               else {Serial.println(F("Write Error"));}
}

void loop() {

}

Вначале мы объявляем массив с 32-я байтами ключа (в ваших реальных проектах это должны быть байты секретного крипто-ключа).

uint8_t hmacKey[] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
Затем функция storeHmacKey() сохраняет переданный ей ключ в микросхеме ATSHA204A.
 
void storeHmacKey(uint8_t* key) {
  retCode = sha204.sha204m_execute(SHA204_WRITE,
                                   SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 0,
                                   SHA204_ZONE_ACCESS_32, key,
                                   0, NULL,
                                   0, NULL,
                                   WRITE_COUNT_LONG, bufTx,
                                   WRITE_RSP_SIZE,   bufRx);
                                   
  if (retCode == 0) {Serial.println(F("Write Ok"));}
               else {Serial.println(F("Write Error"));}
}

И выводит результат проведения операции «Ok» или «Error».

  if (retCode == 0) {Serial.println(F("Write Ok"));}
               else {Serial.println(F("Write Error"));}
Саму работу по записи ключа осуществляет библиотечная функция sha204.sha204m_execute().
 
  retCode = sha204.sha204m_execute(SHA204_WRITE,
                                   SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 0,
                                   SHA204_ZONE_ACCESS_32, key,
                                   0, NULL,
                                   0, NULL,
                                   WRITE_COUNT_LONG, bufTx,
                                   WRITE_RSP_SIZE,   bufRx);

Вот результат работы нашего скетча на экземпляре микросхемы ATSHA204A с заблокированной зоной конфигурации (и разблокированной Data Zone).

Как видите, запись ключа произведена успешно. Можно несколько раз запустить скетч и изменить байты ключа — операция записи также будет проходить успешно — до тех пор, пока не будет заблокирована зона данных, можно свободно перезаписывать сохранённый ключ.

Теперь для проверки попробуем запустить тот же скетч на микросхеме с незаблокированной конфигурационной зоной. Вот результат такой попытки:

Всё верно, как и ожидалось, попытка записать ключ в зону данных микросхемы ATSHA204A с незаблокированной конфигурационной зоной окончилась неудачей.

Обратите внимание, мы находимся на этапе, когда зона конфигурации заблокирована, а зона данных — нет и в этом состоянии мы не можем проверить правильность записи ключа в память ATSHA204A, мы можем только полагаться на код результата выполнения операции записи и доверять ему. Проверить и удостовериться, что ключ (ключи и прочие данные) корректно записаны в Data Zone мы сможем только после блокировки самой Data Zone.

Заключение

В этой статье мы рассмотрели работу с микросхемой ATSHA204A в режиме заблокированной конфигурационной зоны и незаблокированной Data Zone. Блокировка конфигурационной зоны позволяет включить некоторые функции ATSHA204A, а также открывает на запись зоны Data и OTP.

В следующих статьях мы подробно разберём организацию зон памяти ATSHA204A и приёмы сохранения в них ключей, паролей, секретных данных и счётчиков (counters) и прочих ресурсов.

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

Работа с SHA-256

ATSHA204 - Обзор

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

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

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

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

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

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

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

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

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

ATSHA204A - Config Lock

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

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

ATSHA204A - Data Lock

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

ATSHA204A - Команда MAC

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

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