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