Как защитить железку от Китайцев, если вы им передаете всю производственную документацию?

от автора

1. Стоимость взлома как главный барьер

В области Hardware Security действует базовое правило: абсолютной защиты не существует. Любое электронное устройство можно реверсить, вскрыть и скопировать. Это лишь вопрос времени, денег и наличия специализированного оборудования — например, установок для послойного стравливания кремния или FIB-микроскопов (Focus Laser/Ion Beam).

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

2. Сценарий: Атака доверенного производства («Третья смена»)

Передача фабрике-изготовителю (контрактному производству в Китае) полного комплекта документации и ПО — это стандартная практика и одновременно главный кошмар разработчика. Вы отдаете:

  • Гербер-файлы и спецификацию платы (BOM).

  • Финальный бинарный код микроконтроллера.

  • Тех процесс (скажем толщины масок для пасты), технологию тестирования.

  • Скомпилированный битстрим (rbf) для FPGA.

В этом случае классические методы защиты — шифрование прошивки на стороне разработчика или закрытие интерфейсов отладки (JTAG) фьюзами — не работают. Завод имеет легальный доступ ко всем файлам. Ничто не мешает ему запустить конвейер сверх оплаченного вами лимита, выпустить неограниченную партию «левых» клонов, залить туда ваши оригинальные прошивки и продать на рынке.

С точки зрения софта клон будет идентичен оригиналу. Но у него есть одна уязвимость, которую невозможно скопировать файлами — он собран на другом физическом кремнии. Именно эту разницу мы и используем для разрушения бизнес-модели бесконтрольного производства.

3. Архитектура решения: PUF на свободных задержках

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

Вместо хранения секретного ключа в энергонезависимой памяти, мы заставляем FPGA вычислять его «на лету» с помощью PUF (Physically Unclonable Function) — физически неклонируемой функции, основанной на уникальных наноструктурных дефектах кремния.

Логика работы системы делится на четыре этапа:

Как же эта «магия» работает? Разобьем технологию на 4 этапа.

Этап 1. Снятие слепка кристалла

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

Внутри FPGA мы размещаем кольцевые генераторы (Ring Oscillators) и подключенные к ним счетчики. Запуская их одновременно, мы фиксируем стабильную разницу их частот. Это — цифровой «отпечаток пальца» кристалла.

Этап 2. Проверка лимитов на сервере

При первом включении на заводском стенде FPGA «вычисляет чистый» PUF-слепок и отправляет его на Ваш удаленный сервер. Устройство на данном этапе ничего не знает о ключах. Сервер сверяет запрос со своей базой данных: если лимит токенов (выпущенных лицензий) для данной фабрики не исчерпан, сервер уменьшает баланс доступных устройств. Если лимит равен нулю — сервер отклоняет запрос, предотвращая появление «третьей смены».

Этап 3. Формирование пакета («Крипто-ключ»)

Сервер берет присланный PUF-отпечаток, подмешивает криптографическую соль и шифрует данные. Формируется индивидуальный, закрытый блок данных — «крипто-ключ». Этот процесс происходит исключительно на стороне сервера, скрывая математику шифрования от глаз фабрики. Готовый пакет отправляется обратно на устройство, которое просто записывает его «как есть» в энергонезависимую память, а затем просто считывает и передает в вычислитель PUF FPGA.

Этап 4. Отложенный саботаж

Если проверка не прошла, устройство не блокируется мгновенно. Иначе хакер сразу поймет, в какой точке сработала защита, и начнет искать инструкцию ветвления. Но, если плата штатно работает около 5 минут (логику «около» крайне рекомендовано внедрять) тут возникают «непонятки», ведь на заводе нет точного понимания качества сборки и «бракованности» компонентов.

4. Криптографический ключ и защита от Replay-атак

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

Чтобы этого не произошло, криптографический ключ и сопутствующий пакет активации должны быть жестко привязаны к физическому слою кремния.

Математика генерации токена активации:

