2 * Routines to support checksumming of bytes.
4 * Copyright (C) 1996 Andrew Tridgell
5 * Copyright (C) 1996 Paul Mackerras
6 * Copyright (C) 2004-2022 Wayne Davison
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * In addition, as a special exception, the copyright holders give
14 * permission to dynamically link rsync with the OpenSSL and xxhash
15 * libraries when those libraries are being distributed in compliance
16 * with their license terms, and to distribute a dynamically linked
17 * combination of rsync and these libraries. This is also considered
18 * to be covered under the GPL's System Libraries exception.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, visit the http://fsf.org website.
33 # if XXH_VERSION_NUMBER >= 800
34 # define SUPPORT_XXH3 1
39 extern int whole_file
;
40 extern int checksum_seed
;
41 extern int protocol_version
;
42 extern int proper_seed_order
;
43 extern const char *checksum_choice
;
45 #define NNI_BUILTIN (1<<0)
46 #define NNI_EVP (1<<1)
47 #define NNI_EVP_OK (1<<2)
49 struct name_num_item valid_checksums_items
[] = {
51 { CSUM_XXH3_128
, 0, "xxh128", NULL
},
52 { CSUM_XXH3_64
, 0, "xxh3", NULL
},
55 { CSUM_XXH64
, 0, "xxh64", NULL
},
56 { CSUM_XXH64
, 0, "xxhash", NULL
},
58 { CSUM_MD5
, NNI_BUILTIN
|NNI_EVP
, "md5", NULL
},
59 { CSUM_MD4
, NNI_BUILTIN
|NNI_EVP
, "md4", NULL
},
60 #ifdef SHA_DIGEST_LENGTH
61 { CSUM_SHA1
, NNI_EVP
, "sha1", NULL
},
63 { CSUM_NONE
, 0, "none", NULL
},
67 struct name_num_obj valid_checksums
= {
68 "checksum", NULL
, 0, 0, valid_checksums_items
71 struct name_num_item valid_auth_checksums_items
[] = {
72 #ifdef SHA512_DIGEST_LENGTH
73 { CSUM_SHA512
, NNI_EVP
, "sha512", NULL
},
75 #ifdef SHA256_DIGEST_LENGTH
76 { CSUM_SHA256
, NNI_EVP
, "sha256", NULL
},
78 #ifdef SHA_DIGEST_LENGTH
79 { CSUM_SHA1
, NNI_EVP
, "sha1", NULL
},
81 { CSUM_MD5
, NNI_BUILTIN
|NNI_EVP
, "md5", NULL
},
82 { CSUM_MD4
, NNI_BUILTIN
|NNI_EVP
, "md4", NULL
},
86 struct name_num_obj valid_auth_checksums
= {
87 "daemon auth checksum", NULL
, 0, 0, valid_auth_checksums_items
90 /* These cannot make use of openssl, so they're marked just as built-in */
91 struct name_num_item implied_checksum_md4
=
92 { CSUM_MD4
, NNI_BUILTIN
, "md4", NULL
};
93 struct name_num_item implied_checksum_md5
=
94 { CSUM_MD5
, NNI_BUILTIN
, "md5", NULL
};
96 struct name_num_item
*xfer_sum_nni
; /* used for the transfer checksum2 computations */
98 struct name_num_item
*file_sum_nni
; /* used for the pre-transfer --checksum computations */
99 int file_sum_len
, file_sum_extra_cnt
;
102 const EVP_MD
*xfer_sum_evp_md
;
103 const EVP_MD
*file_sum_evp_md
;
104 EVP_MD_CTX
*ctx_evp
= NULL
;
107 static int initialized_choices
= 0;
109 struct name_num_item
*parse_csum_name(const char *name
, int len
)
111 struct name_num_item
*nni
;
116 init_checksum_choices();
118 if (!name
|| (len
== 4 && strncasecmp(name
, "auto", 4) == 0)) {
119 if (protocol_version
>= 30) {
120 if (!proper_seed_order
)
121 return &implied_checksum_md5
;
125 if (protocol_version
>= 27)
126 implied_checksum_md4
.num
= CSUM_MD4_OLD
;
127 else if (protocol_version
>= 21)
128 implied_checksum_md4
.num
= CSUM_MD4_BUSTED
;
130 implied_checksum_md4
.num
= CSUM_MD4_ARCHAIC
;
131 return &implied_checksum_md4
;
135 nni
= get_nni_by_name(&valid_checksums
, name
, len
);
138 rprintf(FERROR
, "unknown checksum name: %s\n", name
);
139 exit_cleanup(RERR_UNSUPPORTED
);
146 static const EVP_MD
*csum_evp_md(struct name_num_item
*nni
)
149 if (!(nni
->flags
& NNI_EVP
))
153 if (nni
->num
== CSUM_MD5
)
157 emd
= EVP_get_digestbyname(nni
->name
);
158 if (emd
&& !(nni
->flags
& NNI_EVP_OK
)) { /* Make sure it works before we advertise it */
159 if (!ctx_evp
&& !(ctx_evp
= EVP_MD_CTX_create()))
160 out_of_memory("csum_evp_md");
161 /* Some routines are marked as legacy and are not enabled in the openssl.cnf file.
162 * If we can't init the emd, we'll fall back to our built-in code. */
163 if (EVP_DigestInit_ex(ctx_evp
, emd
, NULL
) == 0)
166 nni
->flags
= (nni
->flags
& ~NNI_BUILTIN
) | NNI_EVP_OK
;
169 nni
->flags
&= ~NNI_EVP
;
174 void parse_checksum_choice(int final_call
)
176 if (valid_checksums
.negotiated_nni
)
177 xfer_sum_nni
= file_sum_nni
= valid_checksums
.negotiated_nni
;
179 char *cp
= checksum_choice
? strchr(checksum_choice
, ',') : NULL
;
181 xfer_sum_nni
= parse_csum_name(checksum_choice
, cp
- checksum_choice
);
182 file_sum_nni
= parse_csum_name(cp
+1, -1);
184 xfer_sum_nni
= file_sum_nni
= parse_csum_name(checksum_choice
, -1);
185 if (am_server
&& checksum_choice
)
186 validate_choice_vs_env(NSTR_CHECKSUM
, xfer_sum_nni
->num
, file_sum_nni
->num
);
188 xfer_sum_len
= csum_len_for_type(xfer_sum_nni
->num
, 0);
189 file_sum_len
= csum_len_for_type(file_sum_nni
->num
, 0);
191 xfer_sum_evp_md
= csum_evp_md(xfer_sum_nni
);
192 file_sum_evp_md
= csum_evp_md(file_sum_nni
);
195 file_sum_extra_cnt
= (file_sum_len
+ EXTRA_LEN
- 1) / EXTRA_LEN
;
197 if (xfer_sum_nni
->num
== CSUM_NONE
)
200 /* Snag the checksum name for both write_batch's option output & the following debug output. */
201 if (valid_checksums
.negotiated_nni
)
202 checksum_choice
= valid_checksums
.negotiated_nni
->name
;
203 else if (checksum_choice
== NULL
)
204 checksum_choice
= xfer_sum_nni
->name
;
206 if (final_call
&& DEBUG_GTE(NSTR
, am_server
? 3 : 1)) {
207 rprintf(FINFO
, "%s%s checksum: %s\n",
208 am_server
? "Server" : "Client",
209 valid_checksums
.negotiated_nni
? " negotiated" : "",
214 int csum_len_for_type(int cst
, BOOL flist_csum
)
219 case CSUM_MD4_ARCHAIC
:
220 /* The oldest checksum code is rather weird: the file-list code only sent
221 * 2-byte checksums, but all other checksums were full MD4 length. */
222 return flist_csum
? 2 : MD4_DIGEST_LEN
;
225 case CSUM_MD4_BUSTED
:
226 return MD4_DIGEST_LEN
;
228 return MD5_DIGEST_LEN
;
229 #ifdef SHA_DIGEST_LENGTH
231 return SHA_DIGEST_LENGTH
;
233 #ifdef SHA256_DIGEST_LENGTH
235 return SHA256_DIGEST_LENGTH
;
237 #ifdef SHA512_DIGEST_LENGTH
239 return SHA512_DIGEST_LENGTH
;
246 default: /* paranoia to prevent missing case values */
247 exit_cleanup(RERR_UNSUPPORTED
);
252 /* Returns 0 if the checksum is not canonical (i.e. it includes a seed value).
253 * Returns 1 if the public sum order matches our internal sum order.
254 * Returns -1 if the public sum order is the reverse of our internal sum order.
256 int canonical_checksum(int csum_type
)
260 case CSUM_MD4_ARCHAIC
:
262 case CSUM_MD4_BUSTED
:
274 default: /* paranoia to prevent missing case values */
275 exit_cleanup(RERR_UNSUPPORTED
);
280 #ifndef USE_ROLL_SIMD /* See simd-checksum-*.cpp. */
282 a simple 32 bit checksum that can be updated from either end
283 (inspired by Mark Adler's Adler-32 checksum)
285 uint32
get_checksum1(char *buf1
, int32 len
)
289 schar
*buf
= (schar
*)buf1
;
292 for (i
= 0; i
< (len
-4); i
+=4) {
293 s2
+= 4*(s1
+ buf
[i
]) + 3*buf
[i
+1] + 2*buf
[i
+2] + buf
[i
+3] + 10*CHAR_OFFSET
;
294 s1
+= (buf
[i
+0] + buf
[i
+1] + buf
[i
+2] + buf
[i
+3] + 4*CHAR_OFFSET
);
296 for (; i
< len
; i
++) {
297 s1
+= (buf
[i
]+CHAR_OFFSET
); s2
+= s1
;
299 return (s1
& 0xffff) + (s2
<< 16);
303 void get_checksum2(char *buf
, int32 len
, char *sum
)
306 if (xfer_sum_evp_md
) {
307 static EVP_MD_CTX
*evp
= NULL
;
309 if (!evp
&& !(evp
= EVP_MD_CTX_create()))
310 out_of_memory("get_checksum2");
311 EVP_DigestInit_ex(evp
, xfer_sum_evp_md
, NULL
);
313 SIVALu(seedbuf
, 0, checksum_seed
);
314 EVP_DigestUpdate(evp
, seedbuf
, 4);
316 EVP_DigestUpdate(evp
, (uchar
*)buf
, len
);
317 EVP_DigestFinal_ex(evp
, (uchar
*)sum
, NULL
);
320 switch (xfer_sum_nni
->num
) {
321 #ifdef SUPPORT_XXHASH
323 SIVAL64(sum
, 0, XXH64(buf
, len
, checksum_seed
));
328 SIVAL64(sum
, 0, XXH3_64bits_withSeed(buf
, len
, checksum_seed
));
330 case CSUM_XXH3_128
: {
331 XXH128_hash_t digest
= XXH3_128bits_withSeed(buf
, len
, checksum_seed
);
332 SIVAL64(sum
, 0, digest
.low64
);
333 SIVAL64(sum
, 8, digest
.high64
);
341 if (proper_seed_order
) {
343 SIVALu(seedbuf
, 0, checksum_seed
);
344 md5_update(&m5
, seedbuf
, 4);
346 md5_update(&m5
, (uchar
*)buf
, len
);
348 md5_update(&m5
, (uchar
*)buf
, len
);
350 SIVALu(seedbuf
, 0, checksum_seed
);
351 md5_update(&m5
, seedbuf
, 4);
354 md5_result(&m5
, (uchar
*)sum
);
359 case CSUM_MD4_BUSTED
:
360 case CSUM_MD4_ARCHAIC
: {
371 buf1
= new_array(char, len
+4);
375 memcpy(buf1
, buf
, len
);
377 SIVAL(buf1
,len
,checksum_seed
);
381 for (i
= 0; i
+ CSUM_CHUNK
<= len
; i
+= CSUM_CHUNK
)
382 mdfour_update(&m
, (uchar
*)(buf1
+i
), CSUM_CHUNK
);
385 * Prior to version 27 an incorrect MD4 checksum was computed
386 * by failing to call mdfour_tail() for block sizes that
387 * are multiples of 64. This is fixed by calling mdfour_update()
388 * even when there are no more bytes.
390 if (len
- i
> 0 || xfer_sum_nni
->num
> CSUM_MD4_BUSTED
)
391 mdfour_update(&m
, (uchar
*)(buf1
+i
), len
-i
);
393 mdfour_result(&m
, (uchar
*)sum
);
396 default: /* paranoia to prevent missing case values */
397 exit_cleanup(RERR_UNSUPPORTED
);
401 void file_checksum(const char *fname
, const STRUCT_STAT
*st_p
, char *sum
)
403 struct map_struct
*buf
;
404 OFF_T i
, len
= st_p
->st_size
;
408 fd
= do_open(fname
, O_RDONLY
, 0);
410 memset(sum
, 0, file_sum_len
);
414 buf
= map_file(fd
, len
, MAX_MAP_SIZE
, CHUNK_SIZE
);
417 if (file_sum_evp_md
) {
418 static EVP_MD_CTX
*evp
= NULL
;
419 if (!evp
&& !(evp
= EVP_MD_CTX_create()))
420 out_of_memory("file_checksum");
422 EVP_DigestInit_ex(evp
, file_sum_evp_md
, NULL
);
424 for (i
= 0; i
+ CHUNK_SIZE
<= len
; i
+= CHUNK_SIZE
)
425 EVP_DigestUpdate(evp
, (uchar
*)map_ptr(buf
, i
, CHUNK_SIZE
), CHUNK_SIZE
);
427 remainder
= (int32
)(len
- i
);
429 EVP_DigestUpdate(evp
, (uchar
*)map_ptr(buf
, i
, remainder
), remainder
);
431 EVP_DigestFinal_ex(evp
, (uchar
*)sum
, NULL
);
434 switch (file_sum_nni
->num
) {
435 #ifdef SUPPORT_XXHASH
437 static XXH64_state_t
* state
= NULL
;
438 if (!state
&& !(state
= XXH64_createState()))
439 out_of_memory("file_checksum");
441 XXH64_reset(state
, 0);
443 for (i
= 0; i
+ CHUNK_SIZE
<= len
; i
+= CHUNK_SIZE
)
444 XXH64_update(state
, (uchar
*)map_ptr(buf
, i
, CHUNK_SIZE
), CHUNK_SIZE
);
446 remainder
= (int32
)(len
- i
);
448 XXH64_update(state
, (uchar
*)map_ptr(buf
, i
, remainder
), remainder
);
450 SIVAL64(sum
, 0, XXH64_digest(state
));
456 static XXH3_state_t
* state
= NULL
;
457 if (!state
&& !(state
= XXH3_createState()))
458 out_of_memory("file_checksum");
460 XXH3_64bits_reset(state
);
462 for (i
= 0; i
+ CHUNK_SIZE
<= len
; i
+= CHUNK_SIZE
)
463 XXH3_64bits_update(state
, (uchar
*)map_ptr(buf
, i
, CHUNK_SIZE
), CHUNK_SIZE
);
465 remainder
= (int32
)(len
- i
);
467 XXH3_64bits_update(state
, (uchar
*)map_ptr(buf
, i
, remainder
), remainder
);
469 SIVAL64(sum
, 0, XXH3_64bits_digest(state
));
472 case CSUM_XXH3_128
: {
473 XXH128_hash_t digest
;
474 static XXH3_state_t
* state
= NULL
;
475 if (!state
&& !(state
= XXH3_createState()))
476 out_of_memory("file_checksum");
478 XXH3_128bits_reset(state
);
480 for (i
= 0; i
+ CHUNK_SIZE
<= len
; i
+= CHUNK_SIZE
)
481 XXH3_128bits_update(state
, (uchar
*)map_ptr(buf
, i
, CHUNK_SIZE
), CHUNK_SIZE
);
483 remainder
= (int32
)(len
- i
);
485 XXH3_128bits_update(state
, (uchar
*)map_ptr(buf
, i
, remainder
), remainder
);
487 digest
= XXH3_128bits_digest(state
);
488 SIVAL64(sum
, 0, digest
.low64
);
489 SIVAL64(sum
, 8, digest
.high64
);
498 for (i
= 0; i
+ CHUNK_SIZE
<= len
; i
+= CHUNK_SIZE
)
499 md5_update(&m5
, (uchar
*)map_ptr(buf
, i
, CHUNK_SIZE
), CHUNK_SIZE
);
501 remainder
= (int32
)(len
- i
);
503 md5_update(&m5
, (uchar
*)map_ptr(buf
, i
, remainder
), remainder
);
505 md5_result(&m5
, (uchar
*)sum
);
510 case CSUM_MD4_BUSTED
:
511 case CSUM_MD4_ARCHAIC
: {
516 for (i
= 0; i
+ CSUM_CHUNK
<= len
; i
+= CSUM_CHUNK
)
517 mdfour_update(&m
, (uchar
*)map_ptr(buf
, i
, CSUM_CHUNK
), CSUM_CHUNK
);
519 /* Prior to version 27 an incorrect MD4 checksum was computed
520 * by failing to call mdfour_tail() for block sizes that
521 * are multiples of 64. This is fixed by calling mdfour_update()
522 * even when there are no more bytes. */
523 remainder
= (int32
)(len
- i
);
524 if (remainder
> 0 || file_sum_nni
->num
> CSUM_MD4_BUSTED
)
525 mdfour_update(&m
, (uchar
*)map_ptr(buf
, i
, remainder
), remainder
);
527 mdfour_result(&m
, (uchar
*)sum
);
531 rprintf(FERROR
, "Invalid checksum-choice for --checksum: %s (%d)\n",
532 file_sum_nni
->name
, file_sum_nni
->num
);
533 exit_cleanup(RERR_UNSUPPORTED
);
540 static int32 sumresidue
;
541 static md_context ctx_md
;
542 #ifdef SUPPORT_XXHASH
543 static XXH64_state_t
* xxh64_state
;
546 static XXH3_state_t
* xxh3_state
;
548 static struct name_num_item
*cur_sum_nni
;
552 static const EVP_MD
*cur_sum_evp_md
;
555 /* Initialize a hash digest accumulator. Data is supplied via
556 * sum_update() and the resulting binary digest is retrieved via
557 * sum_end(). This only supports one active sum at a time. */
558 int sum_init(struct name_num_item
*nni
, int seed
)
563 nni
= parse_csum_name(NULL
, 0);
565 cur_sum_len
= csum_len_for_type(nni
->num
, 0);
567 cur_sum_evp_md
= csum_evp_md(nni
);
571 if (cur_sum_evp_md
) {
572 if (!ctx_evp
&& !(ctx_evp
= EVP_MD_CTX_create()))
573 out_of_memory("file_checksum");
574 EVP_DigestInit_ex(ctx_evp
, cur_sum_evp_md
, NULL
);
577 switch (cur_sum_nni
->num
) {
578 #ifdef SUPPORT_XXHASH
580 if (!xxh64_state
&& !(xxh64_state
= XXH64_createState()))
581 out_of_memory("sum_init");
582 XXH64_reset(xxh64_state
, 0);
587 if (!xxh3_state
&& !(xxh3_state
= XXH3_createState()))
588 out_of_memory("sum_init");
589 XXH3_64bits_reset(xxh3_state
);
592 if (!xxh3_state
&& !(xxh3_state
= XXH3_createState()))
593 out_of_memory("sum_init");
594 XXH3_128bits_reset(xxh3_state
);
601 mdfour_begin(&ctx_md
);
605 case CSUM_MD4_BUSTED
:
606 case CSUM_MD4_ARCHAIC
:
607 mdfour_begin(&ctx_md
);
614 default: /* paranoia to prevent missing case values */
615 exit_cleanup(RERR_UNSUPPORTED
);
621 /* Feed data into a hash digest accumulator. */
622 void sum_update(const char *p
, int32 len
)
625 if (cur_sum_evp_md
) {
626 EVP_DigestUpdate(ctx_evp
, (uchar
*)p
, len
);
629 switch (cur_sum_nni
->num
) {
630 #ifdef SUPPORT_XXHASH
632 XXH64_update(xxh64_state
, p
, len
);
637 XXH3_64bits_update(xxh3_state
, p
, len
);
640 XXH3_128bits_update(xxh3_state
, p
, len
);
644 md5_update(&ctx_md
, (uchar
*)p
, len
);
648 case CSUM_MD4_BUSTED
:
649 case CSUM_MD4_ARCHAIC
:
650 if (len
+ sumresidue
< CSUM_CHUNK
) {
651 memcpy(ctx_md
.buffer
+ sumresidue
, p
, len
);
657 int32 i
= CSUM_CHUNK
- sumresidue
;
658 memcpy(ctx_md
.buffer
+ sumresidue
, p
, i
);
659 mdfour_update(&ctx_md
, (uchar
*)ctx_md
.buffer
, CSUM_CHUNK
);
664 while (len
>= CSUM_CHUNK
) {
665 mdfour_update(&ctx_md
, (uchar
*)p
, CSUM_CHUNK
);
672 memcpy(ctx_md
.buffer
, p
, sumresidue
);
676 default: /* paranoia to prevent missing case values */
677 exit_cleanup(RERR_UNSUPPORTED
);
681 /* The sum buffer only needs to be as long as the current checksum's digest
682 * len, not MAX_DIGEST_LEN. Note that for CSUM_MD4_ARCHAIC that is the full
683 * MD4_DIGEST_LEN even if the file-list code is going to ignore all but the
684 * first 2 bytes of it. */
685 void sum_end(char *sum
)
688 if (cur_sum_evp_md
) {
689 EVP_DigestFinal_ex(ctx_evp
, (uchar
*)sum
, NULL
);
692 switch (cur_sum_nni
->num
) {
693 #ifdef SUPPORT_XXHASH
695 SIVAL64(sum
, 0, XXH64_digest(xxh64_state
));
700 SIVAL64(sum
, 0, XXH3_64bits_digest(xxh3_state
));
702 case CSUM_XXH3_128
: {
703 XXH128_hash_t digest
= XXH3_128bits_digest(xxh3_state
);
704 SIVAL64(sum
, 0, digest
.low64
);
705 SIVAL64(sum
, 8, digest
.high64
);
710 md5_result(&ctx_md
, (uchar
*)sum
);
714 mdfour_update(&ctx_md
, (uchar
*)ctx_md
.buffer
, sumresidue
);
715 mdfour_result(&ctx_md
, (uchar
*)sum
);
717 case CSUM_MD4_BUSTED
:
718 case CSUM_MD4_ARCHAIC
:
720 mdfour_update(&ctx_md
, (uchar
*)ctx_md
.buffer
, sumresidue
);
721 mdfour_result(&ctx_md
, (uchar
*)sum
);
726 default: /* paranoia to prevent missing case values */
727 exit_cleanup(RERR_UNSUPPORTED
);
731 #if defined SUPPORT_XXH3 || defined USE_OPENSSL
732 static void verify_digest(struct name_num_item
*nni
, BOOL check_auth_list
)
735 static int xxh3_result
= 0;
738 static int prior_num
= 0, prior_flags
= 0, prior_result
= 0;
742 if (nni
->num
== CSUM_XXH3_64
|| nni
->num
== CSUM_XXH3_128
) {
746 for (j
= 0; j
< (int)sizeof buf
; j
++)
747 buf
[j
] = ' ' + (j
% 96);
749 sum_update(buf
, 32816);
750 sum_update(buf
, 31152);
751 sum_update(buf
, 32474);
752 sum_update(buf
, 9322);
753 xxh3_result
= XXH3_64bits_digest(xxh3_state
) != 0xadbcf16d4678d1de ? -1 : 1;
756 nni
->num
= CSUM_gone
;
762 if (BITS_SETnUNSET(nni
->flags
, NNI_EVP
, NNI_BUILTIN
|NNI_EVP_OK
)) {
763 if (nni
->num
== prior_num
&& nni
->flags
== prior_flags
) {
764 nni
->flags
= prior_result
;
765 if (!(nni
->flags
& NNI_EVP
))
766 nni
->num
= CSUM_gone
;
768 prior_num
= nni
->num
;
769 prior_flags
= nni
->flags
;
770 if (!csum_evp_md(nni
))
771 nni
->num
= CSUM_gone
;
772 prior_result
= nni
->flags
;
773 if (check_auth_list
&& (nni
= get_nni_by_num(&valid_auth_checksums
, prior_num
)) != NULL
)
774 verify_digest(nni
, False
);
781 void init_checksum_choices()
783 #if defined SUPPORT_XXH3 || defined USE_OPENSSL
784 struct name_num_item
*nni
;
787 if (initialized_choices
)
790 #if defined SUPPORT_XXH3 || defined USE_OPENSSL
791 for (nni
= valid_checksums
.list
; nni
->name
; nni
++)
792 verify_digest(nni
, True
);
794 for (nni
= valid_auth_checksums
.list
; nni
->name
; nni
++)
795 verify_digest(nni
, False
);
798 initialized_choices
= 1;