7RCSID(
"$Id: f0f12cababa84b8d644abad5470737f90710a899 $")
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);
107 EVP_MD_CTX_free(*ctx);
116 EVP_DigestUpdate(ctx,
in,
inlen);
126 EVP_DigestFinal(ctx,
out, &len);
132 .
reset = fr_md5_openssl_ctx_reset,
133 .copy = fr_md5_openssl_ctx_copy,
134 .alloc = fr_md5_openssl_ctx_alloc,
135 .free = fr_md5_openssl_ctx_free,
136 .update = fr_md5_openssl_update,
137 .final = fr_md5_openssl_final
141# define MD5_BLOCK_LENGTH 64
164#define PUT_64BIT_LE(cp, value) do {\
165 (cp)[7] = (value)[1] >> 24;\
166 (cp)[6] = (value)[1] >> 16;\
167 (cp)[5] = (value)[1] >> 8;\
168 (cp)[4] = (value)[1];\
169 (cp)[3] = (value)[0] >> 24;\
170 (cp)[2] = (value)[0] >> 16;\
171 (cp)[1] = (value)[0] >> 8;\
172 (cp)[0] = (value)[0];\
175#define PUT_32BIT_LE(cp, value) do {\
176 (cp)[3] = (value) >> 24;\
177 (cp)[2] = (value) >> 16;\
178 (cp)[1] = (value) >> 8;\
183 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
190#define MD5_F1(x, y, z) (z ^ (x & (y ^ z)))
191#define MD5_F2(x, y, z) MD5_F1(z, x, y)
192#define MD5_F3(x, y, z) (x ^ y ^ z)
193#define MD5_F4(x, y, z) (y ^ (x | ~z))
196#define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
307 ctx_local->
count[0] = 0;
308 ctx_local->
count[1] = 0;
309 ctx_local->
state[0] = 0x67452301;
310 ctx_local->
state[1] = 0xefcdab89;
311 ctx_local->
state[2] = 0x98badcfe;
312 ctx_local->
state[3] = 0x10325476;
313 memset(ctx_local->
buffer, 0,
sizeof(ctx_local->
buffer));
324 memcpy(ctx_local_dst, ctx_local_src,
sizeof(*ctx_local_dst));
335 if (
unlikely(!ctx_local))
return NULL;
380 ctx_local->
count[1]++;
386 memcpy(ctx_local->
buffer + have,
in, need);
426 for (i = 0; i < 4; i++)
429 memset(ctx_local, 0,
sizeof(*ctx_local));
454 if (free_list[i].
used)
continue;
485 if (
unlikely(md_ctx == NULL))
goto oom;
487 free_list[i].
md_ctx = md_ctx;
494 if (free_list[i].
used)
continue;
496 free_list[i].
used =
true;
497 return free_list[i].
md_ctx;
516 if (free_list[i].md_ctx == *ctx) {
517 free_list[i].
used =
false;
529#ifdef HAVE_OPENSSL_EVP_H
530void fr_md5_openssl_init(
void)
536 if (!EVP_default_properties_is_fips_enabled(NULL))
return;
549void 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