md2c.c revision 50476
1/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm 2 * $FreeBSD: head/lib/libmd/md2c.c 50476 1999-08-28 00:22:10Z peter $ 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 padding. 135 */ 136void MD2Pad (context) 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 151/* MD2 finalization. Ends an MD2 message-digest operation, writing the 152 message digest and zeroizing the context. 153 */ 154void MD2Final (digest, context) 155unsigned char digest[16]; /* message digest */ 156MD2_CTX *context; /* context */ 157{ 158 /* Do padding */ 159 MD2Pad (context); 160 161 /* Store state in digest */ 162 memcpy ((POINTER)digest, (POINTER)context->state, 16); 163 164 /* Zeroize sensitive information. 165 */ 166 memset ((POINTER)context, 0, sizeof (*context)); 167} 168 169/* MD2 basic transformation. Transforms state and updates checksum 170 based on block. 171 */ 172static void MD2Transform (state, checksum, block) 173unsigned char state[16]; 174unsigned char checksum[16]; 175const unsigned char block[16]; 176{ 177 unsigned int i, j, t; 178 unsigned char x[48]; 179 180 /* Form encryption block from state, block, state ^ block. 181 */ 182 memcpy ((POINTER)x, (POINTER)state, 16); 183 memcpy ((POINTER)x+16, (POINTER)block, 16); 184 for (i = 0; i < 16; i++) 185 x[i+32] = state[i] ^ block[i]; 186 187 /* Encrypt block (18 rounds). 188 */ 189 t = 0; 190 for (i = 0; i < 18; i++) { 191 for (j = 0; j < 48; j++) 192 t = x[j] ^= PI_SUBST[t]; 193 t = (t + i) & 0xff; 194 } 195 196 /* Save new state */ 197 memcpy ((POINTER)state, (POINTER)x, 16); 198 199 /* Update checksum. 200 */ 201 t = checksum[15]; 202 for (i = 0; i < 16; i++) 203 t = checksum[i] ^= PI_SUBST[block[i] ^ t]; 204 205 /* Zeroize sensitive information. 206 */ 207 memset ((POINTER)x, 0, sizeof (x)); 208} 209