7 RCSID(
"$Id: f0fb0cd327ee2b9cc26de098074244a01d1bd07b $")
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>
41 # include <openssl/provider.h>
43 static int have_openssl_md5 = -1;
50 EVP_MD_CTX *md_ctx = ctx;
52 EVP_MD_CTX_reset(md_ctx);
53 (void)EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL);
61 EVP_MD_CTX_copy_ex(dst, src);
71 md_ctx = EVP_MD_CTX_new();
74 if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) != 1) {
77 ERR_error_string_n(ERR_get_error(),
buffer,
sizeof(
buffer));
79 EVP_MD_CTX_free(md_ctx);
92 EVP_MD_CTX_free(*ctx);
101 EVP_DigestUpdate(ctx,
in,
inlen);
111 EVP_DigestFinal(ctx,
out, &len);
117 # define MD5_BLOCK_LENGTH 64
140 #define PUT_64BIT_LE(cp, value) do {\
141 (cp)[7] = (value)[1] >> 24;\
142 (cp)[6] = (value)[1] >> 16;\
143 (cp)[5] = (value)[1] >> 8;\
144 (cp)[4] = (value)[1];\
145 (cp)[3] = (value)[0] >> 24;\
146 (cp)[2] = (value)[0] >> 16;\
147 (cp)[1] = (value)[0] >> 8;\
148 (cp)[0] = (value)[0];\
151 #define PUT_32BIT_LE(cp, value) do {\
152 (cp)[3] = (value) >> 24;\
153 (cp)[2] = (value) >> 16;\
154 (cp)[1] = (value) >> 8;\
159 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
166 #define MD5_F1(x, y, z) (z ^ (x & (y ^ z)))
167 #define MD5_F2(x, y, z) MD5_F1(z, x, y)
168 #define MD5_F3(x, y, z) (x ^ y ^ z)
169 #define MD5_F4(x, y, z) (y ^ (x | ~z))
172 #define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
283 ctx_local->
count[0] = 0;
284 ctx_local->
count[1] = 0;
285 ctx_local->
state[0] = 0x67452301;
286 ctx_local->
state[1] = 0xefcdab89;
287 ctx_local->
state[2] = 0x98badcfe;
288 ctx_local->
state[3] = 0x10325476;
289 memset(ctx_local->
buffer, 0,
sizeof(ctx_local->
buffer));
300 memcpy(ctx_local_dst, ctx_local_src,
sizeof(*ctx_local_dst));
310 #ifdef HAVE_OPENSSL_EVP_H
311 if (
unlikely(have_openssl_md5 == -1)) {
317 if (!EVP_default_properties_is_fips_enabled(NULL)) {
318 have_openssl_md5 = 1;
334 have_openssl_md5 = 0;
338 if (
unlikely(!ctx_local))
return NULL;
383 ctx_local->
count[1]++;
389 memcpy(ctx_local->
buffer + have,
in, need);
429 for (i = 0; i < 4; i++)
432 memset(ctx_local, 0,
sizeof(*ctx_local));
467 if (free_list[i].
used)
continue;
498 if (
unlikely(md_ctx == NULL))
goto oom;
500 free_list[i].
md_ctx = md_ctx;
507 if (free_list[i].
used)
continue;
509 free_list[i].
used =
true;
510 return free_list[i].
md_ctx;
529 if (free_list[i].md_ctx == *ctx) {
530 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