Почему для проверки подписи E CC нужны случайные числа (иногда занимающие много времени) в OpenSSL 1.1? - PullRequest
2 голосов
/ 15 апреля 2020

Я работал над Linux средством проверки подписи при загрузке (kinit) с использованием сертификатов E CC, переходя с необработанных подписей RSA на подписи CMS-формата E CC. При этом я обнаружил, что функция CMS_Verify() останавливается до тех пор, пока ядро ​​не напечатает «crng init done», указывая, что ему нужно ждать, пока будет достаточно системной энтропии для криптографически безопасного генерирования случайных чисел . Поскольку в системе больше ничего не происходит, для Beaglebone Black это заняло около 90 секунд.

Это удивило меня, я ожидал, что для генерации сертификата или, возможно, для генерации подписи потребуются безопасные случайные числа, но В проверке подписи с помощью ключа * publi c нет секретов, которые нужно защищать. Так что же дает?

(я понял это, но не смог найти решение где-либо еще, поэтому ответ для других ниже).

1 Ответ

2 голосов
/ 15 апреля 2020

Благодаря кропотливому процессу отладки по printf (мой лучший вариант, учитывая, что это kinit), я обнаружил, что фундаментальная операция E CC использует случайные числа в качестве защиты от атак по побочному каналу. Это называется «ослеплением» и помогает предотвратить раскрытие злоумышленниками секретов, основанных на том, сколько времени занимает вычисление, пропадание кэша, скачки мощности и т. Д. c. добавив некоторую неопределенность.

Из комментариев глубоко в источнике OpenSSL:

/*-
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
* Since we don't have a Mont structure here, SCA hardening is with blinding.
*/
int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                            BN_CTX *ctx)

и эта функция продолжает вызывать BN_priv_rand_range().

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

    RAND_seed( "\xe5\xe3[...29 other characters...]\x9a", 32 );

НЕ ДЕЛАЙТЕ ЭТОГО, если ваша программа работает с секретирует или генерирует любые ключи, подписи или случайные числа. В проверке подписи все нормально. В программе, которая требовала большей безопасности, я мог бы заполнить данные встроенного RNG-оборудования (/ dev / hw_random) или сохранить некоторую энтропию в безопасном хранилище, если оно у меня было, или поглотил ее и дождался завершения crng init .

...