📄 md.cpp
字号:
/*******************************************************************
md.c
Message Digest Algorithms: MD2, MD4, MD5, SHA-1
Written & Modified by Zhuang Hao S.S.* (Jerrey <jerrey@usa.net>)
Copyright(C) 1998
All Rights Reserved.
-------------------------------------------------------------------
ANY MODIFICATION MADE TO THIS SOURCE CODE IS AT YOUR OWN RISK.
Please ask the author for the permission.
*******************************************************************
THE MD2, MD4 & MD5 ALGORITHMS ARE MODIFIED FROM THE SOURCE CODE
GIVEN IN RFC1319-1321. PLEASE READ THE COPYRIGHT DECLARATION
BELOW. NOTE THAT THE SOURCE CODES BELOW ARE *NOT* THE SAME AS
THOSE GIVEN IN RFC1319-1321.
*******************************************************************/
/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
rights reserved.
License to copy and use this software is granted for
non-commercial Internet Privacy-Enhanced Mail provided that it is
identified as the "RSA Data Security, Inc. MD2 Message Digest
Algorithm" in all material mentioning or referencing this software
or this function.
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.
*/
/*
Revised by :Xu jianzhuo(1998)
I find there is somthing wrong with SHA1 function.
The Lenth of the result must be 20 bytes long while it was 16 bytes in
the program from zhuangHao.I revise it here.
If you find any wrong with it Please use the old version from ZhuangHao.
*/
/*
Add two direc-using function by Meng Hongwen, 2005
*/
#include "md.h"
#define ROTL32(x, n) (((x) << (n))|((x) >> (32-(n))))
const BYTE md2_OBJECTID[] = {
0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02
/* { rsadsi digestAlgorithm(2) 2} ::= { 1 2 840 113549 2 2 }
*/
};
const BYTE md4_OBJECTID[] = {
0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04
/* { rsadsi digestAlgorithm(2) 4} ::= { 1 2 840 113549 2 4 }
*/
};
const BYTE md5_OBJECTID[] = {
0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05
/* { rsadsi digestAlgorithm(2) 5} ::= { 1 2 840 113549 2 5 }
*/
};
const BYTE sha1_OBJECTID[] = {
0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a
/* { iso(1) identified-organization(3) iow(14) secsig(3)
algorithms(2) 26}
*/
};
static void EncodeLH PROTO_LIST ((BYTE *, const UINT4 *, UINT));
static void DecodeLH PROTO_LIST ((UINT4 *, const BYTE *, UINT));
static void EncodeHL PROTO_LIST ((BYTE *, const UINT4 *, UINT));
static void DecodeHL PROTO_LIST ((UINT4 *, const BYTE *, UINT));
/* Encodes input (UINT4) into output (BYTE). Assumes len is
a multiple of 4. (LSB first & MSB last)
*/
static void EncodeLH (BYTE *output, const UINT4 *input, UINT len)
{
UINT i, j;
for (i = 0, j = 0; j < len; ++i, j += 4) {
output[j] = (BYTE)(input[i]);
output[j+1] = (BYTE)(input[i] >> 8);
output[j+2] = (BYTE)(input[i] >> 16);
output[j+3] = (BYTE)(input[i] >> 24);
}
}
/* Decodes input (BYTE) into output (UINT4). Assumes len is
a multiple of 4. (first byte to LSB & last byte to MSB)
*/
static void DecodeLH (UINT4 *output, const BYTE *input, UINT len)
{
UINT i, j;
for (i = 0, j = 0; j < len; ++i, j += 4) {
output[i] = ((UINT4)input[j])|(((UINT4)input[j+1]) << 8)|
(((UINT4)input[j+2]) << 16)|(((UINT4)input[j+3]) << 24);
}
}
/* Encodes input (UINT4) into output (BYTE). Assumes len is
a multiple of 4. (MSB first & LSB last)
*/
static void EncodeHL (BYTE *output, const UINT4 *input, UINT len)
{
UINT i, j;
for (i = 0, j = 0; j < len; ++i, j += 4) {
output[j] = (BYTE)(input[i] >> 24);
output[j+1] = (BYTE)(input[i] >> 16);
output[j+2] = (BYTE)(input[i] >> 8);
output[j+3] = (BYTE)(input[i]);
}
}
/* Decodes input (BYTE) into output (UINT4). Assumes len is
a multiple of 4. (first byte to MSB & last byte to LSB)
*/
static void DecodeHL (UINT4 *output, const BYTE *input, UINT len)
{
UINT i, j;
for (i = 0, j = 0; j < len; ++i, j += 4) {
output[i] = (((UINT4)input[j]) << 24)|(((UINT4)input[j+1]) << 16)|
(((UINT4)input[j+2]) << 8)|((UINT4)input[j+3]);
}
}
/* MD2 ---------------------------------------------------------------
*/
/* Permutation of 0..255 constructed from the digits of pi. It gives a
"random" nonlinear byte substitution operation.
*/
static const BYTE PI_SUBST[256] = {
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76,
130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138,
23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142,
187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16,
137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 39, 53, 62,
204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 181, 209, 215,
94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 150, 164, 125, 182,
118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 112, 89, 100, 113, 135,
32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 96, 37, 173, 174, 176,
185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 85, 71, 163, 35, 221,
81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, 44, 83, 13, 110,
133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, 106, 220, 55,
200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, 120, 136,
149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, 242,
239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131,
20
};
static const BYTE *MD2_PADDING[] = {
(BYTE *)"",
(BYTE *)"\001",
(BYTE *)"\002\002",
(BYTE *)"\003\003\003",
(BYTE *)"\004\004\004\004",
(BYTE *)"\005\005\005\005\005",
(BYTE *)"\006\006\006\006\006\006",
(BYTE *)"\007\007\007\007\007\007\007",
(BYTE *)"\010\010\010\010\010\010\010\010",
(BYTE *)"\011\011\011\011\011\011\011\011\011",
(BYTE *)"\012\012\012\012\012\012\012\012\012\012",
(BYTE *)"\013\013\013\013\013\013\013\013\013\013\013",
(BYTE *)"\014\014\014\014\014\014\014\014\014\014\014\014",
(BYTE *)"\015\015\015\015\015\015\015\015\015\015\015\015\015",
(BYTE *)"\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
(BYTE *)"\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
(BYTE *)"\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
};
static void Md2_Transform PROTO_LIST
((BYTE [16], BYTE [16], const BYTE [16]));
/* MD2 basic transformation. Transforms state and updates checksum
based on block.
*/
static void Md2_Transform (BYTE state[16], BYTE checksum[16], const BYTE block[16])
{
UINT i, j, t;
BYTE x[48];
/* Form encryption block from state, block, state ^ block.
*/
T_memcpy (x, state, 16);
T_memcpy (x+16, block, 16);
for (i = 0; i < 16; x[i+32] = state[i]^block[i], ++i);
/* Encrypt block (18 rounds).
*/
for (t = i = 0; i < 18; ++i) {
for (j = 0; j < 48; t = x[j] ^= PI_SUBST[t], ++j);
t = (t+i)&0xff;
}
/* Save new state
*/
T_memcpy (state, x, 16);
/* Update checksum.
*/
for (t = checksum[15], i = 0; i < 16;
t = checksum[i] ^= PI_SUBST[block[i]^t], ++i);
/* Zeroize sensitive information.
*/
T_memset (x, 0, sizeof (x));
}
/* MD2 initialization. Begins an MD2 operation, writing a new context.
*/
void MD2_Init (MD2CTX *context)
{
context->count = 0;
T_memset (context->state, 0, sizeof (context->state));
T_memset (context->checksum, 0, sizeof (context->checksum));
}
/* MD2 block update operation. Continues an MD2 message-digest
operation, processing another message block, and updating the
context.
*/
void MD2_Update (MD2CTX *context, const BYTE *input, UINT inputLen)
{
UINT i, index, partLen;
/* Update number of bytes mod 16
*/
index = context->count;
context->count = (index+inputLen)&0xf;
partLen = 16-index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
T_memcpy (&context->buffer[index], input, partLen);
Md2_Transform (context->state, context->checksum, context->buffer);
for (i = partLen; i+15 < inputLen; i += 16) {
Md2_Transform (context->state, context->checksum, input+i);
}
index = 0;
}
else {
i = 0;
}
/* Buffer remaining input
*/
T_memcpy (&context->buffer[index], input+i, inputLen-i);
}
/* MD2 finalization. Ends an MD2 message-digest operation, writing the
message digest and zeroizing the context.
*/
void MD2_Final (BYTE digest[16], MD2CTX *context)
{
UINT index, padLen;
/* Pad out to multiple of 16.
*/
index = context->count;
padLen = 16-index;
MD2_Update (context, MD2_PADDING[padLen], padLen);
/* Extend with checksum
*/
MD2_Update (context, context->checksum, 16);
/* Store state in digest
*/
T_memcpy (digest, context->state, 16);
/* Zeroize sensitive information.
*/
T_memset (context, 0, sizeof (*context));
}
/* MD4 ---------------------------------------------------------------
*/
/* Constants for Md4_Transform routine.
*/
#define MD4_S11 3
#define MD4_S12 7
#define MD4_S13 11
#define MD4_S14 19
#define MD4_S21 3
#define MD4_S22 5
#define MD4_S23 9
#define MD4_S24 13
#define MD4_S31 3
#define MD4_S32 9
#define MD4_S33 11
#define MD4_S34 15
/* MD4_F, MD4_G and MD4_H are basic MD4 functions.
*/
#define MD4_F(x, y, z) (((x)&(y))|((~x)&(z)))
#define MD4_G(x, y, z) (((x)&(y))|((x)&(z))|((y)&(z)))
#define MD4_H(x, y, z) ((x)^(y)^(z))
/* MD4_FF, MD4_GG and MD4_HH are transformations for rounds 1, 2 and 3
Rotation is separate from addition to prevent recomputation */
#define MD4_FF(a, b, c, d, x, s) { \
(a) += MD4_F ((b), (c), (d))+(x); \
(a) = ROTL32 ((a), (s)); \
}
#define MD4_GG(a, b, c, d, x, s) { \
(a) += MD4_G ((b), (c), (d))+(x)+(UINT4)0x5a827999; \
(a) = ROTL32 ((a), (s)); \
}
#define MD4_HH(a, b, c, d, x, s) { \
(a) += MD4_H ((b), (c), (d))+(x)+(UINT4)0x6ed9eba1; \
(a) = ROTL32 ((a), (s)); \
}
static const BYTE MD4_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
};
static void Md4_Transform PROTO_LIST ((UINT4 [4], const BYTE [64]));
/* MD4 basic transformation. Transforms state based on block.
*/
static void Md4_Transform (UINT4 state[4], const BYTE block[64])
{
UINT4 a, b, c, d, x[16];
a = state[0], b = state[1], c = state[2], d = state[3];
DecodeLH (x, block, 64);
/* Round 1 */
MD4_FF (a, b, c, d, x[ 0], MD4_S11); /* 1 */
MD4_FF (d, a, b, c, x[ 1], MD4_S12); /* 2 */
MD4_FF (c, d, a, b, x[ 2], MD4_S13); /* 3 */
MD4_FF (b, c, d, a, x[ 3], MD4_S14); /* 4 */
MD4_FF (a, b, c, d, x[ 4], MD4_S11); /* 5 */
MD4_FF (d, a, b, c, x[ 5], MD4_S12); /* 6 */
MD4_FF (c, d, a, b, x[ 6], MD4_S13); /* 7 */
MD4_FF (b, c, d, a, x[ 7], MD4_S14); /* 8 */
MD4_FF (a, b, c, d, x[ 8], MD4_S11); /* 9 */
MD4_FF (d, a, b, c, x[ 9], MD4_S12); /* 10 */
MD4_FF (c, d, a, b, x[10], MD4_S13); /* 11 */
MD4_FF (b, c, d, a, x[11], MD4_S14); /* 12 */
MD4_FF (a, b, c, d, x[12], MD4_S11); /* 13 */
MD4_FF (d, a, b, c, x[13], MD4_S12); /* 14 */
MD4_FF (c, d, a, b, x[14], MD4_S13); /* 15 */
MD4_FF (b, c, d, a, x[15], MD4_S14); /* 16 */
/* Round 2 */
MD4_GG (a, b, c, d, x[ 0], MD4_S21); /* 17 */
MD4_GG (d, a, b, c, x[ 4], MD4_S22); /* 18 */
MD4_GG (c, d, a, b, x[ 8], MD4_S23); /* 19 */
MD4_GG (b, c, d, a, x[12], MD4_S24); /* 20 */
MD4_GG (a, b, c, d, x[ 1], MD4_S21); /* 21 */
MD4_GG (d, a, b, c, x[ 5], MD4_S22); /* 22 */
MD4_GG (c, d, a, b, x[ 9], MD4_S23); /* 23 */
MD4_GG (b, c, d, a, x[13], MD4_S24); /* 24 */
MD4_GG (a, b, c, d, x[ 2], MD4_S21); /* 25 */
MD4_GG (d, a, b, c, x[ 6], MD4_S22); /* 26 */
MD4_GG (c, d, a, b, x[10], MD4_S23); /* 27 */
MD4_GG (b, c, d, a, x[14], MD4_S24); /* 28 */
MD4_GG (a, b, c, d, x[ 3], MD4_S21); /* 29 */
MD4_GG (d, a, b, c, x[ 7], MD4_S22); /* 30 */
MD4_GG (c, d, a, b, x[11], MD4_S23); /* 31 */
MD4_GG (b, c, d, a, x[15], MD4_S24); /* 32 */
/* Round 3 */
MD4_HH (a, b, c, d, x[ 0], MD4_S31); /* 33 */
MD4_HH (d, a, b, c, x[ 8], MD4_S32); /* 34 */
MD4_HH (c, d, a, b, x[ 4], MD4_S33); /* 35 */
MD4_HH (b, c, d, a, x[12], MD4_S34); /* 36 */
MD4_HH (a, b, c, d, x[ 2], MD4_S31); /* 37 */
MD4_HH (d, a, b, c, x[10], MD4_S32); /* 38 */
MD4_HH (c, d, a, b, x[ 6], MD4_S33); /* 39 */
MD4_HH (b, c, d, a, x[14], MD4_S34); /* 40 */
MD4_HH (a, b, c, d, x[ 1], MD4_S31); /* 41 */
MD4_HH (d, a, b, c, x[ 9], MD4_S32); /* 42 */
MD4_HH (c, d, a, b, x[ 5], MD4_S33); /* 43 */
MD4_HH (b, c, d, a, x[13], MD4_S34); /* 44 */
MD4_HH (a, b, c, d, x[ 3], MD4_S31); /* 45 */
MD4_HH (d, a, b, c, x[11], MD4_S32); /* 46 */
MD4_HH (c, d, a, b, x[ 7], MD4_S33); /* 47 */
MD4_HH (b, c, d, a, x[15], MD4_S34); /* 48 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
T_memset (x, 0, sizeof (x));
}
/* MD4 initialization. Begins an MD4 operation, writing a new context.
*/
void MD4_Init (MD4CTX *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;
}
/* MD4 block update operation. Continues an MD4 message-digest
operation, processing another message block, and updating the
context.
*/
void MD4_Update (MD4CTX *context, const BYTE *input, UINT inputLen)
{
UINT i, index, partLen;
/* Compute number of bytes mod 64
*/
index = (UINT)((context->count[0] >> 3) & 0x3F);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -