Благодаря кропотливому процессу отладки по 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 .