45435

[i] Обход ошибки сбора данных с ГСЧ в МК К1986ВК025 ревизий 1 и 1.1 (errata 0007)

Дата последнего изменения: 26.04.2022 09:38:30

В микроконтроллере К1986ВК025 реализован физический блок ГСЧ, который осуществляет сбор данных с кольцевых генераторов.

До ревизии 2 при аппаратном накоплении случайных чисел ГСЧ осуществлял их сбор с недостаточной энтропией, что не позволяет их использовать без программной обработки/выборки в криптографических алгоритмах. Данная ошибка исправлена в ревизии 2. В ревизиях 1 и 1.1 требует программного сбора данных с блока для её обхода.

В качестве программного сбора предлагается следующий алгоритм:

// вспомогательная функция
unsigned int parity(unsigned int v) {
    v ^= v >> 16;
    v ^= v >> 8;
    v ^= v >> 4;
    v &= 0xf;
    return (0x6996 >> v) & 1;
}

// вспомогательные переменные
unsigned int w, b1, b2;
unsigned int c = 0, b;

int main() {
    // Инициализация RNG
    ....
    // процесс сбора случайный чисел – в данном примере реализован циклически
    while (1) {
          // ожидание окончания процесса сбора 32-битного числа блоком
          while ((MDR_RANDOM->STAT & (1 << 3)) == 0);
          // считывание результата аппаратного сбора
          w = MDR_RANDOM->OUTPUT;
          // программная постобработка
          b1 = parity(w >> 16);
          b2 = parity(w & 0xFFFF);
          if (b1! = b2) {
                b = (b << 1) | b1;
                if (++c == 8) {
                     c = 0;
                     // переменная b содержит случайное число, которое можно использовать
                     // можно, например, отправить его по UART с помощью printf()
                     printf("%u\r\n", b);
                }
          }
    }
}

или:

// вспомогательная функция
unsigned int parity(unsigned int v) {
    v ^= v >> 16;
    v ^= v >> 8;
    v ^= v >> 4;
    v &= 0xf;
    return (0x6996 >> v) & 1;
}

// вспомогательные переменные
unsigned int w, b1, b2;
unsigned int c = 0, b;

int main() {
    // Инициализация RNG
    ....
    // процесс сбора случайный чисел – в данном примере реализован циклически
    while (1) {
          // ожидание окончания процесса сбора 32-битного числа блоком
          while ((MDR_RANDOM->STAT & (1 << 3)) == 0);
          // считывание результата аппаратного сбора и программная постобработка
          b = (b << 1) | parity(MDR_RANDOM->OUTPUT);
          if (++c == 8) {
                c = 0;
                // переменная b содержит случайное число, которое можно использовать
                // можно, например, отправить его по UART с помощью printf()
                printf("%u\r\n", b);
          }
    }
}

В разделе "Файлы для скачивания" приведен проект для среды Eclipse, в котором случайные числа, получаемые путем первого предложенного метода программного сбора случайных чисел, складываются в массив.

Сохранить статью в PDF

Файлы для скачивания

Документация

Теги

Была ли статья полезной?