NeoMutt  2022-04-29-178-g3b62e6
Teaching an old dog new tricks
DOXYGEN
md5.h File Reference

Calculate the MD5 checksum of a buffer. More...

#include <stdint.h>
#include <stdio.h>
+ Include dependency graph for md5.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Md5Ctx
 Cursor for the MD5 hashing. More...
 

Typedefs

typedef uint32_t md5_uint32
 

Functions

void * mutt_md5 (const char *str, void *buf)
 Calculate the MD5 hash of a NULL-terminated string. More...
 
void * mutt_md5_bytes (const void *buffer, size_t len, void *resbuf)
 Calculate the MD5 hash of a buffer. More...
 
void * mutt_md5_finish_ctx (struct Md5Ctx *md5ctx, void *resbuf)
 Process the remaining bytes in the buffer. More...
 
void mutt_md5_init_ctx (struct Md5Ctx *md5ctx)
 Initialise the MD5 computation. More...
 
void mutt_md5_process (const char *str, struct Md5Ctx *md5ctx)
 Process a NULL-terminated string. More...
 
void mutt_md5_process_bytes (const void *buf, size_t buflen, struct Md5Ctx *md5ctx)
 Process a block of data. More...
 
void mutt_md5_toascii (const void *digest, char *resbuf)
 Convert a binary MD5 digest into ASCII Hexadecimal. More...
 

Detailed Description

Calculate the MD5 checksum of a buffer.

Authors
  • Free Software Foundation, Inc.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file md5.h.

Typedef Documentation

◆ md5_uint32

typedef uint32_t md5_uint32

Definition at line 29 of file md5.h.

Function Documentation

◆ mutt_md5()

void * mutt_md5 ( const char *  str,
void *  buf 
)

Calculate the MD5 hash of a NULL-terminated string.

Parameters
strString to hash
bufBuffer for result
Return values
ptrResults buffer

Definition at line 318 of file md5.c.

319{
320 if (!str)
321 return NULL;
322
323 return mutt_md5_bytes(str, strlen(str), buf);
324}
void * mutt_md5_bytes(const void *buffer, size_t len, void *resbuf)
Calculate the MD5 hash of a buffer.
Definition: md5.c:337
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_md5_bytes()

void * mutt_md5_bytes ( const void *  buffer,
size_t  len,
void *  resbuf 
)

Calculate the MD5 hash of a buffer.

Parameters
bufferBuffer to hash
lenLength of buffer
resbufBuffer for result
Return values
ptrResults buffer

Compute MD5 message digest for LEN bytes beginning at Buffer. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest.

Definition at line 337 of file md5.c.

338{
339 struct Md5Ctx md5ctx;
340
341 /* Initialize the computation context. */
342 mutt_md5_init_ctx(&md5ctx);
343
344 /* Process whole buffer but last len % 64 bytes. */
345 mutt_md5_process_bytes(buffer, len, &md5ctx);
346
347 /* Put result in desired memory area. */
348 return mutt_md5_finish_ctx(&md5ctx, resbuf);
349}
void mutt_md5_process_bytes(const void *buf, size_t buflen, struct Md5Ctx *md5ctx)
Process a block of data.
Definition: md5.c:374
void mutt_md5_init_ctx(struct Md5Ctx *md5ctx)
Initialise the MD5 computation.
Definition: md5.c:262
void * mutt_md5_finish_ctx(struct Md5Ctx *md5ctx, void *resbuf)
Process the remaining bytes in the buffer.
Definition: md5.c:286
Cursor for the MD5 hashing.
Definition: md5.h:37
md5_uint32 buffer[32]
Definition: md5.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_md5_finish_ctx()

void * mutt_md5_finish_ctx ( struct Md5Ctx md5ctx,
void *  resbuf 
)

Process the remaining bytes in the buffer.

Parameters
md5ctxMD5 context
resbufBuffer for result
Return values
ptrResults buffer

Process the remaining bytes in the internal buffer and the usual prologue according to the standard and write the result to RESBUF.

Definition at line 286 of file md5.c.

