Description: Use the OpenSSL EVP_Digest*() functions.
Forwarded: https://github.com/rpm-software-management/drpm/pull/19
Author: Peter Pentchev <roam@ringlet.net>
Last-Update: 2022-09-07

--- a/src/drpm.c
+++ b/src/drpm.c
@@ -513,7 +513,7 @@
     size_t cpio_files_len = 0;
     struct blocks *blks = NULL;
     int filedesc;
-    MD5_CTX md5;
+    EVP_MD_CTX *md5 = NULL;
     unsigned char md5_digest[MD5_DIGEST_LENGTH];
     bool no_full_md5;
     bool has_md5;
@@ -635,7 +635,8 @@
         goto cleanup;
     }
 
-    if (MD5_Init(&md5) != 1) {
+    if (md5 = EVP_MD_CTX_new(), md5 == NULL ||
+        EVP_DigestInit_ex(md5, EVP_md5(), NULL) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup;
     }
@@ -645,7 +646,7 @@
         error = DRPM_ERR_IO;
         goto cleanup;
     }
-    if (!no_full_md5 && MD5_Update(&md5, delta.tgt_leadsig, delta.tgt_leadsig_len) != 1) {
+    if (!no_full_md5 && EVP_DigestUpdate(md5, delta.tgt_leadsig, delta.tgt_leadsig_len) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup;
     }
@@ -659,7 +660,7 @@
             error = DRPM_ERR_IO;
             goto cleanup;
         }
