1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * This is derived from material copyright RSA Data Security, Inc. 17 * Their notice is reproduced below in its entirety. 18 * 19 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 20 * rights reserved. 21 * 22 * License to copy and use this software is granted provided that it 23 * is identified as the "RSA Data Security, Inc. MD4 Message-Digest 24 * Algorithm" in all material mentioning or referencing this software 25 * or this function. 26 * 27 * License is also granted to make and use derivative works provided 28 * that such works are identified as "derived from the RSA Data 29 * Security, Inc. MD4 Message-Digest Algorithm" in all material 30 * mentioning or referencing the derived work. 31 * 32 * RSA Data Security, Inc. makes no representations concerning either 33 * the merchantability of this software or the suitability of this 34 * software for any particular purpose. It is provided "as is" 35 * without express or implied warranty of any kind. 36 * 37 * These notices must be retained in any copies of any part of this 38 * documentation and/or software. 39 */ 40 41#include "apr_strings.h" 42#include "apr_md4.h" 43#include "apr_lib.h" 44 45#if APR_HAVE_STRING_H 46#include <string.h> 47#endif 48#if APR_HAVE_UNISTD_H 49#include <unistd.h> 50#endif 51 52/* Constants for MD4Transform routine. 53 */ 54 55#define S11 3 56#define S12 7 57#define S13 11 58#define S14 19 59#define S21 3 60#define S22 5 61#define S23 9 62#define S24 13 63#define S31 3 64#define S32 9 65#define S33 11 66#define S34 15 67 68static void MD4Transform(apr_uint32_t state[4], const unsigned char block[64]); 69static void Encode(unsigned char *output, const apr_uint32_t *input, 70 unsigned int len); 71static void Decode(apr_uint32_t *output, const unsigned char *input, 72 unsigned int len); 73 74static unsigned char PADDING[64] = 75{ 76 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 79}; 80 81#if APR_CHARSET_EBCDIC 82static apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md4_encode() */ 83#endif 84 85/* F, G and I are basic MD4 functions. 86 */ 87#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 88#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 89#define H(x, y, z) ((x) ^ (y) ^ (z)) 90 91/* ROTATE_LEFT rotates x left n bits. 92 */ 93#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 94 95/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ 96/* Rotation is separate from addition to prevent recomputation */ 97 98#define FF(a, b, c, d, x, s) { \ 99 (a) += F ((b), (c), (d)) + (x); \ 100 (a) = ROTATE_LEFT ((a), (s)); \ 101 } 102#define GG(a, b, c, d, x, s) { \ 103 (a) += G ((b), (c), (d)) + (x) + (apr_uint32_t)0x5a827999; \ 104 (a) = ROTATE_LEFT ((a), (s)); \ 105 } 106#define HH(a, b, c, d, x, s) { \ 107 (a) += H ((b), (c), (d)) + (x) + (apr_uint32_t)0x6ed9eba1; \ 108 (a) = ROTATE_LEFT ((a), (s)); \ 109 } 110 111/* MD4 initialization. Begins an MD4 operation, writing a new context. 112 */ 113APU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context) 114{ 115 context->count[0] = context->count[1] = 0; 116 117 /* Load magic initialization constants. */ 118 context->state[0] = 0x67452301; 119 context->state[1] = 0xefcdab89; 120 context->state[2] = 0x98badcfe; 121 context->state[3] = 0x10325476; 122 123#if APR_HAS_XLATE 124 context->xlate = NULL; 125#endif 126 127 return APR_SUCCESS; 128} 129 130#if APR_HAS_XLATE 131/* MD4 translation setup. Provides the APR translation handle 132 * to be used for translating the content before calculating the 133 * digest. 134 */ 135APU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context, 136 apr_xlate_t *xlate) 137{ 138 apr_status_t rv; 139 int is_sb; 140 141 /* TODO: remove the single-byte-only restriction from this code 142 */ 143 rv = apr_xlate_sb_get(xlate, &is_sb); 144 if (rv != APR_SUCCESS) { 145 return rv; 146 } 147 if (!is_sb) { 148 return APR_EINVAL; 149 } 150 context->xlate = xlate; 151 return APR_SUCCESS; 152} 153#endif /* APR_HAS_XLATE */ 154 155/* MD4 block update operation. Continues an MD4 message-digest 156 * operation, processing another message block, and updating the 157 * context. 158 */ 159APU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context, 160 const unsigned char *input, 161 apr_size_t inputLen) 162{ 163 unsigned int i, idx, partLen; 164#if APR_HAS_XLATE 165 apr_size_t inbytes_left, outbytes_left; 166#endif 167 168 /* Compute number of bytes mod 64 */ 169 idx = (unsigned int)((context->count[0] >> 3) & 0x3F); 170 171 /* Update number of bits */ 172 if ((context->count[0] += ((apr_uint32_t)inputLen << 3)) 173 < ((apr_uint32_t)inputLen << 3)) 174 context->count[1]++; 175 context->count[1] += (apr_uint32_t)inputLen >> 29; 176 177 partLen = 64 - idx; 178 179 /* Transform as many times as possible. */ 180#if !APR_HAS_XLATE 181 if (inputLen >= partLen) { 182 memcpy(&context->buffer[idx], input, partLen); 183 MD4Transform(context->state, context->buffer); 184 185 for (i = partLen; i + 63 < inputLen; i += 64) 186 MD4Transform(context->state, &input[i]); 187 188 idx = 0; 189 } 190 else 191 i = 0; 192 193 /* Buffer remaining input */ 194 memcpy(&context->buffer[idx], &input[i], inputLen - i); 195#else /*APR_HAS_XLATE*/ 196 if (inputLen >= partLen) { 197 if (context->xlate) { 198 inbytes_left = outbytes_left = partLen; 199 apr_xlate_conv_buffer(context->xlate, (const char *)input, 200 &inbytes_left, 201 (char *)&context->buffer[idx], 202 &outbytes_left); 203 } 204 else { 205 memcpy(&context->buffer[idx], input, partLen); 206 } 207 MD4Transform(context->state, context->buffer); 208 209 for (i = partLen; i + 63 < inputLen; i += 64) { 210 if (context->xlate) { 211 unsigned char inp_tmp[64]; 212 inbytes_left = outbytes_left = 64; 213 apr_xlate_conv_buffer(context->xlate, (const char *)&input[i], 214 &inbytes_left, 215 (char *)inp_tmp, &outbytes_left); 216 MD4Transform(context->state, inp_tmp); 217 } 218 else { 219 MD4Transform(context->state, &input[i]); 220 } 221 } 222 223 idx = 0; 224 } 225 else 226 i = 0; 227 228 /* Buffer remaining input */ 229 if (context->xlate) { 230 inbytes_left = outbytes_left = inputLen - i; 231 apr_xlate_conv_buffer(context->xlate, (const char *)&input[i], 232 &inbytes_left, (char *)&context->buffer[idx], 233 &outbytes_left); 234 } 235 else { 236 memcpy(&context->buffer[idx], &input[i], inputLen - i); 237 } 238#endif /*APR_HAS_XLATE*/ 239 return APR_SUCCESS; 240} 241 242/* MD4 finalization. Ends an MD4 message-digest operation, writing the 243 * the message digest and zeroizing the context. 244 */ 245APU_DECLARE(apr_status_t) apr_md4_final( 246 unsigned char digest[APR_MD4_DIGESTSIZE], 247 apr_md4_ctx_t *context) 248{ 249 unsigned char bits[8]; 250 unsigned int idx, padLen; 251 252 /* Save number of bits */ 253 Encode(bits, context->count, 8); 254 255#if APR_HAS_XLATE 256 /* apr_md4_update() should not translate for this final round. */ 257 context->xlate = NULL; 258#endif /*APR_HAS_XLATE*/ 259 260 /* Pad out to 56 mod 64. */ 261 idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); 262 padLen = (idx < 56) ? (56 - idx) : (120 - idx); 263 apr_md4_update(context, PADDING, padLen); 264 265 /* Append length (before padding) */ 266 apr_md4_update(context, bits, 8); 267 268 /* Store state in digest */ 269 Encode(digest, context->state, APR_MD4_DIGESTSIZE); 270 271 /* Zeroize sensitive information. */ 272 memset(context, 0, sizeof(*context)); 273 274 return APR_SUCCESS; 275} 276 277/* MD4 computation in one step (init, update, final) 278 */ 279APU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE], 280 const unsigned char *input, 281 apr_size_t inputLen) 282{ 283 apr_md4_ctx_t ctx; 284 apr_status_t rv; 285 286 apr_md4_init(&ctx); 287 288 if ((rv = apr_md4_update(&ctx, input, inputLen)) != APR_SUCCESS) 289 return rv; 290 291 return apr_md4_final(digest, &ctx); 292} 293 294/* MD4 basic transformation. Transforms state based on block. */ 295static void MD4Transform(apr_uint32_t state[4], const unsigned char block[64]) 296{ 297 apr_uint32_t a = state[0], b = state[1], c = state[2], d = state[3], 298 x[APR_MD4_DIGESTSIZE]; 299 300 Decode(x, block, 64); 301 302 /* Round 1 */ 303 FF (a, b, c, d, x[ 0], S11); /* 1 */ 304 FF (d, a, b, c, x[ 1], S12); /* 2 */ 305 FF (c, d, a, b, x[ 2], S13); /* 3 */ 306 FF (b, c, d, a, x[ 3], S14); /* 4 */ 307 FF (a, b, c, d, x[ 4], S11); /* 5 */ 308 FF (d, a, b, c, x[ 5], S12); /* 6 */ 309 FF (c, d, a, b, x[ 6], S13); /* 7 */ 310 FF (b, c, d, a, x[ 7], S14); /* 8 */ 311 FF (a, b, c, d, x[ 8], S11); /* 9 */ 312 FF (d, a, b, c, x[ 9], S12); /* 10 */ 313 FF (c, d, a, b, x[10], S13); /* 11 */ 314 FF (b, c, d, a, x[11], S14); /* 12 */ 315 FF (a, b, c, d, x[12], S11); /* 13 */ 316 FF (d, a, b, c, x[13], S12); /* 14 */ 317 FF (c, d, a, b, x[14], S13); /* 15 */ 318 FF (b, c, d, a, x[15], S14); /* 16 */ 319 320 /* Round 2 */ 321 GG (a, b, c, d, x[ 0], S21); /* 17 */ 322 GG (d, a, b, c, x[ 4], S22); /* 18 */ 323 GG (c, d, a, b, x[ 8], S23); /* 19 */ 324 GG (b, c, d, a, x[12], S24); /* 20 */ 325 GG (a, b, c, d, x[ 1], S21); /* 21 */ 326 GG (d, a, b, c, x[ 5], S22); /* 22 */ 327 GG (c, d, a, b, x[ 9], S23); /* 23 */ 328 GG (b, c, d, a, x[13], S24); /* 24 */ 329 GG (a, b, c, d, x[ 2], S21); /* 25 */ 330 GG (d, a, b, c, x[ 6], S22); /* 26 */ 331 GG (c, d, a, b, x[10], S23); /* 27 */ 332 GG (b, c, d, a, x[14], S24); /* 28 */ 333 GG (a, b, c, d, x[ 3], S21); /* 29 */ 334 GG (d, a, b, c, x[ 7], S22); /* 30 */ 335 GG (c, d, a, b, x[11], S23); /* 31 */ 336 GG (b, c, d, a, x[15], S24); /* 32 */ 337 338 /* Round 3 */ 339 HH (a, b, c, d, x[ 0], S31); /* 33 */ 340 HH (d, a, b, c, x[ 8], S32); /* 34 */ 341 HH (c, d, a, b, x[ 4], S33); /* 35 */ 342 HH (b, c, d, a, x[12], S34); /* 36 */ 343 HH (a, b, c, d, x[ 2], S31); /* 37 */ 344 HH (d, a, b, c, x[10], S32); /* 38 */ 345 HH (c, d, a, b, x[ 6], S33); /* 39 */ 346 HH (b, c, d, a, x[14], S34); /* 40 */ 347 HH (a, b, c, d, x[ 1], S31); /* 41 */ 348 HH (d, a, b, c, x[ 9], S32); /* 42 */ 349 HH (c, d, a, b, x[ 5], S33); /* 43 */ 350 HH (b, c, d, a, x[13], S34); /* 44 */ 351 HH (a, b, c, d, x[ 3], S31); /* 45 */ 352 HH (d, a, b, c, x[11], S32); /* 46 */ 353 HH (c, d, a, b, x[ 7], S33); /* 47 */ 354 HH (b, c, d, a, x[15], S34); /* 48 */ 355 356 state[0] += a; 357 state[1] += b; 358 state[2] += c; 359 state[3] += d; 360 361 /* Zeroize sensitive information. */ 362 memset(x, 0, sizeof(x)); 363} 364 365/* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is 366 * a multiple of 4. 367 */ 368static void Encode(unsigned char *output, const apr_uint32_t *input, 369 unsigned int len) 370{ 371 unsigned int i, j; 372 apr_uint32_t k; 373 374 for (i = 0, j = 0; j < len; i++, j += 4) { 375 k = input[i]; 376 output[j] = (unsigned char)(k & 0xff); 377 output[j + 1] = (unsigned char)((k >> 8) & 0xff); 378 output[j + 2] = (unsigned char)((k >> 16) & 0xff); 379 output[j + 3] = (unsigned char)((k >> 24) & 0xff); 380 } 381} 382 383/* Decodes input (unsigned char) into output (apr_uint32_t). Assumes len is 384 * a multiple of 4. 385 */ 386static void Decode(apr_uint32_t *output, const unsigned char *input, 387 unsigned int len) 388{ 389 unsigned int i, j; 390 391 for (i = 0, j = 0; j < len; i++, j += 4) 392 output[i] = ((apr_uint32_t)input[j]) | 393 (((apr_uint32_t)input[j + 1]) << 8) | 394 (((apr_uint32_t)input[j + 2]) << 16) | 395 (((apr_uint32_t)input[j + 3]) << 24); 396} 397 398#if APR_CHARSET_EBCDIC 399APU_DECLARE(apr_status_t) apr_MD4InitEBCDIC(apr_xlate_t *xlate) 400{ 401 xlate_ebcdic_to_ascii = xlate; 402 return APR_SUCCESS; 403} 404#endif 405