|
|
1.1 ! root 1: /* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm ! 2: */ ! 3: ! 4: /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All ! 5: rights reserved. ! 6: ! 7: License to copy and use this software is granted for ! 8: non-commercial Internet Privacy-Enhanced Mail provided that it is ! 9: identified as the "RSA Data Security, Inc. MD2 Message Digest ! 10: Algorithm" in all material mentioning or referencing this software ! 11: or this function. ! 12: ! 13: RSA Data Security, Inc. makes no representations concerning either ! 14: the merchantability of this software or the suitability of this ! 15: software for any particular purpose. It is provided "as is" ! 16: without express or implied warranty of any kind. ! 17: ! 18: These notices must be retained in any copies of any part of this ! 19: documentation and/or software. ! 20: */ ! 21: ! 22: #include "global.h" ! 23: #include "md2.h" ! 24: ! 25: static void MD2Transform PROTO_LIST ! 26: ((unsigned char [16], unsigned char [16], unsigned char [16])); ! 27: static void MD2_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); ! 28: static void MD2_memset PROTO_LIST ((POINTER, int, unsigned int)); ! 29: ! 30: /* Permutation of 0..255 constructed from the digits of pi. It gives a ! 31: "random" nonlinear byte substitution operation. ! 32: */ ! 33: static unsigned char PI_SUBST[256] = { ! 34: 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, ! 35: 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, ! 36: 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, ! 37: 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, ! 38: 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, ! 39: 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, ! 40: 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, ! 41: 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, ! 42: 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, ! 43: 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, ! 44: 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, ! 45: 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, ! 46: 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, ! 47: 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, ! 48: 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, ! 49: 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, ! 50: 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, ! 51: 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 ! 52: }; ! 53: ! 54: static unsigned char *PADDING[] = { ! 55: (unsigned char *)"", ! 56: (unsigned char *)"\001", ! 57: (unsigned char *)"\002\002", ! 58: (unsigned char *)"\003\003\003", ! 59: (unsigned char *)"\004\004\004\004", ! 60: (unsigned char *)"\005\005\005\005\005", ! 61: (unsigned char *)"\006\006\006\006\006\006", ! 62: (unsigned char *)"\007\007\007\007\007\007\007", ! 63: (unsigned char *)"\010\010\010\010\010\010\010\010", ! 64: (unsigned char *)"\011\011\011\011\011\011\011\011\011", ! 65: (unsigned char *)"\012\012\012\012\012\012\012\012\012\012", ! 66: (unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013", ! 67: (unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014", ! 68: (unsigned char *) ! 69: "\015\015\015\015\015\015\015\015\015\015\015\015\015", ! 70: (unsigned char *) ! 71: "\016\016\016\016\016\016\016\016\016\016\016\016\016\016", ! 72: (unsigned char *) ! 73: "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017", ! 74: (unsigned char *) ! 75: "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020" ! 76: }; ! 77: ! 78: /* MD2 initialization. Begins an MD2 operation, writing a new context. ! 79: */ ! 80: void MD2Init (context) ! 81: MD2_CTX *context; /* context */ ! 82: { ! 83: context->count = 0; ! 84: MD2_memset ((POINTER)context->state, 0, sizeof (context->state)); ! 85: MD2_memset ! 86: ((POINTER)context->checksum, 0, sizeof (context->checksum)); ! 87: } ! 88: ! 89: /* MD2 block update operation. Continues an MD2 message-digest ! 90: operation, processing another message block, and updating the ! 91: context. ! 92: */ ! 93: void MD2Update (context, input, inputLen) ! 94: MD2_CTX *context; /* context */ ! 95: unsigned char *input; /* input block */ ! 96: unsigned int inputLen; /* length of input block */ ! 97: { ! 98: unsigned int i, index, partLen; ! 99: ! 100: /* Update number of bytes mod 16 */ ! 101: index = context->count; ! 102: context->count = (index + inputLen) & 0xf; ! 103: ! 104: partLen = 16 - index; ! 105: ! 106: /* Transform as many times as possible. ! 107: */ ! 108: if (inputLen >= partLen) { ! 109: MD2_memcpy ! 110: ((POINTER)&context->buffer[index], (POINTER)input, partLen); ! 111: MD2Transform (context->state, context->checksum, context->buffer); ! 112: ! 113: for (i = partLen; i + 15 < inputLen; i += 16) ! 114: MD2Transform (context->state, context->checksum, &input[i]); ! 115: ! 116: index = 0; ! 117: } ! 118: else ! 119: i = 0; ! 120: ! 121: /* Buffer remaining input */ ! 122: MD2_memcpy ! 123: ((POINTER)&context->buffer[index], (POINTER)&input[i], ! 124: inputLen-i); ! 125: } ! 126: ! 127: /* MD2 finalization. Ends an MD2 message-digest operation, writing the ! 128: message digest and zeroizing the context. ! 129: */ ! 130: void MD2Final (digest, context) ! 131: unsigned char digest[16]; /* message digest */ ! 132: MD2_CTX *context; /* context */ ! 133: { ! 134: unsigned int index, padLen; ! 135: ! 136: /* Pad out to multiple of 16. ! 137: */ ! 138: index = context->count; ! 139: padLen = 16 - index; ! 140: MD2Update (context, PADDING[padLen], padLen); ! 141: ! 142: /* Extend with checksum */ ! 143: MD2Update (context, context->checksum, 16); ! 144: ! 145: /* Store state in digest */ ! 146: MD2_memcpy ((POINTER)digest, (POINTER)context->state, 16); ! 147: ! 148: /* Zeroize sensitive information. ! 149: */ ! 150: MD2_memset ((POINTER)context, 0, sizeof (*context)); ! 151: } ! 152: ! 153: /* MD2 basic transformation. Transforms state and updates checksum ! 154: based on block. ! 155: */ ! 156: static void MD2Transform (state, checksum, block) ! 157: unsigned char state[16]; ! 158: unsigned char checksum[16]; ! 159: unsigned char block[16]; ! 160: { ! 161: unsigned int i, j, t; ! 162: unsigned char x[48]; ! 163: ! 164: /* Form encryption block from state, block, state ^ block. ! 165: */ ! 166: MD2_memcpy ((POINTER)x, (POINTER)state, 16); ! 167: MD2_memcpy ((POINTER)x+16, (POINTER)block, 16); ! 168: for (i = 0; i < 16; i++) ! 169: x[i+32] = state[i] ^ block[i]; ! 170: ! 171: /* Encrypt block (18 rounds). ! 172: */ ! 173: t = 0; ! 174: for (i = 0; i < 18; i++) { ! 175: for (j = 0; j < 48; j++) ! 176: t = x[j] ^= PI_SUBST[t]; ! 177: t = (t + i) & 0xff; ! 178: } ! 179: ! 180: /* Save new state */ ! 181: MD2_memcpy ((POINTER)state, (POINTER)x, 16); ! 182: ! 183: /* Update checksum. ! 184: */ ! 185: t = checksum[15]; ! 186: for (i = 0; i < 16; i++) ! 187: t = checksum[i] ^= PI_SUBST[block[i] ^ t]; ! 188: ! 189: /* Zeroize sensitive information. ! 190: */ ! 191: MD2_memset ((POINTER)x, 0, sizeof (x)); ! 192: } ! 193: ! 194: /* Note: Replace "for loop" with standard memcpy if possible. ! 195: */ ! 196: static void MD2_memcpy (output, input, len) ! 197: POINTER output; ! 198: POINTER input; ! 199: unsigned int len; ! 200: { ! 201: unsigned int i; ! 202: ! 203: for (i = 0; i < len; i++) ! 204: output[i] = input[i]; ! 205: } ! 206: ! 207: /* Note: Replace "for loop" with standard memset if possible. ! 208: */ ! 209: static void MD2_memset (output, value, len) ! 210: POINTER output; ! 211: int value; ! 212: unsigned int len; ! 213: { ! 214: unsigned int i; ! 215: ! 216: for (i = 0; i < len; i++) ! 217: ((char *)output)[i] = (char)value; ! 218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.