Процесс регистрации устройства на заводском стенде выглядит следующим образом:

  1. Сбор сырого отпечатка: FPGA запускает кольцевые генераторы и формирует сырой массив данных разности частот PUF.

  2. Передача на сервер: Этот массив (Challenge Response) отправляется на сервер производителя. Сам по себе он не является секретом — это просто уникальный шум конкретного кристалла.

  3. Формирование криптографического ключа на сервере:

    • Сервер проверяет лимит доступных токенов для данной партии.

    • Если лимит не исчерпан, сервер с помощью криптографической функции формирования ключа генерирует уникальный мастер-ключ устройства и секретную серверную соль.

    • Для обеспечения стабильности (ведь физический PUF-отпечаток имеет погрешность из-за температуры) сервер рассчитывает вспомогательные данные для коррекции ошибок — Helper Data (код Хэмминга или BCH-код).

  4. Упаковка «шифровки»: Сервер формирует монолитный зашифрованный пакет, содержащий HelperData, зашифрованную конфигурацию и контрольную сумму (HMAC). Этот пакет отправляется обратно на устройство и зашивается в NVM платы.

Почему Replay-атака не сработает?

Если злоумышленник скопирует весь дамп NVM (вместе с Helper Data и зашифрованным ключом) с легальной платы на клон:

  1. При старте клон считает свои собственные физические параметры PUF.

  2. Попытается применить скопированные HelperData для восстановления ключа.

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

  4. В результате FPGA сгенерирует абсолютно случайный, «кривой» криптографический ключ. Контрольная сумма пакета (HMAC) не совпадет, и устройство зафиксирует факт взлома.

Таким образом, ключ валиден только на одном-единственном физическом кристалле, для которого он был рассчитан на сервере.

В чем экономическая эффективность?

Схема перекладывает финансовое бремя защиты на взломщика:

  • Прямое клонирование бесполезно: Копии плат без валидного ключа превращаются в неработоспособный хлам через 5 минут после включения.

  • Высокая стоимость реверс-инжиниринга: Чтобы запустить клоны, заводу придется декомпилировать битстрим FPGA (netlist), вручную искать запрятанные среди тысяч ячеек кольцевые генераторы, счетчики и логику саботажа, а затем модифицировать проект. Затраты на оплату сотен часов работы инженеров такого уровня полностью уничтожают маржинальность кражи чужого устройства.

  • Математика брутфорса против перебора пар: Попытка обойти защиту лобовым перебором ключей или конфигураций генераторов полностью разбивается о комбинаторику. Предположим, в нашей системе развернута матрица всего из N = 128 кольцевых генераторов. Количество уникальных пар, которые можно из них составить для сравнения частот, вычисляется через число сочетаний:

C_N^2 = \frac{N!}{2!(N-2)!} = \frac{128 \times 127}{2} = 8128 \text{ пар}

Каждая пара генераторов в результате сравнения выдает ровно 1 бит информации (кто оказался быстрее). Даже если для формирования финального криптографического ключа мы берем не все пары, а только линейно независимое подмножество из 64 стабильных комбинаций, пространство состояний для брутфорса составит 2^64 вариантов. Если бы у злоумышленника был суперкомпьютер, способный проверять по 1 миллиарду (10^9) ключей в секунду, время полного перебора составило бы:

T = \frac{2^{64}}{10^9 \times 365 \times 24 \times 3600} \approx 585 \text{ лет}

Ситуацию для взломщика усложняет и наш 5-минутный таймер: из-за того, что устройство начинает умышленно глючить, автоматизировать перебор на реальном железе физически невозможно. Математика делает атаку перебором бессмысленной, оставляя пиратам только экономически неокупаемый реверс-инжиниринг битстрима.

Рассмотрим однако реальную физику. Предположим после жесткого отсева по температурной стабильности и флуктуациям питания (PVT-вариациям) мы выбрали из них всего K = 11 надежных пар для формирования уникального идентификатора. Пространство вариантов ключа в таком случае составляет 2^{11} = 2048 комбинаций. Если же стабильных пар удалось выжать чуть больше — например, K = 15, то пространство вариантов расширяется до 2^{15} = 32768 комбинаций. Казалось бы, для современного ПК перебрать 32 тысячи вариантов — дело доли секунды. Но злоумышленник привязан к физической плате клона. Чтобы проверить, подошел ли ключ, ему нужно запустить устройство и дождаться прохождения 5-минутного интервала. Если ключ неверный — через 5 минут плата начнет глючить. Посчитаем время перебора для худшего (K = 11) и лучшего (K = 15) сценариев: При K = 11 (2048 комбинаций):

T_{min}  = 2048 \times 5 \text{ минут} = 10240 \text{ минут} \approx 7 \text{ суток}

