I am trying to understand how the hashing functions in md_rand.c
works. Suppose I declare a variable MD_CTX m
, and I am trying to see the contents of m
after each MD_Update
function.
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);
However, I always get the same value printed out for all 4 printf
statements after every MD_Update
. What should I do to get the updated value in m
?
What should I do to get the updated value in m?
When you printf("%X\n",*(&m));
, you are just printing the address of MD_CTX
on the stack. It never changes, hence the reason for your observations.
A MD_CTX
is an opaque structure, meaning you are not supposed to look into it. Its a typedef, and you can locate it with:
$ 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;
Then, following 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 {
And finally, from evp.h
around line 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 */ ;
And here's a related struct from around line 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 */ ;