• XSS.stack #1 – первый литературный журнал от юзеров форума

BearSSL и STM32. Как реализовать шифрование для самодельного гаджета

pablo

(L2) cache
Пользователь
Регистрация
01.02.2019
Сообщения
433
Реакции
1 524
BearSSL и STM32. Как реализовать шифрование для самодельного гаджета

В этой статье мы сделаем свой девайс, запустив шифрованное соединение TLS на микроконтроллере STM32.


Железо

Нам понадобятся официальная оценочная плата Discovery компании STMicroelectronics и модуль Wi-Fi на ESP8266. Последних существует огромное количество, подойдет практически любой. Главное, чтобы там были выводы RX/TX UART и стандартная прошивка для работы с АТ-командами. Я использую отечественный Troyka (модуль компании «Амперка») просто потому, что он у меня уже есть.

first.jpg

Главные герои статьи

F746G Discovery — это практически Ferrari в мире хобби-электроники. Мощный микроконтроллер (Cortex-M7, 216 МГц) тут сочетается с микросхемой SDRAM внушительных объемов (целых 8 Мбайт) и полезной периферией: экран 480 × 272 с 24-битным цветом, интерфейс SDIO для карт памяти, разъемы аудио и Ethernet.

Я не буду перечислять все доступные возможности этой платы — ты можешь найти подробности на сайте производителя STMicroelectronics. Все то, что раньше приходилось добавлять к Arduino с помощью дочерних плат расширения или модулей, тут доступно «из коробки». Да, цена соответствующая — порядка 6500 рублей. Но когда это спортивные автомобили были для простого народа?

F746G Discovery — не единственный вариант демоплаты для этого проекта. Ты можешь с таким же успехом использовать, например, отладочную плату из серии Nucleo: F767ZI Nucleo. Для нее тоже есть поддержка в пакете STM32duino, и она гораздо дешевле — около 3000 рублей. Такого разнообразия периферии у нее, правда, нет.
Полноценно нагрузить все компоненты и использовать возможности F746 Discovery на сто процентов в одном проекте непросто. Сегодня с помощью библиотеки bearSSL мы протестируем только вычислительную мощь ядра Cortex-M7 в прикладных задачах криптографии.

Программирование под STM32 предполагает внимательное изучение сопроводительной документации. Сегодня я постараюсь осветить все подробности и интересности, которые встретятся нам на пути, но в дальнейшем все же настоятельно рекомендую обратиться к следующим материалам (все ссылки — на PDF):
  • UM1907 — самая полная информация о плате Discovery: компоненты, схемы, назначение разъемов и прочее.
  • DS10916 — даташит на микроконтроллер. Полезен распиновкой микросхемы F746NG в различных корпусах.
  • RM0385 — говорят, на тех, кто осилит полностью все 1700+ страниц мануала, снисходит божественное просветление.

Настраиваем IDE

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

Изначально в Arduino IDE доступны только платы на AVR-микроконтроллерах, ни о каком ARM она и не слышала. Чтобы включить поддержку плат STM32duino, нужно перейти в раздел Arduino → Preferences и добавить дополнительную ссылку. После этого в «Менеджере плат» ты сможешь скачать все необходимые файлы пакета.

Во время установки опция с STM32duino может и не появиться в списке доступных для установки расширений. В этом случае проверь разрешения для Arduino IDE на работу по сети или добавь в список исключений для антивируса.


Ищем пропавший Serial

Если ты еще не проверил корректность работы компилятора и самой платы на парочке простых примеров из числа встроенных, то сейчас самое время. Потому что мы переходим к правке исходных файлов по адресу «Библиотеки → Arduino15 → packages → STM32 → hardware → stm32» (советую сделать копию папки, ты знаешь, как оно бывает). Все дело в том, что проект STM32duino поддерживается энтузиастами (хотя сейчас им заинтересовалась сама STMicroelectronics) и, как следствие, часть функций Arduino реализована, а часть почему-то оказалась забыта.

Например, по умолчанию отсутствует последовательный порт (Serial) на выводах D0 и D1 разъема Arduino. Если ты знаком с оригинальными итальянскими платами (и их многочисленными китайскими клонами), то знаешь, что этот порт связан с разъемом USB через UART — USB-преобразователь в основном используется для общения с компьютером и при перепрошивке флеш-памяти. На Discovery все несколько по-другому.

