1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251876Speter * contributor license agreements. See the NOTICE file distributed with 3251876Speter * this work for additional information regarding copyright ownership. 4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251876Speter * (the "License"); you may not use this file except in compliance with 6251876Speter * the License. You may obtain a copy of the License at 7251876Speter * 8251876Speter * http://www.apache.org/licenses/LICENSE-2.0 9251876Speter * 10251876Speter * Unless required by applicable law or agreed to in writing, software 11251876Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251876Speter * See the License for the specific language governing permissions and 14251876Speter * limitations under the License. 15251876Speter * 16251876Speter * This is derived from material copyright RSA Data Security, Inc. 17251876Speter * Their notice is reproduced below in its entirety. 18251876Speter * 19251876Speter * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 20251876Speter * rights reserved. 21251876Speter * 22251876Speter * License to copy and use this software is granted provided that it 23251876Speter * is identified as the "RSA Data Security, Inc. MD4 Message-Digest 24251876Speter * Algorithm" in all material mentioning or referencing this software 25251876Speter * or this function. 26251876Speter * 27251876Speter * License is also granted to make and use derivative works provided 28251876Speter * that such works are identified as "derived from the RSA Data 29251876Speter * Security, Inc. MD4 Message-Digest Algorithm" in all material 30251876Speter * mentioning or referencing the derived work. 31251876Speter * 32251876Speter * RSA Data Security, Inc. makes no representations concerning either 33251876Speter * the merchantability of this software or the suitability of this 34251876Speter * software for any particular purpose. It is provided "as is" 35251876Speter * without express or implied warranty of any kind. 36251876Speter * 37251876Speter * These notices must be retained in any copies of any part of this 38251876Speter * documentation and/or software. 39251876Speter */ 40251876Speter 41251876Speter#include "apr_strings.h" 42251876Speter#include "apr_md4.h" 43251876Speter#include "apr_lib.h" 44251876Speter 45251876Speter#if APR_HAVE_STRING_H 46251876Speter#include <string.h> 47251876Speter#endif 48251876Speter#if APR_HAVE_UNISTD_H 49251876Speter#include <unistd.h> 50251876Speter#endif 51251876Speter 52251876Speter/* Constants for MD4Transform routine. 53251876Speter */ 54251876Speter 55251876Speter#define S11 3 56251876Speter#define S12 7 57251876Speter#define S13 11 58251876Speter#define S14 19 59251876Speter#define S21 3 60251876Speter#define S22 5 61251876Speter#define S23 9 62251876Speter#define S24 13 63251876Speter#define S31 3 64251876Speter#define S32 9 65251876Speter#define S33 11 66251876Speter#define S34 15 67251876Speter 68251876Speterstatic void MD4Transform(apr_uint32_t state[4], const unsigned char block[64]); 69251876Speterstatic void Encode(unsigned char *output, const apr_uint32_t *input, 70251876Speter unsigned int len); 71251876Speterstatic void Decode(apr_uint32_t *output, const unsigned char *input, 72251876Speter unsigned int len); 73251876Speter 74251876Speterstatic unsigned char PADDING[64] = 75251876Speter{ 76251876Speter 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77251876Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78251876Speter 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 79251876Speter}; 80251876Speter 81251876Speter#if APR_CHARSET_EBCDIC 82251876Speterstatic apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md4_encode() */ 83251876Speter#endif 84251876Speter 85251876Speter/* F, G and I are basic MD4 functions. 86251876Speter */ 87251876Speter#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 88251876Speter#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 89251876Speter#define H(x, y, z) ((x) ^ (y) ^ (z)) 90251876Speter 91251876Speter/* ROTATE_LEFT rotates x left n bits. 92251876Speter */ 93251876Speter#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 94251876Speter 95251876Speter/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ 96251876Speter/* Rotation is separate from addition to prevent recomputation */ 97251876Speter 98251876Speter#define FF(a, b, c, d, x, s) { \ 99251876Speter (a) += F ((b), (c), (d)) + (x); \ 100251876Speter (a) = ROTATE_LEFT ((a), (s)); \ 101251876Speter } 102251876Speter#define GG(a, b, c, d, x, s) { \ 103251876Speter (a) += G ((b), (c), (d)) + (x) + (apr_uint32_t)0x5a827999; \ 104251876Speter (a) = ROTATE_LEFT ((a), (s)); \ 105251876Speter } 106251876Speter#define HH(a, b, c, d, x, s) { \ 107251876Speter (a) += H ((b), (c), (d)) + (x) + (apr_uint32_t)0x6ed9eba1; \ 108251876Speter (a) = ROTATE_LEFT ((a), (s)); \ 109251876Speter } 110251876Speter 111251876Speter/* MD4 initialization. Begins an MD4 operation, writing a new context. 112251876Speter */ 113251876SpeterAPU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context) 114251876Speter{ 115251876Speter context->count[0] = context->count[1] = 0; 116251876Speter 117251876Speter /* Load magic initialization constants. */ 118251876Speter context->state[0] = 0x67452301; 119251876Speter context->state[1] = 0xefcdab89; 120251876Speter context->state[2] = 0x98badcfe; 121251876Speter context->state[3] = 0x10325476; 122251876Speter 123251876Speter#if APR_HAS_XLATE 124251876Speter context->xlate = NULL; 125251876Speter#endif 126251876Speter 127251876Speter return APR_SUCCESS; 128251876Speter} 129251876Speter 130251876Speter#if APR_HAS_XLATE 131251876Speter/* MD4 translation setup. Provides the APR translation handle 132251876Speter * to be used for translating the content before calculating the 133251876Speter * digest. 134251876Speter */ 135251876SpeterAPU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context, 136251876Speter apr_xlate_t *xlate) 137251876Speter{ 138251876Speter apr_status_t rv; 139251876Speter int is_sb; 140251876Speter 141251876Speter /* TODO: remove the single-byte-only restriction from this code 142251876Speter */ 143251876Speter rv = apr_xlate_sb_get(xlate, &is_sb); 144251876Speter if (rv != APR_SUCCESS) { 145251876Speter return rv; 146251876Speter } 147251876Speter if (!is_sb) { 148251876Speter return APR_EINVAL; 149251876Speter } 150251876Speter context->xlate = xlate; 151251876Speter return APR_SUCCESS; 152251876Speter} 153251876Speter#endif /* APR_HAS_XLATE */ 154251876Speter 155251876Speter/* MD4 block update operation. Continues an MD4 message-digest 156251876Speter * operation, processing another message block, and updating the 157251876Speter * context. 158251876Speter */ 159251876SpeterAPU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context, 160251876Speter const unsigned char *input, 161251876Speter apr_size_t inputLen) 162251876Speter{ 163251876Speter unsigned int i, idx, partLen; 164251876Speter#if APR_HAS_XLATE 165251876Speter apr_size_t inbytes_left, outbytes_left; 166251876Speter#endif 167251876Speter 168251876Speter /* Compute number of bytes mod 64 */ 169251876Speter idx = (unsigned int)((context->count[0] >> 3) & 0x3F); 170251876Speter 171251876Speter /* Update number of bits */ 172251876Speter if ((context->count[0] += ((apr_uint32_t)inputLen << 3)) 173251876Speter < ((apr_uint32_t)inputLen << 3)) 174251876Speter context->count[1]++; 175251876Speter context->count[1] += (apr_uint32_t)inputLen >> 29; 176251876Speter 177251876Speter partLen = 64 - idx; 178251876Speter 179251876Speter /* Transform as many times as possible. */ 180251876Speter#if !APR_HAS_XLATE 181251876Speter if (inputLen >= partLen) { 182251876Speter memcpy(&context->buffer[idx], input, partLen); 183251876Speter MD4Transform(context->state, context->buffer); 184251876Speter 185251876Speter for (i = partLen; i + 63 < inputLen; i += 64) 186251876Speter MD4Transform(context->state, &input[i]); 187251876Speter 188251876Speter idx = 0; 189251876Speter } 190251876Speter else 191251876Speter i = 0; 192251876Speter 193251876Speter /* Buffer remaining input */ 194251876Speter memcpy(&context->buffer[idx], &input[i], inputLen - i); 195251876Speter#else /*APR_HAS_XLATE*/ 196251876Speter if (inputLen >= partLen) { 197251876Speter if (context->xlate) { 198251876Speter inbytes_left = outbytes_left = partLen; 199251876Speter apr_xlate_conv_buffer(context->xlate, (const char *)input, 200251876Speter &inbytes_left, 201251876Speter (char *)&context->buffer[idx], 202251876Speter &outbytes_left); 203251876Speter } 204251876Speter else { 205251876Speter memcpy(&context->buffer[idx], input, partLen); 206251876Speter } 207251876Speter MD4Transform(context->state, context->buffer); 208251876Speter 209251876Speter for (i = partLen; i + 63 < inputLen; i += 64) { 210251876Speter if (context->xlate) { 211251876Speter unsigned char inp_tmp[64]; 212251876Speter inbytes_left = outbytes_left = 64; 213251876Speter apr_xlate_conv_buffer(context->xlate, (const char *)&input[i], 214251876Speter &inbytes_left, 215251876Speter (char *)inp_tmp, &outbytes_left); 216251876Speter MD4Transform(context->state, inp_tmp); 217251876Speter } 218251876Speter else { 219251876Speter MD4Transform(context->state, &input[i]); 220251876Speter } 221251876Speter } 222251876Speter 223251876Speter idx = 0; 224251876Speter } 225251876Speter else 226251876Speter i = 0; 227251876Speter 228251876Speter /* Buffer remaining input */ 229251876Speter if (context->xlate) { 230251876Speter inbytes_left = outbytes_left = inputLen - i; 231251876Speter apr_xlate_conv_buffer(context->xlate, (const char *)&input[i], 232251876Speter &inbytes_left, (char *)&context->buffer[idx], 233251876Speter &outbytes_left); 234251876Speter } 235251876Speter else { 236251876Speter memcpy(&context->buffer[idx], &input[i], inputLen - i); 237251876Speter } 238251876Speter#endif /*APR_HAS_XLATE*/ 239251876Speter return APR_SUCCESS; 240251876Speter} 241251876Speter 242251876Speter/* MD4 finalization. Ends an MD4 message-digest operation, writing the 243251876Speter * the message digest and zeroizing the context. 244251876Speter */ 245251876SpeterAPU_DECLARE(apr_status_t) apr_md4_final( 246251876Speter unsigned char digest[APR_MD4_DIGESTSIZE], 247251876Speter apr_md4_ctx_t *context) 248251876Speter{ 249251876Speter unsigned char bits[8]; 250251876Speter unsigned int idx, padLen; 251251876Speter 252251876Speter /* Save number of bits */ 253251876Speter Encode(bits, context->count, 8); 254251876Speter 255251876Speter#if APR_HAS_XLATE 256251876Speter /* apr_md4_update() should not translate for this final round. */ 257251876Speter context->xlate = NULL; 258251876Speter#endif /*APR_HAS_XLATE*/ 259251876Speter 260251876Speter /* Pad out to 56 mod 64. */ 261251876Speter idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); 262251876Speter padLen = (idx < 56) ? (56 - idx) : (120 - idx); 263251876Speter apr_md4_update(context, PADDING, padLen); 264251876Speter 265251876Speter /* Append length (before padding) */ 266251876Speter apr_md4_update(context, bits, 8); 267251876Speter 268251876Speter /* Store state in digest */ 269251876Speter Encode(digest, context->state, APR_MD4_DIGESTSIZE); 270251876Speter 271251876Speter /* Zeroize sensitive information. */ 272251876Speter memset(context, 0, sizeof(*context)); 273251876Speter 274251876Speter return APR_SUCCESS; 275251876Speter} 276251876Speter 277251876Speter/* MD4 computation in one step (init, update, final) 278251876Speter */ 279251876SpeterAPU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE], 280251876Speter const unsigned char *input, 281251876Speter apr_size_t inputLen) 282251876Speter{ 283251876Speter apr_md4_ctx_t ctx; 284251876Speter apr_status_t rv; 285251876Speter 286251876Speter apr_md4_init(&ctx); 287251876Speter 288251876Speter if ((rv = apr_md4_update(&ctx, input, inputLen)) != APR_SUCCESS) 289251876Speter return rv; 290251876Speter 291251876Speter return apr_md4_final(digest, &ctx); 292251876Speter} 293251876Speter 294251876Speter/* MD4 basic transformation. Transforms state based on block. */ 295251876Speterstatic void MD4Transform(apr_uint32_t state[4], const unsigned char block[64]) 296251876Speter{ 297251876Speter apr_uint32_t a = state[0], b = state[1], c = state[2], d = state[3], 298251876Speter x[APR_MD4_DIGESTSIZE]; 299251876Speter 300251876Speter Decode(x, block, 64); 301251876Speter 302251876Speter /* Round 1 */ 303251876Speter FF (a, b, c, d, x[ 0], S11); /* 1 */ 304251876Speter FF (d, a, b, c, x[ 1], S12); /* 2 */ 305251876Speter FF (c, d, a, b, x[ 2], S13); /* 3 */ 306251876Speter FF (b, c, d, a, x[ 3], S14); /* 4 */ 307251876Speter FF (a, b, c, d, x[ 4], S11); /* 5 */ 308251876Speter FF (d, a, b, c, x[ 5], S12); /* 6 */ 309251876Speter FF (c, d, a, b, x[ 6], S13); /* 7 */ 310251876Speter FF (b, c, d, a, x[ 7], S14); /* 8 */ 311251876Speter FF (a, b, c, d, x[ 8], S11); /* 9 */ 312251876Speter FF (d, a, b, c, x[ 9], S12); /* 10 */ 313251876Speter FF (c, d, a, b, x[10], S13); /* 11 */ 314251876Speter FF (b, c, d, a, x[11], S14); /* 12 */ 315251876Speter FF (a, b, c, d, x[12], S11); /* 13 */ 316251876Speter FF (d, a, b, c, x[13], S12); /* 14 */ 317251876Speter FF (c, d, a, b, x[14], S13); /* 15 */ 318251876Speter FF (b, c, d, a, x[15], S14); /* 16 */ 319251876Speter 320251876Speter /* Round 2 */ 321251876Speter GG (a, b, c, d, x[ 0], S21); /* 17 */ 322251876Speter GG (d, a, b, c, x[ 4], S22); /* 18 */ 323251876Speter GG (c, d, a, b, x[ 8], S23); /* 19 */ 324251876Speter GG (b, c, d, a, x[12], S24); /* 20 */ 325251876Speter GG (a, b, c, d, x[ 1], S21); /* 21 */ 326251876Speter GG (d, a, b, c, x[ 5], S22); /* 22 */ 327251876Speter GG (c, d, a, b, x[ 9], S23); /* 23 */ 328251876Speter GG (b, c, d, a, x[13], S24); /* 24 */ 329251876Speter GG (a, b, c, d, x[ 2], S21); /* 25 */ 330251876Speter GG (d, a, b, c, x[ 6], S22); /* 26 */ 331251876Speter GG (c, d, a, b, x[10], S23); /* 27 */ 332251876Speter GG (b, c, d, a, x[14], S24); /* 28 */ 333251876Speter GG (a, b, c, d, x[ 3], S21); /* 29 */ 334251876Speter GG (d, a, b, c, x[ 7], S22); /* 30 */ 335251876Speter GG (c, d, a, b, x[11], S23); /* 31 */ 336251876Speter GG (b, c, d, a, x[15], S24); /* 32 */ 337251876Speter 338251876Speter /* Round 3 */ 339251876Speter HH (a, b, c, d, x[ 0], S31); /* 33 */ 340251876Speter HH (d, a, b, c, x[ 8], S32); /* 34 */ 341251876Speter HH (c, d, a, b, x[ 4], S33); /* 35 */ 342251876Speter HH (b, c, d, a, x[12], S34); /* 36 */ 343251876Speter HH (a, b, c, d, x[ 2], S31); /* 37 */ 344251876Speter HH (d, a, b, c, x[10], S32); /* 38 */ 345251876Speter HH (c, d, a, b, x[ 6], S33); /* 39 */ 346251876Speter HH (b, c, d, a, x[14], S34); /* 40 */ 347251876Speter HH (a, b, c, d, x[ 1], S31); /* 41 */ 348251876Speter HH (d, a, b, c, x[ 9], S32); /* 42 */ 349251876Speter HH (c, d, a, b, x[ 5], S33); /* 43 */ 350251876Speter HH (b, c, d, a, x[13], S34); /* 44 */ 351251876Speter HH (a, b, c, d, x[ 3], S31); /* 45 */ 352251876Speter HH (d, a, b, c, x[11], S32); /* 46 */ 353251876Speter HH (c, d, a, b, x[ 7], S33); /* 47 */ 354251876Speter HH (b, c, d, a, x[15], S34); /* 48 */ 355251876Speter 356251876Speter state[0] += a; 357251876Speter state[1] += b; 358251876Speter state[2] += c; 359251876Speter state[3] += d; 360251876Speter 361251876Speter /* Zeroize sensitive information. */ 362251876Speter memset(x, 0, sizeof(x)); 363251876Speter} 364251876Speter 365251876Speter/* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is 366251876Speter * a multiple of 4. 367251876Speter */ 368251876Speterstatic void Encode(unsigned char *output, const apr_uint32_t *input, 369251876Speter unsigned int len) 370251876Speter{ 371251876Speter unsigned int i, j; 372251876Speter apr_uint32_t k; 373251876Speter 374251876Speter for (i = 0, j = 0; j < len; i++, j += 4) { 375251876Speter k = input[i]; 376251876Speter output[j] = (unsigned char)(k & 0xff); 377251876Speter output[j + 1] = (unsigned char)((k >> 8) & 0xff); 378251876Speter output[j + 2] = (unsigned char)((k >> 16) & 0xff); 379251876Speter output[j + 3] = (unsigned char)((k >> 24) & 0xff); 380251876Speter } 381251876Speter} 382251876Speter 383251876Speter/* Decodes input (unsigned char) into output (apr_uint32_t). Assumes len is 384251876Speter * a multiple of 4. 385251876Speter */ 386251876Speterstatic void Decode(apr_uint32_t *output, const unsigned char *input, 387251876Speter unsigned int len) 388251876Speter{ 389251876Speter unsigned int i, j; 390251876Speter 391251876Speter for (i = 0, j = 0; j < len; i++, j += 4) 392251876Speter output[i] = ((apr_uint32_t)input[j]) | 393251876Speter (((apr_uint32_t)input[j + 1]) << 8) | 394251876Speter (((apr_uint32_t)input[j + 2]) << 16) | 395251876Speter (((apr_uint32_t)input[j + 3]) << 24); 396251876Speter} 397251876Speter 398251876Speter#if APR_CHARSET_EBCDIC 399251876SpeterAPU_DECLARE(apr_status_t) apr_MD4InitEBCDIC(apr_xlate_t *xlate) 400251876Speter{ 401251876Speter xlate_ebcdic_to_ascii = xlate; 402251876Speter return APR_SUCCESS; 403251876Speter} 404251876Speter#endif 405