Обзор
У меня есть несколько конкретных вопросов, касающихся реализации rsa_meth_st
(также известного как RSA_METHOD) в openSSL, однако я также обычно не понимаю, где именно мой движок «зацеплен» (или должен быть) пользователем при выполнении стандартных операций RSA.
Фон
Я пытаюсь разработать механизм для пользовательского аппаратного ускорителя RSA, и у меня есть несколько вопросов о реализации структуры RSA_METHOD.
Некоторый контекст: для шифрования мой ускоритель принимает в качестве входных данных базу, общедоступную экспоненту и модуль и возвращает результирующий зашифрованный текст. Для расшифровки он принимает в качестве входных данных базу и модуль. Ему не нужен закрытый ключ, так как он хранится в аппаратном обеспечении и может быть настроен только через внеполосный канал. У меня уже есть модуль ядра, который предоставляет API пользовательским программам для использования ускорителя. Теперь мне просто нужно интегрировать его в openSSL.
Я уже создал аналогичный движок для AES и SHA256, однако у меня проблемы с RSA. В идеале я бы хотел не беспокоиться ни о чем, кроме как о выполнении модульного возведения в степень для предварительно заполненного и подготовленного фрагмента данных. Для SHA и AES это просто: все, что было об этом позаботился интерфейс EVP, поэтому все, о чем мне нужно было беспокоиться, это передача данных на мои ускорители и обратно. Но это не так просто для RSA (пожалуйста, поправьте меня, если я ошибаюсь).
Мои конкретные вопросы
Я не понимаю, какие указатели функций RSA_METHOD нужно реализовать моему движку. Я показываю структуру ниже для справки:
struct rsa_meth_st {
char *name;
int (*rsa_pub_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_pub_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
/* ....stuff.... */
int flags;
/* .... stuff ... */
}; // TYPEDEF'ED TO RSA_METHOD in include/ossl_typ.h
Итак, три вопроса:
- Возможно ли, чтобы стандартная реализация OpenSSL RSA использовала функцию «модульного возведения в степень» моего движка без необходимости переписывать семейство функций
RSA_[public|private]_[encrypt|decrypt]
из /include/openssl/rsa.h? - Если да, то достаточно ли реализовать только функцию rsa_mod_exp? Или я должен также реализовать функции public_enc/dec и private_enc/dec? Я спрашиваю, потому что исходный код старого движка Intel RSAX делает это, но я не могу не выяснить, как и когда в «потоке RSA» вызывается функция движка.
В /include/openssl/rsa.h я увидел следующий макрос для поля флага RSA_METHOD (строка 61):
/*
* This flag means the private key operations will be handled by rsa_mod_exp
* and that they do not depend on the private key components being present:
* for example a key stored in external hardware. Without this flag
* bn_mod_exp gets called when private key components are absent.
*/
# define RSA_FLAG_EXT_PKEY 0x0020
- Означает ли это, что если я использую этот флаг в поле «флаги» RSA_METHOD, мне НЕ нужно реализовывать rsa_pub_enc/dec и другие? Думаю, я просто не понимаю, в какой момент процесса шифрования/дешифрования RSA должен запускаться мой движок.
Любые слова мудрости будут очень признательны.