При K = 15 (32768 комбинаций):

T_{max} = 32768 \times 5 \text{ минут} = 163840 \text{ минут} \approx 113 \text{ суток}

Таким образом, даже при минимальном наборе из 11 стабильных бит взломщику потребуется неделя непрерывного сидения у одной платы, чтобы вручную или по UART перебрать ключи, постоянно перезагружая устройство по питанию каждые 5 минут. При 15 стабильных парах процесс растягивается почти на 4 месяца. Учитывая, что китайский завод планирует тиражировать клоны тысячами, тратить по 100 дней работы инженера и тестового стенда на запуск каждого отдельного экземпляра устройства — это экономическое самоубийство. Математика времени ожидания делает атаку на реальном железе абсолютно бессмысленной.

Физический слой: Схема Ring Oscillator внутри FPGA

Чтобы получить уникальный цифровой слепок, нам нужно построить схему, которая реагирует на наноструктурные различия кремния. В FPGA для этого идеально подходит Ring Oscillator PUF (RO-PUF) — кольцевой генератор на базе задержек в логических элементах.

Как устроен генератор на LUT

Внутри любой FPGA базовым вычислительным кирпичиком является LUT (Look-Up Table) — таблица истинности, на которой синтезируется любая комбинаторная логика. Кольцевой генератор создается путем последовательного соединения нечетного количества инверторов в замкнутую петлю.

Единичный генератор для пары (RO1 или RO2)

Единичный генератор для пары (RO1 или RO2)
  • Синхронный старт: Сигнал Enable одновременно запускает два генератора (RO 1 и RO 2).

  • Накопление: Каждый генератор тактирует свой собственный независимый быстрый счетчик (например, 16-битный).

  • Остановка: Ровно через фиксированное количество системных тактов (или когда один из счетчиков переполнится) оба генератора останавливаются.

  • Вычисление разности: Из показаний первого счетчика вычитаются показания второго:

Delta = Count_1 - Count_2

Значение Delta и является стабильной разницей, которая уникальна для этой конкретной пары LUT на этом конкретном чипе на этом конкретном LUT.

Главные грабли: Температурный дрейф и напряжение

Физика кремния накладывает жесткое ограничение: при изменении температуры кристалла и флуктуациях напряжения питания (PVT-вариации) скорость работы LUT меняется. При нагревании кремния сопротивление каналов растет, и частота генераторов падает.

Если спроектировать схему «в лоб», то устройство, активированное на заводе при +25°C, на морозе в -10°C или в закрытом корпусе при +60°C выдаст совершенно другую разницу счетчиков, не примет легальный ключ и уйдет в саботаж.

Как с этим бороться в практической реализации?

  1. Симметричная топология (Hard Macros):
    Нельзя отдавать размещение генераторов на откуп автоматическому трассировщику (Place & Route) в Квартусе или Вивадо. Их нужно жестко запереть в соседних логических блоках (LAB/SLICE) с помощью атрибутов локализации (например, LOC ограничений). Они должны находиться на расстоянии микронов друг от друга. В таком случае внешняя температура нагревает или охлаждает их абсолютно одинаково, и тепловой дрейф частоты взаимно уничтожается при вычитании.

  2. Метод пары лидеров (RO Ordering):
    Вместо использования абсолютного значения разницы Delta, берется только знак результата (бинарный выбор). Мы сравниваем не «на сколько один быстрее другого», а просто определяем, кто из них выиграл гонку:

Bit=\begin{cases}1,&\text{if\ }Count_{1}>Count_{2}\\ 0,&\text{if\ }Count_{1}\le Count_{2}\end{cases}

3. Для формирования длинного ключа создается матрица из десятков таких генераторов, и сравниваются пары с гарантированно сильным разбросом частот!!! Нужен гарантированный «запас», если счетчики приблизительно равные, то им доверять нельзя!!! Знак разности между физически быстрой и физически медленной ячейками не изменится даже при экстремальном нагреве или охлаждении (хотя вы сами должны провести эксперименты на температурную стабильность).

4. Хелперы на стороне сервера:
Как мы уже упоминали в главе про криптографию, сервер рассчитывает избыточные данные (Helper Data) для кодов коррекции ошибок. При запуске FPGA использует эти данные, чтобы аппаратно «дотянуть» слегка уплывшие от температуры счетчики до эталонного заводского состояния, прежде чем генерировать финальный ключ. Это важно!

