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