1/* Functions to compute MD5 message digest of files or memory blocks.
2 according to the definition of MD5 in RFC 1321 from April 1992.
3 Copyright (C) 1995-2024 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
19
20/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
21
22#include <string.h>
23#include <endian.h>
24#include "md5.h"
25
26#if __BYTE_ORDER == __BIG_ENDIAN
27# define WORDS_BIGENDIAN 1
28#endif
29
30#ifdef WORDS_BIGENDIAN
31# define SWAP(n) \
32 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
33#else
34# define SWAP(n) (n)
35#endif
36
37
38/* This array contains the bytes used to pad the buffer to the next
39 64-byte boundary. (RFC 1321, 3.1: Step 1) */
40static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
41
42
43/* Initialize structure containing state of computation.
44 (RFC 1321, 3.3: Step 3) */
45void
46__md5_init_ctx (struct md5_ctx *ctx)
47{
48 ctx->A = 0x67452301;
49 ctx->B = 0xefcdab89;
50 ctx->C = 0x98badcfe;
51 ctx->D = 0x10325476;
52
53 ctx->total[0] = ctx->total[1] = 0;
54 ctx->buflen = 0;
55}
56
57/* Put result from CTX in first 16 bytes following RESBUF. The result
58 must be in little endian byte order.
59
60 IMPORTANT: On some systems it is required that RESBUF is correctly
61 aligned for a 32 bits value. */
62void *
63__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
64{
65 ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
66 ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
67 ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
68 ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
69
70 return resbuf;
71}
72
73/* Process the remaining bytes in the internal buffer and the usual
74 prolog according to the standard and write the result to RESBUF.
75
76 IMPORTANT: On some systems it is required that RESBUF is correctly
77 aligned for a 32 bits value. */
78void *
79__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
80{
81 /* Take yet unprocessed bytes into account. */
82 md5_uint32 bytes = ctx->buflen;
83 size_t pad;
84
85 /* Now count remaining bytes. */
86 ctx->total[0] += bytes;
87 if (ctx->total[0] < bytes)
88 ++ctx->total[1];
89
90 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
91 memcpy (dest: &ctx->buffer[bytes], src: fillbuf, n: pad);
92
93 /* Put the 64-bit file length in *bits* at the end of the buffer. */
94 ctx->buffer32[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3);
95 ctx->buffer32[(bytes + pad + 4) / 4] = SWAP ((ctx->total[1] << 3)
96 | (ctx->total[0] >> 29));
97
98 /* Process last bytes. */
99 __md5_process_block (buffer: ctx->buffer, len: bytes + pad + 8, ctx);
100
101 return __md5_read_ctx (ctx, resbuf);
102}
103
104/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
105 result is always in little endian byte order, so that a byte-wise
106 output yields to the wanted ASCII representation of the message
107 digest. */
108void *
109__md5_buffer (const char *buffer, size_t len, void *resblock)
110{
111 struct md5_ctx ctx;
112
113 /* Initialize the computation context. */
114 __md5_init_ctx (ctx: &ctx);
115
116 /* Process whole buffer but last len % 64 bytes. */
117 __md5_process_bytes (buffer, len, ctx: &ctx);
118
119 /* Put result in desired memory area. */
120 return __md5_finish_ctx (ctx: &ctx, resbuf: resblock);
121}
122
123
124void
125__md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
126{
127 /* When we already have some bits in our internal buffer concatenate
128 both inputs first. */
129 if (ctx->buflen != 0)
130 {
131 size_t left_over = ctx->buflen;
132 size_t add = 128 - left_over > len ? len : 128 - left_over;
133
134 memcpy (dest: &ctx->buffer[left_over], src: buffer, n: add);
135 ctx->buflen += add;
136
137 if (ctx->buflen > 64)
138 {
139 __md5_process_block (buffer: ctx->buffer, len: ctx->buflen & ~63, ctx);
140
141 ctx->buflen &= 63;
142 /* The regions in the following copy operation cannot overlap. */
143 memcpy (dest: ctx->buffer, src: &ctx->buffer[(left_over + add) & ~63],
144 n: ctx->buflen);
145 }
146
147 buffer = (const char *) buffer + add;
148 len -= add;
149 }
150
151 /* Process available complete blocks. */
152 if (len >= 64)
153 {
154 while (len > 64)
155 {
156 __md5_process_block (buffer: memcpy (dest: ctx->buffer, src: buffer, n: 64), len: 64, ctx);
157 buffer = (const char *) buffer + 64;
158 len -= 64;
159 }
160 }
161
162 /* Move remaining bytes in internal buffer. */
163 if (len > 0)
164 {
165 size_t left_over = ctx->buflen;
166
167 memcpy (dest: &ctx->buffer[left_over], src: buffer, n: len);
168 left_over += len;
169 if (left_over >= 64)
170 {
171 __md5_process_block (buffer: ctx->buffer, len: 64, ctx);
172 left_over -= 64;
173 memcpy (dest: ctx->buffer, src: &ctx->buffer[64], n: left_over);
174 }
175 ctx->buflen = left_over;
176 }
177}
178
179#include <md5-block.c>
180

source code of glibc/locale/programs/md5.c