Чтобы не быть голословным. Вот пример реализации на Verilog (только счетчики):

verilog

// Модуль одного кольцевого генератора (Ring Oscillator)module ring_oscillator #(    parameter STAGES = 3 // Количество инверторов (обязательно нечетное))(    input  wire enable,    output wire osc_out);    // Атрибуты для запрета оптимизации и объединения LUT-ячеек    (* keep = "true" *) (* syn_keep = "true" *) wire [STAGES:0] delay_chain;    // Первый элемент — И-НЕ (NAND) для управления запуском    assign delay_chain[0] = ~(delay_chain[STAGES] & enable);    // Цепочка инверторов    genvar i;    generate        for (i = 0; i < STAGES; i = i + 1) begin: puf_chain            (* keep = "true" *) (* syn_keep = "true" *)            assign delay_chain[i+1] = ~delay_chain[i];        end    endgenerate    // Выход генератора    assign osc_out = delay_chain[STAGES];endmodule// Топ-модуль измерения PUF: два генератора и счетчики разностиmodule puf_measurement (    input  wire clk,         // Системный тактовый сигнал    input  wire rst_n,       // Сброс (активный низкий)    input  wire start_puf,   // Команда на запуск измерения    output reg  puf_ready,   // Флаг окончания замера    output reg  [15:0] puf_delta // Итоговая разница счетчиков);    wire osc1_out;    wire osc2_out;        reg  enable_oscillators;    reg  [15:0] ref_timer;    reg  [15:0] counter1;    reg  [15:0] counter2;        // Первый кольцевой генератор    ring_oscillator #(.STAGES(3)) ro1 (        .enable(enable_oscillators),        .osc_out(osc1_out)    );    // Второй кольцевой генератор    ring_oscillator #(.STAGES(3)) ro2 (        .enable(enable_oscillators),        .osc_out(osc2_out)    );    // Логика счета на асинхронных часах от RO    always @(posedge osc1_out or negedge rst_n) begin        if (!rst_n)             counter1 <= 16'd0;        else if (enable_oscillators)             counter1 <= counter1 + 1'b1;    end    always @(posedge osc2_out or negedge rst_n) begin        if (!rst_n)             counter2 <= 16'd0;        else if (enable_oscillators)             counter2 <= counter2 + 1'b1;    end    // Управляющий автомат на системной частоте    always @(posedge clk or negedge rst_n) begin        if (!rst_n) begin            enable_oscillators <= 1'b0;            ref_timer          <= 16'd0;            puf_ready          <= 1'b0;            puf_delta          <= 16'd0;        end else begin            if (start_puf && !enable_oscillators && !puf_ready) begin                // Старт замера                enable_oscillators <= 1'b1;                ref_timer          <= 16'd0;                puf_ready          <= 1'b0;            end else if (enable_oscillators) begin                // Ограничиваем время замера по системному таймеру (например, 1000 тактов)                if (ref_timer >= 16'd1000) begin                    enable_oscillators <= 1'b0;                    puf_ready          <= 1'b1;                    // Вычисляем разницу                    puf_delta          <= counter1 - counter2;                end else begin                    ref_timer <= ref_timer + 1'b1;                end            end else if (!start_puf) begin                puf_ready <= 1'b0;            end        end    endendmodule

6. Борьба с компилятором: Физические ограничения размещения (Placement Constraints)

Написать код кольцевого генератора на Verilog — это только треть дела. По умолчанию компиляторы (Quartus, Vivado) заточены под оптимизацию таймингов и энергопотребления. Если оставить проект как есть, САПР совершит одну из двух ошибок:

  1. Разнесет инверторы по разным углам кристалла. Длина трассировочных дорожек между LUT станет случайной. В итоге ваш PUF будет измерять не уникальные свойства транзисторов в кремнии, а то, как «навычислял» алгоритм автоматического размещения (Place & Route).

  2. Сгруппирует их слишком хаотично от чипа к чипу. Разводка внутри пар генераторов будет неидентичной.

Чтобы PUF выдавал стабильные и воспроизводимые результаты, пары кольцевых генераторов должны быть размещены максимально близко друг к другу (в соседних ячейках) и иметь абсолютно одинаковую геометрию связей. Достигается это с помощью жестких ограничений (Floorplanning).

