<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://wiki.me-robotics.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%90%D0%BD%D0%B4%D1%80%D0%B5%D0%B9</id>
	<title>me-robotics wiki - Вклад участника [ru]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.me-robotics.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%90%D0%BD%D0%B4%D1%80%D0%B5%D0%B9"/>
	<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/%D0%90%D0%BD%D0%B4%D1%80%D0%B5%D0%B9"/>
	<updated>2026-07-10T20:08:47Z</updated>
	<subtitle>Вклад участника</subtitle>
	<generator>MediaWiki 1.35.2</generator>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1407</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1407"/>
		<updated>2023-03-03T11:39:58Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим глобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
Размер массива для вектора инициализации можно задать с помощью макросов:&lt;br /&gt;
&lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CBC&lt;br /&gt;
* IV_LENGTH_MAGMA_CBC    &lt;br /&gt;
* IV_LENGTH_AES_CBC      &lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CTR&lt;br /&gt;
* IV_LENGTH_MAGMA_CTR    &lt;br /&gt;
* IV_LENGTH_AES_CTR      &lt;br /&gt;
&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                        0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                        0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                        0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length);     &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_decode для расшифровки&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CBC_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CBC_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. CBC.png|мини|Вывод в UART. CBC]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;br /&gt;
Количество слов в данных может быть любым.  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CTR_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                        0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                        0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                        0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция kuznechik_CTR_decode &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CTR_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CTR_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CTR_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CTR_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. CTR.png|мини|Вывод в UART. CTR]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D0%B2_UART._CTR.png&amp;diff=1406</id>
		<title>Файл:Вывод в UART. CTR.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D0%B2_UART._CTR.png&amp;diff=1406"/>
		<updated>2023-03-03T11:32:20Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Вывод в UART. CTR&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1405</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1405"/>
		<updated>2023-03-03T11:27:48Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим глобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
Размер массива для вектора инициализации можно задать с помощью макросов:&lt;br /&gt;
&lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CBC&lt;br /&gt;
* IV_LENGTH_MAGMA_CBC    &lt;br /&gt;
* IV_LENGTH_AES_CBC      &lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CTR&lt;br /&gt;
* IV_LENGTH_MAGMA_CTR    &lt;br /&gt;
* IV_LENGTH_AES_CTR      &lt;br /&gt;
&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                        0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                        0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                        0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length);     &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_decode для расшифровки&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CBC_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CBC_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. CBC.png|мини|Вывод в UART. CBC]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;br /&gt;
Количество слов в данных может быть любым.  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CTR_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                        0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                        0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                        0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция kuznechik_CTR_decode &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CTR_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CTR_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CTR_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CTR_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1404</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1404"/>
		<updated>2023-03-03T11:25:55Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим глобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
Размер массива для вектора инициализации можно задать с помощью макросов:&lt;br /&gt;
&lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CBC&lt;br /&gt;
* IV_LENGTH_MAGMA_CBC    &lt;br /&gt;
* IV_LENGTH_AES_CBC      &lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CTR&lt;br /&gt;
* IV_LENGTH_MAGMA_CTR    &lt;br /&gt;
* IV_LENGTH_AES_CTR      &lt;br /&gt;
&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                        0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                        0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                        0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length);     &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_decode для расшифровки&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CBC_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CBC_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. CBC.png|мини|Вывод в UART. CBC]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;br /&gt;
Количество слов в данных может быть любым.  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CTR_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                        0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                        0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                        0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция kuznechik_CTR_decode &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CTR_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CTR_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CTR_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CTR_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1403</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1403"/>
		<updated>2023-03-03T11:23:58Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим глобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
Размер массива для вектора инициализации можно задать с помощью макросов:&lt;br /&gt;
&lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CBC&lt;br /&gt;
* IV_LENGTH_MAGMA_CBC    &lt;br /&gt;
* IV_LENGTH_AES_CBC      &lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CTR&lt;br /&gt;
* IV_LENGTH_MAGMA_CTR    &lt;br /&gt;
* IV_LENGTH_AES_CTR      &lt;br /&gt;
&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                        0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                        0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                        0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length);     &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_decode для расшифровки&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CBC_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CBC_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. CBC.png|мини|Вывод в UART. CBC]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;br /&gt;
Количество слов в данных может быть любым.  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CTR_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CTR_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CTR] = {0x12341235, 0x5BCDABCD};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0xf12504ea, 0x08bf9cd4, 0x2c1daede, 0x98792153, &lt;br /&gt;
                                        0x2b92cfc8, 0xca2e1091, 0x2bf5d2b7, 0xe2179b86,&lt;br /&gt;
                                        0xab37ec96, 0x918795fe, 0xe6c2e8fa, 0xc2773e7b,&lt;br /&gt;
                                        0x74d3290d, 0xcd9aaf15&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CTR);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция kuznechik_CTR_decode &lt;br /&gt;
Функция main&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1402</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1402"/>
		<updated>2023-03-03T10:14:55Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим глобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
Размер массива для вектора инициализации можно задать с помощью макросов:&lt;br /&gt;
&lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CBC&lt;br /&gt;
* IV_LENGTH_MAGMA_CBC    &lt;br /&gt;
* IV_LENGTH_AES_CBC      &lt;br /&gt;
* IV_LENGTH_KUZNECHIK_CTR&lt;br /&gt;
* IV_LENGTH_MAGMA_CTR    &lt;br /&gt;
* IV_LENGTH_AES_CTR      &lt;br /&gt;
&lt;br /&gt;
Количество слов в данных для зашифровки должно быть кратно размеру блока (для кузнечика 4 слова или 128 бит).  Если данных меньше, то их нужно дополнить вручную.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                        0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                        0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                        0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length);     &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_CBC_decode для расшифровки&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_CBC_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t init_vector[IV_LENGTH_KUZNECHIK_CBC] = {0x12341234, 0x11114444, 0xABCDABCD, 0xAAAABBBB};&lt;br /&gt;
    &lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x50796e7f, 0x4094ce10, 0xbab7374c, 0x981047e3, &lt;br /&gt;
                                0x1ee4f83b, 0x334948ed, 0x86a0873c, 0x86bff9a2, &lt;br /&gt;
                                0xa084f5fa, 0x965481e4, 0xb64be9bd, 0x32ef21e3, &lt;br /&gt;
                                0xa6e376cf, 0x95e8a097, 0x9a46ba33, 0x152b1843&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_CBC);&lt;br /&gt;
    /* Установка вектора инициализации */  &lt;br /&gt;
    HAL_Crypto_SetIV(&amp;amp;hcrypto, init_vector, sizeof(init_vector)/sizeof(*init_vector)); &lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_CBC_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_CBC_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_CBC_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. CBC.png|мини|Вывод в UART. CBC]]&lt;br /&gt;
