1

概述

我有一些关于在 openSSL 中实现rsa_meth_st(又名 RSA_METHOD)的具体问题,但是在执行标准 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

所以,三个问题:

  1. 标准 OpenSSL RSA 实现是否可以使用我的引擎的“模幂”函数,而不必重写RSA_[public|private]_[encrypt|decrypt]/include/openssl/rsa.h 中的函数系列?
  2. 如果是这样,只实现 rsa_mod_exp 函数就足够了吗?还是我必须同时实现 public_enc/dec 和 private_enc/dec 函数?我问,因为旧英特尔 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
  1. 这是否意味着如果我在 RSA_METHOD 的“标志”字段中使用此标志,我不需要实现 rsa_pub_enc/dec 和朋友?我想我只是对在 RSA 加密/解密过程中应该在什么时候调用我的引擎感到困惑。

任何智慧之言将不胜感激。

4

1 回答 1

0

免责声明我从未编写过 Openssl 模块/引擎,但这些天我正在研究 OpenSSL 的 RSA 代码。

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

恕我直言,我只修改几个属性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.

于 2017-09-10T20:58:22.550 回答