1 /* sys-crypto-md.h - message digest (MD) wrapper 2 * 3 * message digest (MD) algorithms are not necessarily cryptographically secure 4 * (often provided by crypto libraries, hence this file named sys-crypto-md.h) 5 * 6 * Copyright(c) 2020 Glenn Strauss gstrauss()gluelogic.com All rights reserved 7 * License: BSD 3-clause (same as lighttpd) 8 */ 9 #ifndef LI_SYS_CRYPTO_MD_H 10 #define LI_SYS_CRYPTO_MD_H 11 #include "first.h" 12 13 #include "sys-crypto.h" /* USE_LIB_CRYPTO */ 14 #ifdef USE_LIB_CRYPTO 15 16 #if defined(USE_NETTLE_CRYPTO) 17 18 #include <nettle/md4.h> 19 #include <nettle/md5.h> 20 #include <nettle/sha.h> 21 22 #define USE_LIB_CRYPTO_MD4 23 typedef struct md4_ctx MD4_CTX; 24 static inline int 25 MD4_Init(MD4_CTX *ctx) 26 { 27 nettle_md4_init(ctx); 28 return 1; 29 } 30 static inline int 31 MD4_Final(unsigned char *digest, MD4_CTX *ctx) 32 { 33 nettle_md4_digest(ctx, MD4_DIGEST_SIZE, digest); 34 return 1; 35 } 36 static inline int 37 MD4_Update(MD4_CTX *ctx, const void *data, size_t length) 38 { 39 nettle_md4_update(ctx, length, data); 40 return 1; 41 } 42 43 #define USE_LIB_CRYPTO_MD5 44 typedef struct md5_ctx MD5_CTX; 45 static inline int 46 MD5_Init(MD5_CTX *ctx) 47 { 48 nettle_md5_init(ctx); 49 return 1; 50 } 51 static inline int 52 MD5_Final(unsigned char *digest, MD5_CTX *ctx) 53 { 54 nettle_md5_digest(ctx, MD5_DIGEST_SIZE, digest); 55 return 1; 56 } 57 static inline int 58 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 59 { 60 nettle_md5_update(ctx, length, data); 61 return 1; 62 } 63 64 #define USE_LIB_CRYPTO_SHA1 65 typedef struct sha1_ctx SHA_CTX; 66 static inline int 67 SHA1_Init(SHA_CTX *ctx) 68 { 69 nettle_sha1_init(ctx); 70 return 1; 71 } 72 static inline int 73 SHA1_Final(unsigned char *digest, SHA_CTX *ctx) 74 { 75 nettle_sha1_digest(ctx, SHA1_DIGEST_SIZE, digest); 76 return 1; 77 } 78 static inline int 79 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 80 { 81 nettle_sha1_update(ctx, length, data); 82 return 1; 83 } 84 85 #define USE_LIB_CRYPTO_SHA256 86 typedef struct sha256_ctx SHA256_CTX; 87 static inline int 88 SHA256_Init(SHA256_CTX *ctx) 89 { 90 nettle_sha256_init(ctx); 91 return 1; 92 } 93 static inline int 94 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) 95 { 96 nettle_sha256_digest(ctx, SHA256_DIGEST_SIZE, digest); 97 return 1; 98 } 99 static inline int 100 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 101 { 102 nettle_sha256_update(ctx, length, data); 103 return 1; 104 } 105 106 #define USE_LIB_CRYPTO_SHA512_256 107 #ifndef SHA512_256_DIGEST_LENGTH 108 #define SHA512_256_DIGEST_LENGTH 32 109 #endif 110 typedef struct sha512_256_ctx SHA512_CTX; /*(yes, SHA512_CTX)*/ 111 static inline int 112 SHA512_256_Init(SHA512_CTX *ctx) 113 { 114 nettle_sha512_256_init(ctx); 115 return 1; 116 } 117 static inline int 118 SHA512_256_Final(unsigned char *digest, SHA512_CTX *ctx) 119 { 120 nettle_sha512_256_digest(ctx, SHA256_DIGEST_SIZE, digest); 121 return 1; 122 } 123 static inline int 124 SHA512_256_Update(SHA512_CTX *ctx, const void *data, size_t length) 125 { 126 nettle_sha512_update(ctx, length, data); /*(yes, nettle_sha512_update())*/ 127 return 1; 128 } 129 130 #elif defined(USE_MBEDTLS_CRYPTO) 131 132 #ifdef MBEDTLS_MD4_C 133 #define USE_LIB_CRYPTO_MD4 134 #include <mbedtls/md4.h> 135 typedef struct mbedtls_md4_context MD4_CTX; 136 static inline int 137 MD4_Init(MD4_CTX *ctx) 138 { 139 mbedtls_md4_init(ctx); 140 return (0 == mbedtls_md4_starts_ret(ctx)); 141 } 142 static inline int 143 MD4_Final(unsigned char *digest, MD4_CTX *ctx) 144 { 145 int rc = mbedtls_md4_finish_ret(ctx, digest); 146 mbedtls_md4_free(ctx); 147 return (0 == rc); 148 } 149 static inline int 150 MD4_Update(MD4_CTX *ctx, const void *data, size_t length) 151 { 152 return (0 == mbedtls_md4_update_ret(ctx, data, length)); 153 } 154 #endif 155 156 #ifdef MBEDTLS_MD5_C 157 #define USE_LIB_CRYPTO_MD5 158 #include <mbedtls/md5.h> 159 typedef struct mbedtls_md5_context MD5_CTX; 160 static inline int 161 MD5_Init(MD5_CTX *ctx) 162 { 163 mbedtls_md5_init(ctx); 164 return (0 == mbedtls_md5_starts_ret(ctx)); 165 } 166 static inline int 167 MD5_Final(unsigned char *digest, MD5_CTX *ctx) 168 { 169 int rc = mbedtls_md5_finish_ret(ctx, digest); 170 mbedtls_md5_free(ctx); 171 return (0 == rc); 172 } 173 static inline int 174 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 175 { 176 return (0 == mbedtls_md5_update_ret(ctx, data, length)); 177 } 178 #endif 179 180 #ifdef MBEDTLS_SHA1_C 181 #define USE_LIB_CRYPTO_SHA1 182 #include <mbedtls/sha1.h> 183 typedef struct mbedtls_sha1_context SHA_CTX; 184 static inline int 185 SHA1_Init(SHA_CTX *ctx) 186 { 187 mbedtls_sha1_init(ctx); 188 return (0 == mbedtls_sha1_starts_ret(ctx)); 189 } 190 static inline int 191 SHA1_Final(unsigned char *digest, SHA_CTX *ctx) 192 { 193 int rc = mbedtls_sha1_finish_ret(ctx, digest); 194 mbedtls_sha1_free(ctx); 195 return (0 == rc); 196 } 197 static inline int 198 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 199 { 200 return (0 == mbedtls_sha1_update_ret(ctx, data, length)); 201 } 202 #endif 203 204 #ifdef MBEDTLS_SHA256_C 205 #define USE_LIB_CRYPTO_SHA256 206 #include <mbedtls/sha256.h> 207 typedef struct mbedtls_sha256_context SHA256_CTX; 208 static inline int 209 SHA256_Init(SHA256_CTX *ctx) 210 { 211 mbedtls_sha256_init(ctx); 212 return (0 == mbedtls_sha256_starts_ret(ctx, 0)); 213 } 214 static inline int 215 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) 216 { 217 int rc = mbedtls_sha256_finish_ret(ctx, digest); 218 mbedtls_sha256_free(ctx); 219 return (0 == rc); 220 } 221 static inline int 222 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 223 { 224 return (0 == mbedtls_sha256_update_ret(ctx, data, length)); 225 } 226 #endif 227 228 #elif defined(USE_WOLFSSL_CRYPTO) && !defined(USE_OPENSSL_CRYPTO) 229 230 /* WolfSSL compatibility API for OpenSSL unnecessarily bounces through an extra 231 * layer of indirection. However, to avoid conflicting typedefs when includers 232 * also include headers from the WolfSSL compatibility API for OpenSSL, we 233 * include those headers here, as well, and use the compatibility API typedefs. 234 * (undef of OPENSSL_EXTRA and NO_OLD_WC_NAMES not sufficient, and not friendly 235 * to do in a header when others might rely on them) */ 236 237 #ifndef NO_MD4 238 #include <wolfssl/wolfcrypt/md4.h> 239 #include <wolfssl/openssl/md4.h> 240 #undef MD4_Init 241 #undef MD4_Final 242 #undef MD4_Update 243 #define USE_LIB_CRYPTO_MD4 244 /*typedef Md4 MD4_CTX;*/ 245 static inline int 246 MD4_Init(MD4_CTX *ctx) 247 { 248 wc_InitMd4((Md4 *)ctx); 249 return 1; 250 } 251 static inline int 252 MD4_Final(unsigned char *digest, MD4_CTX *ctx) 253 { 254 wc_Md4Final((Md4 *)ctx, digest); 255 return 1; 256 } 257 static inline int 258 MD4_Update(MD4_CTX *ctx, const void *data, size_t length) 259 { 260 wc_Md4Update((Md4 *)ctx, data, length); 261 return 1; 262 } 263 #endif 264 265 #ifndef NO_MD5 266 #include <wolfssl/wolfcrypt/md5.h> 267 #include <wolfssl/openssl/md5.h> 268 #undef MD5_Init 269 #undef MD5_Final 270 #undef MD5_Update 271 #define USE_LIB_CRYPTO_MD5 272 /*typedef wc_Md5 MD5_CTX;*/ 273 static inline int 274 MD5_Init(MD5_CTX *ctx) 275 { 276 return (0 == wc_InitMd5((wc_Md5 *)ctx)); 277 } 278 static inline int 279 MD5_Final(unsigned char *digest, MD5_CTX *ctx) 280 { 281 return (0 == wc_Md5Final((wc_Md5 *)ctx, digest)); 282 } 283 static inline int 284 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 285 { 286 wc_Md5Update((wc_Md5 *)ctx, data, length); 287 return 1; 288 } 289 #endif 290 291 #ifndef NO_SHA 292 #include <wolfssl/wolfcrypt/sha.h> 293 #include <wolfssl/openssl/sha.h> 294 #undef SHA1_Init 295 #undef SHA1_Final 296 #undef SHA1_Update 297 #define USE_LIB_CRYPTO_SHA1 298 /*typedef wc_Sha SHA_CTX;*/ 299 static inline int 300 SHA1_Init(SHA_CTX *ctx) 301 { 302 return (0 == wc_InitSha((wc_Sha *)ctx)); 303 } 304 static inline int 305 SHA1_Final(unsigned char *digest, SHA_CTX *ctx) 306 { 307 return (0 == wc_ShaFinal((wc_Sha *)ctx, digest)); 308 } 309 static inline int 310 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 311 { 312 wc_ShaUpdate((wc_Sha *)ctx, data, length); 313 return 1; 314 } 315 #endif 316 317 #ifndef NO_SHA256 318 #include <wolfssl/wolfcrypt/sha256.h> 319 #include <wolfssl/openssl/sha.h> 320 #undef SHA256_Init 321 #undef SHA256_Final 322 #undef SHA256_Update 323 #define USE_LIB_CRYPTO_SHA256 324 /*typedef wc_Sha256 SHA256_CTX;*/ 325 static inline int 326 SHA256_Init(SHA256_CTX *ctx) 327 { 328 return (0 == wc_InitSha256((wc_Sha256 *)ctx)); 329 } 330 static inline int 331 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) 332 { 333 return (0 == wc_Sha256Final((wc_Sha256 *)ctx, digest)); 334 } 335 static inline int 336 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 337 { 338 wc_Sha256Update((wc_Sha256 *)ctx, data, length); 339 return 1; 340 } 341 #endif 342 343 #elif defined(USE_OPENSSL_CRYPTO) 344 345 #include <openssl/md4.h> 346 #include <openssl/md5.h> 347 #include <openssl/sha.h> 348 #ifndef OPENSSL_NO_MD4 349 #define USE_LIB_CRYPTO_MD4 350 #endif 351 #ifndef OPENSSL_NO_MD5 352 #define USE_LIB_CRYPTO_MD5 353 #endif 354 #define USE_LIB_CRYPTO_SHA1 355 #define USE_LIB_CRYPTO_SHA256 356 #ifdef SHA512_256_DIGEST_LENGTH 357 #define USE_LIB_CRYPTO_SHA512_256 358 #endif 359 360 #include <openssl/opensslv.h> 361 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 362 #include <openssl/evp.h> 363 364 #ifdef USE_LIB_CRYPTO_MD4 365 #define MD4_CTX EVP_MD4_CTX 366 #define MD4_Init EVP_MD4_Init 367 #define MD4_Final EVP_MD4_Final 368 #define MD4_Update EVP_MD4_Update 369 typedef EVP_MD_CTX * MD4_CTX; 370 static inline int 371 EVP_MD4_Init(EVP_MD4_CTX *ctx) 372 { 373 return ((*ctx = EVP_MD_CTX_new()) != NULL 374 && 1 == EVP_DigestInit_ex(*ctx, EVP_md4(), NULL)); 375 } 376 static inline int 377 EVP_MD4_Final(unsigned char *digest, EVP_MD4_CTX *ctx) 378 { 379 /* MD4_DIGEST_LENGTH; EVP_MD_size(EVP_md4()) */ 380 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL); 381 EVP_MD_CTX_free(*ctx); 382 return (1 == rc); 383 } 384 static inline int 385 EVP_MD4_Update(EVP_MD4_CTX *ctx, const void *data, size_t length) 386 { 387 return (1 == EVP_DigestUpdate(*ctx, data, length)); 388 } 389 #endif 390 391 #ifdef USE_LIB_CRYPTO_MD5 392 #define MD5_CTX EVP_MD5_CTX 393 #define MD5_Init EVP_MD5_Init 394 #define MD5_Final EVP_MD5_Final 395 #define MD5_Update EVP_MD5_Update 396 typedef EVP_MD_CTX * EVP_MD5_CTX; 397 static inline int 398 EVP_MD5_Init(EVP_MD5_CTX *ctx) 399 { 400 return ((*ctx = EVP_MD_CTX_new()) != NULL 401 && 1 == EVP_DigestInit_ex(*ctx, EVP_md5(), NULL)); 402 } 403 static inline int 404 EVP_MD5_Final(unsigned char *digest, EVP_MD5_CTX *ctx) 405 { 406 /* MD5_DIGEST_LENGTH; EVP_MD_size(EVP_md5()) */ 407 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL); 408 EVP_MD_CTX_free(*ctx); 409 return (1 == rc); 410 } 411 static inline int 412 EVP_MD5_Update(EVP_MD5_CTX *ctx, const void *data, size_t length) 413 { 414 return (1 == EVP_DigestUpdate(*ctx, data, length)); 415 } 416 #endif 417 418 #ifdef USE_LIB_CRYPTO_SHA1 419 #define SHA_CTX EVP_SHA1_CTX 420 #define SHA1_Init EVP_SHA1_Init 421 #define SHA1_Final EVP_SHA1_Final 422 #define SHA1_Update EVP_SHA1_Update 423 typedef EVP_MD_CTX * EVP_SHA1_CTX; 424 static inline int 425 EVP_SHA1_Init(EVP_SHA1_CTX *ctx) 426 { 427 return ((*ctx = EVP_MD_CTX_new()) != NULL 428 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha1(), NULL)); 429 } 430 static inline int 431 EVP_SHA1_Final(unsigned char *digest, EVP_SHA1_CTX *ctx) 432 { 433 /* SHA_DIGEST_LENGTH; EVP_MD_size(EVP_sha1()) */ 434 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL); 435 EVP_MD_CTX_free(*ctx); 436 return (1 == rc); 437 } 438 static inline int 439 EVP_SHA1_Update(EVP_SHA1_CTX *ctx, const void *data, size_t length) 440 { 441 return (1 == EVP_DigestUpdate(*ctx, data, length)); 442 } 443 #endif 444 445 #ifdef USE_LIB_CRYPTO_SHA256 446 #define SHA256_CTX EVP_SHA256_CTX 447 #define SHA256_Init EVP_SHA256_Init 448 #define SHA256_Final EVP_SHA256_Final 449 #define SHA256_Update EVP_SHA256_Update 450 typedef EVP_MD_CTX * EVP_SHA256_CTX; 451 static inline int 452 EVP_SHA256_Init(EVP_SHA256_CTX *ctx) 453 { 454 return ((*ctx = EVP_MD_CTX_new()) != NULL 455 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha256(), NULL)); 456 } 457 static inline int 458 EVP_SHA256_Final(unsigned char *digest, EVP_SHA256_CTX *ctx) 459 { 460 /* SHA256_DIGEST_LENGTH; EVP_MD_size(EVP_sha256()) */ 461 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL); 462 EVP_MD_CTX_free(*ctx); 463 return (1 == rc); 464 } 465 static inline int 466 EVP_SHA256_Update(EVP_SHA256_CTX *ctx, const void *data, size_t length) 467 { 468 return (1 == EVP_DigestUpdate(*ctx, data, length)); 469 } 470 #endif 471 472 #ifdef USE_LIB_CRYPTO_SHA512_256 473 #define SHA512_256_CTX EVP_SHA512_256_CTX 474 #define SHA512_256_Init EVP_SHA512_256_Init 475 #define SHA512_256_Final EVP_SHA512_256_Final 476 #define SHA512_256_Update EVP_SHA512_256_Update 477 typedef EVP_MD_CTX * EVP_SHA512_256_CTX; 478 static inline int 479 EVP_SHA512_256_Init(EVP_SHA512_256_CTX *ctx) 480 { 481 return ((*ctx = EVP_MD_CTX_new()) != NULL 482 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)); 483 } 484 static inline int 485 EVP_SHA512_256_Final(unsigned char *digest, EVP_SHA512_256_CTX *ctx) 486 { 487 /* SHA256_DIGEST_LENGTH; EVP_MD_size(EVP_sha512_256()) */ 488 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL); 489 EVP_MD_CTX_free(*ctx); 490 return (1 == rc); 491 } 492 static inline int 493 EVP_SHA512_256_Update(EVP_SHA512_256_CTX *ctx, const void *data, size_t length) 494 { 495 return (1 == EVP_DigestUpdate(*ctx, data, length)); 496 } 497 #endif 498 499 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ 500 501 #elif defined(USE_GNUTLS_CRYPTO) 502 503 #include <gnutls/crypto.h> 504 #include "buffer.h" /* SEGFAULT() */ 505 506 #define USE_LIB_CRYPTO_MD5 507 typedef gnutls_hash_hd_t MD5_CTX; 508 static inline int 509 MD5_Init(MD5_CTX *ctx) 510 { 511 if (gnutls_hash_init(ctx, GNUTLS_DIG_MD5) < 0) 512 SEGFAULT(); 513 return 1; 514 } 515 static inline int 516 MD5_Final(unsigned char *digest, MD5_CTX *ctx) 517 { 518 gnutls_hash_deinit(*ctx, digest); 519 return 1; 520 } 521 static inline int 522 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 523 { 524 gnutls_hash(*ctx, data, length); 525 return 1; 526 } 527 528 #define USE_LIB_CRYPTO_SHA1 529 typedef gnutls_hash_hd_t SHA_CTX; 530 static inline int 531 SHA1_Init(SHA_CTX *ctx) 532 { 533 if (gnutls_hash_init(ctx, GNUTLS_DIG_SHA1) < 0) 534 SEGFAULT(); 535 return 1; 536 } 537 static inline int 538 SHA1_Final(unsigned char *digest, SHA_CTX *ctx) 539 { 540 gnutls_hash_deinit(*ctx, digest); 541 return 1; 542 } 543 static inline int 544 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 545 { 546 gnutls_hash(*ctx, data, length); 547 return 1; 548 } 549 550 #define USE_LIB_CRYPTO_SHA256 551 typedef gnutls_hash_hd_t SHA256_CTX; 552 static inline int 553 SHA256_Init(SHA256_CTX *ctx) 554 { 555 if (gnutls_hash_init(ctx, GNUTLS_DIG_SHA256) < 0) 556 SEGFAULT(); 557 return 1; 558 } 559 static inline int 560 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) 561 { 562 gnutls_hash_deinit(*ctx, digest); 563 return 1; 564 } 565 static inline int 566 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 567 { 568 gnutls_hash(*ctx, data, length); 569 return 1; 570 } 571 572 #elif defined(USE_NSS_CRYPTO) 573 574 /* basic algorithms fail if NSS library has not been init'd (WTH). 575 * lighttpd defers initialization of rand and crypto until first use 576 * to attempt to avoid long, blocking init at startup while waiting 577 * for sufficient system entropy to become available */ 578 #ifdef NSS_VER_INCLUDE 579 #include <nss3/nss.h> /* NSS_IsInitialized() NSS_NoDB_Init() */ 580 #else 581 #include <nss/nss.h> /* NSS_IsInitialized() NSS_NoDB_Init() */ 582 #endif 583 #include <stdlib.h> /* abort() */ 584 __attribute_cold__ 585 static inline void 586 nss_requires_explicit_init_for_basic_crypto_wth(void) 587 { 588 if (NSS_NoDB_Init(NULL) < 0) 589 abort(); 590 } 591 592 #ifdef NSS_VER_INCLUDE 593 #include <nss3/sechash.h> 594 #else 595 #include <nss/sechash.h> 596 #endif 597 598 #define NSS_gen_hashfuncs(name, typ) \ 599 static inline int \ 600 name##_Init(void **ctx) \ 601 { \ 602 if (!NSS_IsInitialized()) \ 603 nss_requires_explicit_init_for_basic_crypto_wth(); \ 604 const SECHashObject * const hashObj = HASH_GetHashObject(typ); \ 605 return ((*ctx=hashObj->create()) != NULL) ? (hashObj->begin(*ctx),1) : 0; \ 606 } \ 607 static inline int \ 608 name##_Final(unsigned char *dest, void **ctx) \ 609 { \ 610 const SECHashObject * const hashObj = HASH_GetHashObject(typ); \ 611 unsigned int retLen; \ 612 hashObj->end(*ctx, dest, &retLen, hashObj->length); \ 613 hashObj->destroy(*ctx, PR_TRUE); \ 614 return 1; \ 615 } \ 616 static inline int \ 617 name##_Update(void **ctx, const void *src, size_t len) \ 618 { \ 619 const SECHashObject * const hashObj = HASH_GetHashObject(typ); \ 620 hashObj->update(*ctx, src, (int)len); \ 621 return 1; \ 622 } \ 623 typedef void * name##_CTX 624 typedef void * SHA_CTX; 625 626 #define USE_LIB_CRYPTO_MD5 627 /* MD5_Init() 628 * MD5_Update() 629 * MD5_Final() */ 630 NSS_gen_hashfuncs(MD5, HASH_AlgMD5); 631 632 #define USE_LIB_CRYPTO_SHA1 633 /* SHA1_Init() 634 * SHA1_Update() 635 * SHA1_Final() */ 636 NSS_gen_hashfuncs(SHA1, HASH_AlgSHA1); 637 638 #define USE_LIB_CRYPTO_SHA256 639 /* SHA256_Init() 640 * SHA256_Update() 641 * SHA256_Final() */ 642 NSS_gen_hashfuncs(SHA256, HASH_AlgSHA256); 643 644 #endif 645 646 #endif /* USE_LIB_CRYPTO */ 647 648 649 #ifdef USE_LIB_CRYPTO_MD5 650 #ifndef MD5_DIGEST_LENGTH 651 #define MD5_DIGEST_LENGTH 16 652 #endif 653 #include "algo_md5.h" /*(for legacy li_MD5_*() name mangling)*/ 654 #else 655 #include "algo_md5.h" 656 #endif 657 658 659 #ifdef USE_LIB_CRYPTO_SHA1 660 #ifndef SHA_DIGEST_LENGTH 661 #define SHA_DIGEST_LENGTH 20 662 #endif 663 #else 664 #include "algo_sha1.h" 665 #endif 666 667 668 #endif /* LI_SYS_CRYPTO_MD_H */ 669