Если у вас включен UART или подключен common.h, или объявлен #define MIK32_CRYPTO_DEBUG, то можно посмотреть вывод xprintf. Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D0%B2_UART._CBC.png&amp;diff=1401</id>
		<title>Файл:Вывод в UART. CBC.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D0%B2_UART._CBC.png&amp;diff=1401"/>
		<updated>2023-03-03T10:11:25Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Вывод в UART. CBC&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1400</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1400"/>
		<updated>2023-03-03T08:27:36Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадимглобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Функция main&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1399</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1399"/>
		<updated>2023-03-03T08:26:39Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадимглобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Внутри  kuznechik_ECB_code сначала задается режим шифрования функцией HAL_Crypto_SetCipherMode (Если другие режимы использовать не планируется, то этого можно не делать так как этот режим шифрования уже задан после инициализации функцией Crypto_Init), затем устанавливается мастер-ключ функцией HAL_Crypto_SetKey. Так как ключ должен быть инициализирован в режиме шифрования, то после функции HAL_Crypto_SetKey блок находится в режиме зашифровки данных. После этого используется функция HAL_Crypto_Encode для зашифровки данных. &lt;br /&gt;
&lt;br /&gt;
В конце поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* plain_text - полученные расшифрованные данные;&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1398</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1398"/>
		<updated>2023-03-03T08:16:01Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадимглобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
* plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1397</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1397"/>
		<updated>2023-03-03T08:15:21Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадимглобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать значение счетчика состоящего из синхропосылки, длинна которой равна половине длине блока, и такого же количества нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
* expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
* plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1396</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1396"/>
		<updated>2023-03-03T08:13:28Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадимглобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка (вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR в регистр INIT следует записывать синхропосылку, длинна которой равна половине длине блока, и такое же количество нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
* expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
* plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1395</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1395"/>
		<updated>2023-03-03T08:09:46Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадимглобальный массив для ключа. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка(вектор инициализации), в соответствии с ГОСТ 34.13—2015, для разных режимов может иметь разную длину, : &lt;br /&gt;
&lt;br /&gt;
*В режиме ECB синхропосылка не используется;&lt;br /&gt;
*В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число. Поддерживается только случай z=1, m=n, где n - длина блока (4 слова для Кузнечика и AES, 2 слова для Магмы);&lt;br /&gt;
*В режиме CTR длинна синхропосылки равна половине длинны блока и такое же количество нулей. В итоге размер синхропосылки будет равен размеру блока.&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены (Electronic Codebook, ЕСВ)===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
* expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                    0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                    0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                    0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                             }; &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Зашифровать данные */&lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == plain_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
* plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] =     {            &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0, &lt;br /&gt;
                                    0x0, 0x0, 0x0, 0x0&lt;br /&gt;
                                };&lt;br /&gt;
    &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             }; &lt;br /&gt;
    &lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
    uint32_t key_length = sizeof(crypto_key)/sizeof(*crypto_key);&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Задать режим шифрования */&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /* Расшифровать данные */&lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; key_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if(expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;error\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((i+1) == cipher_text_length)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;Successfull\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
===Режим гаммирования (Counter, CTR)===&lt;br /&gt;
&lt;br /&gt;
===Режим простой замены с зацеплением (Cipher Block Chaining, СВС)===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1394</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1394"/>
		<updated>2023-02-27T13:05:42Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main после функции инициализации Crypto_Init запишем ключ в регистр KEY с помощью функции HAL_Crypto_SetKey.&lt;br /&gt;
&lt;br /&gt;
Для режимов шифрования ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка(вектор инициализации) для разных режимов может иметь разную длину: &lt;br /&gt;
&lt;br /&gt;
* В режиме ECB синхропосылка не используется;&lt;br /&gt;
* В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число;&lt;br /&gt;
* В режиме CTR длинна синхропосылки равна половине длинны блока.&lt;br /&gt;
&lt;br /&gt;
=== Режим простой замены (Electronic Codebook, ЕСВ) ===&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[plain_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
*plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
                &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text[cipher_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);     /* Настройка режима шифрования */ &lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
=== Режим гаммирования (Counter, CTR) ===&lt;br /&gt;
&lt;br /&gt;
=== Режим простой замены с зацеплением (Cipher Block Chaining, СВС) ===&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1393</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1393"/>
		<updated>2023-02-27T10:56:25Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main после функции инициализации Crypto_Init запишем ключ в регистр KEY с помощью функции HAL_Crypto_SetKey.&lt;br /&gt;
&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[plain_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
*plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
                &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text[cipher_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);     /* Настройка режима шифрования */ &lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
Для режимов ECB и CBC длина данных должна быть кратна длине блока. Иначе данные следует дополнить.&lt;br /&gt;
&lt;br /&gt;
Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка(вектор инициализации) для разных режимов может иметь разную длину: &lt;br /&gt;
&lt;br /&gt;
* В режиме ECB синхропосылка не используется; &lt;br /&gt;
* В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число;&lt;br /&gt;
* В режиме CTR длинна синхропосылки равна половине длинны блока.&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1392</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1392"/>
		<updated>2023-02-27T10:55:29Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main после функции инициализации Crypto_Init запишем ключ в регистр KEY с помощью функции HAL_Crypto_SetKey.&lt;br /&gt;
&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
*plain_text - незашифрованные данные;&lt;br /&gt;
*expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
*cipher_text - полученные зашифрованные данные.&lt;br /&gt;
Количество слов в данных должно быть кратно 4 (блок - 128 бит).  Если данных меньше, то их нужно дополнить вручную. ГОСТ 34.13—2015 определяет три возможные процедуры дополнения. Можно, например, дополнить остаток нулями до размера блока.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[plain_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
*cipher_text - зашифрованные данные;&lt;br /&gt;
*expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
*plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
                &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text[cipher_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);     /* Настройка режима шифрования */ &lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;br /&gt;
&lt;br /&gt;
Функции для режимов CBC и CTR аналогичны, но содержат другие данные в массивах.&lt;br /&gt;
&lt;br /&gt;
Отличие этих режимов в том, что они перед каждой новой расшифровкой или зашифровкой требуют записи вектора инициализации с помощью функции HAL_Crypto_SetINIT. &lt;br /&gt;
&lt;br /&gt;
Для режимов ECB и CBC длина данных должна быть кратна длине блока. Для режима CTR длинна данных может быть любой. В этом режиме дополнения не требуются.&lt;br /&gt;
&lt;br /&gt;
Синхропосылка(вектор инициализации) для разных режимов может иметь разную длину: &lt;br /&gt;
&lt;br /&gt;
В режиме ECB синхропосылка не используется; &lt;br /&gt;
&lt;br /&gt;
В режиме CBC синхропосылка должна быть длинной m*z, где m - длина блока (128 бит для алгоритма Кузнечик), z - целое число;&lt;br /&gt;
&lt;br /&gt;
В режиме CTR длинна синхропосылки равна половине длинны блока.&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1391</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1391"/>
		<updated>2023-02-27T08:32:46Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик) и IV_LENGTH_KUZNECHIK (количество слов в векторе инициализации).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH_KUZNECHIK] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main после функции инициализации Crypto_Init запишем ключ в регистр KEY с помощью функции HAL_Crypto_SetKey.&lt;br /&gt;
&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_ECB_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
* plain_text - незашифрованные данные;&lt;br /&gt;
* expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
* cipher_text - полученные зашифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[plain_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция kuznechik_ECB_decode аналогична, но в ней используются другие массивы:&lt;br /&gt;
&lt;br /&gt;
* cipher_text - зашифрованные данные;&lt;br /&gt;
* expect_plain_text - расшифрованные данные, которые ожидается получить;&lt;br /&gt;
* plain_text - полученные расшифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Для расшифровки данных используется функция HAL_Crypto_Decode&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_decode&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_decode()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t expect_plain_text[] =  {            &lt;br /&gt;
                                        0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                        0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                        0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                        0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
                &lt;br /&gt;
    uint32_t cipher_text[] = {  &lt;br /&gt;
                                0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                             };&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text_length = sizeof(cipher_text)/sizeof(*cipher_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text[cipher_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Decode(&amp;amp;hcrypto, cipher_text, plain_text, cipher_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; cipher_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_plain_text[i] != plain_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main перед вызовом kuznechik_ECB_code для наглядности можно добавить функцию HAL_Crypto_SetCipherMode для активации нужного режима шифрования. Но этого можно не делать так как режим шифрования уже задан в Crypto_Init.&lt;br /&gt;
&lt;br /&gt;
Функция main&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    Crypto_Init();&lt;br /&gt;
&lt;br /&gt;
    /* Установка ключа */&lt;br /&gt;
    HAL_Crypto_SetKey(&amp;amp;hcrypto, crypto_key);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_code\n&amp;quot;);&lt;br /&gt;
    HAL_Crypto_SetCipherMode(&amp;amp;hcrypto, CRYPTO_CIPHER_MODE_ECB);     /* Настройка режима шифрования */ &lt;br /&gt;
    kuznechik_ECB_code();&lt;br /&gt;
    xprintf(&amp;quot;\nkuznechik_ECB_decode\n&amp;quot;);   &lt;br /&gt;
    kuznechik_ECB_decode();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:Вывод в UART. Режим ECB.png|мини|Вывод в UART]]&lt;br /&gt;
Вывод в UART изображен на рисунке.&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D0%B2_UART._%D0%A0%D0%B5%D0%B6%D0%B8%D0%BC_ECB.png&amp;diff=1390</id>
		<title>Файл:Вывод в UART. Режим ECB.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D0%B2_UART._%D0%A0%D0%B5%D0%B6%D0%B8%D0%BC_ECB.png&amp;diff=1390"/>
		<updated>2023-02-27T08:32:22Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Вывод в UART. Режим ECB&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1389</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1389"/>
		<updated>2023-02-27T08:17:12Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик) и IV_LENGTH_KUZNECHIK (количество слов в векторе инициализации).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH_KUZNECHIK] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;В функции main после функции инициализации Crypto_Init запишем ключ в регистр KEY с помощью функции HAL_Crypto_SetKey.&lt;br /&gt;
&lt;br /&gt;
Теперь напишем функции для зашифровки и расшифровки данных в режиме шифрования ECB - kuznechik_ECB_code и kuznechik_CTR_decode соответственно. &lt;br /&gt;
&lt;br /&gt;
В функции kuznechik_ECB_code будет три массива данных:&lt;br /&gt;
&lt;br /&gt;
* plain_text - незашифрованные данные;&lt;br /&gt;
* expect_cipher_text - зашифрованные данные, которые ожидается получить;&lt;br /&gt;
* cipher_text - полученные зашифрованные данные.&lt;br /&gt;
&lt;br /&gt;
Кроме этого нам понадобится функция HAL_Crypto_Encode для зашифровки данных. После этого поочередно выведем каждый из массивов в UART. После этого проведем сравнение полученных данных и ожидаемых.&lt;br /&gt;
&lt;br /&gt;
Функция kuznechik_ECB_code&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void kuznechik_ECB_code()&lt;br /&gt;
{&lt;br /&gt;
    uint32_t plain_text[] = {            &lt;br /&gt;
                                0x11223344, 0x55667700, 0xffeeddcc, 0xbbaa9988,&lt;br /&gt;
                                0x00112233, 0x44556677, 0x8899aabb, 0xcceeff0a,&lt;br /&gt;
                                0x11223344, 0x55667788, 0x99aabbcc, 0xeeff0a00,&lt;br /&gt;
                                0x22334455, 0x66778899, 0xaabbccee, 0xff0a0011&lt;br /&gt;
                            };&lt;br /&gt;
&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
    uint32_t expect_cipher_text[] = {&lt;br /&gt;
                                        0x7f679d90, 0xbebc2430, 0x5a468d42, 0xb9d4edcd, &lt;br /&gt;
                                        0xb429912c, 0x6e0032f9, 0x285452d7, 0x6718d08b, &lt;br /&gt;
                                        0xf0ca3354, 0x9d247cee, 0xf3f5a531, 0x3bd4b157, &lt;br /&gt;
                                        0xd0b09ccd, 0xe830b9eb, 0x3a02c4c5, 0xaa8ada98&lt;br /&gt;
                                    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    uint32_t plain_text_length = sizeof(plain_text)/sizeof(*plain_text);&lt;br /&gt;
&lt;br /&gt;
    uint32_t cipher_text[plain_text_length];&lt;br /&gt;
    &lt;br /&gt;
    HAL_Crypto_Encode(&amp;amp;hcrypto, plain_text, cipher_text, plain_text_length); &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;KEY &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; CRYPTO_KEY_KUZNECHIK; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x &amp;quot;, crypto_key[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);  &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;plain: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, plain_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);   &lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;cipher: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    xprintf(&amp;quot;expect: &amp;quot;);&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;0x%08x, &amp;quot;, expect_cipher_text[i]);&lt;br /&gt;
    }&lt;br /&gt;
    xprintf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    uint8_t error = 0;&lt;br /&gt;
    for (uint32_t i = 0; i &amp;lt; plain_text_length; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (expect_cipher_text[i] != cipher_text[i])&lt;br /&gt;
        {&lt;br /&gt;
            error = 1;&lt;br /&gt;
        }  &lt;br /&gt;
    }&lt;br /&gt;
    if (error)&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Error\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        xprintf(&amp;quot;Matched\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1388</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1388"/>
		<updated>2023-02-22T12:28:27Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик) и IV_LENGTH_KUZNECHIK (количество слов в векторе инициализации).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH_KUZNECHIK] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1387</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1387"/>
		<updated>2023-02-22T12:27:50Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init. Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик) и IV_LENGTH_KUZNECHIK (количество слов в векторе инициализации).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH_KUZNECHIK] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1386</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1386"/>
		<updated>2023-02-22T12:26:02Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init. Создадим два глобальных массива для ключа и вектора инициализации. Количество элементов массива можно задать с помощью макросов CRYPTO_KEY_KUZNECHIK (количество слов в ключе для алгоритма кузнечик) и  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH_KUZNECHIK] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1385</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1385"/>
		<updated>2023-02-22T11:27:19Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Создадим два глобальных массива для ключа и вектора инициализации. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1384</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1384"/>
		<updated>2023-02-22T11:26:53Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Создадим два глобальных массива для ключа и вектора инициализации. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t crypto_key[CRYPTO_KEY_KUZNECHIK] = {0x8899aabb, 0xccddeeff, 0x00112233, 0x44556677, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef};&lt;br /&gt;
