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
MD4_Init(MD4_CTX * ctx)25 MD4_Init(MD4_CTX *ctx)
26 {
27 nettle_md4_init(ctx);
28 return 1;
29 }
30 static inline int
MD4_Final(unsigned char * digest,MD4_CTX * ctx)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
MD4_Update(MD4_CTX * ctx,const void * data,size_t length)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
MD5_Init(MD5_CTX * ctx)46 MD5_Init(MD5_CTX *ctx)
47 {
48 nettle_md5_init(ctx);
49 return 1;
50 }
51 static inline int
MD5_Final(unsigned char * digest,MD5_CTX * ctx)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
MD5_Update(MD5_CTX * ctx,const void * data,size_t length)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
SHA1_Init(SHA_CTX * ctx)67 SHA1_Init(SHA_CTX *ctx)
68 {
69 nettle_sha1_init(ctx);
70 return 1;
71 }
72 static inline int
SHA1_Final(unsigned char * digest,SHA_CTX * ctx)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
SHA1_Update(SHA_CTX * ctx,const void * data,size_t length)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
SHA256_Init(SHA256_CTX * ctx)88 SHA256_Init(SHA256_CTX *ctx)
89 {
90 nettle_sha256_init(ctx);
91 return 1;
92 }
93 static inline int
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)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
SHA256_Update(SHA256_CTX * ctx,const void * data,size_t length)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 #define SHA512_256_CTX SHA512_CTX
108 /*(nettle/sha2.h: #define sha512_256_ctx sha512_ctx)*/
109 /*typedef struct sha512_256_ctx SHA512_CTX;*/ /*(yes, SHA512_CTX)*/
110 typedef struct sha512_ctx SHA512_CTX;
111 static inline int
SHA512_256_Init(SHA512_CTX * ctx)112 SHA512_256_Init(SHA512_CTX *ctx)
113 {
114 nettle_sha512_256_init(ctx);
115 return 1;
116 }
117 static inline int
SHA512_256_Final(unsigned char * digest,SHA512_CTX * ctx)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
SHA512_256_Update(SHA512_CTX * ctx,const void * data,size_t length)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 #define USE_LIB_CRYPTO_SHA512
131 /*typedef struct sha512_ctx SHA512_CTX;*//*(defined above)*/
132 static inline int
SHA512_Init(SHA512_CTX * ctx)133 SHA512_Init(SHA512_CTX *ctx)
134 {
135 nettle_sha512_init(ctx);
136 return 1;
137 }
138 static inline int
SHA512_Final(unsigned char * digest,SHA512_CTX * ctx)139 SHA512_Final(unsigned char *digest, SHA512_CTX *ctx)
140 {
141 nettle_sha512_digest(ctx, SHA512_DIGEST_SIZE, digest);
142 return 1;
143 }
144 static inline int
SHA512_Update(SHA512_CTX * ctx,const void * data,size_t length)145 SHA512_Update(SHA512_CTX *ctx, const void *data, size_t length)
146 {
147 nettle_sha512_update(ctx, length, data);
148 return 1;
149 }
150
151 #elif defined(USE_MBEDTLS_CRYPTO)
152
153 #include <mbedtls/config.h>
154
155 #ifdef MBEDTLS_MD4_C
156 #define USE_LIB_CRYPTO_MD4
157 #include <mbedtls/md4.h>
158 typedef struct mbedtls_md4_context MD4_CTX;
159 static inline int
MD4_Init(MD4_CTX * ctx)160 MD4_Init(MD4_CTX *ctx)
161 {
162 mbedtls_md4_init(ctx);
163 return (0 == mbedtls_md4_starts_ret(ctx));
164 }
165 static inline int
MD4_Final(unsigned char * digest,MD4_CTX * ctx)166 MD4_Final(unsigned char *digest, MD4_CTX *ctx)
167 {
168 int rc = mbedtls_md4_finish_ret(ctx, digest);
169 mbedtls_md4_free(ctx);
170 return (0 == rc);
171 }
172 static inline int
MD4_Update(MD4_CTX * ctx,const void * data,size_t length)173 MD4_Update(MD4_CTX *ctx, const void *data, size_t length)
174 {
175 return (0 == mbedtls_md4_update_ret(ctx, data, length));
176 }
177 #endif
178
179 #ifdef MBEDTLS_MD5_C
180 #define USE_LIB_CRYPTO_MD5
181 #include <mbedtls/md5.h>
182 typedef struct mbedtls_md5_context MD5_CTX;
183 static inline int
MD5_Init(MD5_CTX * ctx)184 MD5_Init(MD5_CTX *ctx)
185 {
186 mbedtls_md5_init(ctx);
187 return (0 == mbedtls_md5_starts_ret(ctx));
188 }
189 static inline int
MD5_Final(unsigned char * digest,MD5_CTX * ctx)190 MD5_Final(unsigned char *digest, MD5_CTX *ctx)
191 {
192 int rc = mbedtls_md5_finish_ret(ctx, digest);
193 mbedtls_md5_free(ctx);
194 return (0 == rc);
195 }
196 static inline int
MD5_Update(MD5_CTX * ctx,const void * data,size_t length)197 MD5_Update(MD5_CTX *ctx, const void *data, size_t length)
198 {
199 return (0 == mbedtls_md5_update_ret(ctx, data, length));
200 }
201 #endif
202
203 #ifdef MBEDTLS_SHA1_C
204 #define USE_LIB_CRYPTO_SHA1
205 #include <mbedtls/sha1.h>
206 typedef struct mbedtls_sha1_context SHA_CTX;
207 static inline int
SHA1_Init(SHA_CTX * ctx)208 SHA1_Init(SHA_CTX *ctx)
209 {
210 mbedtls_sha1_init(ctx);
211 return (0 == mbedtls_sha1_starts_ret(ctx));
212 }
213 static inline int
SHA1_Final(unsigned char * digest,SHA_CTX * ctx)214 SHA1_Final(unsigned char *digest, SHA_CTX *ctx)
215 {
216 int rc = mbedtls_sha1_finish_ret(ctx, digest);
217 mbedtls_sha1_free(ctx);
218 return (0 == rc);
219 }
220 static inline int
SHA1_Update(SHA_CTX * ctx,const void * data,size_t length)221 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length)
222 {
223 return (0 == mbedtls_sha1_update_ret(ctx, data, length));
224 }
225 #endif
226
227 #ifdef MBEDTLS_SHA256_C
228 #define USE_LIB_CRYPTO_SHA256
229 #include <mbedtls/sha256.h>
230 typedef struct mbedtls_sha256_context SHA256_CTX;
231 static inline int
SHA256_Init(SHA256_CTX * ctx)232 SHA256_Init(SHA256_CTX *ctx)
233 {
234 mbedtls_sha256_init(ctx);
235 return (0 == mbedtls_sha256_starts_ret(ctx, 0));
236 }
237 static inline int
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)238 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
239 {
240 int rc = mbedtls_sha256_finish_ret(ctx, digest);
241 mbedtls_sha256_free(ctx);
242 return (0 == rc);
243 }
244 static inline int
SHA256_Update(SHA256_CTX * ctx,const void * data,size_t length)245 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length)
246 {
247 return (0 == mbedtls_sha256_update_ret(ctx, data, length));
248 }
249 #endif
250
251 #ifdef MBEDTLS_SHA512_C
252 #define USE_LIB_CRYPTO_SHA512
253 #include <mbedtls/sha512.h>
254 typedef struct mbedtls_sha512_context SHA512_CTX;
255 static inline int
SHA512_Init(SHA512_CTX * ctx)256 SHA512_Init(SHA512_CTX *ctx)
257 {
258 mbedtls_sha512_init(ctx);
259 return (0 == mbedtls_sha512_starts_ret(ctx, 0));
260 }
261 static inline int
SHA512_Final(unsigned char * digest,SHA512_CTX * ctx)262 SHA512_Final(unsigned char *digest, SHA512_CTX *ctx)
263 {
264 int rc = mbedtls_sha512_finish_ret(ctx, digest);
265 mbedtls_sha512_free(ctx);
266 return (0 == rc);
267 }
268 static inline int
SHA512_Update(SHA512_CTX * ctx,const void * data,size_t length)269 SHA512_Update(SHA512_CTX *ctx, const void *data, size_t length)
270 {
271 return (0 == mbedtls_sha512_update_ret(ctx, data, length));
272 }
273 #endif
274
275 #elif defined(USE_WOLFSSL_CRYPTO)
276
277 /* WolfSSL compatibility API for OpenSSL unnecessarily bounces through an extra
278 * layer of indirection. However, to avoid conflicting typedefs when includers
279 * also include headers from the WolfSSL compatibility API for OpenSSL, we
280 * include those headers here, as well, and use the compatibility API typedefs.
281 * (undef of OPENSSL_EXTRA and NO_OLD_WC_NAMES not sufficient, and not friendly
282 * to do in a header when others might rely on them) */
283
284 /* workaround fragile code in wolfssl/wolfcrypto/types.h */
285 #if !defined(SIZEOF_LONG) || !defined(SIZEOF_LONG_LONG)
286 #undef SIZEOF_LONG
287 #undef SIZEOF_LONG_LONG
288 #endif
289
290 #include <wolfssl/options.h> /* wolfssl NO_* macros */
291
292 #ifndef NO_MD4
293 #include <wolfssl/wolfcrypt/md4.h>
294 #include <wolfssl/openssl/md4.h>
295 #undef MD4_Init
296 #undef MD4_Final
297 #undef MD4_Update
298 #define USE_LIB_CRYPTO_MD4
299 /*typedef Md4 MD4_CTX;*/
300 static inline int
MD4_Init(MD4_CTX * ctx)301 MD4_Init(MD4_CTX *ctx)
302 {
303 wc_InitMd4((Md4 *)ctx);
304 return 1;
305 }
306 static inline int
MD4_Final(unsigned char * digest,MD4_CTX * ctx)307 MD4_Final(unsigned char *digest, MD4_CTX *ctx)
308 {
309 wc_Md4Final((Md4 *)ctx, digest);
310 return 1;
311 }
312 static inline int
MD4_Update(MD4_CTX * ctx,const void * data,size_t length)313 MD4_Update(MD4_CTX *ctx, const void *data, size_t length)
314 {
315 wc_Md4Update((Md4 *)ctx, data, length);
316 return 1;
317 }
318 #endif
319
320 #ifndef NO_MD5
321 #include <wolfssl/wolfcrypt/md5.h>
322 #include <wolfssl/openssl/md5.h>
323 #undef MD5_Init
324 #undef MD5_Final
325 #undef MD5_Update
326 #define USE_LIB_CRYPTO_MD5
327 /*typedef wc_Md5 MD5_CTX;*/
328 static inline int
MD5_Init(MD5_CTX * ctx)329 MD5_Init(MD5_CTX *ctx)
330 {
331 return (0 == wc_InitMd5((wc_Md5 *)ctx));
332 }
333 static inline int
MD5_Final(unsigned char * digest,MD5_CTX * ctx)334 MD5_Final(unsigned char *digest, MD5_CTX *ctx)
335 {
336 return (0 == wc_Md5Final((wc_Md5 *)ctx, digest));
337 }
338 static inline int
MD5_Update(MD5_CTX * ctx,const void * data,size_t length)339 MD5_Update(MD5_CTX *ctx, const void *data, size_t length)
340 {
341 wc_Md5Update((wc_Md5 *)ctx, data, length);
342 return 1;
343 }
344 #endif
345
346 #ifndef NO_SHA
347 #include <wolfssl/wolfcrypt/sha.h>
348 #include <wolfssl/openssl/sha.h>
349 #undef SHA1_Init
350 #undef SHA1_Final
351 #undef SHA1_Update
352 #define USE_LIB_CRYPTO_SHA1
353 /*typedef wc_Sha SHA_CTX;*/
354 static inline int
SHA1_Init(SHA_CTX * ctx)355 SHA1_Init(SHA_CTX *ctx)
356 {
357 return (0 == wc_InitSha((wc_Sha *)ctx));
358 }
359 static inline int
SHA1_Final(unsigned char * digest,SHA_CTX * ctx)360 SHA1_Final(unsigned char *digest, SHA_CTX *ctx)
361 {
362 return (0 == wc_ShaFinal((wc_Sha *)ctx, digest));
363 }
364 static inline int
SHA1_Update(SHA_CTX * ctx,const void * data,size_t length)365 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length)
366 {
367 wc_ShaUpdate((wc_Sha *)ctx, data, length);
368 return 1;
369 }
370 #endif
371
372 #ifndef NO_SHA256
373 #include <wolfssl/wolfcrypt/sha256.h>
374 #include <wolfssl/openssl/sha.h>
375 #undef SHA256_Init
376 #undef SHA256_Final
377 #undef SHA256_Update
378 #define USE_LIB_CRYPTO_SHA256
379 /*typedef wc_Sha256 SHA256_CTX;*/
380 static inline int
SHA256_Init(SHA256_CTX * ctx)381 SHA256_Init(SHA256_CTX *ctx)
382 {
383 return (0 == wc_InitSha256((wc_Sha256 *)ctx));
384 }
385 static inline int
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)386 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
387 {
388 return (0 == wc_Sha256Final((wc_Sha256 *)ctx, digest));
389 }
390 static inline int
SHA256_Update(SHA256_CTX * ctx,const void * data,size_t length)391 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length)
392 {
393 wc_Sha256Update((wc_Sha256 *)ctx, data, length);
394 return 1;
395 }
396 #endif
397
398 #ifndef NO_SHA512
399 #ifdef WOLFSSL_SHA512
400 #include <wolfssl/wolfcrypt/sha512.h>
401 #include <wolfssl/openssl/sha.h>
402 #undef SHA512_Init
403 #undef SHA512_Final
404 #undef SHA512_Update
405 #define USE_LIB_CRYPTO_SHA512
406 /*typedef wc_Sha512 SHA512_CTX;*/
407 static inline int
SHA512_Init(SHA512_CTX * ctx)408 SHA512_Init(SHA512_CTX *ctx)
409 {
410 return (0 == wc_InitSha512((wc_Sha512 *)ctx));
411 }
412 static inline int
SHA512_Final(unsigned char * digest,SHA512_CTX * ctx)413 SHA512_Final(unsigned char *digest, SHA512_CTX *ctx)
414 {
415 return (0 == wc_Sha512Final((wc_Sha512 *)ctx, digest));
416 }
417 static inline int
SHA512_Update(SHA512_CTX * ctx,const void * data,size_t length)418 SHA512_Update(SHA512_CTX *ctx, const void *data, size_t length)
419 {
420 wc_Sha512Update((wc_Sha512 *)ctx, data, length);
421 return 1;
422 }
423 #endif
424 #endif
425
426 #elif defined(USE_OPENSSL_CRYPTO)
427
428 #include <openssl/md4.h>
429 #include <openssl/md5.h>
430 #include <openssl/sha.h>
431 #ifndef OPENSSL_NO_MD4
432 #define USE_LIB_CRYPTO_MD4
433 #endif
434 #ifndef OPENSSL_NO_MD5
435 #define USE_LIB_CRYPTO_MD5
436 #endif
437 #define USE_LIB_CRYPTO_SHA1
438 #define USE_LIB_CRYPTO_SHA256
439 #ifdef SHA512_256_DIGEST_LENGTH
440 #define USE_LIB_CRYPTO_SHA512_256
441 #endif
442 #ifdef SHA512_DIGEST_LENGTH
443 #define USE_LIB_CRYPTO_SHA512
444 #endif
445
446 #include <openssl/opensslv.h>
447 #ifdef BORINGSSL_API_VERSION
448 typedef SHA512_CTX SHA512_256_CTX;
449 #endif
450 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
451 #include <openssl/evp.h>
452
453 #ifdef USE_LIB_CRYPTO_MD4
454 #define MD4_CTX EVP_MD4_CTX
455 #define MD4_Init EVP_MD4_Init
456 #define MD4_Final EVP_MD4_Final
457 #define MD4_Update EVP_MD4_Update
458 typedef EVP_MD_CTX * MD4_CTX;
459 static inline int
EVP_MD4_Init(EVP_MD4_CTX * ctx)460 EVP_MD4_Init(EVP_MD4_CTX *ctx)
461 {
462 return ((*ctx = EVP_MD_CTX_new()) != NULL
463 && 1 == EVP_DigestInit_ex(*ctx, EVP_md4(), NULL));
464 }
465 static inline int
EVP_MD4_Final(unsigned char * digest,EVP_MD4_CTX * ctx)466 EVP_MD4_Final(unsigned char *digest, EVP_MD4_CTX *ctx)
467 {
468 /* MD4_DIGEST_LENGTH; EVP_MD_size(EVP_md4()) */
469 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL);
470 EVP_MD_CTX_free(*ctx);
471 return (1 == rc);
472 }
473 static inline int
EVP_MD4_Update(EVP_MD4_CTX * ctx,const void * data,size_t length)474 EVP_MD4_Update(EVP_MD4_CTX *ctx, const void *data, size_t length)
475 {
476 return (1 == EVP_DigestUpdate(*ctx, data, length));
477 }
478 #endif
479
480 #ifdef USE_LIB_CRYPTO_MD5
481 #define MD5_CTX EVP_MD5_CTX
482 #define MD5_Init EVP_MD5_Init
483 #define MD5_Final EVP_MD5_Final
484 #define MD5_Update EVP_MD5_Update
485 typedef EVP_MD_CTX * EVP_MD5_CTX;
486 static inline int
EVP_MD5_Init(EVP_MD5_CTX * ctx)487 EVP_MD5_Init(EVP_MD5_CTX *ctx)
488 {
489 return ((*ctx = EVP_MD_CTX_new()) != NULL
490 && 1 == EVP_DigestInit_ex(*ctx, EVP_md5(), NULL));
491 }
492 static inline int
EVP_MD5_Final(unsigned char * digest,EVP_MD5_CTX * ctx)493 EVP_MD5_Final(unsigned char *digest, EVP_MD5_CTX *ctx)
494 {
495 /* MD5_DIGEST_LENGTH; EVP_MD_size(EVP_md5()) */
496 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL);
497 EVP_MD_CTX_free(*ctx);
498 return (1 == rc);
499 }
500 static inline int
EVP_MD5_Update(EVP_MD5_CTX * ctx,const void * data,size_t length)501 EVP_MD5_Update(EVP_MD5_CTX *ctx, const void *data, size_t length)
502 {
503 return (1 == EVP_DigestUpdate(*ctx, data, length));
504 }
505 #endif
506
507 #ifdef USE_LIB_CRYPTO_SHA1
508 #define SHA_CTX EVP_SHA1_CTX
509 #define SHA1_Init EVP_SHA1_Init
510 #define SHA1_Final EVP_SHA1_Final
511 #define SHA1_Update EVP_SHA1_Update
512 typedef EVP_MD_CTX * EVP_SHA1_CTX;
513 static inline int
EVP_SHA1_Init(EVP_SHA1_CTX * ctx)514 EVP_SHA1_Init(EVP_SHA1_CTX *ctx)
515 {
516 return ((*ctx = EVP_MD_CTX_new()) != NULL
517 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha1(), NULL));
518 }
519 static inline int
EVP_SHA1_Final(unsigned char * digest,EVP_SHA1_CTX * ctx)520 EVP_SHA1_Final(unsigned char *digest, EVP_SHA1_CTX *ctx)
521 {
522 /* SHA_DIGEST_LENGTH; EVP_MD_size(EVP_sha1()) */
523 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL);
524 EVP_MD_CTX_free(*ctx);
525 return (1 == rc);
526 }
527 static inline int
EVP_SHA1_Update(EVP_SHA1_CTX * ctx,const void * data,size_t length)528 EVP_SHA1_Update(EVP_SHA1_CTX *ctx, const void *data, size_t length)
529 {
530 return (1 == EVP_DigestUpdate(*ctx, data, length));
531 }
532 #endif
533
534 #ifdef USE_LIB_CRYPTO_SHA256
535 #define SHA256_CTX EVP_SHA256_CTX
536 #define SHA256_Init EVP_SHA256_Init
537 #define SHA256_Final EVP_SHA256_Final
538 #define SHA256_Update EVP_SHA256_Update
539 typedef EVP_MD_CTX * EVP_SHA256_CTX;
540 static inline int
EVP_SHA256_Init(EVP_SHA256_CTX * ctx)541 EVP_SHA256_Init(EVP_SHA256_CTX *ctx)
542 {
543 return ((*ctx = EVP_MD_CTX_new()) != NULL
544 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha256(), NULL));
545 }
546 static inline int
EVP_SHA256_Final(unsigned char * digest,EVP_SHA256_CTX * ctx)547 EVP_SHA256_Final(unsigned char *digest, EVP_SHA256_CTX *ctx)
548 {
549 /* SHA256_DIGEST_LENGTH; EVP_MD_size(EVP_sha256()) */
550 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL);
551 EVP_MD_CTX_free(*ctx);
552 return (1 == rc);
553 }
554 static inline int
EVP_SHA256_Update(EVP_SHA256_CTX * ctx,const void * data,size_t length)555 EVP_SHA256_Update(EVP_SHA256_CTX *ctx, const void *data, size_t length)
556 {
557 return (1 == EVP_DigestUpdate(*ctx, data, length));
558 }
559 #endif
560
561 #ifdef USE_LIB_CRYPTO_SHA512_256
562 #define SHA512_256_CTX EVP_SHA512_256_CTX
563 #define SHA512_256_Init EVP_SHA512_256_Init
564 #define SHA512_256_Final EVP_SHA512_256_Final
565 #define SHA512_256_Update EVP_SHA512_256_Update
566 typedef EVP_MD_CTX * EVP_SHA512_256_CTX;
567 static inline int
EVP_SHA512_256_Init(EVP_SHA512_256_CTX * ctx)568 EVP_SHA512_256_Init(EVP_SHA512_256_CTX *ctx)
569 {
570 return ((*ctx = EVP_MD_CTX_new()) != NULL
571 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL));
572 }
573 static inline int
EVP_SHA512_256_Final(unsigned char * digest,EVP_SHA512_256_CTX * ctx)574 EVP_SHA512_256_Final(unsigned char *digest, EVP_SHA512_256_CTX *ctx)
575 {
576 /* SHA256_DIGEST_LENGTH; EVP_MD_size(EVP_sha512_256()) */
577 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL);
578 EVP_MD_CTX_free(*ctx);
579 return (1 == rc);
580 }
581 static inline int
EVP_SHA512_256_Update(EVP_SHA512_256_CTX * ctx,const void * data,size_t length)582 EVP_SHA512_256_Update(EVP_SHA512_256_CTX *ctx, const void *data, size_t length)
583 {
584 return (1 == EVP_DigestUpdate(*ctx, data, length));
585 }
586 #endif
587
588 #ifdef USE_LIB_CRYPTO_SHA512
589 #define SHA512_CTX EVP_SHA512_CTX
590 #define SHA512_Init EVP_SHA512_Init
591 #define SHA512_Final EVP_SHA512_Final
592 #define SHA512_Update EVP_SHA512_Update
593 typedef EVP_MD_CTX * EVP_SHA512_CTX;
594 static inline int
EVP_SHA512_Init(EVP_SHA512_CTX * ctx)595 EVP_SHA512_Init(EVP_SHA512_CTX *ctx)
596 {
597 return ((*ctx = EVP_MD_CTX_new()) != NULL
598 && 1 == EVP_DigestInit_ex(*ctx, EVP_sha512(), NULL));
599 }
600 static inline int
EVP_SHA512_Final(unsigned char * digest,EVP_SHA512_CTX * ctx)601 EVP_SHA512_Final(unsigned char *digest, EVP_SHA512_CTX *ctx)
602 {
603 /* SHA512_DIGEST_LENGTH; EVP_MD_size(EVP_sha512()) */
604 int rc = EVP_DigestFinal_ex(*ctx, digest, NULL);
605 EVP_MD_CTX_free(*ctx);
606 return (1 == rc);
607 }
608 static inline int
EVP_SHA512_Update(EVP_SHA512_CTX * ctx,const void * data,size_t length)609 EVP_SHA512_Update(EVP_SHA512_CTX *ctx, const void *data, size_t length)
610 {
611 return (1 == EVP_DigestUpdate(*ctx, data, length));
612 }
613 #endif
614
615 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
616
617 #elif defined(USE_GNUTLS_CRYPTO)
618
619 #include <gnutls/crypto.h>
620 #include "ck.h"
621
622 #define USE_LIB_CRYPTO_MD5
623 typedef gnutls_hash_hd_t MD5_CTX;
624 static inline int
MD5_Init(MD5_CTX * ctx)625 MD5_Init(MD5_CTX *ctx)
626 {
627 if (gnutls_hash_init(ctx, GNUTLS_DIG_MD5) < 0)
628 ck_bt_abort(__FILE__, __LINE__, "aborted");
629 return 1;
630 }
631 static inline int
MD5_Final(unsigned char * digest,MD5_CTX * ctx)632 MD5_Final(unsigned char *digest, MD5_CTX *ctx)
633 {
634 gnutls_hash_deinit(*ctx, digest);
635 return 1;
636 }
637 static inline int
MD5_Update(MD5_CTX * ctx,const void * data,size_t length)638 MD5_Update(MD5_CTX *ctx, const void *data, size_t length)
639 {
640 gnutls_hash(*ctx, data, length);
641 return 1;
642 }
643
644 #define USE_LIB_CRYPTO_SHA1
645 typedef gnutls_hash_hd_t SHA_CTX;
646 static inline int
SHA1_Init(SHA_CTX * ctx)647 SHA1_Init(SHA_CTX *ctx)
648 {
649 if (gnutls_hash_init(ctx, GNUTLS_DIG_SHA1) < 0)
650 ck_bt_abort(__FILE__, __LINE__, "aborted");
651 return 1;
652 }
653 static inline int
SHA1_Final(unsigned char * digest,SHA_CTX * ctx)654 SHA1_Final(unsigned char *digest, SHA_CTX *ctx)
655 {
656 gnutls_hash_deinit(*ctx, digest);
657 return 1;
658 }
659 static inline int
SHA1_Update(SHA_CTX * ctx,const void * data,size_t length)660 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length)
661 {
662 gnutls_hash(*ctx, data, length);
663 return 1;
664 }
665
666 #define USE_LIB_CRYPTO_SHA256
667 typedef gnutls_hash_hd_t SHA256_CTX;
668 static inline int
SHA256_Init(SHA256_CTX * ctx)669 SHA256_Init(SHA256_CTX *ctx)
670 {
671 if (gnutls_hash_init(ctx, GNUTLS_DIG_SHA256) < 0)
672 ck_bt_abort(__FILE__, __LINE__, "aborted");
673 return 1;
674 }
675 static inline int
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)676 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
677 {
678 gnutls_hash_deinit(*ctx, digest);
679 return 1;
680 }
681 static inline int
SHA256_Update(SHA256_CTX * ctx,const void * data,size_t length)682 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length)
683 {
684 gnutls_hash(*ctx, data, length);
685 return 1;
686 }
687
688 #define USE_LIB_CRYPTO_SHA512
689 typedef gnutls_hash_hd_t SHA512_CTX;
690 static inline int
SHA512_Init(SHA512_CTX * ctx)691 SHA512_Init(SHA512_CTX *ctx)
692 {
693 if (gnutls_hash_init(ctx, GNUTLS_DIG_SHA512) < 0)
694 ck_bt_abort(__FILE__, __LINE__, "aborted");
695 return 1;
696 }
697 static inline int
SHA512_Final(unsigned char * digest,SHA512_CTX * ctx)698 SHA512_Final(unsigned char *digest, SHA512_CTX *ctx)
699 {
700 gnutls_hash_deinit(*ctx, digest);
701 return 1;
702 }
703 static inline int
SHA512_Update(SHA512_CTX * ctx,const void * data,size_t length)704 SHA512_Update(SHA512_CTX *ctx, const void *data, size_t length)
705 {
706 gnutls_hash(*ctx, data, length);
707 return 1;
708 }
709
710 #elif defined(USE_NSS_CRYPTO)
711
712 #ifdef __has_include
713 #if __has_include(<nss3/nss.h>)
714 #define NSS_VER_INCLUDE
715 #endif
716 #endif
717
718 /* basic algorithms fail if NSS library has not been init'd (WTH).
719 * lighttpd defers initialization of rand and crypto until first use
720 * to attempt to avoid long, blocking init at startup while waiting
721 * for sufficient system entropy to become available */
722 #ifdef NSS_VER_INCLUDE
723 #include <nss3/nss.h> /* NSS_IsInitialized() NSS_NoDB_Init() */
724 #else
725 #include <nss/nss.h> /* NSS_IsInitialized() NSS_NoDB_Init() */
726 #endif
727 #include <stdlib.h> /* abort() */
728 __attribute_cold__
729 static inline void
nss_requires_explicit_init_for_basic_crypto_wth(void)730 nss_requires_explicit_init_for_basic_crypto_wth(void)
731 {
732 if (NSS_NoDB_Init(NULL) < 0)
733 abort();
734 }
735
736 #ifdef NSS_VER_INCLUDE
737 #include <nss3/sechash.h>
738 #else
739 #include <nss/sechash.h>
740 #endif
741
742 #define NSS_gen_hashfuncs(name, typ) \
743 static inline int \
744 name##_Init(void **ctx) \
745 { \
746 if (!NSS_IsInitialized()) \
747 nss_requires_explicit_init_for_basic_crypto_wth(); \
748 const SECHashObject * const hashObj = HASH_GetHashObject(typ); \
749 return ((*ctx=hashObj->create()) != NULL) ? (hashObj->begin(*ctx),1) : 0; \
750 } \
751 static inline int \
752 name##_Final(unsigned char *dest, void **ctx) \
753 { \
754 const SECHashObject * const hashObj = HASH_GetHashObject(typ); \
755 unsigned int retLen; \
756 hashObj->end(*ctx, dest, &retLen, hashObj->length); \
757 hashObj->destroy(*ctx, PR_TRUE); \
758 return 1; \
759 } \
760 static inline int \
761 name##_Update(void **ctx, const void *src, size_t len) \
762 { \
763 const SECHashObject * const hashObj = HASH_GetHashObject(typ); \
764 hashObj->update(*ctx, src, (int)len); \
765 return 1; \
766 } \
767 typedef void * name##_CTX
768 typedef void * SHA_CTX;
769
770 #define USE_LIB_CRYPTO_MD5
771 /* MD5_Init()
772 * MD5_Update()
773 * MD5_Final() */
774 NSS_gen_hashfuncs(MD5, HASH_AlgMD5);
775
776 #define USE_LIB_CRYPTO_SHA1
777 /* SHA1_Init()
778 * SHA1_Update()
779 * SHA1_Final() */
780 NSS_gen_hashfuncs(SHA1, HASH_AlgSHA1);
781
782 #define USE_LIB_CRYPTO_SHA256
783 /* SHA256_Init()
784 * SHA256_Update()
785 * SHA256_Final() */
786 NSS_gen_hashfuncs(SHA256, HASH_AlgSHA256);
787
788 #define USE_LIB_CRYPTO_SHA512
789 /* SHA512_Init()
790 * SHA512_Update()
791 * SHA512_Final() */
792 NSS_gen_hashfuncs(SHA512, HASH_AlgSHA512);
793
794 #endif
795
796 #endif /* USE_LIB_CRYPTO */
797
798
799 #ifdef USE_LIB_CRYPTO_MD4
800 #ifndef MD4_DIGEST_LENGTH
801 #define MD4_DIGEST_LENGTH 16
802 #endif
803 #undef MD_DIGEST_LENGTH_MAX
804 #define MD_DIGEST_LENGTH_MAX MD4_DIGEST_LENGTH
805 #endif
806
807
808 #ifdef USE_LIB_CRYPTO_MD5
809 #ifndef MD5_DIGEST_LENGTH
810 #define MD5_DIGEST_LENGTH 16
811 #endif
812 #include "algo_md5.h" /*(for legacy li_MD5_*() name mangling)*/
813 #else
814 #include "algo_md5.h" /* MD5 implementation included with lighttpd */
815 #endif
816 #undef MD_DIGEST_LENGTH_MAX
817 #define MD_DIGEST_LENGTH_MAX MD5_DIGEST_LENGTH
818
819
820 #ifdef USE_LIB_CRYPTO_SHA1
821 typedef SHA_CTX SHA1_CTX; /*(naming consistency with other algos)*/
822 #ifndef SHA_DIGEST_LENGTH
823 #define SHA_DIGEST_LENGTH 20
824 #endif
825 #ifndef SHA1_DIGEST_LENGTH /*(naming consistency with other algos)*/
826 #define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
827 #endif
828 #else
829 #include "algo_sha1.h" /* SHA1 implementation included with lighttpd */
830 typedef SHA_CTX SHA1_CTX; /*(naming consistency with other algos)*/
831 #endif
832 #undef MD_DIGEST_LENGTH_MAX
833 #define MD_DIGEST_LENGTH_MAX SHA_DIGEST_LENGTH
834
835
836 #ifdef USE_LIB_CRYPTO_SHA256
837 #ifndef SHA256_DIGEST_LENGTH
838 #define SHA256_DIGEST_LENGTH 32
839 #endif
840 #undef MD_DIGEST_LENGTH_MAX
841 #define MD_DIGEST_LENGTH_MAX SHA256_DIGEST_LENGTH
842 #endif
843
844
845 #ifdef USE_LIB_CRYPTO_SHA512_256
846 #ifndef SHA512_256_DIGEST_LENGTH
847 #define SHA512_256_DIGEST_LENGTH 32
848 #endif
849 #undef MD_DIGEST_LENGTH_MAX
850 #define MD_DIGEST_LENGTH_MAX SHA512_256_DIGEST_LENGTH
851 #endif
852
853
854 #ifdef USE_LIB_CRYPTO_SHA512
855 #ifndef SHA512_DIGEST_LENGTH
856 #define SHA512_DIGEST_LENGTH 64
857 #endif
858 #undef MD_DIGEST_LENGTH_MAX
859 #define MD_DIGEST_LENGTH_MAX SHA512_DIGEST_LENGTH
860 #endif
861
862
863 /* message digest wrappers operating on single ptr, and on const_iovec */
864
865
866 typedef void(*li_md_once_fn)(unsigned char *digest, const void *data, size_t n);
867
868 #define li_md_once(algo) \
869 static inline void \
870 algo##_once (unsigned char * const digest, \
871 const void * const data, const size_t n) \
872 { \
873 algo##_CTX ctx; \
874 algo##_Init(&ctx); \
875 algo##_Update(&ctx, data, n); \
876 algo##_Final(digest, &ctx); \
877 }
878
879 #ifndef LI_CONST_IOVEC
880 #define LI_CONST_IOVEC
881 struct const_iovec {
882 const void *iov_base;
883 size_t iov_len;
884 };
885 #endif
886
887 typedef void(*li_md_iov_fn)(unsigned char *digest,
888 const struct const_iovec *iov, size_t n);
889
890 #define li_md_iov(algo) \
891 static inline void \
892 algo##_iov (unsigned char * const digest, \
893 const struct const_iovec * const iov, const size_t n) \
894 { \
895 algo##_CTX ctx; \
896 algo##_Init(&ctx); \
897 for (size_t i = 0; i < n; ++i) { \
898 if (iov[i].iov_len) \
899 algo##_Update(&ctx, iov[i].iov_base, iov[i].iov_len); \
900 } \
901 algo##_Final(digest, &ctx); \
902 }
903
904 #ifdef USE_LIB_CRYPTO_MD4
905 li_md_once(MD4)
906 li_md_iov(MD4)
907 #endif /* MD4_once() MD4_iov() */
908
909 /*#ifdef USE_LIB_CRYPTO_MD5*/
910 li_md_once(MD5)
911 li_md_iov(MD5)
912 /*#endif*/ /* MD5_once() MD5_iov() */
913
914 /*#ifdef USE_LIB_CRYPTO_SHA1*/
915 li_md_once(SHA1)
916 li_md_iov(SHA1)
917 /*#endif*/ /* SHA1_once() SHA1_iov() */
918
919 #ifdef USE_LIB_CRYPTO_SHA256
920 li_md_once(SHA256)
921 li_md_iov(SHA256)
922 #endif /* SHA256_once() SHA256_iov() */
923
924 #ifdef USE_LIB_CRYPTO_SHA512_256
925 li_md_once(SHA512_256)
926 li_md_iov(SHA512_256)
927 #endif /* SHA512_256_once() SHA512_256_iov() */
928
929 #ifdef USE_LIB_CRYPTO_SHA512
930 li_md_once(SHA512)
931 li_md_iov(SHA512)
932 #endif /* SHA512_once() SHA512_iov() */
933
934
935 #endif /* LI_SYS_CRYPTO_MD_H */
936