xref: /lighttpd1.4/src/sys-crypto-md.h (revision fb7e5a78)
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