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