How to store openSSL EVP_MD and EVP_MD_CTX in local buffers

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

How to store openSSL EVP_MD and EVP_MD_CTX in local buffers

Vuthur Pavankumar
Hi All,

I was implementing SHA3 multi-call as below using openSSL version openssl-1.1.1j

init:
const EVP_MD *evpmd = EVP_sha3_256();
EVP_MD_CTX *ctx = EVP_MD_CTX_new()
EVP_DigestInit_ex(ctx, evpmd, NULL);
store ctx and evpmd in local buffer. and reuse it for update and final
EVP_MD_CTX_free(ctx)

update:
get ctx and evpmd from local buffer and update ctx with evpmd and pass it to  EVP_DigestUpdate method
  
EVP_DigestUpdate(ctx, msg, msg_len); -> get ctx from  local buffer  

Final:
get ctx and evpmd from local buffer and update ctx with evpmd and pass it to  EVP_DigestUpdate method
if(shake)
EVP_DigestFinalXOF(ctx, md , mdlen); -> get ctx from  local buffer  
else
EVP_DigestFinal_ex(ctx, md, &mdlen)

Note:
some buggy applications may not call the final call and the memory allocated using OpenSSL in Digest init may not be freed.
to avoid it I want to store EVP_MD_CTX and EVP_MD data in a local buffer and reuse it instead of storing *ctx and freeing in the final call.

the problem I am facing:
1.declaring below struct and compiling resulted in an error.
error: field 'evpmd_ctx' has incomplete type
error: field 'evpmd' has incomplete type

typedef struct {
uint16_t abc;
uint16_t xyz;
uint16_t reserved1;
uint16_t reserved2;
EVP_MD_CTX evpmd_ctx;
EVP_MD evpmd;
} SHA3Data;

2.same error for sizeof(EVP_MD_CTX ) and sizeof(EVP_MD )

looks like 
EVP_MD_CTX and EVP_MD data are opaque to applications.  

Do we have any other means to store  EVP_MD_CTX and EVP_MD data in local buffers and reuse them in update and Final calls?

Thanks, 
Pavan

Reply | Threaded
Open this post in threaded view
|

Re: How to store openSSL EVP_MD and EVP_MD_CTX in local buffers

Dr Paul Dale-2
Structures are opaque after OpenSSL 1.0.  There is no way to do what you want.

The recommended path is to call EVP_MD_CTX_dup() to create a copy of the context and use that the second time around.


Pauli


On 24/3/21 2:03 pm, Vuthur Pavankumar wrote:
Hi All,

I was implementing SHA3 multi-call as below using openSSL version openssl-1.1.1j

init:
const EVP_MD *evpmd = EVP_sha3_256();
EVP_MD_CTX *ctx = EVP_MD_CTX_new()
EVP_DigestInit_ex(ctx, evpmd, NULL);
store ctx and evpmd in local buffer. and reuse it for update and final
EVP_MD_CTX_free(ctx)

update:
get ctx and evpmd from local buffer and update ctx with evpmd and pass it to  EVP_DigestUpdate method
  
EVP_DigestUpdate(ctx, msg, msg_len); -> get ctx from  local buffer  

Final:
get ctx and evpmd from local buffer and update ctx with evpmd and pass it to  EVP_DigestUpdate method
if(shake)
EVP_DigestFinalXOF(ctx, md , mdlen); -> get ctx from  local buffer  
else
EVP_DigestFinal_ex(ctx, md, &mdlen)

Note:
some buggy applications may not call the final call and the memory allocated using OpenSSL in Digest init may not be freed.
to avoid it I want to store EVP_MD_CTX and EVP_MD data in a local buffer and reuse it instead of storing *ctx and freeing in the final call.

the problem I am facing:
1.declaring below struct and compiling resulted in an error.
error: field 'evpmd_ctx' has incomplete type
error: field 'evpmd' has incomplete type

typedef struct {
uint16_t abc;
uint16_t xyz;
uint16_t reserved1;
uint16_t reserved2;
EVP_MD_CTX evpmd_ctx;
EVP_MD evpmd;
} SHA3Data;

2.same error for sizeof(EVP_MD_CTX ) and sizeof(EVP_MD )

looks like 
EVP_MD_CTX and EVP_MD data are opaque to applications.  

Do we have any other means to store  EVP_MD_CTX and EVP_MD data in local buffers and reuse them in update and Final calls?

Thanks, 
Pavan