287{
288 if (!md5ctx)
289 return NULL;
290
291 /* Take yet unprocessed bytes into account. */
292 md5_uint32 bytes = md5ctx->buflen;
293 size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
294
295 /* Now count remaining bytes. */
296 md5ctx->total[0] += bytes;
297 if (md5ctx->total[0] < bytes)
298 md5ctx->total[1]++;
299
300 /* Put the 64-bit file length in *bits* at the end of the buffer. */
301 md5ctx->buffer[size - 2] = SWAP(md5ctx->total[0] << 3);
302 md5ctx->buffer[size - 1] = SWAP((md5ctx->total[1] << 3) | (md5ctx->total[0] >> 29));
303
304 memcpy(&((char *) md5ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
305
306 /* Process last bytes. */
307 mutt_md5_process_block(md5ctx->buffer, size * 4, md5ctx);
308
309 return mutt_md5_read_ctx(md5ctx, resbuf);
310}
static void * mutt_md5_read_ctx(const struct Md5Ctx *md5ctx, void *resbuf)
Read from the context into a buffer.
Definition: md5.c:241
static void mutt_md5_process_block(const void *buffer, size_t len, struct Md5Ctx *md5ctx)
Process a block with MD5.
Definition: md5.c:66
#define SWAP(n)
Definition: md5.c:41
static const unsigned char fillbuf[64]
Definition: md5.c:46
uint32_t md5_uint32
Definition: md5.h:29
md5_uint32 total[2]
Definition: md5.h:43
md5_uint32 buflen
Definition: md5.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_md5_init_ctx()

void mutt_md5_init_ctx ( struct Md5Ctx md5ctx)

Initialise the MD5 computation.

Parameters
md5ctxMD5 context

RFC1321, 3.3: Step 3

Definition at line 262 of file md5.c.

263{
264 if (!md5ctx)
265 return;
266
267 md5ctx->A = 0x67452301;
268 md5ctx->B = 0xefcdab89;
269 md5ctx->C = 0x98badcfe;
270 md5ctx->D = 0x10325476;
271
272 md5ctx->total[0] = 0;
273 md5ctx->total[1] = 0;
274 md5ctx->buflen = 0;
275}
md5_uint32 D
Definition: md5.h:41
md5_uint32 C
Definition: md5.h:40
md5_uint32 A
Definition: md5.h:38
md5_uint32 B
Definition: md5.h:39
+ Here is the caller graph for this function:

◆ mutt_md5_process()

void mutt_md5_process ( const char *  str,
struct Md5Ctx md5ctx 
)

Process a NULL-terminated string.

Parameters
strString to process
md5ctxMD5 context

Definition at line 356 of file md5.c.

357{
358 if (!str)
359 return;
360
361 mutt_md5_process_bytes(str, strlen(str), md5ctx);
362}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_md5_process_bytes()

void mutt_md5_process_bytes ( const void *  buf,
size_t  buflen,
struct Md5Ctx md5ctx 
)

Process a block of data.

Parameters
bufBuffer to process
buflenLength of buffer
md5ctxMD5 context

Starting with the result of former calls of this function (or the initialization function update the context for the next BUFLEN bytes starting at Buffer. It is NOT required that BUFLEN is a multiple of 64.

Definition at line 374 of file md5.c.

375{
376 if (!buf || !md5ctx)
377 return;
378
379 /* When we already have some bits in our internal buffer concatenate both
380 * inputs first. */
381 if (md5ctx->buflen != 0)
382 {
383 size_t left_over = md5ctx->buflen;
384 size_t add = ((128 - left_over) > buflen) ? buflen : (128 - left_over);
385
386 memcpy(&((char *) md5ctx->buffer)[left_over], buf, add);
387 md5ctx->buflen += add;
388
389 if (md5ctx->buflen > 64)
390 {
391 mutt_md5_process_block(md5ctx->buffer, md5ctx->buflen & ~63, md5ctx);
392
393 md5ctx->buflen &= 63;
394 /* The regions in the following copy operation can't overlap. */
395 memcpy(md5ctx->buffer, &((char *) md5ctx->buffer)[(left_over + add) & ~63],
396 md5ctx->buflen);
397 }
398
399 buf = (const char *) buf + add;
400 buflen -= add;
401 }
402
403 /* Process available complete blocks. */
404 if (buflen >= 64)
405 {
406#if !defined(_STRING_ARCH_unaligned)
407#define alignof(type) \
408 offsetof( \
409 struct { \
410 char c; \
411 type x; \
412 }, \
413 x)
414#define UNALIGNED_P(p) (((size_t) p) % alignof(md5_uint32) != 0)
415 if (UNALIGNED_P(buf))
416 {
417 while (buflen > 64)
418 {
419 mutt_md5_process_block(memcpy(md5ctx->buffer, buf, 64), 64, md5ctx);
420 buf = (const char *) buf + 64;
421 buflen -= 64;
422 }
423 }
424 else
425#endif
426 {
427 mutt_md5_process_block(buf, buflen & ~63, md5ctx);
428 buf = (const char *) buf + (buflen & ~63);
429 buflen &= 63;
430 }
431 }
432
433 /* Move remaining bytes in internal buffer. */
434 if (buflen > 0)
435 {
436 size_t left_over = md5ctx->buflen;
437
438 memcpy(&((char *) md5ctx->buffer)[left_over], buf, buflen);
439 left_over += buflen;
440 if (left_over >= 64)
441 {
442 mutt_md5_process_block(md5ctx->buffer, 64, md5ctx);
443 left_over -= 64;
444 memmove(md5ctx->buffer, &md5ctx->buffer[16], left_over);
445 }
446 md5ctx->buflen = left_over;
447 }
448}
#define UNALIGNED_P(p)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_md5_toascii()

void mutt_md5_toascii ( const void *  digest,
char *  resbuf 
)

Convert a binary MD5 digest into ASCII Hexadecimal.

Parameters
digestBinary MD5 digest
resbufBuffer for the ASCII result
Note
refbuf must be at least 33 bytes long.

Definition at line 457 of file md5.c.

458{
459 if (!digest || !resbuf)
460 return;
461
462 const unsigned char *c = digest;
463 sprintf(resbuf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
464 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10],
465 c[11], c[12], c[13], c[14], c[15]);
466}
+ Here is the caller graph for this function: