7 RCSID(
"$Id: c3c60049cd3a1776740782409276b17294411651 $")
9 #include <freeradius-devel/util/debug.h>
10 #include <freeradius-devel/util/strerror.h>
11 #include <freeradius-devel/util/atexit.h>
17 #include <freeradius-devel/util/md5.h>
23 #define ARRAY_SIZE (8)
36 #ifdef HAVE_OPENSSL_EVP_H
37 # include <freeradius-devel/tls/openssl_user_macros.h>
38 # include <openssl/evp.h>
39 # include <openssl/crypto.h>
40 # include <openssl/err.h>
42 # if OPENSSL_VERSION_NUMBER >= 0x30000000L
43 # include <openssl/provider.h>
46 static int have_openssl_md5 = -1;
53 EVP_MD_CTX *md_ctx = ctx;
55 EVP_MD_CTX_reset(md_ctx);
56 (void)EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL);
64 EVP_MD_CTX_copy_ex(dst, src);
74 md_ctx = EVP_MD_CTX_new();
77 if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) != 1) {
80 ERR_error_string_n(ERR_get_error(),
buffer,
sizeof(
buffer));
82 EVP_MD_CTX_free(md_ctx);
95 EVP_MD_CTX_free(*ctx);
104 EVP_DigestUpdate(ctx,
in,
inlen);
114 EVP_DigestFinal(ctx,
out, &len);
120 # define MD5_BLOCK_LENGTH 64
143 #define PUT_64BIT_LE(cp, value) do {\
144 (cp)[7] = (value)[1] >> 24;\
145 (cp)[6] = (value)[1] >> 16;\
146 (cp)[5] = (value)[1] >> 8;\
147 (cp)[4] = (value)[1];\
148 (cp)[3] = (value)[0] >> 24;\
149 (cp)[2] = (value)[0] >> 16;\
150 (cp)[1] = (value)[0] >> 8;\
151 (cp)[0] = (value)[0];\
154 #define PUT_32BIT_LE(cp, value) do {\
155 (cp)[3] = (value) >> 24;\
156 (cp)[2] = (value) >> 16;\
157 (cp)[1] = (value) >> 8;\
162 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
169 #define MD5_F1(x, y, z) (z ^ (x & (y ^ z)))
170 #define MD5_F2(x, y, z) MD5_F1(z, x, y)
171 #define MD5_F3(x, y, z) (x ^ y ^ z)
172 #define MD5_F4(x, y, z) (y ^ (x | ~z))
175 #define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
286 ctx_local->
count[0] = 0;
287 ctx_local->
count[1] = 0;
288 ctx_local->
state[0] = 0x67452301;
289 ctx_local->
state[1] = 0xefcdab89;
290 ctx_local->
state[2] = 0x98badcfe;
291 ctx_local->
state[3] = 0x10325476;
292 memset(ctx_local->
buffer, 0,
sizeof(ctx_local->
buffer));
303 memcpy(ctx_local_dst, ctx_local_src,
sizeof(*ctx_local_dst));
313 #ifdef HAVE_OPENSSL_EVP_H
314 if (
unlikely(have_openssl_md5 == -1)) {
320 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
321 if (!EVP_default_properties_is_fips_enabled(NULL)) {
323 if (FIPS_mode() == 0) {
325 have_openssl_md5 = 1;
341 have_openssl_md5 = 0;
345 if (
unlikely(!ctx_local))
return NULL;
390 ctx_local->
count[1]++;
396 memcpy(ctx_local->
buffer + have,
in, need);
437 for (i = 0; i < 4; i++)
440 memset(ctx_local, 0,
sizeof(*ctx_local));
475 if (free_list[i].
used)
continue;
506 if (
unlikely(md_ctx == NULL))
goto oom;
508 free_list[i].
md_ctx = md_ctx;
515 if (free_list[i].
used)
continue;
517 free_list[i].
used =
true;
518 return free_list[i].
md_ctx;
537 if (free_list[i].md_ctx == *ctx) {
538 free_list[i].
used =
false;
static int const char char buffer[256]
#define fr_atexit_thread_local(_name, _free, _uctx)
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define MD5STEP(f, w, x, y, z, data, s)
fr_md5_ctx_alloc_t fr_md5_ctx_alloc
static void fr_md5_local_transform(uint32_t state[static 4], uint8_t const block[static MD5_BLOCK_LENGTH])
The core of the MD5 algorithm.
uint32_t count[2]
Number of bits, mod 2^64.
fr_md5_ctx_free_t fr_md5_ctx_free
static void fr_md5_local_ctx_copy(fr_md5_ctx_t *dst, fr_md5_ctx_t const *src)
static void fr_md5_local_update(fr_md5_ctx_t *ctx, uint8_t const *in, size_t inlen)
fr_md5_update_t fr_md5_update
fr_md5_final_t fr_md5_final
static void fr_md5_local_ctx_reset(fr_md5_ctx_t *ctx)
#define ARRAY_SIZE
The thread local free list.
#define PUT_64BIT_LE(cp, value)
static _Thread_local fr_md5_free_list_t * md5_array
static fr_md5_ctx_t * fr_md5_local_ctx_alloc(void)
fr_md5_ctx_reset_t fr_md5_ctx_reset
void fr_md5_calc(uint8_t out[static MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
Calculate the MD5 hash of the contents of a buffer.
void fr_md5_ctx_free_from_list(fr_md5_ctx_t **ctx)
fr_md5_ctx_t * fr_md5_ctx_alloc_from_list(void)
static int _md5_ctx_free_on_exit(void *arg)
static const uint8_t PADDING[MD5_BLOCK_LENGTH]
fr_md5_ctx_copy_t fr_md5_ctx_copy
static void fr_md5_local_final(uint8_t out[static MD5_DIGEST_LENGTH], fr_md5_ctx_t *ctx)
static void fr_md5_local_ctx_free(fr_md5_ctx_t **ctx)
uint8_t buffer[MD5_BLOCK_LENGTH]
Input buffer.
#define PUT_32BIT_LE(cp, value)
static const uint8_t * zero
void(* fr_md5_update_t)(fr_md5_ctx_t *ctx, uint8_t const *in, size_t inlen)
Ingest plaintext into the digest.
fr_md5_ctx_t *(* fr_md5_ctx_alloc_t)(void)
Allocation function for MD5 digest context.
void(* fr_md5_final_t)(uint8_t out[static MD5_DIGEST_LENGTH], fr_md5_ctx_t *ctx)
Finalise the ctx, producing the digest.
void(* fr_md5_ctx_free_t)(fr_md5_ctx_t **ctx)
Free function for MD5 digest ctx.
void(* fr_md5_ctx_reset_t)(fr_md5_ctx_t *ctx)
Reset the ctx to allow reuse.
void(* fr_md5_ctx_copy_t)(fr_md5_ctx_t *dst, fr_md5_ctx_t const *src)
Copy the contents of a ctx.
#define MD5_DIGEST_LENGTH
#define talloc_get_type_abort_const
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
static size_t char fr_sbuff_t size_t inlen
static size_t char ** out