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