uint32_t init_vector[IV_LENGTH] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1383</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1383"/>
		<updated>2023-02-22T11:23:27Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для крипто-блока, которую использует функция инициализации Crypto_Init.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
Crypto_HandleTypeDef hcrypto;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void Crypto_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Данные для преобразования ЦАП задаются с помощью функции HAL_DAC_SetValue.&lt;br /&gt;
&lt;br /&gt;
Сделаем циклическую смену напряжения от 0В до 1.2В на выводе DAC1 - Port1.12 с шагом 0.24В.&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1382</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1382"/>
		<updated>2023-02-22T11:21:51Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAHB присутствует PM_CLOCK_CRYPTO_M. Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT | PM_CLOCK_CRYPTO_M;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1381</id>
		<title>Шифрование и расшифровка данных</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A8%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=1381"/>
		<updated>2023-02-22T11:20:04Z</updated>

		<summary type="html">&lt;p&gt;Андрей: Новая страница: «В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс б...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет зашифрованы и расшифрованы данные алгоритмом кузнечик. Данный процесс будет рассмотрен с различными режимами шифрования. Шифрования для алгоритмов «Магма» и AES128 полностью аналогичны, за исключением разрядности обрабатываемых данных.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как крипто-блок тактируется от шины AHB_CLK, то зададим делитель AHB_DIV. В данном примере оставим делитель по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого крипто-блока. Для этого откроем вкладку крипто-блок и нажмем включить. После этого появятся несколько настроек. &lt;br /&gt;
[[Файл:Настройки крипто-блока в конфигураторе.png|мини|Настройки крипто-блока в конфигураторе]]&lt;br /&gt;
Зададим им следующие значения:&lt;br /&gt;
&lt;br /&gt;
* Алгоритм шифрования - Кузнечик;&lt;br /&gt;
* Режим шифрования - ECB;&lt;br /&gt;
* В перестановке слова - нет перестановки;&lt;br /&gt;
* Порядок загрузки/выгрузки - От старшего слова к младшему.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке. &lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция Crypto_Init, в которой будут заданы настройки для крипто-блока. Выглядит она так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void Crypto_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hcrypto.Instance = CRYPTO;&lt;br /&gt;
&lt;br /&gt;
    hcrypto.Algorithm = CRYPTO_ALG_KUZNECHIK;&lt;br /&gt;
    hcrypto.CipherMode = CRYPTO_CIPHER_MODE_ECB;&lt;br /&gt;
    hcrypto.SwapMode = CRYPTO_SWAP_MODE_NONE; &lt;br /&gt;
    hcrypto.OrderMode = CRYPTO_ORDER_MODE_MSW;&lt;br /&gt;
&lt;br /&gt;
    HAL_Crypto_Init(&amp;amp;hcrypto);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8_%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE-%D0%B1%D0%BB%D0%BE%D0%BA%D0%B0_%D0%B2_%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B5.png&amp;diff=1380</id>
		<title>Файл:Настройки крипто-блока в конфигураторе.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8_%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE-%D0%B1%D0%BB%D0%BE%D0%BA%D0%B0_%D0%B2_%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B5.png&amp;diff=1380"/>
		<updated>2023-02-22T11:09:54Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Настройки крипто-блока в конфигураторе&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1379</id>
		<title>Crypto</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1379"/>
		<updated>2023-02-22T10:59:53Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Раздел документации&lt;br /&gt;
&lt;br /&gt;
Описание библиотеки HAL_Crypto&lt;br /&gt;
&lt;br /&gt;
=== &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигуратора&amp;#039;&amp;#039;&amp;#039; ===&lt;br /&gt;
[[Шифрование и расшифровка данных]]&lt;br /&gt;
&lt;br /&gt;
Работа с DMA&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1378</id>
		<title>Crypto</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1378"/>
		<updated>2023-02-22T10:59:42Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Раздел документации&lt;br /&gt;
&lt;br /&gt;
Описание библиотеки HAL_Crypto&lt;br /&gt;
&lt;br /&gt;
=== &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигуратора&amp;#039;&amp;#039;&amp;#039; ===&lt;br /&gt;
[[Шифрование и расшифровка данных алгоритмом кузнечик|Шифрование и расшифровка данных]]&lt;br /&gt;
&lt;br /&gt;
Работа с DMA&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1377</id>
		<title>Crypto</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1377"/>
		<updated>2023-02-22T10:54:18Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Раздел документации&lt;br /&gt;