Микроконтроллер F746NGH6 прошивается с помощью встроенного программатора ST-Link/V2-1 (небольшая микросхема возле miniUSB-порта). Он же выступает в качестве преобразователя интерфейсов при отправке данных на ПК. Но все это делается по другому UART — вовсе не тому, который выведен на плате на разъем Arduino (да, у контроллеров ST богатая периферия, об этом следовало сказать заранее).

Если в прошлом ты использовал плату Arduino Leonardo, то можешь предположить, что для этого интерфейса используется объект Serial1. Но нет! В проекте STM32duino нумерация программных портов Serial соответствует номеру аппаратного периферийного блока UART, и поэтому в любом коде для нашей Discovery Serial и Serial1 — это один и тот же объект (используется переопределение).

Как тогда обращаться к UART на разъеме Arduino? Изучив таблицу 4 на странице 23 документации демоплаты, ты узнаешь, что это RX/TX-выводы UART6.

Впрочем, одного лишь этого знания будет недостаточно: компилятор сообщит, что Serial6 не определен. Чтобы добавить порт UART для работы с ESP8266, нужно отредактировать конфигурационные файлы самой платы — они располагаются по адресу stm32 → 1.4.0 → variants → DISCO_746NG. В самих файлах нет ни намека на возможное решение проблемы, но тщательное изучение исходников проекта STM32duino (папка cores на уровне с variants) должно навести на определенные идеи. На самом деле нам достаточно добавить несколько строчек в файл variants.h:
Код:
#define ENABLE_HWSERIAL6        1
#define PIN_SERIAL6_RX          PC7
#define PIN_SERIAL6_TX          PC6
Почему их нельзя было оставить в файле закомментированными, чтобы пользователи не тратили время на знакомство с нюансами реализации Arduino-окружения на платах от ST, — это для меня загадка. Однако теперь объект Serial6 станет доступен в нашем коде, и мы наконец сможем наладить взаимодействие с модулем Wi-Fi.

Следующие шаги опциональные, однако, если ты хочешь получить максимум быстродействия от связки F746 и ESP8266, советую их не пропускать. Тем более что после них с настройкой окружения будет наконец покончено.


Дополнительно

Нам нужно настроить размеры внутренних буферов класса HardwareSerial на прием и передачу информации по интерфейсу UART. По умолчанию размеры подобраны для плат Arduino с микроконтроллерами AVR, и это может стать проблемой при передаче больших массивов данных (как раз наш случай). В папке cores → arduino открой файл HardwareSerial.h и найди в нем такие строчки:
Код:
#define SERIAL_TX_BUFFER_SIZE    64
#define SERIAL_RX_BUFFER_SIZE    64
Это размер буферов в байтах. Исправь 64 на 512, разрядность переменной-индекса при этом будет скорректирована автоматически. Вообще говоря, размеры буферов не обязаны совпадать, и, если в твоем проекте памяти у микроконтроллера остается впритык, стоит увеличивать только буфер RX. Также обрати внимание, что эти изменения затронут все твои скетчи для плат STM32duino (но не для Arduino AVR или ARM).

Теперь осталось только ускорить UART. Изначально все модули ESP8266 со стандартной прошивкой для работы с АТ-командами настроены на скорость 115 200 бод. Если ты используешь программный порт SoftwareSerial, скорость рекомендуют уменьшить до 9600. В нашем случае, напротив, разумней проводить прием и передачу быстрее, контроллер справится, а время терять незачем. Подключи модуль Wi-Fi к плате и залей следующий скетч:
Код:
void setup() {
    Serial.begin(9600);
    Serial6.begin(115200);
}

