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) 26 #define MD4_Final(digest, ctx) \ 27 nettle_md4_digest((ctx),MD4_DIGEST_SIZE,(digest)) 28 static inline void 29 MD4_Update(MD4_CTX *ctx, const void *data, size_t length) 30 { 31 nettle_md4_update(ctx, length, data); 32 } 33 34 #define USE_LIB_CRYPTO_MD5 35 typedef struct md5_ctx MD5_CTX; 36 #define MD5_Init(ctx) \ 37 nettle_md5_init(ctx) 38 #define MD5_Final(digest, ctx) \ 39 nettle_md5_digest((ctx),MD5_DIGEST_SIZE,(digest)) 40 static inline void 41 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 42 { 43 nettle_md5_update(ctx, length, data); 44 } 45 46 #define USE_LIB_CRYPTO_SHA1 47 typedef struct sha1_ctx SHA_CTX; 48 #define SHA1_Init(ctx) \ 49 nettle_sha1_init(ctx) 50 #define SHA1_Final(digest, ctx) \ 51 nettle_sha1_digest((ctx),SHA1_DIGEST_SIZE,(digest)) 52 static inline void 53 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 54 { 55 nettle_sha1_update(ctx, length, data); 56 } 57 58 #define USE_LIB_CRYPTO_SHA256 59 typedef struct sha256_ctx SHA256_CTX; 60 #define SHA256_Init(ctx) \ 61 nettle_sha256_init(ctx) 62 #define SHA256_Final(digest, ctx) \ 63 nettle_sha256_digest((ctx),SHA256_DIGEST_SIZE,(digest)) 64 static inline void 65 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 66 { 67 nettle_sha256_update(ctx, length, data); 68 } 69 70 #define USE_LIB_CRYPTO_SHA512_256 71 #ifndef SHA512_256_DIGEST_LENGTH 72 #define SHA512_256_DIGEST_LENGTH 32 73 #endif 74 typedef struct sha512_256_ctx SHA512_CTX; /*(yes, SHA512_CTX)*/ 75 #define SHA512_256_Init(ctx) \ 76 nettle_sha512_256_init(ctx) 77 #define SHA512_256_Final(digest, ctx) \ 78 nettle_sha512_256_digest((ctx),SHA256_DIGEST_SIZE,(digest)) 79 static inline void 80 SHA512_256_Update(SHA512_CTX *ctx, const void *data, size_t length) 81 { 82 nettle_sha512_update(ctx, length, data); /*(yes, nettle_sha512_update())*/ 83 } 84 85 #elif defined(USE_MBEDTLS_CRYPTO) 86 87 #ifdef MBEDTLS_MD4_C 88 #define USE_LIB_CRYPTO_MD4 89 #include <mbedtls/md4.h> 90 typedef struct mbedtls_md4_context MD4_CTX; 91 #define MD4_Init(ctx) \ 92 (mbedtls_md4_init(ctx), mbedtls_md4_starts_ret(ctx)) 93 #define MD4_Final(digest, ctx) \ 94 (mbedtls_md4_finish_ret((ctx),(digest)), mbedtls_md4_free(ctx)) 95 static inline void 96 MD4_Update(MD4_CTX *ctx, const void *data, size_t length) 97 { 98 mbedtls_md4_update_ret(ctx, data, length); 99 } 100 #endif 101 102 #ifdef MBEDTLS_MD5_C 103 #define USE_LIB_CRYPTO_MD5 104 #include <mbedtls/md5.h> 105 typedef struct mbedtls_md5_context MD5_CTX; 106 #define MD5_Init(ctx) \ 107 (mbedtls_md5_init(ctx), mbedtls_md5_starts_ret(ctx)) 108 #define MD5_Final(digest, ctx) \ 109 (mbedtls_md5_finish_ret((ctx),(digest)), mbedtls_md5_free(ctx)) 110 static inline void 111 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 112 { 113 mbedtls_md5_update_ret(ctx, data, length); 114 } 115 #endif 116 117 #ifdef MBEDTLS_SHA1_C 118 #define USE_LIB_CRYPTO_SHA1 119 #include <mbedtls/sha1.h> 120 typedef struct mbedtls_sha1_context SHA_CTX; 121 #define SHA1_Init(ctx) \ 122 (mbedtls_sha1_init(ctx), mbedtls_sha1_starts_ret(ctx)) 123 #define SHA1_Final(digest, ctx) \ 124 (mbedtls_sha1_finish_ret((ctx),(digest)), mbedtls_sha1_free(ctx)) 125 static inline void 126 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 127 { 128 mbedtls_sha1_update_ret(ctx, data, length); 129 } 130 #endif 131 132 #ifdef MBEDTLS_SHA256_C 133 #define USE_LIB_CRYPTO_SHA256 134 #include <mbedtls/sha256.h> 135 typedef struct mbedtls_sha256_context SHA256_CTX; 136 #define SHA256_Init(ctx) \ 137 (mbedtls_sha256_init(ctx), mbedtls_sha256_starts_ret((ctx),0)) 138 #define SHA256_Final(digest, ctx) \ 139 (mbedtls_sha256_finish_ret((ctx),(digest)), mbedtls_sha256_free(ctx)) 140 static inline void 141 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 142 { 143 mbedtls_sha256_update_ret(ctx, data, length); 144 } 145 #endif 146 147 #elif defined(USE_WOLFSSL_CRYPTO) && !defined(USE_OPENSSL_CRYPTO) 148 149 /* WolfSSL compatibility API for OpenSSL unnecessarily bounces through an extra 150 * layer of indirection. However, to avoid conflicting typedefs when includers 151 * also include headers from the WolfSSL compatibility API for OpenSSL, we 152 * include those headers here, as well, and use the compatibility API typedefs. 153 * (undef of OPENSSL_EXTRA and NO_OLD_WC_NAMES not sufficient, and not friendly 154 * to do in a header when others might rely on them) */ 155 156 #ifndef NO_MD4 157 #include <wolfssl/wolfcrypt/md4.h> 158 #include <wolfssl/openssl/md4.h> 159 #undef MD4_Init 160 #undef MD4_Final 161 #undef MD4_Update 162 #define USE_LIB_CRYPTO_MD4 163 /*typedef Md4 MD4_CTX;*/ 164 static inline int 165 MD4_Init(MD4_CTX *ctx) 166 { 167 wc_InitMd4((Md4 *)ctx); 168 return 1; 169 } 170 static inline int 171 MD4_Final(unsigned char *digest, MD4_CTX *ctx) 172 { 173 wc_Md4Final((Md4 *)ctx, digest); 174 return 1; 175 } 176 static inline void 177 MD4_Update(MD4_CTX *ctx, const void *data, size_t length) 178 { 179 wc_Md4Update((Md4 *)ctx, data, length); 180 } 181 #endif 182 183 #ifndef NO_MD5 184 #include <wolfssl/wolfcrypt/md5.h> 185 #include <wolfssl/openssl/md5.h> 186 #undef MD5_Init 187 #undef MD5_Final 188 #undef MD5_Update 189 #define USE_LIB_CRYPTO_MD5 190 /*typedef wc_Md5 MD5_CTX;*/ 191 static inline int 192 MD5_Init(MD5_CTX *ctx) 193 { 194 return (0 == wc_InitMd5((wc_Md5 *)ctx)); 195 } 196 static inline int 197 MD5_Final(unsigned char *digest, MD5_CTX *ctx) 198 { 199 return (0 == wc_Md5Final((wc_Md5 *)ctx, digest)); 200 } 201 static inline void 202 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 203 { 204 wc_Md5Update((wc_Md5 *)ctx, data, length); 205 } 206 #endif 207 208 #ifndef NO_SHA 209 #include <wolfssl/wolfcrypt/sha.h> 210 #include <wolfssl/openssl/sha.h> 211 #undef SHA1_Init 212 #undef SHA1_Final 213 #undef SHA1_Update 214 #define USE_LIB_CRYPTO_SHA1 215 /*typedef wc_Sha SHA_CTX;*/ 216 static inline int 217 SHA1_Init(SHA_CTX *ctx) 218 { 219 return (0 == wc_InitSha((wc_Sha *)ctx)); 220 } 221 static inline int 222 SHA1_Final(unsigned char *digest, SHA_CTX *ctx) 223 { 224 return (0 == wc_ShaFinal((wc_Sha *)ctx, digest)); 225 } 226 static inline void 227 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 228 { 229 wc_ShaUpdate((wc_Sha *)ctx, data, length); 230 } 231 #endif 232 233 #ifndef NO_SHA256 234 #include <wolfssl/wolfcrypt/sha256.h> 235 #include <wolfssl/openssl/sha.h> 236 #undef SHA256_Init 237 #undef SHA256_Final 238 #undef SHA256_Update 239 #define USE_LIB_CRYPTO_SHA256 240 /*typedef wc_Sha256 SHA256_CTX;*/ 241 static inline int 242 SHA256_Init(SHA256_CTX *ctx) 243 { 244 return (0 == wc_InitSha256((wc_Sha256 *)ctx)); 245 } 246 static inline int 247 SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) 248 { 249 return (0 == wc_Sha256Final((wc_Sha256 *)ctx, digest)); 250 } 251 static inline void 252 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 253 { 254 wc_Sha256Update((wc_Sha256 *)ctx, data, length); 255 } 256 #endif 257 258 #elif defined(USE_OPENSSL_CRYPTO) 259 260 #include <openssl/md4.h> 261 #include <openssl/md5.h> 262 #include <openssl/sha.h> 263 #ifndef OPENSSL_NO_MD4 264 #ifndef NO_MD4 /*(e.g. wolfSSL built without MD4)*/ 265 #define USE_LIB_CRYPTO_MD4 266 #endif 267 #endif 268 #ifndef OPENSSL_NO_MD5 269 #define USE_LIB_CRYPTO_MD5 270 #endif 271 #define USE_LIB_CRYPTO_SHA1 272 #define USE_LIB_CRYPTO_SHA256 273 #ifdef SHA512_256_DIGEST_LENGTH 274 #define USE_LIB_CRYPTO_SHA512_256 275 #endif 276 277 #elif defined(USE_GNUTLS_CRYPTO) 278 279 #include <gnutls/crypto.h> 280 281 #define USE_LIB_CRYPTO_MD5 282 typedef gnutls_hash_hd_t MD5_CTX; 283 #define MD5_Init(ctx) \ 284 do { \ 285 if (gnutls_hash_init((ctx), GNUTLS_DIG_MD5) < 0) \ 286 SEGFAULT(); \ 287 } while (0) 288 #define MD5_Final(digest, ctx) \ 289 gnutls_hash_deinit(*(ctx),(digest)) 290 static inline void 291 MD5_Update(MD5_CTX *ctx, const void *data, size_t length) 292 { 293 gnutls_hash(*ctx, data, length); 294 } 295 296 #define USE_LIB_CRYPTO_SHA1 297 typedef gnutls_hash_hd_t SHA_CTX; 298 #define SHA1_Init(ctx) \ 299 do { \ 300 if (gnutls_hash_init((ctx), GNUTLS_DIG_SHA1) < 0) \ 301 SEGFAULT(); \ 302 } while (0) 303 #define SHA1_Final(digest, ctx) \ 304 gnutls_hash_deinit(*(ctx),(digest)) 305 static inline void 306 SHA1_Update(SHA_CTX *ctx, const void *data, size_t length) 307 { 308 gnutls_hash(*ctx, data, length); 309 } 310 311 #define USE_LIB_CRYPTO_SHA256 312 typedef gnutls_hash_hd_t SHA256_CTX; 313 #define SHA256_Init(ctx) \ 314 do { \ 315 if (gnutls_hash_init((ctx), GNUTLS_DIG_SHA256) < 0) \ 316 SEGFAULT(); \ 317 } while (0) 318 #define SHA256_Final(digest, ctx) \ 319 gnutls_hash_deinit(*(ctx),(digest)) 320 static inline void 321 SHA256_Update(SHA256_CTX *ctx, const void *data, size_t length) 322 { 323 gnutls_hash(*ctx, data, length); 324 } 325 326 #endif 327 328 #endif /* USE_LIB_CRYPTO */ 329 330 331 #ifdef USE_LIB_CRYPTO_MD5 332 #ifndef MD5_DIGEST_LENGTH 333 #define MD5_DIGEST_LENGTH 16 334 #endif 335 #include "algo_md5.h" /*(for legacy li_MD5_*() name mangling)*/ 336 #else 337 #include "algo_md5.h" 338 #endif 339 340 341 #ifdef USE_LIB_CRYPTO_SHA1 342 #ifndef SHA_DIGEST_LENGTH 343 #define SHA_DIGEST_LENGTH 20 344 #endif 345 #else 346 #include "algo_sha1.h" 347 #endif 348 349 350 #endif /* LI_SYS_CRYPTO_MD_H */ 351