&lt;br /&gt;
Описание библиотеки HAL_Crypto&lt;br /&gt;
&lt;br /&gt;
=== &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигуратора&amp;#039;&amp;#039;&amp;#039; ===&lt;br /&gt;
[[Шифрование и расшифровка данных алгоритмом кузнечик]]&lt;br /&gt;
&lt;br /&gt;
Работа с DMA&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1376</id>
		<title>Crypto</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1376"/>
		<updated>2023-02-22T10:54:01Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Раздел документации&lt;br /&gt;
&lt;br /&gt;
Описание библиотеки HAL_Crypto&lt;br /&gt;
&lt;br /&gt;
=== &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигуратора&amp;#039;&amp;#039;&amp;#039; ===&lt;br /&gt;
[[Использование Crypto|Шифрование и расшифровка данных алгоритмом кузнечик]]&lt;br /&gt;
&lt;br /&gt;
Работа с DMA&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1375</id>
		<title>Crypto</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=Crypto&amp;diff=1375"/>
		<updated>2023-02-22T10:52:05Z</updated>

		<summary type="html">&lt;p&gt;Андрей: Новая страница: «Раздел документации  Описание библиотеки HAL_Crypto  === &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигура...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Раздел документации&lt;br /&gt;
&lt;br /&gt;
Описание библиотеки HAL_Crypto&lt;br /&gt;
&lt;br /&gt;
=== &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигуратора&amp;#039;&amp;#039;&amp;#039; ===&lt;br /&gt;
[[Использование Crypto]]&lt;br /&gt;
&lt;br /&gt;
Работа с DMA&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1374</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1374"/>
		<updated>2023-02-20T13:17:25Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Делитель частоты ЦАП это 8 битное число. Частота ЦАП рассчитывается по формуле: F&amp;lt;sub&amp;gt;ЦАП&amp;lt;/sub&amp;gt;=F&amp;lt;sub&amp;gt;IN&amp;lt;/sub&amp;gt;/(Div+1). В примере оставим значение по умолчанию -  0. &lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для ЦАП, которую использует функция инициализации DAC_Init.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
