7RCSID(
"$Id: b236a4acb6bb1283a1c656c7a3dba5693d379fb3 $")
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>
53#ifdef HAVE_OPENSSL_EVP_H
54# include <freeradius-devel/tls/openssl_user_macros.h>
55# include <openssl/evp.h>
56# include <openssl/crypto.h>
57# include <openssl/err.h>
58# include <openssl/provider.h>
65 EVP_MD_CTX *md_ctx = ctx;
67 EVP_MD_CTX_reset(md_ctx);
68 (void)EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL);
76 EVP_MD_CTX_copy_ex(dst, src);
86 md_ctx = EVP_MD_CTX_new();
89 if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) != 1) {
92 ERR_error_string_n(ERR_get_error(),
buffer,
sizeof(
buffer));
94 EVP_MD_CTX_free(md_ctx);
109 EVP_MD_CTX_free(*ctx);
118 EVP_DigestUpdate(ctx,
in,
inlen);
128 EVP_DigestFinal(ctx,
out, &len);
134 .
reset = fr_md5_openssl_ctx_reset,
135 .copy = fr_md5_openssl_ctx_copy,
136 .alloc = fr_md5_openssl_ctx_alloc,
137 .free = fr_md5_openssl_ctx_free,
138 .update = fr_md5_openssl_update,
139 .final = fr_md5_openssl_final
143# define MD5_BLOCK_LENGTH 64
166#define PUT_64BIT_LE(cp, value) do {\
167 (cp)[7] = (value)[1] >> 24;\
168 (cp)[6] = (value)[1] >> 16;\
169 (cp)[5] = (value)[1] >> 8;\
170 (cp)[4] = (value)[1];\
171 (cp)[3] = (value)[0] >> 24;\
172 (cp)[2] = (value)[0] >> 16;\
173 (cp)[1] = (value)[0] >> 8;\
174 (cp)[0] = (value)[0];\
177#define PUT_32BIT_LE(cp, value) do {\
178 (cp)[3] = (value) >> 24;\
179 (cp)[2] = (value) >> 16;\
180 (cp)[1] = (value) >> 8;\
185 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
192#define MD5_F1(x, y, z) (z ^ (x & (y ^ z)))
193#define MD5_F2(x, y, z) MD5_F1(z, x, y)
194#define MD5_F3(x, y, z) (x ^ y ^ z)
195#define MD5_F4(x, y, z) (y ^ (x | ~z))
198#define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
309 ctx_local->
count[0] = 0;
310 ctx_local->
count[1] = 0;
311 ctx_local->
state[0] = 0x67452301;
312 ctx_local->
state[1] = 0xefcdab89;
313 ctx_local->
state[2] = 0x98badcfe;
314 ctx_local->
state[3] = 0x10325476;
315 memset(ctx_local->
buffer, 0,
sizeof(ctx_local->
buffer));
326 memcpy(ctx_local_dst, ctx_local_src,
sizeof(*ctx_local_dst));
337 if (
unlikely(!ctx_local))
return NULL;
382 ctx_local->
count[1]++;
388 memcpy(ctx_local->
buffer + have,
in, need);
428 for (i = 0; i < 4; i++)
431 memset(ctx_local, 0,
sizeof(*ctx_local));
456 if (free_list[i].
used)
continue;
491 if (
unlikely(md_ctx == NULL))
goto oom;
493 free_list[i].
md_ctx = md_ctx;
500 if (free_list[i].
used)
continue;
502 free_list[i].
used =
true;
503 return free_list[i].
md_ctx;
522 if (free_list[i].md_ctx == *ctx) {
523 free_list[i].
used =
false;
535#ifdef HAVE_OPENSSL_EVP_H
559 free_list[i].
md_ctx = md_ctx;
563void fr_md5_openssl_init(
void)
571 if (EVP_default_properties_is_fips_enabled(NULL))
return;
581 md5_free_list_reinit(&md5_openssl_funcs);
584void fr_md5_openssl_free(
void)
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)
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.
static void fr_md5_local_ctx_copy(fr_md5_ctx_t *dst, fr_md5_ctx_t const *src)
Copy the contents of a ctx.
static void fr_md5_local_update(fr_md5_ctx_t *ctx, uint8_t const *in, size_t inlen)
Ingest plaintext into the digest.
static void fr_md5_local_ctx_reset(fr_md5_ctx_t *ctx)
Reset the ctx to allow reuse.
#define ARRAY_SIZE
The thread local free list.
#define PUT_64BIT_LE(cp, value)
static _Thread_local fr_md5_free_list_t * md5_array
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)
Free function for MD5 digest ctx.
static fr_md5_ctx_t * fr_md5_local_ctx_alloc(void)
Allocation function for MD5 digest context.
static int _md5_ctx_free_on_exit(void *arg)
static const uint8_t PADDING[MD5_BLOCK_LENGTH]
fr_md5_funcs_t const * fr_md5_funcs
Swap a single pointer, so all functions get swapped as an atomic operation.
static fr_md5_funcs_t md5_local_funcs
static void fr_md5_local_final(uint8_t out[static MD5_DIGEST_LENGTH], fr_md5_ctx_t *ctx)
Finalise the ctx, producing the digest.
static void fr_md5_local_ctx_free(fr_md5_ctx_t **ctx)
Free function for MD5 digest ctx.
uint8_t buffer[MD5_BLOCK_LENGTH]
Input buffer.
fr_md5_ctx_t * fr_md5_ctx_alloc_from_list(void)
Allocation function for MD5 digest context.
#define PUT_32BIT_LE(cp, value)
static const uint8_t * zero
#define fr_md5_final(_out, _ctx)
Finalise the ctx, producing the digest.
#define fr_md5_ctx_alloc()
Allocation function for MD5 digest context.
#define fr_md5_ctx_reset(_ctx)
Reset the ctx to allow reuse.
#define fr_md5_update(_ctx, _in, _inlen)
Ingest plaintext into the digest.
#define fr_md5_ctx_free(_ctx)
Free function for MD5 digest 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