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

Адресация в сети

Например, можно назначать уникальные номера в общей сети устройств, к примеру в сети CAN. В CAN номер девайса состоит из 11 или 29 бит, можно использовать младшие 29 бит идентификатора в качестве номера.

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

К примеру, в случае CAN при первом включении (или при команде ENUM) каждый микроконтроллер сформирует пакет данных со своим кодом, и отправит на главный контроллер. Благодаря свойствам шины CAN все сообщения обязательно придут, и главный контроллер будет знать номера всех подключенных устройств — что избавляет от необходимости последовательного перебора всех возможных адресов.

Криптоключ

Этот номер можно напрямую использовать как ключ для шифрования процесором CRYP. Конечно, стойкость такого шифрования невысока, но если злоумышленник не может прочесть ID контроллера — он не сможет и взломать ваш код.

Организация передачи прошивок

Как объединение перечисленных выше примеров, можно сделать действительно интересную вещь. При появлении новой прошивки вы можете генерировать на сервере файлы прошивок, зашифрованные этим ключом, и передавать по каким-то проводным или радиоканалам шифрованные файлы. Приняв файл, микроконтроллер его расшифрует, перейдёт в режим прошивки (для этого потребуется собственный бутлоадер) и прошьётся новым firmware.

Криптоблокнот

Можно устроить хранение сообщений, зашифрованных ключами, в открытом виде на сервере. Микроконтроллер будет периодически посещать сервер, загружать все новые сообщения и по очереди пытаться расшифровывать их своим ключом. Очевидно, расшифруются только те сообщения, которые адресованы ему и подписаны его ключом — но злоумышленник не знает этот ключ, для взлома ему придётся перебирать все 96 бит. Микроконтроллер может также зашифровать своё сообщение ключом адресата, и отправить на этот сервер обратно.

Seed для генератора случайных чисел

96 бит дают нам возможность сделать неплохой источник энтропии для инициализации программного генератора случайных чисел, либо для улучшения данных встроенного аппаратного генератора. Можно, к примеру, сделать xor идентификатора и текущего псевдослучайного значения, но лучше, используя встроенный процессор HASH, считать хеш такой суммы — полученное случайное значение + Unique_ID + какой-то ещё источник энтропии, вроде текущего времени или значения с АЦП (младшие биты АЦП очень случайны).

Использование

Прочитать Unique ID очень легко, нужно лишь считать 3 32-битных значения, начиная с адреса 0x1FFFF7E8 (или 0x1FFF7A10 в случае STM32F4).

static unsigned long *Unique_ID = (uint32_t *)0x1FFFF7E8;
unsigned long Unique_ID_0, Unique_ID_1, Unique_ID_2;
Unique_ID_0 = Unique_ID[0];
Unique_ID_1 = Unique_ID[1];
Unique_ID_2 = Unique_ID[2];

В библиотеке itacone есть более удобный метод — функции Unique_ID_Low, Unique_ID_Mid, Unique_ID_Hig, возвращающие int, и функции Unique_ID_Low0 и Unique_ID_Low1, возвращающие 2 shortint-компонента из Unique_ID_Low — т.е. самые младшие два shortint по 2 байта.