-        if (MD5_Update(&md5, header, header_size) != 1) {
+        if (EVP_DigestUpdate(md5, header, header_size) != 1) {
             error = DRPM_ERR_OTHER;
             goto cleanup;
         }
@@ -730,8 +731,8 @@
         goto cleanup;
 
     /* finalizing MD5 of written data */
-    if (MD5_Update(&md5, comp_data, comp_data_len) != 1 ||
-        MD5_Final(md5_digest, &md5) != 1) {
+    if (EVP_DigestUpdate(md5, comp_data, comp_data_len) != 1 ||
+        EVP_DigestFinal_ex(md5, md5_digest, NULL) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup;
     }
@@ -756,6 +757,9 @@
 
 cleanup:
 
+    if (md5 != NULL)
+        EVP_MD_CTX_free(md5);
+
     close(filedesc);
 
     for (size_t i = 0; i < file_count; i++) {
--- a/src/drpm_apply.c
+++ b/src/drpm_apply.c
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <openssl/sha.h>
 
@@ -37,10 +38,7 @@
 
 struct checksum {
     unsigned short digest_algo;
-    union {
-        MD5_CTX md5;
-        SHA256_CTX sha256;
-    } ctx;
+    EVP_MD_CTX *ctx;
 };
 
 static int check_filesize(const char *, unsigned short, const unsigned char *, size_t);
@@ -68,7 +66,7 @@
     struct cpio_file *seqfiles = NULL;
     size_t *positions;
     size_t positions_len = 0;
-    MD5_CTX seq_md5;
+    EVP_MD_CTX *seq_md5 = NULL;
     unsigned char seq_md5_digest[MD5_DIGEST_LENGTH];
     unsigned char digest[MAX(MD5_DIGEST_LENGTH, SHA256_DIGEST_LENGTH)];
     bool even = true;
@@ -165,7 +163,8 @@
         goto cleanup_fail;
     }
 
-    if (MD5_Init(&seq_md5) != 1) {
+    if ((seq_md5 = EVP_MD_CTX_new(), seq_md5 == NULL) ||
+        EVP_DigestInit_ex(seq_md5, EVP_md5(), NULL) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup_fail;
     }
@@ -192,16 +191,16 @@
         if (filename[0] == '/')
             filename++;
 
-        if (MD5_Update(&seq_md5, filename, strlen(filename) + 1) != 1 ||
-            md5_update_be32(&seq_md5, files[i].mode) != 1 ||
-            md5_update_be32(&seq_md5, filesize) != 1 ||
-            md5_update_be32(&seq_md5, rdev) != 1) {
+        if (EVP_DigestUpdate(seq_md5, filename, strlen(filename) + 1) != 1 ||
+            md5_update_be32(seq_md5, files[i].mode) != 1 ||
+            md5_update_be32(seq_md5, filesize) != 1 ||
+            md5_update_be32(seq_md5, rdev) != 1) {
             error = DRPM_ERR_OTHER;
             goto cleanup_fail;
         }
 
         if (S_ISLNK(files[i].mode)) {
-            if (MD5_Update(&seq_md5, files[i].linkto, strlen(files[i].linkto) + 1) != 1) {
+            if (EVP_DigestUpdate(seq_md5, files[i].linkto, strlen(files[i].linkto) + 1) != 1) {
                 error = DRPM_ERR_OTHER;
                 goto cleanup_fail;
             }
@@ -212,7 +211,7 @@
                     error = DRPM_ERR_FORMAT;
                     goto cleanup_fail;
                 }
-                if (MD5_Update(&seq_md5, digest, MD5_DIGEST_LENGTH) != 1) {
+                if (EVP_DigestUpdate(seq_md5, digest, MD5_DIGEST_LENGTH) != 1) {
                     error = DRPM_ERR_OTHER;
                     goto cleanup_fail;
                 }
@@ -222,7 +221,7 @@
                     error = DRPM_ERR_FORMAT;
                     goto cleanup_fail;
                 }
-                if (MD5_Update(&seq_md5, digest, SHA256_DIGEST_LENGTH) != 1) {
+                if (EVP_DigestUpdate(seq_md5, digest, SHA256_DIGEST_LENGTH) != 1) {
                     error = DRPM_ERR_OTHER;
                     goto cleanup_fail;
                 }
@@ -245,7 +244,7 @@
         }
     }
 
-    if (MD5_Final(seq_md5_digest, &seq_md5) != 1) {
+    if (EVP_DigestFinal_ex(seq_md5, seq_md5_digest, NULL) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup_fail;
     }
@@ -276,6 +275,8 @@
 
 cleanup:
     free(positions);
+    if (seq_md5 != NULL)
+        EVP_MD_CTX_free(seq_md5);
 
     return error;
 }
@@ -432,11 +433,13 @@
 
     switch (digest_algo) {
     case DIGESTALGO_MD5:
-        if (MD5_Init(&chsm->ctx.md5) != 1)
+        if ((chsm->ctx = EVP_MD_CTX_new(), chsm->ctx == NULL) ||
+            EVP_DigestInit_ex(chsm->ctx, EVP_md5(), NULL) != 1)
             return DRPM_ERR_OTHER;
         break;
     case DIGESTALGO_SHA256:
-        if (SHA256_Init(&chsm->ctx.sha256) != 1)
+        if ((chsm->ctx = EVP_MD_CTX_new(), chsm->ctx == NULL) ||
+            EVP_DigestInit_ex(chsm->ctx, EVP_sha256(), NULL) != 1)
             return DRPM_ERR_OTHER;
         break;
     default:
@@ -455,9 +458,9 @@
 
     switch (chsm->digest_algo) {
     case DIGESTALGO_MD5:
-        return MD5_Update(&chsm->ctx.md5, buf, len) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
+        return EVP_DigestUpdate(chsm->ctx, buf, len) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
     case DIGESTALGO_SHA256:
-        return SHA256_Update(&chsm->ctx.sha256, buf, len) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
+        return EVP_DigestUpdate(chsm->ctx, buf, len) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
     default:
         return DRPM_ERR_PROG;
     }
@@ -468,11 +471,16 @@
     if (chsm == NULL || digest == NULL)
         return DRPM_ERR_PROG;
 
+    int res;
     switch (chsm->digest_algo) {
     case DIGESTALGO_MD5:
-        return MD5_Final(digest, &chsm->ctx.md5) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
+        res = EVP_DigestFinal_ex(chsm->ctx, digest, NULL) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
+        EVP_MD_CTX_free(chsm->ctx);
+        return res;
     case DIGESTALGO_SHA256:
-        return SHA256_Final(digest, &chsm->ctx.sha256) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
+        res = EVP_DigestFinal_ex(chsm->ctx, digest, NULL) != 1 ? DRPM_ERR_OTHER : DRPM_ERR_OK;
+        EVP_MD_CTX_free(chsm->ctx);
+        return res;
     default:
         return DRPM_ERR_PROG;
     }
--- a/src/drpm_decompstrm.c
+++ b/src/drpm_decompstrm.c
@@ -37,7 +37,7 @@
 #ifdef WITH_ZSTD
 #include <zstd.h>
 #endif
-#include <openssl/md5.h>
+#include <openssl/evp.h>
 
 /* magic bytes for determining compression type */
 #define MAGIC_BZIP2(x) (((x) >> 40) == 0x425A68)
@@ -67,7 +67,7 @@
     int (*read_chunk)(struct decompstrm *);
     void (*finish)(struct decompstrm *);
     size_t comp_size;
-    MD5_CTX *md5;
+    EVP_MD_CTX *md5;
     const unsigned char *buffer;
     size_t buffer_len;
 };
@@ -261,7 +261,7 @@
  * If <md5> is not NULL, input data will be used to update the MD5 context.
  * If <filedesc> is valid, compressed data will be read from the file.
  * Otherwise, input data is read from <buffer> of size <buffer_len>. */
-int decompstrm_init(struct decompstrm **strm, int filedesc, unsigned short *comp, MD5_CTX *md5,
+int decompstrm_init(struct decompstrm **strm, int filedesc, unsigned short *comp, EVP_MD_CTX *md5,
                     const unsigned char *buffer, size_t buffer_len)
 {
     uint64_t magic;
@@ -478,7 +478,7 @@
 
     strm->comp_size = strm->data_len;
 
-    if (strm->md5 != NULL && MD5_Update(strm->md5, buffer, in_len) != 1)
+    if (strm->md5 != NULL && EVP_DigestUpdate(strm->md5, buffer, in_len) != 1)
         return DRPM_ERR_OTHER;
 
     return DRPM_ERR_OK;
@@ -531,7 +531,7 @@
 
     strm->comp_size += in_len;
 
-    if (strm->md5 != NULL && MD5_Update(strm->md5, in_buffer, in_len) != 1)
+    if (strm->md5 != NULL && EVP_DigestUpdate(strm->md5, in_buffer, in_len) != 1)
         return DRPM_ERR_OTHER;
 
     return DRPM_ERR_OK;
@@ -585,7 +585,7 @@
 
     strm->comp_size += in_len;
 
-    if (strm->md5 != NULL && MD5_Update(strm->md5, in_buffer, in_len) != 1)
+    if (strm->md5 != NULL && EVP_DigestUpdate(strm->md5, in_buffer, in_len) != 1)
         return DRPM_ERR_OTHER;
 
     return DRPM_ERR_OK;
@@ -645,7 +645,7 @@
 
     strm->comp_size += in_len;
 
-    if (strm->md5 != NULL && MD5_Update(strm->md5, in_buffer, in_len) != 1)
+    if (strm->md5 != NULL && EVP_DigestUpdate(strm->md5, in_buffer, in_len) != 1)
         return DRPM_ERR_OTHER;
 
     return DRPM_ERR_OK;
@@ -722,7 +722,7 @@
 
     strm->comp_size += in_len;
 
-    if (strm->md5 != NULL && MD5_Update(strm->md5, in_buffer, in_len) != 1)
+    if (strm->md5 != NULL && EVP_DigestUpdate(strm->md5, in_buffer, in_len) != 1)
         return DRPM_ERR_OTHER;
 
     return DRPM_ERR_OK;
@@ -772,7 +772,7 @@
 
     strm->comp_size += in_len;
 
-    if (strm->md5 != NULL && MD5_Update(strm->md5, in_buffer, in_len) != 1)
+    if (strm->md5 != NULL && EVP_DigestUpdate(strm->md5, in_buffer, in_len) != 1)
         return DRPM_ERR_OTHER;
 
     free(buffOut);
--- a/src/drpm_make.c
+++ b/src/drpm_make.c
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #define __USE_XOPEN 1
 #include <sys/stat.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <openssl/sha.h>
 #include <rpm/rpmfi.h>
@@ -302,7 +303,7 @@
 
     unsigned char *sequence = NULL;
     uint32_t sequence_len;
-    MD5_CTX seq_md5;
+    EVP_MD_CTX *seq_md5 = NULL;
     unsigned char seq_md5_digest[MD5_DIGEST_LENGTH];
     struct files_seq seq = SEQ_INIT;
     unsigned char *seq_files = NULL;
@@ -329,11 +330,15 @@
         *offadjn_ret = 0;
     }
 
-    if (MD5_Init(&seq_md5) != 1)
+    if (seq_md5 = EVP_MD_CTX_new(), seq_md5 == NULL)
         return DRPM_ERR_OTHER;
+    if (EVP_DigestInit_ex(seq_md5, EVP_md5(), NULL) != 1) {
+        EVP_MD_CTX_free(seq_md5);
+        return DRPM_ERR_OTHER;
+    }
 
     if ((error = rpm_get_file_info(rpm_file, &files, &file_count, &file_colors)) != DRPM_ERR_OK)
-        return error;
+        goto cleanup_fail;
 
     if ((error = rpm_get_digest_algo(rpm_file, &digest_algo)) != DRPM_ERR_OK)
         goto cleanup_fail;
@@ -483,10 +488,10 @@
                                      CPIO_PADDING(CPIO_HEADER_SIZE + cpio_hdr.namesize))) != DRPM_ERR_OK)
                 goto cleanup_fail;
 
-            if (MD5_Update(&seq_md5, name, name_len) != 1 ||
-                md5_update_be32(&seq_md5, cpio_hdr.mode) != 1 ||
-                md5_update_be32(&seq_md5, cpio_hdr.filesize) != 1 ||
-                md5_update_be32(&seq_md5, makedev(cpio_hdr.rdevmajor,
+            if (EVP_DigestUpdate(seq_md5, name, name_len) != 1 ||
+                md5_update_be32(seq_md5, cpio_hdr.mode) != 1 ||
+                md5_update_be32(seq_md5, cpio_hdr.filesize) != 1 ||
+                md5_update_be32(seq_md5, makedev(cpio_hdr.rdevmajor,
                                                   cpio_hdr.rdevminor)) != 1) {
                 error = DRPM_ERR_OTHER;
                 goto cleanup_fail;
@@ -496,7 +501,7 @@
                 if ((error = cpio_extend(&cpio, &cpio_len, file.linkto, cpio_hdr.filesize)) != DRPM_ERR_OK ||
                     (error = cpio_extend(&cpio, &cpio_len, "\0\0\0", CPIO_PADDING(cpio_hdr.filesize))) != DRPM_ERR_OK)
                     goto cleanup_fail;
-                if (MD5_Update(&seq_md5, file.linkto, cpio_hdr.filesize + 1) != 1) {
+                if (EVP_DigestUpdate(seq_md5, file.linkto, cpio_hdr.filesize + 1) != 1) {
                     error = DRPM_ERR_OTHER;
                     goto cleanup_fail;
                 }
@@ -507,7 +512,7 @@
                         error = DRPM_ERR_FORMAT;
                         goto cleanup_fail;
                     }
-                    if (MD5_Update(&seq_md5, digest, MD5_DIGEST_LENGTH) != 1) {
+                    if (EVP_DigestUpdate(seq_md5, digest, MD5_DIGEST_LENGTH) != 1) {
                         error = DRPM_ERR_OTHER;
                         goto cleanup_fail;
                     }
@@ -517,7 +522,7 @@
                         error = DRPM_ERR_FORMAT;
                         goto cleanup_fail;
                     }
-                    if (MD5_Update(&seq_md5, digest, SHA256_DIGEST_LENGTH) != 1) {
+                    if (EVP_DigestUpdate(seq_md5, digest, SHA256_DIGEST_LENGTH) != 1) {
                         error = DRPM_ERR_OTHER;
                         goto cleanup_fail;
                     }
@@ -574,7 +579,7 @@
     if ((error = seq_final(&seq, &seq_files, &seq_files_len)) != DRPM_ERR_OK)
         goto cleanup_fail;
 
-    if (MD5_Final(seq_md5_digest, &seq_md5) != 1) {
+    if (EVP_DigestFinal_ex(seq_md5, seq_md5_digest, NULL) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup_fail;
     }
@@ -614,6 +619,8 @@
     free(files);
     free(name_buffer);
     free(seq_files);
+    if (seq_md5 != NULL)
+        EVP_MD_CTX_free(seq_md5);
 
     return error;
 }
--- a/src/drpm_private.h
+++ b/src/drpm_private.h
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <unistd.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 
 #define CHUNK_SIZE 1024
@@ -153,7 +154,7 @@
 //drpm_decompstrm.c
 int decompstrm_destroy(struct decompstrm **);
 int decompstrm_get_comp_size(struct decompstrm *, size_t *);
-int decompstrm_init(struct decompstrm **, int, unsigned short *, MD5_CTX *, const unsigned char *, size_t);
+int decompstrm_init(struct decompstrm **, int, unsigned short *, EVP_MD_CTX *, const unsigned char *, size_t);
 int decompstrm_read(struct decompstrm *, size_t, void *);
 int decompstrm_read_be32(struct decompstrm *, uint32_t *);
 int decompstrm_read_be64(struct decompstrm *, uint64_t *);
@@ -232,7 +233,7 @@
 void create_be32(uint32_t, unsigned char *);
 void create_be64(uint64_t, unsigned char *);
 void dump_hex(char *, const unsigned char *, size_t);
-int md5_update_be32(MD5_CTX *, uint32_t);
+int md5_update_be32(EVP_MD_CTX *, uint32_t);
 uint16_t parse_be16(const unsigned char *);
 uint32_t parse_be32(const unsigned char *);
 uint64_t parse_be64(const unsigned char *);
--- a/src/drpm_rpm.c
+++ b/src/drpm_rpm.c
@@ -28,6 +28,7 @@
 #include <rpm/rpmlib.h>
 #include <rpm/rpmts.h>
 #include <rpm/rpmdb.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 
 #define BUFFER_SIZE 4096
@@ -56,7 +57,7 @@
 static int rpm_export_signature(struct rpm *, unsigned char **, size_t *);
 static void rpm_header_unload_region(struct rpm *, rpmTagVal);
 static int rpm_read_archive(struct rpm *, const char *, off_t, bool,
-                            unsigned short *, MD5_CTX *, MD5_CTX *);
+                            unsigned short *, EVP_MD_CTX *, EVP_MD_CTX *);
 
 void rpm_init(struct rpm *rpmst)
 {
@@ -176,14 +177,14 @@
 
 int rpm_read_archive(struct rpm *rpmst, const char *filename,
                      off_t offset, bool decompress, unsigned short *comp_ret,
-                     MD5_CTX *seq_md5, MD5_CTX *full_md5)
+                     EVP_MD_CTX *seq_md5, EVP_MD_CTX *full_md5)
 {
     struct decompstrm *stream = NULL;
     int filedesc;
     unsigned char *archive_tmp;
     unsigned char buffer[BUFFER_SIZE];
     ssize_t bytes_read;
-    MD5_CTX *md5;
+    EVP_MD_CTX *md5;
     int error = DRPM_ERR_OK;
 
     if ((filedesc = open(filename, O_RDONLY)) < 0)
@@ -210,8 +211,8 @@
                 error = DRPM_ERR_MEMORY;
                 goto cleanup;
             }
-            if ((seq_md5 != NULL && MD5_Update(seq_md5, buffer, bytes_read) != 1) ||
-                (full_md5 != NULL && MD5_Update(full_md5, buffer, bytes_read) != 1)) {
+            if ((seq_md5 != NULL && EVP_DigestUpdate(seq_md5, buffer, bytes_read) != 1) ||
+                (full_md5 != NULL && EVP_DigestUpdate(full_md5, buffer, bytes_read) != 1)) {
                 error = DRPM_ERR_OTHER;
                 goto cleanup;
             }
@@ -252,8 +253,8 @@
     off_t file_pos;
     bool include_archive;
     bool decomp_archive = false;
-    MD5_CTX seq_md5;
-    MD5_CTX full_md5;
+    EVP_MD_CTX *seq_md5 = NULL;
+    EVP_MD_CTX *full_md5 = NULL;
     unsigned char *signature = NULL;
     size_t signature_len;
     unsigned char *header = NULL;
@@ -301,8 +302,9 @@
     if (seq_md5_digest != NULL) {
         if ((error = rpm_export_header(*rpmst, &header, &header_len)) != DRPM_ERR_OK)
             goto cleanup_fail;
-        if (MD5_Init(&seq_md5) != 1 ||
-            MD5_Update(&seq_md5, header, header_len) != 1) {
+        if ((seq_md5 = EVP_MD_CTX_new(), seq_md5 == NULL) ||
+            EVP_DigestInit_ex(seq_md5, EVP_md5(), NULL) != 1 ||
+            EVP_DigestUpdate(seq_md5, header, header_len) != 1) {
             error = DRPM_ERR_OTHER;
             goto cleanup_fail;
         }
@@ -312,10 +314,11 @@
         if ((error = rpm_export_signature(*rpmst, &signature, &signature_len)) != DRPM_ERR_OK ||
             (header == NULL && (error = rpm_export_header(*rpmst, &header, &header_len)) != DRPM_ERR_OK))
             goto cleanup_fail;
-        if (MD5_Init(&full_md5) != 1 ||
-            MD5_Update(&full_md5, (*rpmst)->lead, RPMLEAD_SIZE) != 1 ||
-            MD5_Update(&full_md5, signature, signature_len) != 1 ||
-            MD5_Update(&full_md5, header, header_len) != 1) {
+        if ((full_md5 = EVP_MD_CTX_new(), full_md5 == NULL) ||
+            EVP_DigestInit_ex(full_md5, EVP_md5(), NULL) != 1 ||
+            EVP_DigestUpdate(full_md5, (*rpmst)->lead, RPMLEAD_SIZE) != 1 ||
+            EVP_DigestUpdate(full_md5, signature, signature_len) != 1 ||
+            EVP_DigestUpdate(full_md5, header, header_len) != 1) {
             error = DRPM_ERR_OTHER;
             goto cleanup_fail;
         }
@@ -328,13 +331,13 @@
         }
         if ((error = rpm_read_archive(*rpmst, filename, file_pos,
                                       decomp_archive, archive_comp,
-                                      (seq_md5_digest != NULL) ? &seq_md5 : NULL,
-                                      (full_md5_digest != NULL) ? &full_md5 : NULL)) != DRPM_ERR_OK)
+                                      (seq_md5_digest != NULL) ? seq_md5 : NULL,
+                                      (full_md5_digest != NULL) ? full_md5 : NULL)) != DRPM_ERR_OK)
             goto cleanup_fail;
     }
 
-    if ((seq_md5_digest != NULL && MD5_Final(seq_md5_digest, &seq_md5) != 1) ||
-        (full_md5_digest != NULL && MD5_Final(full_md5_digest, &full_md5) != 1)) {
+    if ((seq_md5_digest != NULL && EVP_DigestFinal_ex(seq_md5, seq_md5_digest, NULL) != 1) ||
+        (full_md5_digest != NULL && EVP_DigestFinal_ex(full_md5, full_md5_digest, NULL) != 1)) {
         error = DRPM_ERR_OTHER;
         goto cleanup_fail;
     }
@@ -348,6 +351,10 @@
     free(signature);
     free(header);
     Fclose(file);
+    if (full_md5 != NULL)
+        EVP_MD_CTX_free(full_md5);
+    if (seq_md5 != NULL)
+        EVP_MD_CTX_free(seq_md5);
 
     return error;
 }
@@ -490,7 +497,7 @@
     size_t signature_len;
     unsigned char *header = NULL;
     size_t header_len;
-    MD5_CTX md5;
+    EVP_MD_CTX *md5 = NULL;
 
     if (rpmst == NULL)
         return DRPM_ERR_PROG;
@@ -511,11 +518,12 @@
     }
 
     if (digest != NULL) {
-        if (MD5_Init(&md5) != 1 ||
+        if ((md5 = EVP_MD_CTX_new(), md5 == NULL) ||
+            EVP_DigestInit_ex(md5, EVP_md5(), NULL) != 1 ||
             (full_md5 &&
-             (MD5_Update(&md5, rpmst->lead, RPMLEAD_SIZE) != 1 ||
-              MD5_Update(&md5, signature, signature_len) != 1)) ||
-            MD5_Update(&md5, header, header_len) != 1) {
+             (EVP_DigestUpdate(md5, rpmst->lead, RPMLEAD_SIZE) != 1 ||
+              EVP_DigestUpdate(md5, signature, signature_len) != 1)) ||
+            EVP_DigestUpdate(md5, header, header_len) != 1) {
             error = DRPM_ERR_OTHER;
             goto cleanup;
         }
@@ -527,13 +535,13 @@
             error = DRPM_ERR_IO;
             goto cleanup;
         }
-        if (digest != NULL && MD5_Update(&md5, rpmst->archive, rpmst->archive_size) != 1) {
+        if (digest != NULL && EVP_DigestUpdate(md5, rpmst->archive, rpmst->archive_size) != 1) {
             error = DRPM_ERR_OTHER;
             goto cleanup;
         }
     }
 
-    if (digest != NULL && MD5_Final(digest, &md5) != 1) {
+    if (digest != NULL && EVP_DigestFinal_ex(md5, digest, NULL) != 1) {
         error = DRPM_ERR_OTHER;
         goto cleanup;
     }
@@ -542,6 +550,8 @@
     Fclose(file);
     free(signature);
     free(header);
+    if (md5 != NULL)
+        EVP_MD_CTX_free(md5);
 
     return error;
 }
--- a/src/drpm_utils.c
+++ b/src/drpm_utils.c
@@ -28,6 +28,7 @@
 #include <stdbool.h>
 #include <ctype.h>
 #include <sys/types.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <openssl/sha.h>
 
@@ -83,13 +84,13 @@
     out[7] = in;
 }
 
-int md5_update_be32(MD5_CTX *md5, uint32_t number)
+int md5_update_be32(EVP_MD_CTX *md5, uint32_t number)
 {
     unsigned char be32[4];
 
     create_be32(number, be32);
 
-    return MD5_Update(md5, be32, 4);
+    return EVP_DigestUpdate(md5, be32, 4);
 }
 
 /* Represents array of bytes pointed to by <source> of size <count>
--- a/src/drpm_write.c
+++ b/src/drpm_write.c
@@ -25,6 +25,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <fcntl.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <rpm/rpmlib.h>
 
@@ -77,7 +78,7 @@
     uint32_t ext_copies_size;
     unsigned char *header = NULL;
     uint32_t header_size;
-    MD5_CTX md5;
+    EVP_MD_CTX *md5 = NULL;
     unsigned char md5_digest[MD5_DIGEST_LENGTH] = {0};
     unsigned char *strm_data = NULL;
     size_t strm_data_len;
@@ -211,11 +212,16 @@
         if ((error = rpm_fetch_header(delta->head.tgt_rpm, &header, &header_size)) != DRPM_ERR_OK)
             return error;
 
-        if (MD5_Init(&md5) != 1 ||
-            MD5_Update(&md5, header, header_size) != 1 ||
-            MD5_Update(&md5, strm_data, strm_data_len) != 1 ||
-            MD5_Final(md5_digest, &md5) != 1)
+        if ((md5 = EVP_MD_CTX_new(), md5 == NULL) ||
+            EVP_DigestInit_ex(md5, EVP_md5(), NULL) != 1 ||
+            EVP_DigestUpdate(md5, header, header_size) != 1 ||
+            EVP_DigestUpdate(md5, strm_data, strm_data_len) != 1 ||
+            EVP_DigestFinal_ex(md5, md5_digest, NULL) != 1) {
+            if (md5 != NULL)
+                EVP_MD_CTX_free(md5);
             return DRPM_ERR_OTHER;
+        }
+        EVP_MD_CTX_free(md5);
 
         if ((error = rpm_signature_empty(delta->head.tgt_rpm)) != DRPM_ERR_OK ||
             (error = rpm_signature_set_size(delta->head.tgt_rpm, header_size + strm_data_len)) != DRPM_ERR_OK ||