DAC_HandleTypeDef hdac1;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void DAC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Данные для преобразования ЦАП задаются с помощью функции HAL_DAC_SetValue. &lt;br /&gt;
&lt;br /&gt;
Сделаем циклическую смену напряжения от 0В до 1.2В на выводе DAC1 - Port1.12 с шагом 0.24В. &lt;br /&gt;
&lt;br /&gt;
Напряжение на выводе DAC1 рассчитывается по формуле DAC_Value * Uref / 4095 = DAC_Value * 1.2 / 4095. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!DAC_Value&lt;br /&gt;
!Напряжение на выводе Port1.12, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|819&lt;br /&gt;
|0.24&lt;br /&gt;
|-&lt;br /&gt;
|1638&lt;br /&gt;
|0.48&lt;br /&gt;
|-&lt;br /&gt;
|2457&lt;br /&gt;
|0.72&lt;br /&gt;
|-&lt;br /&gt;
|3276&lt;br /&gt;
|0.96&lt;br /&gt;
|-&lt;br /&gt;
|4095&lt;br /&gt;
|1.2&lt;br /&gt;
|}&lt;br /&gt;
Функция main должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    DAC_Init();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        for (uint16_t DAC_Value = 0; DAC_Value &amp;lt;= 0x0FFF; DAC_Value += 819)&lt;br /&gt;
        {&lt;br /&gt;
            HAL_DAC_SetValue(&amp;amp;hdac1, DAC_Value);&lt;br /&gt;
&lt;br /&gt;
            #ifdef MIK32_DAC_DEBUG&lt;br /&gt;
            if(( (DAC_Value*1200/4095)%1000 ) &amp;gt; 99)&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,0%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            #endif&lt;br /&gt;
&lt;br /&gt;
            for (volatile int i = 0; i &amp;lt; 1000000; i++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если у вас включен UART и в main.c или def_list.h есть #define MIK32_DAC_DEBUG, то вы можете видеть что выводит UART. Пример вывода UART можно видеть на рисунке. Измерим напряжение на выводе DAC1. ЦАП может выводить немного другое значение из-за погрешности ЦАП и измерительных приборов.&lt;br /&gt;
[[Файл:Вывод UART.png|мини|Вывод UART]]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Ожидаемое напряжение, В&lt;br /&gt;
!Измеренное напряжение, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|0.24&lt;br /&gt;
|0.22&lt;br /&gt;
|-&lt;br /&gt;
|0.48&lt;br /&gt;
|0.46&lt;br /&gt;
|-&lt;br /&gt;
|0.72&lt;br /&gt;
|0.69&lt;br /&gt;
|-&lt;br /&gt;
|0.96&lt;br /&gt;
|0.92&lt;br /&gt;
|-&lt;br /&gt;
|1.2&lt;br /&gt;
|1.15&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1373</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1373"/>
		<updated>2023-02-20T13:06:54Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для ЦАП, которую использует функция инициализации DAC_Init.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
DAC_HandleTypeDef hdac1;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void DAC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Данные для преобразования ЦАП задаются с помощью функции HAL_DAC_SetValue. &lt;br /&gt;
&lt;br /&gt;
Сделаем циклическую смену напряжения от 0В до 1.2В на выводе DAC1 - Port1.12 с шагом 0.24В. &lt;br /&gt;
&lt;br /&gt;
Напряжение на выводе DAC1 рассчитывается по формуле DAC_Value * Uref / 4095 = DAC_Value * 1.2 / 4095. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!DAC_Value&lt;br /&gt;
!Напряжение на выводе Port1.12, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|819&lt;br /&gt;
|0.24&lt;br /&gt;
|-&lt;br /&gt;
|1638&lt;br /&gt;
|0.48&lt;br /&gt;
|-&lt;br /&gt;
|2457&lt;br /&gt;
|0.72&lt;br /&gt;
|-&lt;br /&gt;
|3276&lt;br /&gt;
|0.96&lt;br /&gt;
|-&lt;br /&gt;
|4095&lt;br /&gt;
|1.2&lt;br /&gt;
|}&lt;br /&gt;
Функция main должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    DAC_Init();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        for (uint16_t DAC_Value = 0; DAC_Value &amp;lt;= 0x0FFF; DAC_Value += 819)&lt;br /&gt;
        {&lt;br /&gt;
            HAL_DAC_SetValue(&amp;amp;hdac1, DAC_Value);&lt;br /&gt;
&lt;br /&gt;
            #ifdef MIK32_DAC_DEBUG&lt;br /&gt;
            if(( (DAC_Value*1200/4095)%1000 ) &amp;gt; 99)&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,0%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            #endif&lt;br /&gt;
&lt;br /&gt;
            for (volatile int i = 0; i &amp;lt; 1000000; i++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Если у вас включен UART и в main.c или def_list.h есть #define MIK32_DAC_DEBUG, то вы можете видеть что выводит UART. Пример вывода UART можно видеть на рисунке. Измерим напряжение на выводе DAC1. ЦАП может выводить немного другое значение из-за погрешности ЦАП и измерительных приборов.&lt;br /&gt;
[[Файл:Вывод UART.png|мини|Вывод UART]]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Ожидаемое напряжение, В&lt;br /&gt;
!Измеренное напряжение, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|0.24&lt;br /&gt;
|0.22&lt;br /&gt;
|-&lt;br /&gt;
|0.48&lt;br /&gt;
|0.46&lt;br /&gt;
|-&lt;br /&gt;
|0.72&lt;br /&gt;
|0.69&lt;br /&gt;
|-&lt;br /&gt;
|0.96&lt;br /&gt;
|0.92&lt;br /&gt;
|-&lt;br /&gt;
|1.2&lt;br /&gt;
|1.15&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_UART.png&amp;diff=1372</id>
		<title>Файл:Вывод UART.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_UART.png&amp;diff=1372"/>
		<updated>2023-02-20T13:04:35Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Вывод UART&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1371</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1371"/>
		<updated>2023-02-20T13:02:13Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для ЦАП, которую использует функция инициализации DAC_Init.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
DAC_HandleTypeDef hdac1;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void DAC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Данные для преобразования ЦАП задаются с помощью функции HAL_DAC_SetValue. &lt;br /&gt;
&lt;br /&gt;
Сделаем циклическую смену напряжения от 0В до 1.2В на выводе DAC1 - Port1.12 с шагом 0.24В. &lt;br /&gt;
&lt;br /&gt;
Напряжение на выводе DAC1 рассчитывается по формуле DAC_Value * Uref / 4095 = DAC_Value * 1.2 / 4095. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!DAC_Value&lt;br /&gt;
!Напряжение на выводе Port1.12, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|819&lt;br /&gt;
|0.24&lt;br /&gt;
|-&lt;br /&gt;
|1638&lt;br /&gt;
|0.48&lt;br /&gt;
|-&lt;br /&gt;
|2457&lt;br /&gt;
|0.72&lt;br /&gt;
|-&lt;br /&gt;
|3276&lt;br /&gt;
|0.96&lt;br /&gt;
|-&lt;br /&gt;
|4095&lt;br /&gt;
|1.2&lt;br /&gt;
|}&lt;br /&gt;
Функция main должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    DAC_Init();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        for (uint16_t DAC_Value = 0; DAC_Value &amp;lt;= 0x0FFF; DAC_Value += 819)&lt;br /&gt;
        {&lt;br /&gt;
            HAL_DAC_SetValue(&amp;amp;hdac1, DAC_Value);&lt;br /&gt;
&lt;br /&gt;
            #ifdef MIK32_DAC_DEBUG&lt;br /&gt;
            if(( (DAC_Value*1200/4095)%1000 ) &amp;gt; 99)&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,0%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            #endif&lt;br /&gt;
&lt;br /&gt;
            for (volatile int i = 0; i &amp;lt; 1000000; i++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Измерим напряжение на выводе DAC1. Вывод UART можно видеть на рисунке. ЦАП может выводить немного другое значение из-за погрешности ЦАП и измерительных приборов.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Ожидаемое напряжение, В&lt;br /&gt;
!Измеренное напряжение, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|0.24&lt;br /&gt;
|0.22&lt;br /&gt;
|-&lt;br /&gt;
|0.48&lt;br /&gt;
|0.46&lt;br /&gt;
|-&lt;br /&gt;
|0.72&lt;br /&gt;
|0.69&lt;br /&gt;
|-&lt;br /&gt;
|0.96&lt;br /&gt;
|0.92&lt;br /&gt;
|-&lt;br /&gt;
|1.2&lt;br /&gt;
|1.15&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1370</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1370"/>
		<updated>2023-02-20T12:55:18Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для ЦАП, которую использует функция инициализации DAC_Init.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
DAC_HandleTypeDef hdac1;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void DAC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Данные для преобразования ЦАП задаются с помощью функции HAL_DAC_SetValue. &lt;br /&gt;
&lt;br /&gt;
Сделаем циклическую смену напряжения от 0В до 1.2В на выводе DAC1 - Port1.12 с шагом 0.24В. &lt;br /&gt;
&lt;br /&gt;
Напряжение на выводе DAC1 рассчитывается по формуле DAC_Value * Uref / 4095 = DAC_Value * 1.2 / 4095. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!DAC_Value&lt;br /&gt;
!Напряжение на выводе Port1.12, В&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|819&lt;br /&gt;
|0.24&lt;br /&gt;
|-&lt;br /&gt;
|1638&lt;br /&gt;
|0.48&lt;br /&gt;
|-&lt;br /&gt;
|2457&lt;br /&gt;
|0.72&lt;br /&gt;
|-&lt;br /&gt;
|3276&lt;br /&gt;
|0.96&lt;br /&gt;
|-&lt;br /&gt;
|4095&lt;br /&gt;
|1.2&lt;br /&gt;
|}&lt;br /&gt;
Функция main должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
&lt;br /&gt;
    DAC_Init();&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        for (uint16_t DAC_Value = 0; DAC_Value &amp;lt;= 0x0FFF; DAC_Value += 819)&lt;br /&gt;
        {&lt;br /&gt;
            HAL_DAC_SetValue(&amp;amp;hdac1, DAC_Value);&lt;br /&gt;
&lt;br /&gt;
            #ifdef MIK32_DAC_DEBUG&lt;br /&gt;
            if(( (DAC_Value*1200/4095)%1000 ) &amp;gt; 99)&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                xprintf(&amp;quot;DAC: %d (V = %d,0%d)\n&amp;quot;, DAC_Value, ((DAC_Value*1200)/4095)/1000, ((DAC_Value*1200)/4095)%1000);&lt;br /&gt;
            }&lt;br /&gt;
            #endif&lt;br /&gt;
&lt;br /&gt;
            for (volatile int i = 0; i &amp;lt; 1000000; i++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1369</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1369"/>
		<updated>2023-02-20T12:49:36Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для ЦАП, которую использует функция инициализации DAC_Init.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
DAC_HandleTypeDef hdac1;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void DAC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Данные для преобразования ЦАП задаются с помощью функции HAL_DAC_SetValue. &lt;br /&gt;
&lt;br /&gt;
Сделаем циклическую смену напряжения от 0В до 1.2В на выводе DAC1 - Port1.12 с шагом 0.24В. &lt;br /&gt;
&lt;br /&gt;
Функция main должна выглядеть примерно так:&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1368</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1368"/>
		<updated>2023-02-20T12:46:10Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. В начале main.c можно видеть объявление структуры с набором настроек для ЦАП, которую использует функция инициализации DAC_Init.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
DAC_HandleTypeDef hdac1;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void DAC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1367</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1367"/>
		<updated>2023-02-20T12:44:34Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1366</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1366"/>
		<updated>2023-02-20T12:44:13Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1365</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1365"/>
		<updated>2023-02-20T12:43:46Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1364</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1364"/>
		<updated>2023-02-20T12:43:21Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1363</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1363"/>
		<updated>2023-02-20T12:42:44Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1362</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1362"/>
		<updated>2023-02-20T12:41:53Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как ЦАП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого ЦАП. Для этого откроем вкладку ЦАП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала, источника опорного напряжения (ИОН) и делителя частоты. Выберем 1-й канал ЦАП1, которому соответствует вывод Port1.12.&lt;br /&gt;
[[Файл:Настройки ЦАП в конфигураторе.png|мини|Настройки ЦАП в конфигураторе]]&lt;br /&gt;
В ЦАП есть 3 источника опорного напряжения. Внутренний считается встроенным в ЦАП. Настраиваемый ИОН и источник от внешнего вывода DAC_REF считаются внешними по отношению к внутреннему ИОН ЦАП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция DAC_Init, в которой будут заданы настройки для ЦАП. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void DAC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hdac1.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hdac1.Instance_dac = HAL_DAC1;&lt;br /&gt;
    hdac1.Init.DIV = 0;&lt;br /&gt;
    hdac1.Init.EXTRef = DAC_EXTREF_OFF;     /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hdac1.Init.EXTClb = DAC_EXTCLB_DACREF;  /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_DAC_Init(&amp;amp;hdac1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8_%D0%A6%D0%90%D0%9F_%D0%B2_%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B5.png&amp;diff=1361</id>
		<title>Файл:Настройки ЦАП в конфигураторе.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8_%D0%A6%D0%90%D0%9F_%D0%B2_%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B5.png&amp;diff=1361"/>
		<updated>2023-02-20T12:39:14Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Настройки ЦАП в конфигураторе&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1360</id>
		<title>Использование DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_DAC&amp;diff=1360"/>
		<updated>2023-02-20T12:33:55Z</updated>

		<summary type="html">&lt;p&gt;Андрей: Новая страница: «В примере будет запущен ЦАП.  == Работа с конфигуратором (В разработке) == Для начала настро...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будет запущен ЦАП.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как АЦП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого АЦП. Для этого откроем вкладку АЦП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала и источника опорного напряжения (ИОН). Выберем 5-й канал АЦП, которому соответствует вывод Port0.9.&lt;br /&gt;
Настройки ADC в конфигураторе&lt;br /&gt;
В АЦП есть 3 источника опорного напряжения. Внутренний считается встроенным в АЦП. Настраиваемый ИОН и источник от внешнего вывода ADC_REF считаются внешними по отношению к внутреннему ИОН АЦП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_DAC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция ADC_Init, в которой будут заданы настройки для ADC. Выглядит она так:&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=DAC&amp;diff=1359</id>
		<title>DAC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=DAC&amp;diff=1359"/>
		<updated>2023-02-20T12:31:42Z</updated>

		<summary type="html">&lt;p&gt;Андрей: Новая страница: «Раздел документации  Описание библиотеки HAL_DAC  === &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигурато...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Раздел документации&lt;br /&gt;
&lt;br /&gt;
Описание библиотеки HAL_DAC&lt;br /&gt;
&lt;br /&gt;
=== &amp;#039;&amp;#039;&amp;#039;Примеры с использованием конфигуратора&amp;#039;&amp;#039;&amp;#039; ===&lt;br /&gt;
[[Использование DAC]]&lt;br /&gt;
&lt;br /&gt;
Работа с DMA&lt;br /&gt;
&lt;br /&gt;
Работа с прерываниями&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
	<entry>
		<id>http://wiki.me-robotics.ru/index.php?title=%D0%9E%D0%B4%D0%BD%D0%BE%D0%BA%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B5_%D0%B8_%D0%BD%D0%B5%D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B8%D0%B7%D0%BC%D0%B5%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_ADC&amp;diff=1358</id>
		<title>Однократное и непрерывное измерение ADC</title>
		<link rel="alternate" type="text/html" href="http://wiki.me-robotics.ru/index.php?title=%D0%9E%D0%B4%D0%BD%D0%BE%D0%BA%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B5_%D0%B8_%D0%BD%D0%B5%D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B8%D0%B7%D0%BC%D0%B5%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_ADC&amp;diff=1358"/>
		<updated>2023-02-17T14:35:52Z</updated>

		<summary type="html">&lt;p&gt;Андрей: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В примере будут запущены измерения ADC (АЦП) в однократном и непрерывном режиме.&lt;br /&gt;
&lt;br /&gt;
== Работа с конфигуратором (В разработке) ==&lt;br /&gt;
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как АЦП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:&lt;br /&gt;
&lt;br /&gt;
(Картинка тактирования из конфигуратора. В работе)&lt;br /&gt;
&lt;br /&gt;
Затем перейдем к настройке самого АЦП. Для этого откроем вкладку АЦП и нажмем включить.&lt;br /&gt;
&lt;br /&gt;
После этого появится настройки канала и источника опорного напряжения (ИОН). Выберем 5-й канал АЦП, которому соответствует вывод Port0.9. &lt;br /&gt;
[[Файл:Настройки ADC в конфигураторе.png|мини|Настройки ADC в конфигураторе]]&lt;br /&gt;
В АЦП есть 3 источника опорного напряжения. Внутренний считается встроенным в АЦП. Настраиваемый ИОН и источник от внешнего вывода ADC_REF считаются внешними по отношению к внутреннему ИОН АЦП. Выберем &amp;quot;Внутренний&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.&lt;br /&gt;
&lt;br /&gt;
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.&lt;br /&gt;
&lt;br /&gt;
== Использование библиотеки HAL_ADC ==&lt;br /&gt;
В сгенерированном проекте в файле main.c должна быть функция ADC_Init, в которой будут заданы настройки для ADC. Выглядит она так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void ADC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hadc.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hadc.Init.Sel = ADC_CHANNEL5;&lt;br /&gt;
    hadc.Init.EXTRef = ADC_EXTREF_OFF; /* Выбор источника опорного напряжения (внешний или встроенный) */&lt;br /&gt;
    hadc.Init.EXTClb = ADC_EXTCLB_ADCREF; /* Выбор источника внешнего опорного напряжения (внешний вывод или настраиваемый ОИН) */&lt;br /&gt;
&lt;br /&gt;
    HAL_ADC_Init(&amp;amp;hadc);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT).  Сама функция должна выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void SystemClock_Config(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_OscInitTypeDef RCC_OscInit = {0};&lt;br /&gt;
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};&lt;br /&gt;
&lt;br /&gt;
    RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M;   &lt;br /&gt;
    RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M;                          &lt;br /&gt;
    RCC_OscInit.AHBDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBMDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.APBPDivider = 0;                             &lt;br /&gt;
    RCC_OscInit.HSI32MCalibrationValue = 0;                  &lt;br /&gt;
    RCC_OscInit.LSI32KCalibrationValue = 0;&lt;br /&gt;
    HAL_RCC_OscConfig(&amp;amp;RCC_OscInit);&lt;br /&gt;
&lt;br /&gt;
    PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT;    &lt;br /&gt;
    PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_PAD_CONFIG_M;     &lt;br /&gt;
    PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M | PM_CLOCK_ANALOG_REG_M;     &lt;br /&gt;
    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_NO_CLK;&lt;br /&gt;
    PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK;&lt;br /&gt;
    HAL_RCC_ClockConfig(&amp;amp;PeriphClkInit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. &lt;br /&gt;
&lt;br /&gt;
В начале main.c можно видеть объявление структуры с набором настроек для АЦП, которую использует функция инициализации ADC_Init.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
ADC_HandleTypeDef hadc;&lt;br /&gt;
&lt;br /&gt;
void SystemClock_Config(void);&lt;br /&gt;
static void ADC_Init(void);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Для запуска однократного измерения следует использовать функцию HAL_ADC_Single. Для получения значения используйте функцию HAL_ADC_WaitAndGetValue.&lt;br /&gt;
&lt;br /&gt;
Функция main должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
    &lt;br /&gt;
    ADC_Init();&lt;br /&gt;
&lt;br /&gt;
    uint16_t value = 0;&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        HAL_ADC_Single(&amp;amp;hadc);&lt;br /&gt;
        value = HAL_ADC_WaitAndGetValue(&amp;amp;hadc);&lt;br /&gt;
&lt;br /&gt;
        if(( (value*1200/4095)%1000 ) &amp;gt; 99)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;ADC: %d (V = %d,%d)\n&amp;quot;, value, ((value*1200)/4095)/1000, ((value*1200)/4095)%1000);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;ADC: %d (V = %d,0%d)\n&amp;quot;, value, ((value*1200)/4095)/1000, ((value*1200)/4095)%1000);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        for (volatile int i = 0; i &amp;lt; 1000000; i++);&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Файл:АЦП пример 1.png|мини|Вывод UART]]&lt;br /&gt;
[[Файл:АЦП пример 2.png|мини|Вывод UART в примере с внешнем ОИН]]&lt;br /&gt;
[[Файл:АЦП пример 3.png|мини|Вывод UART в примере с АЦП в непрерывном режиме]]&lt;br /&gt;
Подадим на вывод Port0.9 напряжение 0.6В. Вывод UART можно видеть на рисунке. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.&lt;br /&gt;
&lt;br /&gt;
Теперь изменим ИОН на внешний от вывода ADC_REF - Port1.10. Это можно сделать в конфигураторе, либо в функции ADC_Init, которая должна выглядеть так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void ADC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hadc.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hadc.Init.Sel = ADC_CHANNEL5;&lt;br /&gt;
    hadc.Init.EXTRef = ADC_EXTREF_ON; /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hadc.Init.EXTClb = ADC_EXTCLB_ADCREF; /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_ADC_Init(&amp;amp;hadc);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Функция main без изменений. &lt;br /&gt;
&lt;br /&gt;
Подадим на вывод ADC_REF (Port1.10 ) 1.2В, а на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.&lt;br /&gt;
&lt;br /&gt;
Для запуска АЦП в непрерывном режиме следует использовать функцию HAL_ADC_ContiniusEnable, а для считывания результата преобразования HAL_ADC_GetValue.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
static void ADC_Init(void)&lt;br /&gt;
{&lt;br /&gt;
    hadc.Instance = ANALOG_REG;&lt;br /&gt;
&lt;br /&gt;
    hadc.Init.Sel = ADC_CHANNEL5;&lt;br /&gt;
    hadc.Init.EXTRef = ADC_EXTREF_OFF; /* Выбор источника опорного напряжения: «1» - внешний; «0» - встроенный */&lt;br /&gt;
    hadc.Init.EXTClb = ADC_EXTCLB_ADCREF; /* Выбор источника внешнего опорного напряжения: «1» - внешний вывод; «0» - настраиваемый ОИН */&lt;br /&gt;
&lt;br /&gt;
    HAL_ADC_Init(&amp;amp;hadc);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функция main должна выглядеть примерно так:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    SystemClock_Config();&lt;br /&gt;
    &lt;br /&gt;
    ADC_Init();&lt;br /&gt;
&lt;br /&gt;
    uint16_t value = 0;&lt;br /&gt;
    HAL_ADC_ContiniusEnable(&amp;amp;hadc);&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
    {    &lt;br /&gt;
        value = HAL_ADC_GetValue(&amp;amp;hadc);&lt;br /&gt;
&lt;br /&gt;
        if(( (value*1200/4095)%1000 ) &amp;gt; 99)&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;ADC: %d (V = %d,%d)\n&amp;quot;, value, ((value*1200)/4095)/1000, ((value*1200)/4095)%1000);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            xprintf(&amp;quot;ADC: %d (V = %d,0%d)\n&amp;quot;, value, ((value*1200)/4095)/1000, ((value*1200)/4095)%1000);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        for (volatile int i = 0; i &amp;lt; 1000000; i++);&lt;br /&gt;
    }&lt;br /&gt;
       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Подадим на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.&lt;/div&gt;</summary>
		<author><name>Андрей</name></author>
	</entry>
</feed>