void loop {
    if (Serial.available()) {
        Serial6.write(Serial.read());
    }
    if (Serial6.available() {
        Serial.write(Serial6.read());
    }
}
С помощью «Монитора порта» в Arduino IDE ты сможешь изменить настройки UART на ESP8266, используя плату Discovery в качестве ретранслятора (если у тебя есть отдельный преобразователь USB — UART, то все еще проще). Убедись, что конец строки в терминале — это NL & CR. Набери АТ-команду AT+UART_DEF=1000000,8,1,0,0. Это установит скорость работы в 1 Мбод, длину 8 бит и один стартовый бит вначале. Все, пора переходить к главному!


AT-команды

Порой бывает удобно проверить состояние модуля Wi-Fi через «Монитор порта» простыми AT-командами, не используя библиотечные функции. Вот самые полезные:
  • AT — базовая команда, если модуль не отвечает на нее, стоит проверить подключение или питание.
  • AT+CWLAP — показывает список доступных точек доступа.
  • AT+CIPSTATUS — состояние текущего подключения.
Остальные команды ты найдешь в документации.


SSL/TLS — самое необходимое

В этой статье я не буду подробно останавливаться на протоколах SSL/TLS по трем причинам. Первая: вполне вероятно, ты знаешь их лучше меня. Вторая: они доступно описаны в документах RFC (RFC5246 и RFC6101 для TLS 1.2 и SSL 3.0 соответственно). И третья — порог вхождения там невелик, и тебя вряд ли ждут большие затруднения.

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

В нашем примере мы попробуем получить у какого-нибудь сервера в интернете страничку по HTTPS с нашей демоплаты на STM32. Случай с простым HTTP-запросом особого интереса не представляет и хорошо освещен в интернете, как в русскоязычном, так и в англоязычном сегменте. TCP у нас уже есть (благодаря ESP8266 и рабочему Serial6), какого-то особо сложного приложения пока не предвидится, так что вся задача сводится к обеспечению корректной работы библиотеки. Осталось выбрать, какой именно.


Зоопарк диких зверей

Если ты до этого когда-нибудь интересовался доступными вариантами библиотек SSL/TLS, то не мог не слышать о проекте OpenSSL. Это весьма распространенное решение, но для встраиваемых систем, с их относительно скромными ресурсами, желательно найти библиотеку с хорошей портативностью и небольшим объемом итогового кода.

Зачастую для коммерческого использования разработчики выбирают wolfSSL — она предназначена специально для мобильных устройств. Это библиотека с открытым исходным кодом, лицензированным по GPL (есть и коммерческая лицензия), собственным сайтом, форумом и даже некоторой поддержкой со стороны авторов.

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

Поэтому, подробнее изучив альтернативы, я обратил внимание на библиотеку bearSSL. Это сравнительно молодой проект, который с 2016 года развивается и поддерживается усилиями одного программиста. При этом код очень прозрачно организован, хорошо прокомментирован как внутри самих исходных файлов, так и на сайте.

Может показаться, что документации меньше в сравнении c wolfSSL, но при этом ее достаточно, и она не отвлекает от главного. Исходный код также открыт, а условия лицензии даже мягче — это MIT, что в некоторых случаях может быть дополнительным аргументом.

И хотя автор говорит о статусе бета-версии, библиотека полноценно поддерживает стандарт TLS 1.2 (wolfSSL уже доступна с TLS 1.3, но официально RFC8446 был принят только в августе 2018-го).

Примечательно, что работа с этими библиотеками во многом очень схожа (и в итоге были реализованы две рабочие версии прошивки для платы), я остановил выбор на bearSSL.


Приручаем библиотеку

Для работы bearSSL требуется платформозависимая реализация трех вещей: текущего времени, пула случайных чисел и базовых функций ввода-вывода. Их придется написать самостоятельно, но это не займет много времени. Наш код будет взаимодействовать с периферией платы и микроконтроллера, поэтому тут как нельзя кстати пригодятся ссылки, которые я давал в начале статьи.


Дата и время

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

Библиотека bearSSL зависит от стандартной функции _gettimeofday(). Если ты попытаешься скомпилировать проект сейчас, то компоновщик сообщит, что этот символ не определен. Оно и понятно: сразу после подачи питания на микроконтроллер нет какого-то общего способа узнать текущее системное время (тем более в отсутствие ОС). Но у нас есть модуль Wi-Fi, поэтому предлагаю воспользоваться им и сделать запрос к серверу точного времени.
Код:
#include "ESP8266.h" 
#define PORT           (123)
#define BUFFER_SIZE    (48)
#define TIME1970       ((uint32_t)2208988800) /* seconds between 1900 — 1970 */

extern ESP8266 *wifi; /* should be defined in main */

int _gettimeofday(struct timeval *tv, void *tzvp ) {
    /* prepare message */
    uint8_t buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);
    buffer[0] = 0xE3;
    buffer[2] = 0x06;
    buffer[3] = 0xEC;
    buffer[12] = 0x31;
    buffer[13] = 0x4E;
    buffer[14] = 0x31;
    buffer[15] = 0x34;

    /* connect to server */
    wifi -> registerUDP(«time.nist.gov», PORT);
    wifi -> send(buffer, BUFFER_SIZE);
    wifi -> recv(buffer, BUFFER_SIZE, 1000);
    wifi -> unregisterUDP();

    /* calculate the result */
    uint32_t epoch = buffer[40] << 24 | buffer[41] << 16 | buffer[42] << 8 | buffer[43];
    epoch -= TIME1970;

    tv -> tv_sec = epoch;
    tv -> tv_usec = 0; /* do not need this */
    return 0;
}
К слову, ты можешь задавать время либо в процессе компиляции (даже приблизительно), либо воспользовавшись модулем RTC. На результатах проверки срока действия сертификата это сказаться не должно.


