FireBirdLib - Topfield TMS PVR TAP Programming Library
Md5.c
Go to the documentation of this file.
1/*
2 **********************************************************************
3 ** md5.h -- Header file for implementation of MD5 **
4 ** RSA Data Security, Inc. MD5 Message Digest Algorithm **
5 ** Created: 2/17/90 RLR **
6 ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
7 ** Revised (for MD5): RLR 4/27/91 **
8 ** -- G modified to have y&~z instead of y&z **
9 ** -- FF, GG, HH modified to add in last register done **
10 ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
11 ** -- distinct additive constant for each step **
12 ** -- round 4 added, working mod 7 **
13 **********************************************************************
14 */
15
16/*
17 **********************************************************************
18 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
19 ** **
20 ** License to copy and use this software is granted provided that **
21 ** it is identified as the "RSA Data Security, Inc. MD5 Message **
22 ** Digest Algorithm" in all material mentioning or referencing this **
23 ** software or this function. **
24 ** **
25 ** License is also granted to make and use derivative works **
26 ** provided that such works are identified as "derived from the RSA **
27 ** Data Security, Inc. MD5 Message Digest Algorithm" in all **
28 ** material mentioning or referencing the derived work. **
29 ** **
30 ** RSA Data Security, Inc. makes no representations concerning **
31 ** either the merchantability of this software or the suitability **
32 ** of this software for any particular purpose. It is provided "as **
33 ** is" without express or implied warranty of any kind. **
34 ** **
35 ** These notices must be retained in any copies of any part of this **
36 ** documentation and/or software. **
37 **********************************************************************
38 */
39
40#include <fcntl.h>
41#include <unistd.h>
42
43/* typedef a 32 bit type */
44typedef unsigned long int UINT4;
45
46/* Data structure for MD5 (Message Digest) computation */
47typedef struct {
48 UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
49 UINT4 buf[4]; /* scratch buffer */
50 unsigned char in[64]; /* input buffer */
51 unsigned char digest[16]; /* actual digest after MD5Final call */
52} MD5_CTX;
53
54void MD5Init(MD5_CTX *);
55void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
56void MD5Final(MD5_CTX *);
57
58/*
59 **********************************************************************
60 ** End of md5.h **
61 ******************************* (cut) ********************************
62 */
63
64/*
65 **********************************************************************
66 ** md5.c **
67 ** RSA Data Security, Inc. MD5 Message Digest Algorithm **
68 ** Created: 2/17/90 RLR **
69 ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
70 **********************************************************************
71 */
72
73/*
74 **********************************************************************
75 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
76 ** **
77 ** License to copy and use this software is granted provided that **
78 ** it is identified as the "RSA Data Security, Inc. MD5 Message **
79 ** Digest Algorithm" in all material mentioning or referencing this **
80 ** software or this function. **
81 ** **
82 ** License is also granted to make and use derivative works **
83 ** provided that such works are identified as "derived from the RSA **
84 ** Data Security, Inc. MD5 Message Digest Algorithm" in all **
85 ** material mentioning or referencing the derived work. **
86 ** **
87 ** RSA Data Security, Inc. makes no representations concerning **
88 ** either the merchantability of this software or the suitability **
89 ** of this software for any particular purpose. It is provided "as **
90 ** is" without express or implied warranty of any kind. **
91 ** **
92 ** These notices must be retained in any copies of any part of this **
93 ** documentation and/or software. **
94 **********************************************************************
95 */
96
97/* -- include the following line if the md5.h header file is separate -- */
98/* #include "md5.h" */
99
100/* forward declaration */
101static void Transform(UINT4 *, UINT4 *);
102
103static unsigned char PADDING[64] = {
104 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
112};
113
114/* F, G and H are basic MD5 functions: selection, majority, parity */
115#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
116#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
117#define H(x, y, z) ((x) ^ (y) ^ (z))
118#define I(x, y, z) ((y) ^ ((x) | (~z)))
119
120/* ROTATE_LEFT rotates x left n bits */
121#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
122
123/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
124/* Rotation is separate from addition to prevent recomputation */
125#define FF(a, b, c, d, x, s, ac) \
126 {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
127 (a) = ROTATE_LEFT((a), (s)); \
128 (a) += (b); \
129 }
130#define GG(a, b, c, d, x, s, ac) \
131 {(a) += G((b), (c), (d)) + (x) + (UINT4)(ac); \
132 (a) = ROTATE_LEFT((a), (s)); \
133 (a) += (b); \
134 }
135#define HH(a, b, c, d, x, s, ac) \
136 {(a) += H((b), (c), (d)) + (x) + (UINT4)(ac); \
137 (a) = ROTATE_LEFT((a), (s)); \
138 (a) += (b); \
139 }
140#define II(a, b, c, d, x, s, ac) \
141 {(a) += I((b), (c), (d)) + (x) + (UINT4)(ac); \
142 (a) = ROTATE_LEFT((a), (s)); \
143 (a) += (b); \
144 }
145
146void MD5Init(MD5_CTX *mdContext)
147{
148 mdContext->i[0] = mdContext->i[1] = (UINT4)0;
149
150 /* Load magic initialization constants.
151 */
152 mdContext->buf[0] = (UINT4)0x67452301;
153 mdContext->buf[1] = (UINT4)0xefcdab89;
154 mdContext->buf[2] = (UINT4)0x98badcfe;
155 mdContext->buf[3] = (UINT4)0x10325476;
156}
157
158void MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
159{
160 UINT4 in[16];
161 int mdi;
162 unsigned int i, ii;
163
164 /* compute number of bytes mod 64 */
165 mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
166
167 /* update number of bits */
168 if((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
169 mdContext->i[1]++;
170 mdContext->i[0] += ((UINT4)inLen << 3);
171 mdContext->i[1] += ((UINT4)inLen >> 29);
172
173 while(inLen--) {
174 /* add new character to buffer, increment mdi */
175 mdContext->in[mdi++] = *inBuf++;
176
177 /* transform if necessary */
178 if(mdi == 0x40) {
179 for(i = 0, ii = 0; i < 16; i++, ii += 4)
180 in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
181 (((UINT4)mdContext->in[ii+2]) << 16) |
182 (((UINT4)mdContext->in[ii+1]) << 8) |
183 ((UINT4)mdContext->in[ii]);
184 Transform(mdContext->buf, in);
185 mdi = 0;
186 }
187 }
188}
189
190void MD5Final(MD5_CTX *mdContext)
191{
192 UINT4 in[16];
193 int mdi;
194 unsigned int i, ii;
195 unsigned int padLen;
196
197 /* save number of bits */
198 in[14] = mdContext->i[0];
199 in[15] = mdContext->i[1];
200
201 /* compute number of bytes mod 64 */
202 mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
203
204 /* pad out to 56 mod 64 */
205 padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
206 MD5Update(mdContext, PADDING, padLen);
207
208 /* append length in bits and transform */
209 for(i = 0, ii = 0; i < 14; i++, ii += 4)
210 in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
211 (((UINT4)mdContext->in[ii+2]) << 16) |
212 (((UINT4)mdContext->in[ii+1]) << 8) |
213 ((UINT4)mdContext->in[ii]);
214 Transform(mdContext->buf, in);
215
216 /* store buffer in digest */
217 for(i = 0, ii = 0; i < 4; i++, ii += 4) {
218 mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
219 mdContext->digest[ii+1] =
220 (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
221 mdContext->digest[ii+2] =
222 (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
223 mdContext->digest[ii+3] =
224 (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
225 }
226}
227
228/* Basic MD5 step. Transform buf based on in.
229 */
230static void Transform(buf, in)
231UINT4 *buf;
232UINT4 *in;
233{
234 UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
235
236 /* Round 1 */
237#define S11 7
238#define S12 12
239#define S13 17
240#define S14 22
241 FF( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */
242 FF( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */
243 FF( c, d, a, b, in[ 2], S13, 606105819UL); /* 3 */
244 FF( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */
245 FF( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */
246 FF( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */
247 FF( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */
248 FF( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */
249 FF( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */
250 FF( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */
251 FF( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */
252 FF( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */
253 FF( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */
254 FF( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */
255 FF( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */
256 FF( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */
257
258 /* Round 2 */
259#define S21 5
260#define S22 9
261#define S23 14
262#define S24 20
263 GG( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */
264 GG( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */
265 GG( c, d, a, b, in[11], S23, 643717713UL); /* 19 */
266 GG( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */
267 GG( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */
268 GG( d, a, b, c, in[10], S22, 38016083UL); /* 22 */
269 GG( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */
270 GG( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */
271 GG( a, b, c, d, in[ 9], S21, 568446438UL); /* 25 */
272 GG( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */
273 GG( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */
274 GG( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */
275 GG( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */
276 GG( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */
277 GG( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */
278 GG( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */
279
280 /* Round 3 */
281#define S31 4
282#define S32 11
283#define S33 16
284#define S34 23
285 HH( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */
286 HH( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */
287 HH( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */
288 HH( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */
289 HH( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */
290 HH( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */
291 HH( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */
292 HH( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */
293 HH( a, b, c, d, in[13], S31, 681279174UL); /* 41 */
294 HH( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */
295 HH( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */
296 HH( b, c, d, a, in[ 6], S34, 76029189UL); /* 44 */
297 HH( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */
298 HH( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */
299 HH( c, d, a, b, in[15], S33, 530742520UL); /* 47 */
300 HH( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */
301
302 /* Round 4 */
303#define S41 6
304#define S42 10
305#define S43 15
306#define S44 21
307 II( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */
308 II( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */
309 II( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */
310 II( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */
311 II( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */
312 II( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */
313 II( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */
314 II( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */
315 II( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */
316 II( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */
317 II( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */
318 II( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */
319 II( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */
320 II( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */
321 II( c, d, a, b, in[ 2], S43, 718787259UL); /* 63 */
322 II( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */
323
324 buf[0] += a;
325 buf[1] += b;
326 buf[2] += c;
327 buf[3] += d;
328}
329
330/*
331 **********************************************************************
332 ** End of md5.c **
333 ******************************* (cut) ********************************
334 */
335
336/*
337 **********************************************************************
338 ** md5driver.c -- sample routines to test **
339 ** RSA Data Security, Inc. MD5 message digest algorithm. **
340 ** Created: 2/16/90 RLR **
341 ** Updated: 1/91 SRD **
342 **********************************************************************
343 */
344
345/*
346 **********************************************************************
347 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
348 ** **
349 ** RSA Data Security, Inc. makes no representations concerning **
350 ** either the merchantability of this software or the suitability **
351 ** of this software for any particular purpose. It is provided "as **
352 ** is" without express or implied warranty of any kind. **
353 ** **
354 ** These notices must be retained in any copies of any part of this **
355 ** documentation and/or software. **
356 **********************************************************************
357 */
358
359#include <stdio.h>
360#include <sys/types.h>
361#include <time.h>
362#include <string.h>
363
364#include "libFireBird.h"
365/* -- include the following file if the file md5.h is separate -- */
366/* #include "md5.h" */
367
368bool MD5String(char *inString, byte *Digest)
369{
370 TRACEENTER();
371
372 if(!inString)
373 {
374 TRACEEXIT();
375 return FALSE;
376 }
377
378 MD5_CTX mdContext;
379 unsigned int len = strlen(inString);
380
381 MD5Init(&mdContext);
382 MD5Update(&mdContext, inString, len);
383 MD5Final(&mdContext);
384
385 if(Digest) memcpy(Digest, mdContext.digest, 16);
386
387 TRACEEXIT();
388 return TRUE;
389}
390
391bool MD5File(char *FileName, byte *Digest)
392{
393 TRACEENTER();
394
395 int inFile;
396 MD5_CTX mdContext;
397 int bytes;
398 byte data[1024];
399 char AbsFileName[FBLIB_DIR_SIZE];
400
401 if(!FileName || !*FileName)
402 {
403 TRACEEXIT();
404 return FALSE;
405 }
406
407 ConvertPathType(FileName, AbsFileName, PF_FullLinuxPath);
408
409 inFile = open(AbsFileName, O_RDONLY, 0600);
410 if(inFile < 0)
411 {
412 TRACEEXIT();
413 return FALSE;
414 }
415
416 MD5Init(&mdContext);
417 while((bytes = read(inFile, data, 1024)) != 0)
418 MD5Update(&mdContext, data, bytes);
419 MD5Final(&mdContext);
420 close(inFile);
421
422 if(Digest) memcpy(Digest, mdContext.digest, 16);
423
424 TRACEEXIT();
425 return TRUE;
426}
void ConvertPathType(const char *Source, char *Dest, tPathFormat DestFormat)
#define FF(a, b, c, d, x, s, ac)
Definition: Md5.c:125
#define S24
#define S33
#define S32
#define S12
#define S42
void MD5Init(MD5_CTX *)
Definition: Md5.c:146
#define S11
#define S43
#define S23
#define GG(a, b, c, d, x, s, ac)
Definition: Md5.c:130
#define S44
#define S14
void MD5Final(MD5_CTX *)
Definition: Md5.c:190
#define HH(a, b, c, d, x, s, ac)
Definition: Md5.c:135
void MD5Update(MD5_CTX *, unsigned char *, unsigned int)
Definition: Md5.c:158
#define S13
bool MD5String(char *inString, byte *Digest)
Definition: Md5.c:368
#define S41
#define S21
unsigned long int UINT4
Definition: Md5.c:44
#define II(a, b, c, d, x, s, ac)
Definition: Md5.c:140
#define S22
#define S31
bool MD5File(char *FileName, byte *Digest)
Definition: Md5.c:391
#define S34
#define FBLIB_DIR_SIZE
Definition: libFireBird.h:1871
#define TRACEEXIT()
Definition: libFireBird.h:1244
#define TRACEENTER()
Definition: libFireBird.h:1243
@ PF_FullLinuxPath
Definition: libFireBird.h:1926
Definition: Md5.c:47
UINT4 i[2]
Definition: Md5.c:48
unsigned char digest[16]
Definition: Md5.c:51
UINT4 buf[4]
Definition: Md5.c:49
unsigned char in[64]
Definition: Md5.c:50