Ниже приведены практические примеры того, как запереть генераторы в конкретных аппаратных координатах кристалла.

Реализация для AMD/Xilinx Vivado (XDC constraints)

В Vivado для жесткой фиксации элементов используются свойства BEL (Basic Element — конкретный LUT внутри слайса) и LOC (координата самого Slice на кристалле). Также мы упаковываем элементы в логическую группу PBLOCK, чтобы запретить трассировщику прокладывать сторонние цепи через наш PUF.

Предположим, наш модуль RO развернут в иерархии проекта как inst_puf_meas/ro1 и inst_puf_meas/ro2.

tcl

# Запрещаем оптимизацию цепей обратной связи на этапе оптимизации (Design Optimization)set_property DONT_TOUCH true [get_cells inst_puf_meas/ro1/delay_chain*]set_property DONT_TOUCH true [get_cells inst_puf_meas/ro2/delay_chain*]# Фиксируем инверторы первого генератора (RO1) в Slice X0Y50set_property LOC SLICE_X0Y50 [get_cells inst_puf_meas/ro1/puf_chain[0].puf_lut]set_property BEL A6LUT       [get_cells inst_puf_meas/ro1/puf_chain[0].puf_lut]set_property LOC SLICE_X0Y50 [get_cells inst_puf_meas/ro1/puf_chain[1].puf_lut]set_property BEL B6LUT       [get_cells inst_puf_meas/ro1/puf_chain[1].puf_lut]# Фиксируем инверторы второго генератора (RO2) строго параллельно в соседнем Slice X1Y50set_property LOC SLICE_X1Y50 [get_cells inst_puf_meas/ro2/puf_chain[0].puf_lut]set_property BEL A6LUT       [get_cells inst_puf_meas/ro2/puf_chain[0].puf_lut]set_property LOC SLICE_X1Y50 [get_cells inst_puf_meas/ro2/puf_chain[1].puf_lut]set_property BEL B6LUT       [get_cells inst_puf_meas/ro2/puf_chain[1].puf_lut]# Указываем трассировщику использовать идентичные ресурсы для соединений (Routing)set_property LOCK_PINS {I0:A6} [get_cells inst_puf_meas/ro1/puf_chain[*].puf_lut]set_property LOCK_PINS {I0:A6} [get_cells inst_puf_meas/ro2/puf_chain[*].puf_lut]

7. Механизм отложенного саботажа: Почему именно 5 минут?

Частично я объяснял выше, но:

Если устройство проваливает проверку ключа активации, стандартная реакция большинства систем защиты — мгновенная блокировка (глухой «кирпич»). С точки зрения реверс-инжиниринга это грубейшая ошибка. Хакер, подключив осциллограф, логический анализатор или внутрисхемный отладчик, сразу видит четкую точку на временной шкале: «Подали питание — через 50 миллисекунд устройство отключилось». Это позволяет за пару часов локализовать кусок логики FPGA, отвечающий за проверку.

Мы усложняем задачу, разрывая причинно-следственную связь во времени с помощью двух приемов:

  1. Таймер задержки (5 минут): После включения устройство честно и абсолютно корректно выполняет все свои функции в течение 300 секунд. Злоумышленник на тестовом стенде уверен, что его взлом или обход удался — плата работает, данные идут, и мало того в первых партиях вообще не увидит подвоха.

  2. Имитация аппаратного сбоя вместо выключения: По истечении 5 минут FPGA не выключается. Специальный блок саботажа начинает умышленно, но хаотично генерировать «глюки».

