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