Аппаратный ГСЧ

Традиционный подход к генерации случайных чисел в среде Arduino выглядит примерно так:
Код:
int i = analogRead(A0); /* A0 is NOT connected */
srand(i);
int num = rand();
Такой программный метод имеет право на жизнь в простых ситуациях, но для криптографического применения он решительно не подходит. К счастью, у микроконтроллера F746NG богатая периферия и есть ГСЧ (TRNG, True Random Number Generator). Им мы и воспользуемся, предварительно заглянув в документацию (RM0385, с. 543). Там всего-то три регистра, которые отвечают за взаимодействие с аппаратной частью, — RNG_CR (Control Register), RNG_SR (Status Register) и RNG_DR (Data Register).
Код:
#include <stm32f746xx.h> /* for CMSIS defines */

void rng_enable() {
    if (RNG -> CR & RNG_CR_RNGEN) {
        return; /* already enabled */
    }
    RCC -> AHB2ENR |= RCC_AHB2ENR_RNGEN; /* clock enable */
    RCC -> CR |= RNG_CR_RNGEN; /* rng on */
}

uint32_t rng_generate() {
    if (RNG -> SR & (RNG_SR_CECS | RNG_SR_SECS)) {
        return 0; /* seed error or clock error */
    }
    while (!(RNG -> SR & RNG_SR_DRDY)) {
        /* wait for data to appear */
    }
    return RNG -> DR;
}
Без знакомства с документацией такой код может быть сложен для восприятия, но зато это эффективно и, так как мы работаем максимально близко к железу (для языка С, разумеется), требует минимум машинных инструкций (в отличие от библиотек HAL, Hardware Abstraction Layer). Конечно, настройка остальной периферии занимает чуть больше времени и места, но принцип остается тем же. Так что со временем изучение CMSIS обязательно окупит себя.


Функции ввода-вывода

BearSSL внутри состоит из трех глобальных объектов: движок, контекст клиента (или сервера) и контекст проверки сертификатов. Это платформонезависимые вещи, и для связи с внешним миром им нужны всего две базовые функции на прием и передачу, которые необходимо зарегистрировать в библиотеке для обратного вызова. Это ключевая часть пользовательского кода, поэтому есть смысл потратить время и изучить ее подробнее.
Код:
#include "bearssl.h"
#include "ESP8266.h"

#define INPUT_SIZE       (0x2000) /* 8 KiB should be enough */

static uint8_t input[INPUT_SIZE];

/* bearSSL local objects */
static br_ssl_client_context sc;
static br_x509_minimal_context xc;
static br_sslio_context ioc;

/* TCP/SSL driver variables  */
static uint_fast16_t rx_bytes = 0; /* number of received bytes */
static uint_fast16_t p = 0; /* input buffer index */

extern ESP8266 *wifi; /* should be defined in main */

static int wifi_recv(void *ctx, unsigned char *b, size_t len) {
    uint_fast16_t rq_bytes = len; /* bearSSL requested some bytes */
    while (rx_bytes - p < rq_bytes) { /* have to fullfill request */
        while (int rec_len = wifi -> recv(input + rx_bytes, INPUT_SIZE - rx_bytes, 100)) {
            rx_bytes += rec_len; /* received bytes */
        }
    }
    while (rq_bytes-- > 0) {
        *(b++) = input[p++]; /* handle all bytes to bearSSL */
    }
    return len; /* request completed, report success*/
}

