Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
MD5.cpp
Go to the documentation of this file.
1/*
2 * This code is derived from (original license follows):
3 *
4 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
5 * MD5 Message-Digest Algorithm (RFC 1321).
6 *
7 * Homepage:
8 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
9 *
10 * Author:
11 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
12 *
13 * This software was written by Alexander Peslyak in 2001. No copyright is
14 * claimed, and the software is hereby placed in the public domain.
15 * In case this attempt to disclaim copyright and place the software in the
16 * public domain is deemed null and void, then the software is
17 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
18 * general public under the following terms:
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted.
22 *
23 * There's ABSOLUTELY NO WARRANTY, express or implied.
24 *
25 * (This is a heavily cut-down "BSD license".)
26 *
27 * This differs from Colin Plumb's older public domain implementation in that
28 * no exactly 32-bit integer data type is required (any 32-bit or wider
29 * unsigned integer data type will do), there's no compile-time endianness
30 * configuration, and the function prototypes match OpenSSL's. No code from
31 * Colin Plumb's implementation has been reused; this comment merely compares
32 * the properties of the two independent implementations.
33 *
34 * The primary goals of this implementation are portability and ease of use.
35 * It is meant to be fast, but not as fast as possible. Some known
36 * optimizations are not included to reduce source code size and avoid
37 * compile-time configuration.
38 */
39
40#include "llvm/Support/MD5.h"
41#include "llvm/ADT/ArrayRef.h"
42#include "llvm/ADT/SmallString.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/Support/Endian.h"
46#include <array>
47#include <cstdint>
48#include <cstring>
49
50// The basic MD5 functions.
51
52// F and G are optimized compared to their RFC 1321 definitions for
53// architectures that lack an AND-NOT instruction, just like in Colin Plumb's
54// implementation.
55#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
56#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
57#define H(x, y, z) ((x) ^ (y) ^ (z))
58#define I(x, y, z) ((y) ^ ((x) | ~(z)))
59
60// The MD5 transformation for all four rounds.
61#define STEP(f, a, b, c, d, x, t, s) \
62 (a) += f((b), (c), (d)) + (x) + (t); \
63 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
64 (a) += (b);
65
66// SET reads 4 input bytes in little-endian byte order and stores them
67// in a properly aligned word in host byte order.
68#define SET(n) \
69 (InternalState.block[(n)] = (MD5_u32plus)ptr[(n)*4] | \
70 ((MD5_u32plus)ptr[(n)*4 + 1] << 8) | \
71 ((MD5_u32plus)ptr[(n)*4 + 2] << 16) | \
72 ((MD5_u32plus)ptr[(n)*4 + 3] << 24))
73#define GET(n) (InternalState.block[(n)])
74
75using namespacellvm;
76
77/// This processes one or more 64-byte data blocks, but does NOT update
78///the bit counters. There are no alignment requirements.
79constuint8_t *MD5::body(ArrayRef<uint8_t> Data) {
80constuint8_t *ptr;
81 MD5_u32plusa,b,c,d;
82 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
83unsignedlongSize =Data.size();
84
85 ptr =Data.data();
86
87a = InternalState.a;
88b = InternalState.b;
89c = InternalState.c;
90d = InternalState.d;
91
92do {
93 saved_a =a;
94 saved_b =b;
95 saved_c =c;
96 saved_d =d;
97
98// Round 1
99STEP(F,a,b,c,d,SET(0), 0xd76aa478, 7)
100STEP(F,d,a,b,c,SET(1), 0xe8c7b756, 12)
101STEP(F,c,d,a,b,SET(2), 0x242070db, 17)
102STEP(F,b,c,d,a,SET(3), 0xc1bdceee, 22)
103STEP(F,a,b,c,d,SET(4), 0xf57c0faf, 7)
104STEP(F,d,a,b,c,SET(5), 0x4787c62a, 12)
105STEP(F,c,d,a,b,SET(6), 0xa8304613, 17)
106STEP(F,b,c,d,a,SET(7), 0xfd469501, 22)
107STEP(F,a,b,c,d,SET(8), 0x698098d8, 7)
108STEP(F,d,a,b,c,SET(9), 0x8b44f7af, 12)
109STEP(F,c,d,a,b,SET(10), 0xffff5bb1, 17)
110STEP(F,b,c,d,a,SET(11), 0x895cd7be, 22)
111STEP(F,a,b,c,d,SET(12), 0x6b901122, 7)
112STEP(F,d,a,b,c,SET(13), 0xfd987193, 12)
113STEP(F,c,d,a,b,SET(14), 0xa679438e, 17)
114STEP(F,b,c,d,a,SET(15), 0x49b40821, 22)
115
116// Round 2
117STEP(G,a,b,c,d,GET(1), 0xf61e2562, 5)
118STEP(G,d,a,b,c,GET(6), 0xc040b340, 9)
119STEP(G,c,d,a,b,GET(11), 0x265e5a51, 14)
120STEP(G,b,c,d,a,GET(0), 0xe9b6c7aa, 20)
121STEP(G,a,b,c,d,GET(5), 0xd62f105d, 5)
122STEP(G,d,a,b,c,GET(10), 0x02441453, 9)
123STEP(G,c,d,a,b,GET(15), 0xd8a1e681, 14)
124STEP(G,b,c,d,a,GET(4), 0xe7d3fbc8, 20)
125STEP(G,a,b,c,d,GET(9), 0x21e1cde6, 5)
126STEP(G,d,a,b,c,GET(14), 0xc33707d6, 9)
127STEP(G,c,d,a,b,GET(3), 0xf4d50d87, 14)
128STEP(G,b,c,d,a,GET(8), 0x455a14ed, 20)
129STEP(G,a,b,c,d,GET(13), 0xa9e3e905, 5)
130STEP(G,d,a,b,c,GET(2), 0xfcefa3f8, 9)
131STEP(G,c,d,a,b,GET(7), 0x676f02d9, 14)
132STEP(G,b,c,d,a,GET(12), 0x8d2a4c8a, 20)
133
134// Round 3
135STEP(H,a,b,c,d,GET(5), 0xfffa3942, 4)
136STEP(H,d,a,b,c,GET(8), 0x8771f681, 11)
137STEP(H,c,d,a,b,GET(11), 0x6d9d6122, 16)
138STEP(H,b,c,d,a,GET(14), 0xfde5380c, 23)
139STEP(H,a,b,c,d,GET(1), 0xa4beea44, 4)
140STEP(H,d,a,b,c,GET(4), 0x4bdecfa9, 11)
141STEP(H,c,d,a,b,GET(7), 0xf6bb4b60, 16)
142STEP(H,b,c,d,a,GET(10), 0xbebfbc70, 23)
143STEP(H,a,b,c,d,GET(13), 0x289b7ec6, 4)
144STEP(H,d,a,b,c,GET(0), 0xeaa127fa, 11)
145STEP(H,c,d,a,b,GET(3), 0xd4ef3085, 16)
146STEP(H,b,c,d,a,GET(6), 0x04881d05, 23)
147STEP(H,a,b,c,d,GET(9), 0xd9d4d039, 4)
148STEP(H,d,a,b,c,GET(12), 0xe6db99e5, 11)
149STEP(H,c,d,a,b,GET(15), 0x1fa27cf8, 16)
150STEP(H,b,c,d,a,GET(2), 0xc4ac5665, 23)
151
152// Round 4
153STEP(I,a,b,c,d,GET(0), 0xf4292244, 6)
154STEP(I,d,a,b,c,GET(7), 0x432aff97, 10)
155STEP(I,c,d,a,b,GET(14), 0xab9423a7, 15)
156STEP(I,b,c,d,a,GET(5), 0xfc93a039, 21)
157STEP(I,a,b,c,d,GET(12), 0x655b59c3, 6)
158STEP(I,d,a,b,c,GET(3), 0x8f0ccc92, 10)
159STEP(I,c,d,a,b,GET(10), 0xffeff47d, 15)
160STEP(I,b,c,d,a,GET(1), 0x85845dd1, 21)
161STEP(I,a,b,c,d,GET(8), 0x6fa87e4f, 6)
162STEP(I,d,a,b,c,GET(15), 0xfe2ce6e0, 10)
163STEP(I,c,d,a,b,GET(6), 0xa3014314, 15)
164STEP(I,b,c,d,a,GET(13), 0x4e0811a1, 21)
165STEP(I,a,b,c,d,GET(4), 0xf7537e82, 6)
166STEP(I,d,a,b,c,GET(11), 0xbd3af235, 10)
167STEP(I,c,d,a,b,GET(2), 0x2ad7d2bb, 15)
168STEP(I,b,c,d,a,GET(9), 0xeb86d391, 21)
169
170a += saved_a;
171b += saved_b;
172c += saved_c;
173d += saved_d;
174
175 ptr += 64;
176 }while (Size -= 64);
177
178 InternalState.a =a;
179 InternalState.b =b;
180 InternalState.c =c;
181 InternalState.d =d;
182
183return ptr;
184}
185
186MD5::MD5() =default;
187
188/// Incrementally add the bytes in \p Data to the hash.
189voidMD5::update(ArrayRef<uint8_t>Data) {
190MD5_u32plus saved_lo;
191unsignedlong used, free;
192constuint8_t *Ptr =Data.data();
193unsignedlongSize =Data.size();
194
195 saved_lo = InternalState.lo;
196if ((InternalState.lo = (saved_lo +Size) & 0x1fffffff) < saved_lo)
197 InternalState.hi++;
198 InternalState.hi +=Size >> 29;
199
200 used = saved_lo & 0x3f;
201
202if (used) {
203 free = 64 - used;
204
205if (Size < free) {
206 memcpy(&InternalState.buffer[used],Ptr,Size);
207return;
208 }
209
210 memcpy(&InternalState.buffer[used],Ptr, free);
211Ptr =Ptr + free;
212Size -= free;
213 body(ArrayRef(InternalState.buffer, 64));
214 }
215
216if (Size >= 64) {
217Ptr = body(ArrayRef(Ptr,Size & ~(unsignedlong)0x3f));
218Size &= 0x3f;
219 }
220
221 memcpy(InternalState.buffer,Ptr,Size);
222}
223
224/// Add the bytes in the StringRef \p Str to the hash.
225// Note that this isn't a string and so this won't include any trailing NULL
226// bytes.
227voidMD5::update(StringRef Str) {
228ArrayRef<uint8_t> SVal((constuint8_t *)Str.data(), Str.size());
229update(SVal);
230}
231
232/// Finish the hash and place the resulting hash into \p result.
233/// \param Result is assumed to be a minimum of 16-bytes in size.
234voidMD5::final(MD5Result &Result) {
235unsignedlong used, free;
236
237 used = InternalState.lo & 0x3f;
238
239 InternalState.buffer[used++] = 0x80;
240
241 free = 64 - used;
242
243if (free < 8) {
244 memset(&InternalState.buffer[used], 0, free);
245 body(ArrayRef(InternalState.buffer, 64));
246 used = 0;
247 free = 64;
248 }
249
250 memset(&InternalState.buffer[used], 0, free - 8);
251
252 InternalState.lo <<= 3;
253support::endian::write32le(&InternalState.buffer[56], InternalState.lo);
254support::endian::write32le(&InternalState.buffer[60], InternalState.hi);
255
256 body(ArrayRef(InternalState.buffer, 64));
257
258support::endian::write32le(&Result[0], InternalState.a);
259support::endian::write32le(&Result[4], InternalState.b);
260support::endian::write32le(&Result[8], InternalState.c);
261support::endian::write32le(&Result[12], InternalState.d);
262}
263
264MD5::MD5ResultMD5::final() {
265MD5Result Result;
266final(Result);
267return Result;
268}
269
270MD5::MD5ResultMD5::result() {
271auto StateToRestore = InternalState;
272
273auto Hash =final();
274
275// Restore the state
276 InternalState = StateToRestore;
277
278return Hash;
279}
280
281SmallString<32>MD5::MD5Result::digest() const{
282SmallString<32> Str;
283 toHex(*this,/*LowerCase*/true, Str);
284return Str;
285}
286
287voidMD5::stringifyResult(MD5Result &Result,SmallVectorImpl<char> &Str) {
288 toHex(Result,/*LowerCase*/true, Str);
289}
290
291MD5::MD5ResultMD5::hash(ArrayRef<uint8_t>Data) {
292MD5 Hash;
293 Hash.update(Data);
294MD5::MD5Result Res;
295 Hash.final(Res);
296
297return Res;
298}
ArrayRef.h
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Endian.h
STEP
#define STEP(f, a, b, c, d, x, t, s)
Definition:MD5.cpp:61
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
G
#define G(x, y, z)
Definition:MD5.cpp:56
H
#define H(x, y, z)
Definition:MD5.cpp:57
MD5.h
SET
#define SET(ID, TYPE, VAL)
SmallString.h
This file defines the SmallString class.
StringExtras.h
This file contains some functions that are useful when dealing with strings.
StringRef.h
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::MD5
Definition:MD5.h:41
llvm::MD5::a
MD5_u32plus a
Definition:MD5.h:95
llvm::MD5::update
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition:MD5.cpp:189
llvm::MD5::stringifyResult
static void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
Definition:MD5.cpp:287
llvm::MD5::final
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition:MD5.cpp:234
llvm::MD5::final
MD5Result final()
Finishes off the hash, and returns the 16-byte hash data.
Definition:MD5.cpp:264
llvm::MD5::result
MD5Result result()
Finishes off the hash, and returns the 16-byte hash data.
Definition:MD5.cpp:270
llvm::MD5::hash
static MD5Result hash(ArrayRef< uint8_t > Data)
Computes the hash for a given bytes.
Definition:MD5.cpp:291
llvm::MD5::b
MD5_u32plus b
Definition:MD5.h:96
llvm::MD5::d
MD5_u32plus d
Definition:MD5.h:98
llvm::MD5::c
MD5_u32plus c
Definition:MD5.h:97
llvm::MD5::MD5
MD5()
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
uint32_t
uint8_t
llvm::support::endian::write32le
void write32le(void *P, uint32_t V)
Definition:Endian.h:468
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::HTTPMethod::GET
@ GET
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::MD5::MD5Result
Definition:MD5.h:43
llvm::MD5::MD5Result::digest
SmallString< 32 > digest() const
Definition:MD5.cpp:281

Generated on Thu Jul 17 2025 12:40:01 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp