The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
md4.c
Go to the documentation of this file.
1 /** A local MD4 implementation
2  *
3  * @note license is LGPL, but largely derived from a public domain source.
4  *
5  * @file src/lib/util/md4.c
6  */
7 RCSID("$Id: b5564f72eb4799fc57eb4979685d38aa97914d6a $")
8 
9 #include <freeradius-devel/util/debug.h>
10 #include <freeradius-devel/util/strerror.h>
11 #include <freeradius-devel/util/atexit.h>
12 
13 /*
14  * FORCE MD4 TO USE OUR MD4 HEADER FILE!
15  * If we don't do this, it might pick up the systems broken MD4.
16  */
17 #include <freeradius-devel/util/md4.h>
18 
19 /** The thread local free list
20  *
21  * Any entries remaining in the list will be freed when the thread is joined
22  */
23 #define ARRAY_SIZE (8)
24 typedef struct {
25  bool used;
28 static _Thread_local fr_md4_free_list_t *md4_array;
29 /*
30  * If we have OpenSSL's EVP API available, then build wrapper functions.
31  *
32  * We always need to build the local MD4 functions as OpenSSL could
33  * be operating in FIPS mode where MD4 digest functions are unavailable.
34  */
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 
41 # if OPENSSL_VERSION_NUMBER >= 0x30000000L
42 # include <openssl/provider.h>
43 # endif
44 
45 static int have_openssl_md4 = -1;
46 
47 /** @copydoc fr_md4_ctx_reset
48  *
49  */
50 static void fr_md4_openssl_ctx_reset(fr_md4_ctx_t *ctx)
51 {
52  EVP_MD_CTX *md_ctx = ctx;
53 
54  EVP_MD_CTX_reset(md_ctx);
55  EVP_DigestInit_ex(md_ctx, EVP_md4(), NULL);
56 }
57 
58 /** @copydoc fr_md4_ctx_copy
59  *
60  */
61 static void fr_md4_openssl_ctx_copy(fr_md4_ctx_t *dst, fr_md4_ctx_t const *src)
62 {
63  EVP_MD_CTX_copy_ex(dst, src);
64 }
65 
66 /** @copydoc fr_md4_ctx_alloc
67  *
68  */
69 static fr_md4_ctx_t *fr_md4_openssl_ctx_alloc(void)
70 {
71  EVP_MD_CTX *md_ctx;
72 
73  md_ctx = EVP_MD_CTX_new();
74  if (unlikely(!md_ctx)) return NULL;
75 
76  if (EVP_DigestInit_ex(md_ctx, EVP_md4(), NULL) != 1) {
77  char buffer[256];
78 
79  ERR_error_string_n(ERR_get_error(), buffer, sizeof(buffer));
80  fr_strerror_printf("Failed initialising md4 ctx: %s", buffer);
81  EVP_MD_CTX_free(md_ctx);
82 
83  return NULL;
84  }
85 
86  return md_ctx;
87 }
88 
89 /** @copydoc fr_md4_ctx_free
90  *
91  */
92 static void fr_md4_openssl_ctx_free(fr_md4_ctx_t **ctx)
93 {
94  EVP_MD_CTX_free(*ctx);
95  *ctx = NULL;
96 }
97 
98 /** @copydoc fr_md4_update
99  *
100  */
101 static void fr_md4_openssl_update(fr_md4_ctx_t *ctx, uint8_t const *in, size_t inlen)
102 {
103  EVP_DigestUpdate(ctx, in, inlen);
104 }
105 
106 /** @copydoc fr_md4_final
107  *
108  */
109 static void fr_md4_openssl_final(uint8_t out[static MD4_DIGEST_LENGTH], fr_md4_ctx_t *ctx)
110 {
111  unsigned int len;
112 
113  EVP_DigestFinal(ctx, out, &len);
114 
115  if (!fr_cond_assert(len == MD4_DIGEST_LENGTH)) return;
116 }
117 #endif
118 
119 /*
120  * This code implements the MD4 message-digest algorithm.
121  * The algorithm is due to Ron Rivest. This code was
122  * written by Colin Plumb in 1993, no copyright is claimed.
123  * This code is in the public domain; do with it what you wish.
124  * Todd C. Miller modified the md4 code to do MD4 based on RFC 1186.
125  *
126  * Equivalent code is available from RSA Data Security, Inc.
127  * This code has been tested against that, and is equivalent,
128  * except that you don't need to include two pages of legalese
129  * with every copy.
130  *
131  * To compute the message digest of a chunk of bytes, declare an
132  * MD4Context structure, pass it to fr_md4_init, call fr_md4_update as
133  * needed on buffers full of bytes, and then call fr_md4_final, which
134  * will fill a supplied 16-byte array with the digest.
135  */
136 #ifndef WORDS_BIGENDIAN
137 # define htole32_4(buf) /* Nothing */
138 # define htole32_14(buf) /* Nothing */
139 # define htole32_16(buf) /* Nothing */
140 #else
141 /* Sometimes defined by endian.h */
142 # ifndef htole32
143 # define htole32(x)\
144  (((((uint32_t)x) & 0xff000000) >> 24) |\
145  ((((uint32_t)x) & 0x00ff0000) >> 8) |\
146  ((((uint32_t)x) & 0x0000ff00) << 8) |\
147  ((((uint32_t)x) & 0x000000ff) << 24))
148 # endif
149 # define htole32_4(buf) do {\
150  (buf)[0] = htole32((buf)[0]);\
151  (buf)[1] = htole32((buf)[1]);\
152  (buf)[2] = htole32((buf)[2]);\
153  (buf)[3] = htole32((buf)[3]);\
154 } while (0)
155 
156 # define htole32_14(buf) do {\
157  (buf)[0] = htole32((buf)[0]);\
158  (buf)[1] = htole32((buf)[1]);\
159  (buf)[2] = htole32((buf)[2]);\
160  (buf)[3] = htole32((buf)[3]);\
161  (buf)[4] = htole32((buf)[4]);\
162  (buf)[5] = htole32((buf)[5]);\
163  (buf)[6] = htole32((buf)[6]);\
164  (buf)[7] = htole32((buf)[7]);\
165  (buf)[8] = htole32((buf)[8]);\
166  (buf)[9] = htole32((buf)[9]);\
167  (buf)[10] = htole32((buf)[10]);\
168  (buf)[11] = htole32((buf)[11]);\
169  (buf)[12] = htole32((buf)[12]);\
170  (buf)[13] = htole32((buf)[13]);\
171 } while (0)
172 
173 # define htole32_16(buf) do {\
174  (buf)[0] = htole32((buf)[0]);\
175  (buf)[1] = htole32((buf)[1]);\
176  (buf)[2] = htole32((buf)[2]);\
177  (buf)[3] = htole32((buf)[3]);\
178  (buf)[4] = htole32((buf)[4]);\
179  (buf)[5] = htole32((buf)[5]);\
180  (buf)[6] = htole32((buf)[6]);\
181  (buf)[7] = htole32((buf)[7]);\
182  (buf)[8] = htole32((buf)[8]);\
183  (buf)[9] = htole32((buf)[9]);\
184  (buf)[10] = htole32((buf)[10]);\
185  (buf)[11] = htole32((buf)[11]);\
186  (buf)[12] = htole32((buf)[12]);\
187  (buf)[13] = htole32((buf)[13]);\
188  (buf)[14] = htole32((buf)[14]);\
189  (buf)[15] = htole32((buf)[15]);\
190 } while (0)
191 #endif
192 
193 #define MD4_BLOCK_LENGTH 64
194 
195 /* The three core functions - F1 is optimized somewhat */
196 #define MD4_F1(x, y, z) (z ^ (x & (y ^ z)))
197 #define MD4_F2(x, y, z) ((x & y) | (x & z) | (y & z))
198 #define MD4_F3(x, y, z) (x ^ y ^ z)
199 
200 /* This is the central step in the MD4 algorithm. */
201 #define MD4STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s))
202 
203 /** The core of the MD4 algorithm
204  *
205  * This alters an existing MD4 hash to reflect the addition of 16
206  * longwords of new data. fr_md4_update blocks the data and converts bytes
207  * into longwords for this routine.
208  *
209  * @param[in] state 16 bytes of data to feed into the hashing function.
210  * @param[in,out] block MD4 digest block to update.
211  */
212 static void fr_md4_local_transform(uint32_t state[static 4], uint8_t const block[static MD4_BLOCK_LENGTH])
213 {
214  uint32_t a, b, c, d;
215  uint32_t const *in = (uint32_t const *)block;
216 
217  a = state[0];
218  b = state[1];
219  c = state[2];
220  d = state[3];
221 
222  MD4STEP(MD4_F1, a, b, c, d, in[ 0], 3);
223  MD4STEP(MD4_F1, d, a, b, c, in[ 1], 7);
224  MD4STEP(MD4_F1, c, d, a, b, in[ 2], 11);
225  MD4STEP(MD4_F1, b, c, d, a, in[ 3], 19);
226  MD4STEP(MD4_F1, a, b, c, d, in[ 4], 3);
227  MD4STEP(MD4_F1, d, a, b, c, in[ 5], 7);
228  MD4STEP(MD4_F1, c, d, a, b, in[ 6], 11);
229  MD4STEP(MD4_F1, b, c, d, a, in[ 7], 19);
230  MD4STEP(MD4_F1, a, b, c, d, in[ 8], 3);
231  MD4STEP(MD4_F1, d, a, b, c, in[ 9], 7);
232  MD4STEP(MD4_F1, c, d, a, b, in[10], 11);
233  MD4STEP(MD4_F1, b, c, d, a, in[11], 19);
234  MD4STEP(MD4_F1, a, b, c, d, in[12], 3);
235  MD4STEP(MD4_F1, d, a, b, c, in[13], 7);
236  MD4STEP(MD4_F1, c, d, a, b, in[14], 11);
237  MD4STEP(MD4_F1, b, c, d, a, in[15], 19);
238 
239  MD4STEP(MD4_F2, a, b, c, d, in[ 0] + 0x5a827999, 3);
240  MD4STEP(MD4_F2, d, a, b, c, in[ 4] + 0x5a827999, 5);
241  MD4STEP(MD4_F2, c, d, a, b, in[ 8] + 0x5a827999, 9);
242  MD4STEP(MD4_F2, b, c, d, a, in[12] + 0x5a827999, 13);
243  MD4STEP(MD4_F2, a, b, c, d, in[ 1] + 0x5a827999, 3);
244  MD4STEP(MD4_F2, d, a, b, c, in[ 5] + 0x5a827999, 5);
245  MD4STEP(MD4_F2, c, d, a, b, in[ 9] + 0x5a827999, 9);
246  MD4STEP(MD4_F2, b, c, d, a, in[13] + 0x5a827999, 13);
247  MD4STEP(MD4_F2, a, b, c, d, in[ 2] + 0x5a827999, 3);
248  MD4STEP(MD4_F2, d, a, b, c, in[ 6] + 0x5a827999, 5);
249  MD4STEP(MD4_F2, c, d, a, b, in[10] + 0x5a827999, 9);
250  MD4STEP(MD4_F2, b, c, d, a, in[14] + 0x5a827999, 13);
251  MD4STEP(MD4_F2, a, b, c, d, in[ 3] + 0x5a827999, 3);
252  MD4STEP(MD4_F2, d, a, b, c, in[ 7] + 0x5a827999, 5);
253  MD4STEP(MD4_F2, c, d, a, b, in[11] + 0x5a827999, 9);
254  MD4STEP(MD4_F2, b, c, d, a, in[15] + 0x5a827999, 13);
255 
256  MD4STEP(MD4_F3, a, b, c, d, in[ 0] + 0x6ed9eba1, 3);
257  MD4STEP(MD4_F3, d, a, b, c, in[ 8] + 0x6ed9eba1, 9);
258  MD4STEP(MD4_F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
259  MD4STEP(MD4_F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
260  MD4STEP(MD4_F3, a, b, c, d, in[ 2] + 0x6ed9eba1, 3);
261  MD4STEP(MD4_F3, d, a, b, c, in[10] + 0x6ed9eba1, 9);
262  MD4STEP(MD4_F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
263  MD4STEP(MD4_F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
264  MD4STEP(MD4_F3, a, b, c, d, in[ 1] + 0x6ed9eba1, 3);
265  MD4STEP(MD4_F3, d, a, b, c, in[ 9] + 0x6ed9eba1, 9);
266  MD4STEP(MD4_F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
267  MD4STEP(MD4_F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
268  MD4STEP(MD4_F3, a, b, c, d, in[ 3] + 0x6ed9eba1, 3);
269  MD4STEP(MD4_F3, d, a, b, c, in[11] + 0x6ed9eba1, 9);
270  MD4STEP(MD4_F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
271  MD4STEP(MD4_F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
272 
273  state[0] += a;
274  state[1] += b;
275  state[2] += c;
276  state[3] += d;
277 }
278 
279 typedef struct {
280  uint32_t state[4]; //!< State.
281  uint32_t count[2]; //!< Number of bits, mod 2^64.
282  uint8_t buffer[MD4_BLOCK_LENGTH]; //!< Input buffer.
284 
285 /** @copydoc fr_md4_ctx_reset
286  *
287  */
289 {
290  fr_md4_ctx_local_t *ctx_local = talloc_get_type_abort(ctx, fr_md4_ctx_local_t);
291 
292  ctx_local->count[0] = 0;
293  ctx_local->count[1] = 0;
294  ctx_local->state[0] = 0x67452301;
295  ctx_local->state[1] = 0xefcdab89;
296  ctx_local->state[2] = 0x98badcfe;
297  ctx_local->state[3] = 0x10325476;
298 }
299 
300 /** @copydoc fr_md4_ctx_copy
301  *
302  */
303 static void fr_md4_local_ctx_copy(fr_md4_ctx_t *dst, fr_md4_ctx_t const *src)
304 {
306  fr_md4_ctx_local_t *ctx_local_dst = talloc_get_type_abort(dst, fr_md4_ctx_local_t);
307 
308  memcpy(ctx_local_dst, ctx_local_src, sizeof(*ctx_local_dst));
309 }
310 
311 /** @copydoc fr_md4_ctx_alloc
312  *
313  */
315 {
316  fr_md4_ctx_local_t *ctx_local;
317 
318 #ifdef HAVE_OPENSSL_EVP_H
319  if (unlikely(have_openssl_md4 == -1)) {
320  /*
321  * If we're not in FIPS mode, then swap out the
322  * md4 functions, and call the OpenSSL init
323  * function.
324  */
325 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
326  if (!EVP_default_properties_is_fips_enabled(NULL)) {
327 #else
328  if (FIPS_mode() == 0) {
329 #endif
330  have_openssl_md4 = 1;
331 
332  /*
333  * Swap out the functions pointers
334  * for the OpenSSL versions.
335  */
336  fr_md4_ctx_reset = fr_md4_openssl_ctx_reset;
337  fr_md4_ctx_copy = fr_md4_openssl_ctx_copy;
338  fr_md4_ctx_alloc = fr_md4_openssl_ctx_alloc;
339  fr_md4_ctx_free = fr_md4_openssl_ctx_free;
340  fr_md4_update = fr_md4_openssl_update;
341  fr_md4_final = fr_md4_openssl_final;
342 
343  return fr_md4_ctx_alloc();
344  }
345 
346  have_openssl_md4 = 0;
347  }
348 #endif
349  ctx_local = talloc(NULL, fr_md4_ctx_local_t);
350  if (unlikely(!ctx_local)) return NULL;
351  fr_md4_local_ctx_reset(ctx_local);
352 
353  return ctx_local;
354 }
355 
356 /** @copydoc fr_md4_ctx_free
357  *
358  */
360 {
361  talloc_free(*ctx);
362  *ctx = NULL;
363 }
364 
365 static const uint8_t *zero = (uint8_t[]){ 0x00 };
366 
367 /** @copydoc fr_md4_update
368  *
369  */
370 static void fr_md4_local_update(fr_md4_ctx_t *ctx, uint8_t const *in, size_t inlen)
371 {
372  uint32_t count;
373  fr_md4_ctx_local_t *ctx_local = talloc_get_type_abort(ctx, fr_md4_ctx_local_t);
374 
375  /*
376  * Needed so we can calculate the zero
377  * length md4 hash correctly.
378  * ubsan doesn't like arithmetic on
379  * NULL pointers.
380  */
381  if (!in) {
382  in = zero;
383  inlen = 0;
384  }
385 
386  /* Bytes already stored in ctx_local->buffer */
387  count = (uint32_t)((ctx_local->count[0] >> 3) & 0x3f);
388 
389  /* Update bitcount */
390 /* ctx_local->count += (uint64_t)inlen << 3;*/
391  if ((ctx_local->count[0] += ((uint32_t)inlen << 3)) < (uint32_t)inlen) {
392  /* Overflowed ctx_local->count[0] */
393  ctx_local->count[1]++;
394  }
395  ctx_local->count[1] += ((uint32_t)inlen >> 29);
396 
397  /* Handle any leading odd-sized chunks */
398  if (count) {
399  unsigned char *p = (unsigned char *)ctx_local->buffer + count;
400 
402  if (inlen < count) {
403  memcpy(p, in, inlen);
404  return;
405  }
406  memcpy(p, in, count);
407  htole32_16((uint32_t *)ctx_local->buffer);
408  fr_md4_local_transform(ctx_local->state, ctx_local->buffer);
409  in += count;
410  inlen -= count;
411  }
412 
413  /* Process data in MD4_BLOCK_LENGTH-byte chunks */
414  while (inlen >= MD4_BLOCK_LENGTH) {
415  memcpy(ctx_local->buffer, in, MD4_BLOCK_LENGTH);
416  htole32_16((uint32_t *)ctx_local->buffer);
417  fr_md4_local_transform(ctx_local->state, ctx_local->buffer);
418  in += MD4_BLOCK_LENGTH;
420  }
421 
422  /* Handle any remaining bytes of data. */
423  memcpy(ctx_local->buffer, in, inlen);
424 }
425 
426 /** @copydoc fr_md4_final
427  *
428  */
430 {
431  uint32_t count;
432  unsigned char *p;
433  fr_md4_ctx_local_t *ctx_local = talloc_get_type_abort(ctx, fr_md4_ctx_local_t);
434 
435  /* number of bytes mod 64 */
436  count = (uint32_t)(ctx_local->count[0] >> 3) & 0x3f;
437 
438  /*
439  * Set the first char of padding to 0x80.
440  * This is safe since there is always at least one byte free.
441  */
442  p = ctx_local->buffer + count;
443  *p++ = 0x80;
444 
445  /* Bytes of padding needed to make 64 bytes */
446  count = 64 - 1 - count;
447 
448  /* Pad out to 56 mod 64 */
449  if (count < 8) {
450  /* Two lots of padding: Pad the first block to 64 bytes */
451  memset(p, 0, count);
452  htole32_16((uint32_t *)ctx_local->buffer);
453  fr_md4_local_transform(ctx_local->state, ctx_local->buffer);
454 
455  /* Now fill the next block with 56 bytes */
456  memset(ctx_local->buffer, 0, 56);
457  } else {
458  /* Pad block to 56 bytes */
459  memset(p, 0, count - 8);
460  }
461  htole32_14((uint32_t *)ctx_local->buffer);
462 
463  /* Append bit count and transform */
464  ((uint32_t *)ctx_local->buffer)[14] = ctx_local->count[0];
465  ((uint32_t *)ctx_local->buffer)[15] = ctx_local->count[1];
466 
467  fr_md4_local_transform(ctx_local->state, ctx_local->buffer);
468  htole32_4(ctx_local->state);
469  memcpy(out, ctx_local->state, MD4_DIGEST_LENGTH);
470  memset(ctx_local, 0, sizeof(*ctx_local)); /* in case it's sensitive */
471 }
472 
473 /*
474  * Digest function pointers
475  */
482 
483 /** Calculate the MD4 hash of the contents of a buffer
484  *
485  * @param[out] out Where to write the MD4 digest. Must be a minimum of MD4_DIGEST_LENGTH.
486  * @param[in] in Data to hash.
487  * @param[in] inlen Length of the data.
488  */
489 void fr_md4_calc(uint8_t out[static MD4_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
490 {
491  fr_md4_ctx_t *ctx;
492 
494  fr_md4_update(ctx, in, inlen);
495  fr_md4_final(out, ctx);
497 }
498 
499 static int _md4_ctx_free_on_exit(void *arg)
500 {
501  int i;
502  fr_md4_free_list_t *free_list = arg;
503 
504  for (i = 0; i < ARRAY_SIZE; i++) {
505  if (free_list[i].used) continue;
506 
507  fr_md4_ctx_free(&free_list[i].md_ctx);
508  }
509  return talloc_free(free_list);
510 }
511 
512 /** @copydoc fr_md4_ctx_alloc
513  *
514  */
516 {
517  int i;
518  fr_md4_ctx_t *md_ctx;
519  fr_md4_free_list_t *free_list;
520 
521  if (unlikely(!md4_array)) {
522  free_list = talloc_zero_array(NULL, fr_md4_free_list_t, ARRAY_SIZE);
523  if (unlikely(!free_list)) {
524  oom:
525  fr_strerror_const("Out of Memory");
526  return NULL;
527  }
528 
530 
531  /*
532  * Initialize all md4 contexts
533  */
534  for (i = 0; i < ARRAY_SIZE; i++) {
535  md_ctx = fr_md4_ctx_alloc();
536  if (unlikely(md_ctx == NULL)) goto oom;
537 
538  free_list[i].md_ctx = md_ctx;
539  }
540  } else {
541  free_list = md4_array;
542  }
543 
544  for (i = 0; i < ARRAY_SIZE; i++) {
545  if (free_list[i].used) continue;
546 
547  free_list[i].used = true;
548  return free_list[i].md_ctx;
549  }
550 
551  /*
552  * No more free contexts, just allocate a new one.
553  */
554  return fr_md4_ctx_alloc();
555 }
556 
557 /** @copydoc fr_md4_ctx_free
558  *
559  */
561 {
562  int i;
563  fr_md4_free_list_t *free_list = md4_array;
564 
565  if (free_list) {
566  for (i = 0; i < ARRAY_SIZE; i++) {
567  if (free_list[i].md_ctx == *ctx) {
568  free_list[i].used = false;
569  fr_md4_ctx_reset(*ctx);
570  *ctx = NULL;
571  return;
572  }
573  }
574  }
575 
576  fr_md4_ctx_free(*ctx);
577  *ctx = NULL;
578 }
static int const char char buffer[256]
Definition: acutest.h:574
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition: atexit.h:221
#define RCSID(id)
Definition: build.h:444
#define unlikely(_x)
Definition: build.h:378
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:137
static fr_slen_t in
Definition: dict.h:645
talloc_free(reap)
uint8_t buffer[MD4_BLOCK_LENGTH]
Input buffer.
Definition: md4.c:282
static int _md4_ctx_free_on_exit(void *arg)
Definition: md4.c:499
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.
Definition: md4.c:212
#define MD4_F1(x, y, z)
Definition: md4.c:196
uint32_t state[4]
State.
Definition: md4.c:280
fr_md4_ctx_alloc_t fr_md4_ctx_alloc
Definition: md4.c:478
#define MD4STEP(f, w, x, y, z, data, s)
Definition: md4.c:201
#define htole32_16(buf)
Definition: md4.c:139
#define htole32_4(buf)
Definition: md4.c:137
#define MD4_F3(x, y, z)
Definition: md4.c:198
fr_md4_update_t fr_md4_update
Definition: md4.c:480
static void fr_md4_local_ctx_free(fr_md4_ctx_t **ctx)
Definition: md4.c:359
#define ARRAY_SIZE
The thread local free list.
Definition: md4.c:23
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.
Definition: md4.c:489
fr_md4_ctx_reset_t fr_md4_ctx_reset
Definition: md4.c:476
fr_md4_ctx_copy_t fr_md4_ctx_copy
Definition: md4.c:477
uint32_t count[2]
Number of bits, mod 2^64.
Definition: md4.c:281
static void fr_md4_local_update(fr_md4_ctx_t *ctx, uint8_t const *in, size_t inlen)
Definition: md4.c:370
fr_md4_final_t fr_md4_final
Definition: md4.c:481
#define htole32_14(buf)
Definition: md4.c:138
static fr_md4_ctx_t * fr_md4_local_ctx_alloc(void)
Definition: md4.c:314
fr_md4_ctx_t * fr_md4_ctx_alloc_from_list(void)
Definition: md4.c:515
#define MD4_F2(x, y, z)
Definition: md4.c:197
static _Thread_local fr_md4_free_list_t * md4_array
Definition: md4.c:28
static void fr_md4_local_ctx_copy(fr_md4_ctx_t *dst, fr_md4_ctx_t const *src)
Definition: md4.c:303
static void fr_md4_local_final(uint8_t out[static MD4_DIGEST_LENGTH], fr_md4_ctx_t *ctx)
Definition: md4.c:429
fr_md4_ctx_t * md_ctx
Definition: md4.c:26
void fr_md4_ctx_free_from_list(fr_md4_ctx_t **ctx)
Definition: md4.c:560
#define MD4_BLOCK_LENGTH
Definition: md4.c:193
fr_md4_ctx_free_t fr_md4_ctx_free
Definition: md4.c:479
static void fr_md4_local_ctx_reset(fr_md4_ctx_t *ctx)
Definition: md4.c:288
static const uint8_t * zero
Definition: md4.c:365
fr_md4_ctx_t *(* fr_md4_ctx_alloc_t)(void)
Allocation function for MD4 digest context.
Definition: md4.h:53
void(* fr_md4_final_t)(uint8_t out[static MD4_DIGEST_LENGTH], fr_md4_ctx_t *ctx)
Finalise the ctx, producing the digest.
Definition: md4.h:79
void(* fr_md4_ctx_free_t)(fr_md4_ctx_t **ctx)
Free function for MD4 digest ctx.
Definition: md4.h:61
void(* fr_md4_ctx_copy_t)(fr_md4_ctx_t *dst, fr_md4_ctx_t const *src)
Copy the contents of a ctx.
Definition: md4.h:44
#define MD4_DIGEST_LENGTH
Definition: md4.h:25
void(* fr_md4_ctx_reset_t)(fr_md4_ctx_t *ctx)
Reset the ctx to allow reuse.
Definition: md4.h:36
void fr_md4_ctx_t
Definition: md4.h:28
void(* fr_md4_update_t)(fr_md4_ctx_t *ctx, uint8_t const *in, size_t inlen)
Ingest plaintext into the digest.
Definition: md4.h:71
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char uint8_t
Definition: merged_model.c:30
static size_t used
return count
Definition: module.c:175
if(!subtype_vp) goto fail
#define talloc_get_type_abort_const
Definition: talloc.h:270
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_const(_msg)
Definition: strerror.h:223
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:984
static size_t char ** out
Definition: value.h:984