static int wifi_send(void *ctx, const unsigned char *b, size_t len) {
    rx_bytes = p = 0; /* flush input buffer */
    return wifi -> send((uint8_t*) b, len) ? len : 0; /* if not success, report to be called again */
}
Обрати внимание на размер буфера и его расположение. Протокол SSL/TLS предусматривает длину сообщений до 16 Кбайт. На практике ты вряд ли встретишь настолько большие сообщения, поэтому 8 Кбайт выглядят разумным компромиссом. Кроме того, буфер размещен во внутренней SRAM микроконтроллера. Так как буферов у нас будет больше одного, возможно, это не самое удачное место.

В самом начале я говорил о внешней микросхеме SDRAM, которая имеет гораздо больший объем (8 Мбайт против 320 Кбайт) при сравнительно одинаковой скорости и времени доступа. После инициализации FMC и банков памяти это пространство будет доступно для программы, и, скорее всего, это более подходящее место. Однако это увело бы нас чуть в сторону от основной темы статьи.

Основное место в коде занимают методы recv() и send() класса ESP8266. Именно для использования готовой библиотеки пришлось искать пропавший Serial6 в исходниках STM32duino. Зато, уже имея на руках отлаженный код, сравнительно просто организовать учет данных, принятых и переданных bearSSL.

Здесь есть нюанс: иногда метод recv() не находит доступного сегмента и возвращает ноль, хотя прием еще не был завершен. К счастью, библиотека bearSSL лучше знает, сколько байтов должно поступить (для этого в заголовке каждого сообщения SSL/TLS есть поле с количеством байтов в теле), поэтому доверяемся ей и не выходим из внешнего цикла whileдо окончания передачи.


Подключаемся к API

Теперь, когда все готово, надо протестировать наш код на чем-то интересном. Вообще, потребность подключения и настройки библиотеки bearSSL под STM32 лично у меня возникла, когда я захотел парсить данные с рынка в одной популярной многопользовательской игре и выводить их на дополнительный дисплей. Уверен, у тебя уже есть свои мысли, как с пользой применить полученные знания, поэтому буду краток и просто покажу как пример.

board.jpg

Доска объявлений в Final Fantasy X|V

Самый простой способ получить актуальные рыночные цены для FFX|V — это посылать запросы на сторонний сервис, который предоставляет API, он называется XIVAPI. Но сам сервер ограничивает число запросов за секунду, и, чтобы вести подсчет, требуется вместе с запросом посылать уникальный ключ клиента или приложения (стандартно). Именно чтобы сохранять ключ в секрете и не позволить третьей стороне использовать сервис от нашего лица, запрос следует посылать по HTTPS-протоколу с шифрованием SSL/TLS.
Код:
#include "ESP8266.h"
#define PORT              (443)
#define BR_IN_SIZE        (0x2000)
#define BR_OUT_SIZE       (0x2000)
#define BUFFER_SIZE       (0x2000)
#define ENTROPY_SIZE      (8) /* total 256-bits of random from hardware RNG */

const char *ap_name = "wifi_name"; /* user defined */
const char *ap_pswd = "wifi_pswd"; /* user defined */
const char *host = "www.xivapi.com";
const char *path = "/market/cerberus/items/18189/history?key=XXXXXXXXXXXX"; /* user defined */

ESP8266 *wifi;

static uint8_t iobuf_in[BR_IN_SIZE];
static uint8_t iobuf_out[BR_OUT_SIZE];
static uint8_t buffer[BUFFER_SIZE]

