7 RCSID(
"$Id: 8f0f3e17b6b6689d24065998753e49f332e45cc5 $")
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/md4.h>
23 #define ARRAY_SIZE (8)
35 #ifdef HAVE_OPENSSL_EVP_H
36 # include <freeradius-devel/tls/openssl_user_macros.h>
37 # include <openssl/evp.h>
38 # include <openssl/crypto.h>
39 # include <openssl/err.h>
40 # include <openssl/provider.h>
42 static int have_openssl_md4 = -1;
49 EVP_MD_CTX *md_ctx = ctx;
51 EVP_MD_CTX_reset(md_ctx);
52 EVP_DigestInit_ex(md_ctx, EVP_md4(), NULL);
60 EVP_MD_CTX_copy_ex(dst, src);
70 md_ctx = EVP_MD_CTX_new();
73 if (EVP_DigestInit_ex(md_ctx, EVP_md4(), NULL) != 1) {
76 ERR_error_string_n(ERR_get_error(),
buffer,
sizeof(
buffer));
78 EVP_MD_CTX_free(md_ctx);
91 EVP_MD_CTX_free(*ctx);
100 EVP_DigestUpdate(ctx,
in,
inlen);
110 EVP_DigestFinal(ctx,
out, &len);
133 #ifndef WORDS_BIGENDIAN
134 # define htole32_4(buf)
135 # define htole32_14(buf)
136 # define htole32_16(buf)
141 (((((uint32_t)x) & 0xff000000) >> 24) |\
142 ((((uint32_t)x) & 0x00ff0000) >> 8) |\
143 ((((uint32_t)x) & 0x0000ff00) << 8) |\
144 ((((uint32_t)x) & 0x000000ff) << 24))
146 # define htole32_4(buf) do {\
147 (buf)[0] = htole32((buf)[0]);\
148 (buf)[1] = htole32((buf)[1]);\
149 (buf)[2] = htole32((buf)[2]);\
150 (buf)[3] = htole32((buf)[3]);\
153 # define htole32_14(buf) do {\
154 (buf)[0] = htole32((buf)[0]);\
155 (buf)[1] = htole32((buf)[1]);\
156 (buf)[2] = htole32((buf)[2]);\
157 (buf)[3] = htole32((buf)[3]);\
158 (buf)[4] = htole32((buf)[4]);\
159 (buf)[5] = htole32((buf)[5]);\
160 (buf)[6] = htole32((buf)[6]);\
161 (buf)[7] = htole32((buf)[7]);\
162 (buf)[8] = htole32((buf)[8]);\
163 (buf)[9] = htole32((buf)[9]);\
164 (buf)[10] = htole32((buf)[10]);\
165 (buf)[11] = htole32((buf)[11]);\
166 (buf)[12] = htole32((buf)[12]);\
167 (buf)[13] = htole32((buf)[13]);\
170 # define htole32_16(buf) do {\
171 (buf)[0] = htole32((buf)[0]);\
172 (buf)[1] = htole32((buf)[1]);\
173 (buf)[2] = htole32((buf)[2]);\
174 (buf)[3] = htole32((buf)[3]);\
175 (buf)[4] = htole32((buf)[4]);\
176 (buf)[5] = htole32((buf)[5]);\
177 (buf)[6] = htole32((buf)[6]);\
178 (buf)[7] = htole32((buf)[7]);\
179 (buf)[8] = htole32((buf)[8]);\
180 (buf)[9] = htole32((buf)[9]);\
181 (buf)[10] = htole32((buf)[10]);\
182 (buf)[11] = htole32((buf)[11]);\
183 (buf)[12] = htole32((buf)[12]);\
184 (buf)[13] = htole32((buf)[13]);\
185 (buf)[14] = htole32((buf)[14]);\
186 (buf)[15] = htole32((buf)[15]);\
190 #define MD4_BLOCK_LENGTH 64
193 #define MD4_F1(x, y, z) (z ^ (x & (y ^ z)))
194 #define MD4_F2(x, y, z) ((x & y) | (x & z) | (y & z))
195 #define MD4_F3(x, y, z) (x ^ y ^ z)
198 #define MD4STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s))
289 ctx_local->
count[0] = 0;
290 ctx_local->
count[1] = 0;
291 ctx_local->
state[0] = 0x67452301;
292 ctx_local->
state[1] = 0xefcdab89;
293 ctx_local->
state[2] = 0x98badcfe;
294 ctx_local->
state[3] = 0x10325476;
305 memcpy(ctx_local_dst, ctx_local_src,
sizeof(*ctx_local_dst));
315 #ifdef HAVE_OPENSSL_EVP_H
316 if (
unlikely(have_openssl_md4 == -1)) {
322 if (!EVP_default_properties_is_fips_enabled(NULL)) {
323 have_openssl_md4 = 1;
339 have_openssl_md4 = 0;
343 if (
unlikely(!ctx_local))
return NULL;
386 ctx_local->
count[1]++;
392 unsigned char *p = (
unsigned char *)ctx_local->
buffer +
count;
449 memset(ctx_local->
buffer, 0, 56);
452 memset(p, 0,
count - 8);
463 memset(ctx_local, 0,
sizeof(*ctx_local));
498 if (free_list[i].
used)
continue;
529 if (
unlikely(md_ctx == NULL))
goto oom;
531 free_list[i].
md_ctx = md_ctx;
538 if (free_list[i].
used)
continue;
540 free_list[i].
used =
true;
541 return free_list[i].
md_ctx;
560 if (free_list[i].md_ctx == *ctx) {
561 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.
uint8_t buffer[MD4_BLOCK_LENGTH]
Input buffer.
static int _md4_ctx_free_on_exit(void *arg)
static void fr_md4_local_transform(uint32_t state[static 4], uint8_t const block[static MD4_BLOCK_LENGTH])
The core of the MD4 algorithm.
fr_md4_ctx_alloc_t fr_md4_ctx_alloc
#define MD4STEP(f, w, x, y, z, data, s)
fr_md4_update_t fr_md4_update
static void fr_md4_local_ctx_free(fr_md4_ctx_t **ctx)
#define ARRAY_SIZE
The thread local free list.
void fr_md4_calc(uint8_t out[static MD4_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
Calculate the MD4 hash of the contents of a buffer.
fr_md4_ctx_reset_t fr_md4_ctx_reset
fr_md4_ctx_copy_t fr_md4_ctx_copy
uint32_t count[2]
Number of bits, mod 2^64.
static void fr_md4_local_update(fr_md4_ctx_t *ctx, uint8_t const *in, size_t inlen)
fr_md4_final_t fr_md4_final
static fr_md4_ctx_t * fr_md4_local_ctx_alloc(void)
fr_md4_ctx_t * fr_md4_ctx_alloc_from_list(void)
static _Thread_local fr_md4_free_list_t * md4_array
static void fr_md4_local_ctx_copy(fr_md4_ctx_t *dst, fr_md4_ctx_t const *src)
static void fr_md4_local_final(uint8_t out[static MD4_DIGEST_LENGTH], fr_md4_ctx_t *ctx)
void fr_md4_ctx_free_from_list(fr_md4_ctx_t **ctx)
fr_md4_ctx_free_t fr_md4_ctx_free
static void fr_md4_local_ctx_reset(fr_md4_ctx_t *ctx)
static const uint8_t * zero
fr_md4_ctx_t *(* fr_md4_ctx_alloc_t)(void)
Allocation function for MD4 digest context.
void(* fr_md4_final_t)(uint8_t out[static MD4_DIGEST_LENGTH], fr_md4_ctx_t *ctx)
Finalise the ctx, producing the digest.
void(* fr_md4_ctx_free_t)(fr_md4_ctx_t **ctx)
Free function for MD4 digest ctx.
void(* fr_md4_ctx_copy_t)(fr_md4_ctx_t *dst, fr_md4_ctx_t const *src)
Copy the contents of a ctx.
#define MD4_DIGEST_LENGTH
void(* fr_md4_ctx_reset_t)(fr_md4_ctx_t *ctx)
Reset the ctx to allow reuse.
void(* fr_md4_update_t)(fr_md4_ctx_t *ctx, uint8_t const *in, size_t inlen)
Ingest plaintext into the digest.
#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