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