Примеры реализации скрытых глюков в FPGA:

  • Искажение шин данных: Подмешивание случайного бита (инверсия) в потоки SPI, I2C или UART раз в несколько секунд. Для стороннего наблюдателя это выглядит как плохой кабель или наводка по питанию.

  • Сдвиг фазы/таймингов: Внутренний блок фазовой автоподстройки частоты (PLL) делает микроскопический сдвиг фазы тактового сигнала для внешней памяти DDR или контроллера дисплея. Память начинает сыпать циклическими ошибками (CRC errors).

  • Порча контрольных сумм: Логика FPGA начинает портить каждый сотый пакет сетевого интерфейса (Ethernet/CAN). Устройство теряет связь, но софт считает это «проблемой на линии».

  • Генерация шума в звуковом тракте: Если устройство работает с аудиопотоками, через 5 минут после старта блок саботажа в FPGA резко и бесцеремонно заменяет легальный аудиосигнал на шине I2S/AC97 на максимальный по амплитуде белый шум или жесткий высокочастотный писк (генератор меандра на максимальной громкости).Устройство начинает пищать или гудеть. В чем инженерная красота такого лобового удара? Любой hardware-инженер, столкнувшись с резким белым шумом или свистом в динамиках через 5 минут после включения, на 100% будет уверен, что это аппаратная проблема:

    1. Самовозбуждение операционных усилителей в аналоговом тракте из-за нагрева.

    2. Пробой конденсатора в цепи фильтрации питания.

    3. Тепловой дрейф опорного генератора (MCLK) ЦАП, из-за которого поплыла синхронизация.

    Заводские хакеры проведут недели за осциллографами, будут заливать плату фризером, перепаивать микросхемы ЦАП и менять обвязку, пытаясь победить этот «дефект прогрева платы». Им и в голову не прийдет (в первое время), что этот шум генерирует идеально работающий цифровой автомат внутри FPGA, который просто не дождался ключа.

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

Заключение

Использование физически неклонируемых функций (PUF) на базе кольцевых генераторов в FPGA переводит противостояние с недобросовестными производителями из плоскости «кто лучше спрятал прошивку» в плоскость чистой инженерной экономики.

Передавая фабрике полный комплект софта и Gerber-файлов, вы больше не рискуете потерять продукт. Каждая собранная плата — это всего лишь кусок текстолита с кремнием, который не имеет ценности без индивидуального цифрового слепка, рассчитанного на вашем сервере. Ломая бизнес-модель «третьей смены» и заставляя клоны непредсказуемо глючить, вы делаете пиратское тиражирование вашего устройства экономически бессмысленным.

…перед запуском:

Перед тем как отправить финальные файлы на завод и запустить сервер активации, проверьте вашу систему защиты по следующим пунктам:

  • Проверка температурного диапазона: Проверено ли поведение PUF-счетчиков при крайних температурах (например, в климатической камере при -20°C и +60°C)? Гарантирует ли шаг кодов коррекции ошибок (Helper Data) восстановление оригинального ключа при экстремальном нагреве?

  • Анализ уникальности (Inter-distance): Прошить тестовый битстрим в 20-30 разных физических плат? Убедиться что разница счетчиков между разными чипами достаточно велика ( Hamming distance близко к 50%), чтобы сервер не перепутал платы между собой?

  • Физическая изоляция в САПР: Запрещена ли трассировщику оптимизация цепей PUF? И зафиксирован ли жестко PUF блок в координатах кристалла, иначе если вы захотите выпустить обновление, у вас получиться провал. Ибо при компиляции QUARTUS например положит PUF в другое место кремния, и тогда правильный ключ перестанет «быть правильным».

  • Защита от Replay-атак на сервере: Использует ли сервер одноразовые криптографические соли (nonces) и счетчики при обмене данными, чтобы перехваченный трафик первой активации нельзя было повторно использовать для клона?

  • Размазывание логики саботажа: Насколько глубоко блок 5-минутного таймера и генератор «глюков» внедрены в основную логику FPGA? Если хакер сможет локализовать и вырезать сам блок PUF, заблокирует ли это работу основного алгоритма устройства?

  • Логирование лимитов: Настроена ли на сервере система моментального оповещения (Alerts) при попытке запроса ключа активации сверх оплаченного лимита токенов? (Это ваш главный маркер того, что завод начал «третью смену»).

  • Защита от FPGA лаборатории: не используйте стандартные алгоритмы шифрования на стороне FPGA типа AES или XTEA, их видно прямо в битстриме, но если нет вариантов, модифицируйте стандартный алгоритм, не то чтобы до неузнаваемости, поменяйте следование таблиц (AES) или добавьте лавинный XOR (XTEA). Не используйте обычную обфускацию, её может увидеть алгоритм.

Хочу прямо уточнить, я пишу статьи о реально работающих приборах, алгоритмах и/или о том что сам проверял.

За сим завершаю. Надеюсь мои изыскания будут полезны. С уважением и наилучшими пожеланиями, Михаил.

ссылка на оригинал статьи https://habr.com/ru/articles/1060346/