diff --git a/checksum.c b/checksum.c
--- a/checksum.c
+++ b/checksum.c
-@@ -51,6 +51,9 @@ struct name_num_obj valid_checksums = {
- #ifdef SUPPORT_XXHASH
- { CSUM_XXH64, "xxh64", NULL },
- { CSUM_XXH64, "xxhash", NULL },
-+#endif
-+#ifdef SHA_DIGEST_LENGTH
-+ { CSUM_SHA1, "sha1", NULL },
+@@ -54,6 +54,15 @@ struct name_num_obj valid_checksums = {
#endif
{ CSUM_MD5, "md5", NULL },
{ CSUM_MD4, "md4", NULL },
-@@ -61,6 +64,9 @@ struct name_num_obj valid_checksums = {
++#ifdef SHA_DIGEST_LENGTH
++ { CSUM_SHA1, "sha1", NULL },
++#endif
++#ifdef SHA256_DIGEST_LENGTH
++ { CSUM_SHA256, "sha256", NULL },
++#endif
++#ifdef SHA512_DIGEST_LENGTH
++ { CSUM_SHA512, "sha512", NULL },
++#endif
+ { CSUM_NONE, "none", NULL },
+ { 0, NULL, NULL }
+ }
+@@ -61,6 +70,15 @@ struct name_num_obj valid_checksums = {
struct name_num_obj valid_auth_checksums = {
"daemon auth checksum", NULL, NULL, 0, 0, {
++#ifdef SHA512_DIGEST_LENGTH
++ { CSUM_SHA512, "sha512", NULL },
++#endif
++#ifdef SHA256_DIGEST_LENGTH
++ { CSUM_SHA256, "sha256", NULL },
++#endif
+#ifdef SHA_DIGEST_LENGTH
+ { CSUM_SHA1, "sha1", NULL },
+#endif
{ CSUM_MD5, "md5", NULL },
{ CSUM_MD4, "md4", NULL },
{ 0, NULL, NULL }
-@@ -155,6 +161,10 @@ int csum_len_for_type(int cst, BOOL flist_csum)
+@@ -155,6 +173,18 @@ int csum_len_for_type(int cst, BOOL flist_csum)
return MD4_DIGEST_LEN;
case CSUM_MD5:
return MD5_DIGEST_LEN;
+#ifdef SHA_DIGEST_LENGTH
+ case CSUM_SHA1:
+ return SHA_DIGEST_LENGTH;
++#endif
++#ifdef SHA256_DIGEST_LENGTH
++ case CSUM_SHA256:
++ return SHA256_DIGEST_LENGTH;
++#endif
++#ifdef SHA512_DIGEST_LENGTH
++ case CSUM_SHA512:
++ return SHA512_DIGEST_LENGTH;
+#endif
case CSUM_XXH64:
case CSUM_XXH3_64:
return 64/8;
-@@ -180,6 +190,7 @@ int canonical_checksum(int csum_type)
+@@ -180,6 +210,9 @@ int canonical_checksum(int csum_type)
break;
case CSUM_MD4:
case CSUM_MD5:
+ case CSUM_SHA1:
++ case CSUM_SHA256:
++ case CSUM_SHA512:
return -1;
case CSUM_XXH64:
case CSUM_XXH3_64:
-@@ -232,6 +243,18 @@ void get_checksum2(char *buf, int32 len, char *sum)
+@@ -232,6 +265,26 @@ void get_checksum2(char *buf, int32 len, char *sum)
SIVAL64(sum, 8, digest.high64);
break;
}
+#endif
+#ifdef SHA_DIGEST_LENGTH
-+ case CSUM_SHA1: {
-+ SHA_CTX sha;
++ case CSUM_SHA1:
++ case CSUM_SHA256:
++ case CSUM_SHA512: {
++ static EVP_MD_CTX *evp = NULL;
++ static const EVP_MD *emd = NULL;
+ uchar seedbuf[4];
-+ SHA1_Init(&sha);
++ if (!evp) {
++ if (!(evp = EVP_MD_CTX_create()))
++ out_of_memory("get_checksum2");
++ emd = EVP_get_digestbyname(checksum_name(xfer_sum_type));
++ }
++ EVP_DigestInit_ex(evp, emd, NULL);
+ SIVALu(seedbuf, 0, checksum_seed);
-+ SHA1_Update(&sha, seedbuf, 4);
-+ SHA1_Update(&sha, (uchar *)buf, len);
-+ SHA1_Final((uchar *)sum, &sha);
++ EVP_DigestUpdate(evp, seedbuf, 4);
++ EVP_DigestUpdate(evp, (uchar *)buf, len);
++ EVP_DigestFinal_ex(evp, (uchar *)sum, NULL);
+ break;
+ }
#endif
case CSUM_MD5: {
md5_context m5;
-@@ -384,6 +407,23 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+@@ -384,6 +437,31 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
SIVAL64(sum, 8, digest.high64);
break;
}
+#endif
+#ifdef SHA_DIGEST_LENGTH
-+ case CSUM_SHA1: {
-+ SHA_CTX sha;
++ case CSUM_SHA1:
++ case CSUM_SHA256:
++ case CSUM_SHA512: {
++ static EVP_MD_CTX *evp = NULL;
++ static const EVP_MD *emd = NULL;
++ if (!evp) {
++ if (!(evp = EVP_MD_CTX_create()))
++ out_of_memory("file_checksum");
++ emd = EVP_get_digestbyname(checksum_name(xfer_sum_type));
++ }
+
-+ SHA1_Init(&sha);
++ EVP_DigestInit_ex(evp, emd, NULL);
+
+ for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
-+ SHA1_Update(&sha, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
++ EVP_DigestUpdate(evp, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
+
+ remainder = (int32)(len - i);
+ if (remainder > 0)
-+ SHA1_Update(&sha, (uchar *)map_ptr(buf, i, remainder), remainder);
++ EVP_DigestUpdate(evp, (uchar *)map_ptr(buf, i, remainder), remainder);
+
-+ SHA1_Final((uchar *)sum, &sha);
++ EVP_DigestFinal_ex(evp, (uchar *)sum, NULL);
+ break;
+ }
#endif
case CSUM_MD5: {
md5_context m5;
-@@ -454,6 +494,9 @@ static union {
- md_context md;
- #ifdef USE_OPENSSL
- MD4_CTX m4;
-+#endif
-+#ifdef SHA_DIGEST_LENGTH
-+ SHA_CTX sha;
+@@ -457,6 +535,9 @@ static union {
#endif
md5_context m5;
} ctx;
-@@ -494,6 +537,11 @@ int sum_init(int csum_type, int seed)
++#ifdef SHA_DIGEST_LENGTH
++EVP_MD_CTX *ctx_evp = NULL;
++#endif
+ #ifdef SUPPORT_XXHASH
+ static XXH64_state_t* xxh64_state;
+ #endif
+@@ -494,6 +575,17 @@ int sum_init(int csum_type, int seed)
out_of_memory("sum_init");
XXH3_128bits_reset(xxh3_state);
break;
+#endif
+#ifdef SHA_DIGEST_LENGTH
+ case CSUM_SHA1:
-+ SHA1_Init(&ctx.sha);
++ case CSUM_SHA256:
++ case CSUM_SHA512: {
++ const EVP_MD *emd = EVP_get_digestbyname(checksum_name(csum_type));
++ if (!ctx_evp && !(ctx_evp = EVP_MD_CTX_create()))
++ out_of_memory("file_checksum");
++ EVP_DigestInit_ex(ctx_evp, emd, NULL);
+ break;
++ }
#endif
case CSUM_MD5:
md5_begin(&ctx.m5);
-@@ -546,6 +594,11 @@ void sum_update(const char *p, int32 len)
+@@ -546,6 +638,13 @@ void sum_update(const char *p, int32 len)
case CSUM_XXH3_128:
XXH3_128bits_update(xxh3_state, p, len);
break;
+#endif
+#ifdef SHA_DIGEST_LENGTH
+ case CSUM_SHA1:
-+ SHA1_Update(&ctx.sha, (uchar *)p, len);
++ case CSUM_SHA256:
++ case CSUM_SHA512:
++ EVP_DigestUpdate(ctx_evp, (uchar *)p, len);
+ break;
#endif
case CSUM_MD5:
md5_update(&ctx.m5, (uchar *)p, len);
-@@ -611,6 +664,11 @@ void sum_end(char *sum)
+@@ -611,6 +710,13 @@ void sum_end(char *sum)
SIVAL64(sum, 8, digest.high64);
break;
}
+#endif
+#ifdef SHA_DIGEST_LENGTH
+ case CSUM_SHA1:
-+ SHA1_Final((uchar *)sum, &ctx.sha);
++ case CSUM_SHA256:
++ case CSUM_SHA512:
++ EVP_DigestFinal_ex(ctx_evp, (uchar *)sum, NULL);
+ break;
#endif
case CSUM_MD5:
diff --git a/lib/md-defines.h b/lib/md-defines.h
--- a/lib/md-defines.h
+++ b/lib/md-defines.h
-@@ -2,7 +2,11 @@
+@@ -1,8 +1,19 @@
+ /* Keep this simple so both C and ASM can use it */
++/*#undef SHA512_DIGEST_LENGTH*/
++/*#undef SHA256_DIGEST_LENGTH*/
++
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
-+#ifdef SHA_DIGEST_LENGTH
++#if defined SHA512_DIGEST_LENGTH
++#define MAX_DIGEST_LEN SHA512_DIGEST_LENGTH
++#elif defined SHA256_DIGEST_LENGTH
++#define MAX_DIGEST_LEN SHA256_DIGEST_LENGTH
++#elif defined SHA_DIGEST_LENGTH
+#define MAX_DIGEST_LEN SHA_DIGEST_LENGTH
+#else
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#define CSUM_CHUNK 64
-@@ -15,3 +19,4 @@
+@@ -15,3 +26,6 @@
#define CSUM_XXH64 6
#define CSUM_XXH3_64 7
#define CSUM_XXH3_128 8
+#define CSUM_SHA1 9
++#define CSUM_SHA256 10
++#define CSUM_SHA512 11
diff --git a/lib/mdigest.h b/lib/mdigest.h
--- a/lib/mdigest.h
+++ b/lib/mdigest.h
-@@ -3,6 +3,7 @@
+@@ -3,6 +3,8 @@
#ifdef USE_OPENSSL
#include "openssl/md4.h"
#include "openssl/md5.h"
+#include <openssl/sha.h>
++#include <openssl/evp.h>
#endif
#include "md-defines.h"