7RCSID(
"$Id: c8885e9123963185b38c4218a569cc87ac59231e $")
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>
32#ifdef HAVE_OPENSSL_EVP_H
44#ifdef HAVE_OPENSSL_EVP_H
45 .alloc = fr_md5_local_ctx_init,
61#ifdef HAVE_OPENSSL_EVP_H
62# include <freeradius-devel/tls/openssl_user_macros.h>
63# include <openssl/evp.h>
64# include <openssl/crypto.h>
65# include <openssl/err.h>
66# include <openssl/provider.h>
73 EVP_MD_CTX *md_ctx = ctx;
75 EVP_MD_CTX_reset(md_ctx);
76 (void)EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL);
84 EVP_MD_CTX_copy_ex(dst, src);
94 md_ctx = EVP_MD_CTX_new();
97 if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) != 1) {
100 ERR_error_string_n(ERR_get_error(),
buffer,
sizeof(
buffer));
102 EVP_MD_CTX_free(md_ctx);
115 EVP_MD_CTX_free(*ctx);
124 EVP_DigestUpdate(ctx,
in,
inlen);
134 EVP_DigestFinal(ctx,
out, &len);
140 .
reset = fr_md5_openssl_ctx_reset,
141 .copy = fr_md5_openssl_ctx_copy,
142 .alloc = fr_md5_openssl_ctx_alloc,
143 .free = fr_md5_openssl_ctx_free,
144 .update = fr_md5_openssl_update,
145 .final = fr_md5_openssl_final
149# define MD5_BLOCK_LENGTH 64
172#define PUT_64BIT_LE(cp, value) do {\
173 (cp)[7] = (value)[1] >> 24;\
174 (cp)[6] = (value)[1] >> 16;\
175 (cp)[5] = (value)[1] >> 8;\
176 (cp)[4] = (value)[1];\
177 (cp)[3] = (value)[0] >> 24;\
178 (cp)[2] = (value)[0] >> 16;\
179 (cp)[1] = (value)[0] >> 8;\
180 (cp)[0] = (value)[0];\
183#define PUT_32BIT_LE(cp, value) do {\
184 (cp)[3] = (value) >> 24;\
185 (cp)[2] = (value) >> 16;\
186 (cp)[1] = (value) >> 8;\
191 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
198#define MD5_F1(x, y, z) (z ^ (x & (y ^ z)))
199#define MD5_F2(x, y, z) MD5_F1(z, x, y)
200#define MD5_F3(x, y, z) (x ^ y ^ z)
201#define MD5_F4(x, y, z) (y ^ (x | ~z))
204#define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
315 ctx_local->
count[0] = 0;
316 ctx_local->
count[1] = 0;
317 ctx_local->
state[0] = 0x67452301;
318 ctx_local->
state[1] = 0xefcdab89;
319 ctx_local->
state[2] = 0x98badcfe;
320 ctx_local->
state[3] = 0x10325476;
321 memset(ctx_local->
buffer, 0,
sizeof(ctx_local->
buffer));
332 memcpy(ctx_local_dst, ctx_local_src,
sizeof(*ctx_local_dst));
343 if (
unlikely(!ctx_local))
return NULL;
349#ifdef HAVE_OPENSSL_EVP_H
358 if (!EVP_default_properties_is_fips_enabled(NULL)) {
415 ctx_local->
count[1]++;
421 memcpy(ctx_local->
buffer + have,
in, need);
461 for (i = 0; i < 4; i++)
464 memset(ctx_local, 0,
sizeof(*ctx_local));
489 if (free_list[i].
used)
continue;
520 if (
unlikely(md_ctx == NULL))
goto oom;
522 free_list[i].
md_ctx = md_ctx;
529 if (free_list[i].
used)
continue;
531 free_list[i].
used =
true;
532 return free_list[i].
md_ctx;
551 if (free_list[i].md_ctx == *ctx) {
552 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)
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