打印来自 MD_CTX 的内容

printing contents from MD_CTX

我想了解 md_rand.c 中的散列函数是如何工作的。假设我声明了一个变量 MD_CTX m,并且我试图在每个 MD_Update 函数之后查看 m 的内容。

MD_Init(&m);
printf("%X\n",*(&m));
MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
printf("%X\n",*(&m));
MD_Update(&m,local_md,MD_DIGEST_LENGTH);
printf("%X\n",*(&m));
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
MD_Update(&m,md,MD_DIGEST_LENGTH);
printf("%X\n",*(&m));       
MD_Final(md,&m);

但是,我总是在每 MD_Update 之后为所有 4 printf 条语句打印出相同的值。我应该怎么做才能获得 m 中的更新值?

What should I do to get the updated value in m?

当你printf("%X\n",*(&m));时,你只是在堆栈上打印MD_CTX的地址。它永远不会改变,因此是您观察的原因。

A MD_CTX 是一个不透明的结构,这意味着您不应该查看它。它是一个 typedef,您可以通过以下方式找到它:

$ cd openssl-1.0.2d
$ grep -R EVP_MD * | grep struct | egrep "(\.h|\.c)"
crypto/ossl_typ.h:typedef struct env_md_st EVP_MD;
crypto/ossl_typ.h:typedef struct env_md_ctx_st EVP_MD_CTX;
engines/ccgost/gost_lcl.h:/* EVP_MD structure for GOST R 34.11 */
engines/ccgost/gost_lcl.h:/* EVP_MD structure for GOST 28147 in MAC mode */
include/openssl/ossl_typ.h:typedef struct env_md_st EVP_MD;
include/openssl/ossl_typ.h:typedef struct env_md_ctx_st EVP_MD_CTX;

然后,struct env_md_ctx_st

$ grep -R "struct env_md_ctx_st" * | grep "{"
crypto/evp/evp.h:struct env_md_ctx_st {
include/openssl/evp.h:struct env_md_ctx_st {

最后,从 evp.h 第 260 行开始:

struct env_md_ctx_st {
    const EVP_MD *digest;
    ENGINE *engine;             /* functional reference if 'digest' is
                                 * ENGINE-provided */
    unsigned long flags;
    void *md_data;
    /* Public key context for sign/verify */
    EVP_PKEY_CTX *pctx;
    /* Update function: usually copied from EVP_MD */
    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
} /* EVP_MD_CTX */ ;

这是第 160 行附近的一个相关结构:

struct env_md_st {
    int type;
    int pkey_type;
    int md_size;
    unsigned long flags;
    int (*init) (EVP_MD_CTX *ctx);
    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
    int (*cleanup) (EVP_MD_CTX *ctx);
    /* FIXME: prototype these some day */
    int (*sign) (int type, const unsigned char *m, unsigned int m_length,
                 unsigned char *sigret, unsigned int *siglen, void *key);
    int (*verify) (int type, const unsigned char *m, unsigned int m_length,
                   const unsigned char *sigbuf, unsigned int siglen,
                   void *key);
    int required_pkey_type[5];  /* EVP_PKEY_xxx */
    int block_size;
    int ctx_size;               /* how big does the ctx->md_data need to be */
    /* control function */
    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
} /* EVP_MD */ ;