With rare exceptions ...
- Always separate line continuation characters by one space from
preceding code.
- Always use two-space indentation. Never use tabs.
- Always use K&R-style conditional blocks.
- Always surround operators with spaces, except in raw assembly code.
- Always put a space after, but not before, a comma.
- Never put a space between type casts and variables/function calls.
- Never put a space between the function name and the argument list in
function declarations and prototypes.
- Always surround braces ('{' and '}') with spaces.
- Always surround statements (if, for, else, catch, while, do, switch)
with spaces.
- Always attach pointer symbols ('*' and '**') to the variable or
function name.
- Always precede pointer symbols ('*' and '**') by a space in type
casts.
- Use the MIN() macro from jpegint.h within the libjpeg and TurboJPEG
API libraries (using min() from tjutil.h is still necessary for
TJBench.)
- Where it makes sense (particularly in the TurboJPEG code), put a blank
line after variable declaration blocks.
- Always separate statements in one-liners by two spaces.
The purpose of this was to ease maintenance on my part and also to make
it easier for contributors to figure out how to format patch
submissions. This was admittedly confusing (even to me sometimes) when
we had 3 or 4 different style conventions in the same source tree. The
new convention is more consistent with the formatting of other OSS code
bases.
This commit corrects deviations from the chosen formatting style in the
libjpeg API code and reformats the TurboJPEG API code such that it
conforms to the same standard.
NOTES:
- Although it is no longer necessary for the function name in function
declarations to begin in Column 1 (this was historically necessary
because of the ansi2knr utility, which allowed libjpeg to be built
with non-ANSI compilers), we retain that formatting for the libjpeg
code because it improves readability when using libjpeg's function
attribute macros (GLOBAL(), etc.)
- This reformatting project was accomplished with the help of AStyle and
Uncrustify, although neither was completely up to the task, and thus
a great deal of manual tweaking was required. Note to developers of
code formatting utilities: the libjpeg-turbo code base is an
excellent test bed, because AFAICT, it breaks every single one of the
utilities that are currently available.
- The legacy (MMX, SSE, 3DNow!) assembly code for i386 has been
formatted to match the SSE2 code (refer to
ff5685d5344273df321eb63a005eaae19d2496e3.) I hadn't intended to
bother with this, but the Loongson MMI implementation demonstrated
that there is still academic value to the MMX implementation, as an
algorithmic model for other 64-bit vector implementations. Thus, it
is desirable to improve its readability in the same manner as that of
the SSE2 implementation.
323 lines
9.8 KiB
C
323 lines
9.8 KiB
C
/*
|
|
* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
|
*
|
|
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
|
|
* All rights reserved.
|
|
*
|
|
* License to copy and use this software is granted provided that it
|
|
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
|
* Algorithm" in all material mentioning or referencing this software
|
|
* or this function.
|
|
*
|
|
* License is also granted to make and use derivative works provided
|
|
* that such works are identified as "derived from the RSA Data
|
|
* Security, Inc. MD5 Message-Digest Algorithm" in all material
|
|
* mentioning or referencing the derived work.
|
|
*
|
|
* RSA Data Security, Inc. makes no representations concerning either
|
|
* the merchantability of this software or the suitability of this
|
|
* software for any particular purpose. It is provided "as is"
|
|
* without express or implied warranty of any kind.
|
|
*
|
|
* These notices must be retained in any copies of any part of this
|
|
* documentation and/or software.
|
|
*
|
|
* This code is the same as the code published by RSA Inc. It has been
|
|
* edited for clarity and style only.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <string.h>
|
|
|
|
#include "./md5.h"
|
|
|
|
#ifdef __amigaos4__
|
|
#include <machine/endian.h>
|
|
#define le32toh(x) (((x & 0xff) << 24) | \
|
|
((x & 0xff00) << 8) | \
|
|
((x & 0xff0000) >> 8) | \
|
|
((x & 0xff000000) >> 24))
|
|
#define htole32(x) le32toh(x)
|
|
#endif
|
|
|
|
static void MD5Transform(unsigned int [4], const unsigned char [64]);
|
|
|
|
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
|
#define Encode memcpy
|
|
#define Decode memcpy
|
|
#else
|
|
|
|
/*
|
|
* OS X doesn't have le32toh() or htole32()
|
|
*/
|
|
#ifdef __APPLE__
|
|
#include <libkern/OSByteOrder.h>
|
|
#define le32toh(x) OSSwapLittleToHostInt32(x)
|
|
#define htole32(x) OSSwapHostToLittleInt32(x)
|
|
#endif
|
|
|
|
/*
|
|
* Encodes input (unsigned int) into output (unsigned char). Assumes len is
|
|
* a multiple of 4.
|
|
*/
|
|
|
|
static void Encode(unsigned char *output, unsigned int *input,
|
|
unsigned int len)
|
|
{
|
|
unsigned int i;
|
|
unsigned int *op = (unsigned int *)output;
|
|
|
|
for (i = 0; i < len / 4; i++)
|
|
op[i] = htole32(input[i]);
|
|
}
|
|
|
|
/*
|
|
* Decodes input (unsigned char) into output (unsigned int). Assumes len is
|
|
* a multiple of 4.
|
|
*/
|
|
|
|
static void Decode(unsigned int *output, const unsigned char *input,
|
|
unsigned int len)
|
|
{
|
|
unsigned int i;
|
|
const unsigned int *ip = (const unsigned int *)input;
|
|
|
|
for (i = 0; i < len / 4; i++)
|
|
output[i] = le32toh(ip[i]);
|
|
}
|
|
#endif
|
|
|
|
static unsigned char PADDING[64] = {
|
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
/* F, G, H and I are basic MD5 functions. */
|
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
|
|
|
/* ROTATE_LEFT rotates x left n bits. */
|
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
|
|
|
/*
|
|
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
|
* Rotation is separate from addition to prevent recomputation.
|
|
*/
|
|
#define FF(a, b, c, d, x, s, ac) { \
|
|
(a) += F((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
|
(a) = ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
#define GG(a, b, c, d, x, s, ac) { \
|
|
(a) += G((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
|
(a) = ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
#define HH(a, b, c, d, x, s, ac) { \
|
|
(a) += H((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
|
(a) = ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
#define II(a, b, c, d, x, s, ac) { \
|
|
(a) += I((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
|
(a) = ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
|
|
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
|
|
|
|
void MD5Init(MD5_CTX *context)
|
|
{
|
|
context->count[0] = context->count[1] = 0;
|
|
|
|
/* Load magic initialization constants. */
|
|
context->state[0] = 0x67452301;
|
|
context->state[1] = 0xefcdab89;
|
|
context->state[2] = 0x98badcfe;
|
|
context->state[3] = 0x10325476;
|
|
}
|
|
|
|
/*
|
|
* MD5 block update operation. Continues an MD5 message-digest
|
|
* operation, processing another message block, and updating the
|
|
* context.
|
|
*/
|
|
|
|
void MD5Update(MD5_CTX *context, const void *in, unsigned int inputLen)
|
|
{
|
|
unsigned int i, idx, partLen;
|
|
const unsigned char *input = in;
|
|
|
|
/* Compute number of bytes mod 64 */
|
|
idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
|
|
|
/* Update number of bits */
|
|
if ((context->count[0] += ((unsigned int)inputLen << 3)) <
|
|
((unsigned int)inputLen << 3))
|
|
context->count[1]++;
|
|
context->count[1] += ((unsigned int)inputLen >> 29);
|
|
|
|
partLen = 64 - idx;
|
|
|
|
/* Transform as many times as possible. */
|
|
if (inputLen >= partLen) {
|
|
memcpy((void *)&context->buffer[idx], (const void *)input, partLen);
|
|
MD5Transform(context->state, context->buffer);
|
|
|
|
for (i = partLen; i + 63 < inputLen; i += 64)
|
|
MD5Transform(context->state, &input[i]);
|
|
|
|
idx = 0;
|
|
} else
|
|
i = 0;
|
|
|
|
/* Buffer remaining input */
|
|
memcpy((void *)&context->buffer[idx], (const void *)&input[i], inputLen - i);
|
|
}
|
|
|
|
/*
|
|
* MD5 padding. Adds padding followed by original length.
|
|
*/
|
|
|
|
void MD5Pad(MD5_CTX *context)
|
|
{
|
|
unsigned char bits[8];
|
|
unsigned int idx, padLen;
|
|
|
|
/* Save number of bits */
|
|
Encode(bits, context->count, 8);
|
|
|
|
/* Pad out to 56 mod 64. */
|
|
idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
|
padLen = (idx < 56) ? (56 - idx) : (120 - idx);
|
|
MD5Update(context, PADDING, padLen);
|
|
|
|
/* Append length (before padding) */
|
|
MD5Update(context, bits, 8);
|
|
}
|
|
|
|
/*
|
|
* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
|
* the message digest and zeroizing the context.
|
|
*/
|
|
|
|
void MD5Final(unsigned char digest[16], MD5_CTX *context)
|
|
{
|
|
/* Do padding. */
|
|
MD5Pad(context);
|
|
|
|
/* Store state in digest */
|
|
Encode(digest, context->state, 16);
|
|
|
|
/* Zeroize sensitive information. */
|
|
memset((void *)context, 0, sizeof(*context));
|
|
}
|
|
|
|
/* MD5 basic transformation. Transforms state based on block. */
|
|
|
|
static void MD5Transform(unsigned int state[4], const unsigned char block[64])
|
|
{
|
|
unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
|
|
|
Decode(x, block, 64);
|
|
|
|
/* Round 1 */
|
|
#define S11 7
|
|
#define S12 12
|
|
#define S13 17
|
|
#define S14 22
|
|
FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
|
FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
|
FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
|
FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
|
FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
|
FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
|
FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
|
FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
|
FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
|
FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
|
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
|
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
|
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
|
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
|
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
|
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
|
|
|
/* Round 2 */
|
|
#define S21 5
|
|
#define S22 9
|
|
#define S23 14
|
|
#define S24 20
|
|
GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
|
GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
|
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
|
GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
|
GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
|
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
|
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
|
GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
|
GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
|
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
|
GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
|
GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
|
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
|
GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
|
GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
|
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
|
|
|
/* Round 3 */
|
|
#define S31 4
|
|
#define S32 11
|
|
#define S33 16
|
|
#define S34 23
|
|
HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
|
HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
|
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
|
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
|
HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
|
HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
|
HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
|
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
|
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
|
HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
|
HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
|
HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
|
HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
|
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
|
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
|
HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
|
|
|
/* Round 4 */
|
|
#define S41 6
|
|
#define S42 10
|
|
#define S43 15
|
|
#define S44 21
|
|
II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
|
II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
|
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
|
II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
|
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
|
II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
|
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
|
II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
|
II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
|
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
|
II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
|
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
|
II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
|
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
|
II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
|
II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
|
|
|
state[0] += a;
|
|
state[1] += b;
|
|
state[2] += c;
|
|
state[3] += d;
|
|
|
|
/* Zeroize sensitive information. */
|
|
memset((void *)x, 0, sizeof(x));
|
|
}
|