ssl - 正确实现 OpenSSL RSA 引擎 : questions about rsa_meth_st

标签 ssl openssl cryptography rsa openssl-engine

概览

我有一些关于在 openSSL 中实现 rsa_meth_st(又名 RSA_METHOD)的具体问题,但是我通常也对我的引擎到底(或应该)“ Hook ”的地方感到困惑由用户在执行标准 RSA 操作时。

背景

我正在尝试为自定义 RSA 硬件加速器开发引擎,并且有几个关于 RSA_METHOD 结构实现的问题。

一些上下文:为了加密,我的加速器将基数、公共(public)指数和模数作为输入,并返回生成的密文。对于解密,它将基数和模数作为输入。它不需要私钥,因为它存储在硬件中,并且只能通过带外 channel 进行配置。我已经有一个内核模块,它向用户空间程序公开一个 API 以使用加速器。现在我只需要将它集成到 openSSL 中。

我已经为 AES 和 SHA256 创建了一个类似的引擎,但是我正在努力处理 RSA。 理想情况下,除了对预先填充和准备好的数据 block 执行模幂运算之外,我不想担心任何其他事情。对于 SHA 和 AES,这很简单:所有这些都是由 EVP 接口(interface)处理,所以我需要担心的只是从我的加速器中获取数据。但对于 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

那么,三个问题:

  1. 标准 OpenSSL RSA 实现是否可以使用我的引擎的“模幂”函数,而不必重写 RSA_[public|private]_[encrypt|decrypt]/include/openssl/rsa.h?
  2. 如果是这样,是否只实现 rsa_mod_exp 函数就足够了?或者我必须同时实现 public_enc/dec 和 private_enc/dec 函数吗?请问,因为源代码为旧Intel RSAX engine这样做,但我无法弄清楚在“RSA 流”中如何以及何时调用引擎的函数。

在/include/openssl/rsa.h 中,我看到了 RSA_METHOD 标志字段的以下宏 (line 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
  1. 这是否意味着如果我在 RSA_METHOD 的“标志”字段中使用此标志,我就不需要实现 rsa_pub_enc/dec 和 friend ?我想我只是对应该在 RSA 加密/解密过程中的什么时候调用我的引擎感到困惑。

任何智慧的话将不胜感激。

最佳答案

免责声明 我从来没有写过Openssl模块/引擎,但最近在研究OpenSSL的RSA代码。

  1. 我认为您不能重写 RSA_[public|private]_[encrypt|decrypt] 函数族。我会尝试在文件 crypto/rsa/rsa_ossl.c 中制作结构 rsa_pkcs1_ossl_meth 的修改版本
  2. 我找到了加载引擎方法的位置。它在 crypto/rsa/rsa_lib.c在函数 RSA_new_method 中调用 ENGINE_get_RSA(ret->engine)。使用指向类似于 rsa_pkcs1_ossl_methRSA_METHOD strcut 的指针初始化您的 engine->rsa_meth
  3. 我不知道如何使用 RSA_FLAG_EXT_PKEY 标志,但它用于 crypto/rsa/rsa_ossl.c就像在 /include/openssl/rsa.h
  4. 中所说的一样

恕我直言,我只修改了 rsa_pkcs1_ossl_meth 的几个属性来创建你的 RSA_METHOD 结构 ENGINE:

static RSA_METHOD rsa_pkcs1_ossl_meth = {
    "my_RSA",
    rsa_ossl_public_encrypt,
    rsa_ossl_public_decrypt,     /* signature verification */
    rsa_ossl_private_encrypt,    /* signing */
    rsa_ossl_private_decrypt,
    my_mod_exp,                  //<------- YOUR mod_exp_function
    NULL,
    rsa_ossl_init,
    rsa_ossl_finish,
    RSA_FLAG_FIPS_METHOD | RSA_FLAG_EXT_PKEY,       //<--- flags
                // RSA_FLAG_EXT_PKEY tells to use hardware */
    NULL,
    0,                          /* rsa_sign */
    0,                          /* rsa_verify */
    NULL                        /* rsa_keygen */
};

通过这种方式,您可以重用默认 OpenSSL 引擎的代码,您只需实现 my_mod_exp 并设置 RSA_FLAG_EXT_PKEY

关于ssl - 正确实现 OpenSSL RSA 引擎 : questions about rsa_meth_st,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45842540/

相关文章:

java - 使用 OpenJDK 14 java 模块运行时时 TLS 1.3 握手失败

swift - 如何生成用于不记名 token 的加密安全随机数?

java - Java RMI + SSL +压缩=不可能!

python - 如何使用 python 将证书安装到受信任的根证书?

c++ - 我可以在单独的 ssl 上下文之间重用 openssl x509store 吗?

php - JWT RS256 是否需要 OpenSSL?无法在 Php 中解码 JWT

java - 尝试调用加密算法生成 NoSuchAlgorithmException

c# - 使用来自 Thales nShield HSM 的 PKCS11interop c# 包装器库导出/导入 RSA key 对?

tomcat - 为 Tomcat 编写自定义 SSL 上下文

spring - 使用 Spring + SSL 连接到 EMS JMS 队列