Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advice needed for migration of low level OpenSSL API to high level OpenSSL APIs

I am new to OpenSSL and is currently working on a C++ project that has a dependency on OpenSSL. Recently i started using a machine that had openSSL 3.0 installed but is unable to build the project because i get compiler errors like below ( please note that warnings are treated as error in the project)

error: 'MD5' is deprecated
    if (!MD5((uint8_t*)key.data(), key.size(), hashOutput)) {
         ^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/md5.h:52:1: note: 'MD5' has been explicitly marked deprecated here
OSSL_DEPRECATEDIN_3_0 unsigned char *MD5(const unsigned char *d, size_t n,
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/macros.h:182:49: note: expanded from macro 'OSSL_DEPRECATEDIN_3_0'
#   define OSSL_DEPRECATEDIN_3_0                OSSL_DEPRECATED(3.0)
                                                ^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/macros.h:62:52: note: expanded from macro 'OSSL_DEPRECATED'
#     define OSSL_DEPRECATED(since) __attribute__((deprecated))
                                                   ^
1 error generated.

Doing some investigation i found that these API's were deprecated in OpenSSL 3.0.0 and now i have three options

  1. Ignore the warnings. They are just warnings. The deprecated functions are still present and you may still use them. However be aware that they may be removed from a future version of OpenSSL.

  2. Suppress the warnings. Refer to your compiler documentation on how to do this.

  3. Remove your usage of the low level APIs. In this case you will need to rewrite your code to use the high level APIs instead.

I choose the third option but even after reading documentations related to OpenSSL, i am still not sure what is the EVP API equivalent of the MD5 method which got deprecated in OpenSSL 3.0.0. If you check the link https://www.openssl.org/docs/manmaster/man3/MD5.html it states that

All of the functions described on this page are deprecated. Applications should instead use EVP_DigestInit_ex(3), EVP_DigestUpdate(3) and EVP_DigestFinal_ex(3).

Would be great if someone can provide me some feedback/help or additional resources/links that might help me understand using the high Level OpenSSL API's in general so that i can make it work for my use case i.e MD5 encryption.

I must also mention that i downloaded OpenSSL repo from github and found that the implementation of md5 method is as below

    unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
{
    MD5_CTX c;
    static unsigned char m[MD5_DIGEST_LENGTH];

    if (md == NULL)
        md = m;
    if (!MD5_Init(&c))
        return NULL;
#ifndef CHARSET_EBCDIC
    MD5_Update(&c, d, n);
#else
    {
        char temp[1024];
        unsigned long chunk;

        while (n > 0) {
            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
            ebcdic2ascii(temp, d, chunk);
            MD5_Update(&c, temp, chunk);
            n -= chunk;
            d += chunk;
        }
    }
#endif
    MD5_Final(md, &c);
    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
    return md;
}
like image 232
bourne Avatar asked Sep 14 '25 22:09

bourne


1 Answers

I hope this example would help (I'm not checking for errors and exceptions in my example, so be aware of that):

Deprecated Implementation

#include <openssl/md5.h>

static void calculate_md5(unsigned char* buf, unsigned int buf_size)
{
    unsigned char md5_digest[MD5_DIGEST_LENGTH];
    MD5_CTX md5ctx;

    MD5_Init(&md5ctx);
    MD5_Update(&md5ctx, buf, buf_size);
    MD5_Final(md5_digest, &md5ctx);
}

New Implementation:

#include <openssl/evp.h>

static void calculate_md5(unsigned char* buf, unsigned int buf_size)
{
    EVP_MD_CTX *mdctx;
    unsigned char *md5_digest;
    unsigned int md5_digest_len = EVP_MD_size(EVP_md5());
    
    // MD5_Init
    mdctx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);

    // MD5_Update
    EVP_DigestUpdate(mdctx, buf, buf_size);

    // MD5_Final
    md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len);
    EVP_DigestFinal_ex(mdctx, md5_digest, &md5_digest_len);
    EVP_MD_CTX_free(mdctx);
}
like image 64
J.M. Avatar answered Sep 19 '25 06:09

J.M.