void setup() {
    uint32_t entropy_pool[ENTROPY_SIZE];

    Serial.begin();
    Serial.println();
    wifi = new ESP8266(Serial6, 1000000);
    wif -> joinAP(ap_name, ap_pswd);

    br_ssl_client_init_full(&sc, &xc, TAs, TAs_NUM); /* user defined trust anchors */
    br_ssl_engine_set_buffers_bidi(&sc.eng, iobuf_in, sizeof(iobuf_in),
                                                                       iobuf_out, sizeof(iobuf_out));

    rng_enable();
    for (uint_fast8_t i = 0; i < ENTROPY_SIZE; ++i) {
        entropy_pool[i] = rng_generate();
    }
    br_ssl_engine_inject_entropy(&sc.eng, entropy_pool, sizeof(entropy_pool));
    br_sslio_init(&ioc, &sc.eng, wifi_recv, wifi, wifi_send, wifi);
}

void loop() {
    wifi -> createTCP(host, PORT);

    /* send request */
    br_ssl_client_reset(&sc, host, 0);
    br_sslio_write_all(&ioc, "GET ", 4);
    br_sslio_write_all(&ioc, path, strlen(path));
    br_sslio_write_all(&ioc, " HTTP/1.1\r\nHost: ", 17);
    br_sslio_write_all(&ioc, host, strlen(host));
    br_sslio_write_all(&ioc, "\r\n\r\n", 4);
    br_sslio_flush(&ioc);

    /* receive answer */
    for (uint_fast16_t count = 0, len = 0;; count += len) {
        len = br_sslio_read(&ioc, buffer + count, BUFFER_SIZE - count);
        if (len < 10) { /* last record */
            buffer[count] = '\0';
            break;
        }
    }
    br_sslio_flush(&ioc);

    wifi -> releaseTCP();

    Serial.println((char*)buffer);
    delay(10000);
}
Если ты запустишь этот код (и если Хаканубис услышит твои молитвы), то в «Мониторе порта» увидишь стандартный ответ сервера HTTP и полезную нагрузку — JSON с ценами на сервере Cerberus для предмета с ID 18189 (к слову, это High Steel Longsword).

output.jpg


Распарсить объект и получить любую интересующую информацию теперь легко с помощью библиотеки rapidjson. Я обрабатываю данные сразу на микроконтроллере и вывожу на дисплей с помощью периферийного модуля LTDC. Это и близко не исчерпывает возможности микросхемы F746NG, поэтому лично для меня впереди еще много работы по этому проекту.

third.jpg

Конкурентное преимущество на рынке выглядит как-то так. Интересно, за это банят?


Заключение

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

К сожалению, я не смог в объеме статьи уместить полноценную обработку ошибок или вывод отладочной информации (попробуй ради любопытства выводить тело сообщений SSL/TLS и сравни их с описанием в RFC). Но возможно, это и к лучшему. У тебя есть стимул дополнить и самостоятельно улучшить код, как тебе будет нужно.

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

Еще один важный аспект производительности — это время, которое приходится потратить на обработку запроса. Сейчас первое подключение к сервису и рукопожатие занимают от 4 до 6 секунд, последующие сообщения от 2 до 2,5 секунды (когда параметры сессии уже в кеше). Это не так уж плохо, все-таки криптография требует приличного количества ресурсов, да и запрос у нас с реальной полезной нагрузкой, а не просто HTTP/1.0 200 OK.

На самом деле в линейке F7 от STMicroelectronics уже есть микросхемы с аппаратными блоками HASH и CRYP. По тестам, это позволяет сократить время некоторых вычислений от двух до четырех раз! К сожалению, на F746NG эта периферия недоступна, да и bearSSL их пока не поддерживает.

Вместе с дополнительными библиотеками (для JSON и GUI) код занимает всего 186 Кбайт ПЗУ (ROM) и 45 Кбайт ОЗУ (RAM). При этом около 40% уходит на графический интерфейс и шрифты для экрана. Если использовать внешнее хранилище в виде QSPI flash или карты microSD, то расход по памяти можно еще сократить. Напомню, у микроконтроллера целый мегабайт ПЗУ и 320 Кбайт ОЗУ, так что реализовать можно еще много интересного. Дерзай!


(c) faberge
 
Немного оффтоп: Есть хоть крупицы о дампинге STM прошивок? Хитрожопые ребятки срезают 2 пятака на чипе и стандартно в случае попытки слива - затирается область. Не хотелось бы 5к$ терять и очень нужна любая инфа о данном направлении. Знаю одно - китайцы делают за 1000-6000$ и есть очень мало о "по секторному проходу" на hackday (не реклама), но там дампили старую ревизию.
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх