View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.proxy.utils;
    21
    22  import java.security.DigestException;
    23  import java.security.MessageDigestSpi;
    24
    25  /**
    26   * MD4.java - An implementation of Ron Rivest's MD4 message digest algorithm.
    27   * The MD4 algorithm is designed to be quite fast on 32-bit machines. In
    28   * addition, the MD4 algorithm does not require any large substitution
    29   * tables.
    30   *
    31   * @see The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a> Message-
    32   *    Digest Algorithm by R. Rivest.
    33   *
    34   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    35   * @since MINA 2.0.0-M3
    36   */
    37  public class MD4 extends MessageDigestSpi {
    38
    39      /**
    40       * The MD4 algorithm message digest length is 16 bytes wide.
    41       */
    42      public static final int BYTE_DIGEST_LENGTH = 16;
    43
    44      /**
    45       * The MD4 algorithm block length is 64 bytes wide.
    46       */
    47      public static final int BYTE_BLOCK_LENGTH = 64;
    48
    49      /**
    50       * The initial values of the four registers. RFC gives the values
    51       * in LE so we converted it as JAVA uses BE endianness.
    52       */
    53      private final static int A = 0x67452301;
    54
    55      private final static int B = 0xefcdab89;
    56
    57      private final static int C = 0x98badcfe;
    58
    59      private final static int D = 0x10325476;
    60
    61      /**
    62       * The four registers initialized with the above IVs.
    63       */
    64      private int a = A;
    65
    66      private int b = B;
    67
    68      private int c = C;
    69
    70      private int d = D;
    71
    72      /**
    73       * Counts the total length of the data being digested.
    74       */
    75      private long msgLength;
    76
    77      /**
    78       * The internal buffer is {@link BLOCK_LENGTH} wide.
    79       */
    80      private final byte[] buffer = new byte[BYTE_BLOCK_LENGTH];
    81
    82      /**
    83       * Default constructor.
    84       */
    85      public MD4() {
    86          // Do nothing
    87      }
    88
    89      /**
    90       * Returns the digest length in bytes.
    91       *
    92       * @return the digest length in bytes.
    93       */
    94      protected int engineGetDigestLength() {
    95          return BYTE_DIGEST_LENGTH;
    96      }
    97
    98      /**
    99       * {@inheritDoc}
    100      */
    101     protected void engineUpdate(byte b) {
    102         int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
    103         buffer[pos] = b;
    104         msgLength++;
    105
    106         // If buffer contains enough data then process it.
    107         if (pos == (BYTE_BLOCK_LENGTH - 1)) {
    108             process(buffer, 0);
    109         }
    110     }
    111
    112     /**
    113      * {@inheritDoc}
    114      */
    115     protected void engineUpdate(byte[] b, int offset, int len) {
    116         int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
    117         int nbOfCharsToFillBuf = BYTE_BLOCK_LENGTH - pos;
    118         int blkStart = 0;
    119
    120         msgLength += len;
    121
    122         // Process each full block
    123         if (len >= nbOfCharsToFillBuf) {
    124             System.arraycopy(b, offset, buffer, pos, nbOfCharsToFillBuf);
    125             process(buffer, 0);
    126             for (blkStart = nbOfCharsToFillBuf; blkStart + BYTE_BLOCK_LENGTH - 1 < len; blkStart += BYTE_BLOCK_LENGTH) {
    127                 process(b, offset + blkStart);
    128             }
    129             pos = 0;
    130         }
    131
    132         // Fill buffer with the remaining data
    133         if (blkStart < len) {
    134             System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
    135         }
    136     }
    137
    138     /**
    139      * {@inheritDoc}
    140      */
    141     protected byte[] engineDigest() {
    142         byte[] p = pad();
    143         engineUpdate(p, 0, p.length);
    144         byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16), (byte) (a >>> 24), (byte) b, (byte) (b >>> 8),
    145                 (byte) (b >>> 16), (byte) (b >>> 24), (byte) c, (byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24),
    146                 (byte) d, (byte) (d >>> 8), (byte) (d >>> 16), (byte) (d >>> 24) };
    147
    148         engineReset();
    149
    150         return digest;
    151     }
    152
    153     /**
    154      * {@inheritDoc}
    155      */
    156     protected int engineDigest(byte[] buf, int offset, int len) throws DigestException {
    157         if (offset < 0 || offset + len >= buf.length) {
    158             throw new DigestException("Wrong offset or not enough space to store the digest");
    159         }
    160         int destLength = Math.min(len, BYTE_DIGEST_LENGTH);
    161         System.arraycopy(engineDigest(), 0, buf, offset, destLength);
    162         return destLength;
    163     }
    164
    165     /**
    166      * {@inheritDoc}
    167      */
    168     protected void engineReset() {
    169         a = A;
    170         b = B;
    171         c = C;
    172         d = D;
    173         msgLength = 0;
    174     }
    175
    176     /**
    177      * Pads the buffer by appending the byte 0x80, then append as many zero
    178      * bytes as necessary to make the buffer length a multiple of 64 bytes.
    179      * The last 8 bytes will be filled with the length of the buffer in bits.
    180      * If there's no room to store the length in bits in the block i.e the block
    181      * is larger than 56 bytes then an additionnal 64-bytes block is appended.
    182      *
    183      * @see sections 3.1 & 3.2 of the RFC 1320.
    184      *
    185      * @return the pad byte array
    186      */
    187     private byte[] pad() {
    188         int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
    189         int padLength = (pos < 56) ? (64 - pos) : (128 - pos);
    190         byte[] pad = new byte[padLength];
    191
    192         // First bit of the padding set to 1
    193         pad[0] = (byte) 0x80;
    194
    195         long bits = msgLength << 3;
    196         int index = padLength - 8;
    197         for (int i = 0; i < 8; i++) {
    198             pad[index++] = (byte) (bits >>> (i << 3));
    199         }
    200
    201         return pad;
    202     }
    203
    204     /**
    205      * Process one 64-byte block. Algorithm is constituted by three rounds.
    206      * Note that F, G and H functions were inlined for improved performance.
    207      *
    208      * @param in the byte array to process
    209      * @param offset the offset at which the 64-byte block is stored
    210      */
    211     private void process(byte[] in, int offset) {
    212         // Save previous state.
    213         int aa = a;
    214         int bb = b;
    215         int cc = c;
    216         int dd = d;
    217
    218         // Copy the block to process into X array
    219         int[] X = new int[16];
    220         for (int i = 0; i < 16; i++) {
    221             X[i] = (in[offset++] & 0xff) | (in[offset++] & 0xff) << 8 | (in[offset++] & 0xff) << 16
    222                     | (in[offset++] & 0xff) << 24;
    223         }
    224
    225         // Round 1
    226         a += ((b & c) | (~b & d)) + X[0];
    227         a = a << 3 | a >>> (32 - 3);
    228         d += ((a & b) | (~a & c)) + X[1];
    229         d = d << 7 | d >>> (32 - 7);
    230         c += ((d & a) | (~d & b)) + X[2];
    231         c = c << 11 | c >>> (32 - 11);
    232         b += ((c & d) | (~c & a)) + X[3];
    233         b = b << 19 | b >>> (32 - 19);
    234         a += ((b & c) | (~b & d)) + X[4];
    235         a = a << 3 | a >>> (32 - 3);
    236         d += ((a & b) | (~a & c)) + X[5];
    237         d = d << 7 | d >>> (32 - 7);
    238         c += ((d & a) | (~d & b)) + X[6];
    239         c = c << 11 | c >>> (32 - 11);
    240         b += ((c & d) | (~c & a)) + X[7];
    241         b = b << 19 | b >>> (32 - 19);
    242         a += ((b & c) | (~b & d)) + X[8];
    243         a = a << 3 | a >>> (32 - 3);
    244         d += ((a & b) | (~a & c)) + X[9];
    245         d = d << 7 | d >>> (32 - 7);
    246         c += ((d & a) | (~d & b)) + X[10];
    247         c = c << 11 | c >>> (32 - 11);
    248         b += ((c & d) | (~c & a)) + X[11];
    249         b = b << 19 | b >>> (32 - 19);
    250         a += ((b & c) | (~b & d)) + X[12];
    251         a = a << 3 | a >>> (32 - 3);
    252         d += ((a & b) | (~a & c)) + X[13];
    253         d = d << 7 | d >>> (32 - 7);
    254         c += ((d & a) | (~d & b)) + X[14];
    255         c = c << 11 | c >>> (32 - 11);
    256         b += ((c & d) | (~c & a)) + X[15];
    257         b = b << 19 | b >>> (32 - 19);
    258
    259         // Round 2
    260         a += ((b & (c | d)) | (c & d)) + X[0] + 0x5a827999;
    261         a = a << 3 | a >>> (32 - 3);
    262         d += ((a & (b | c)) | (b & c)) + X[4] + 0x5a827999;
    263         d = d << 5 | d >>> (32 - 5);
    264         c += ((d & (a | b)) | (a & b)) + X[8] + 0x5a827999;
    265         c = c << 9 | c >>> (32 - 9);
    266         b += ((c & (d | a)) | (d & a)) + X[12] + 0x5a827999;
    267         b = b << 13 | b >>> (32 - 13);
    268         a += ((b & (c | d)) | (c & d)) + X[1] + 0x5a827999;
    269         a = a << 3 | a >>> (32 - 3);
    270         d += ((a & (b | c)) | (b & c)) + X[5] + 0x5a827999;
    271         d = d << 5 | d >>> (32 - 5);
    272         c += ((d & (a | b)) | (a & b)) + X[9] + 0x5a827999;
    273         c = c << 9 | c >>> (32 - 9);
    274         b += ((c & (d | a)) | (d & a)) + X[13] + 0x5a827999;
    275         b = b << 13 | b >>> (32 - 13);
    276         a += ((b & (c | d)) | (c & d)) + X[2] + 0x5a827999;
    277         a = a << 3 | a >>> (32 - 3);
    278         d += ((a & (b | c)) | (b & c)) + X[6] + 0x5a827999;
    279         d = d << 5 | d >>> (32 - 5);
    280         c += ((d & (a | b)) | (a & b)) + X[10] + 0x5a827999;
    281         c = c << 9 | c >>> (32 - 9);
    282         b += ((c & (d | a)) | (d & a)) + X[14] + 0x5a827999;
    283         b = b << 13 | b >>> (32 - 13);
    284         a += ((b & (c | d)) | (c & d)) + X[3] + 0x5a827999;
    285         a = a << 3 | a >>> (32 - 3);
    286         d += ((a & (b | c)) | (b & c)) + X[7] + 0x5a827999;
    287         d = d << 5 | d >>> (32 - 5);
    288         c += ((d & (a | b)) | (a & b)) + X[11] + 0x5a827999;
    289         c = c << 9 | c >>> (32 - 9);
    290         b += ((c & (d | a)) | (d & a)) + X[15] + 0x5a827999;
    291         b = b << 13 | b >>> (32 - 13);
    292
    293         // Round 3
    294         a += (b ^ c ^ d) + X[0] + 0x6ed9eba1;
    295         a = a << 3 | a >>> (32 - 3);
    296         d += (a ^ b ^ c) + X[8] + 0x6ed9eba1;
    297         d = d << 9 | d >>> (32 - 9);
    298         c += (d ^ a ^ b) + X[4] + 0x6ed9eba1;
    299         c = c << 11 | c >>> (32 - 11);
    300         b += (c ^ d ^ a) + X[12] + 0x6ed9eba1;
    301         b = b << 15 | b >>> (32 - 15);
    302         a += (b ^ c ^ d) + X[2] + 0x6ed9eba1;
    303         a = a << 3 | a >>> (32 - 3);
    304         d += (a ^ b ^ c) + X[10] + 0x6ed9eba1;
    305         d = d << 9 | d >>> (32 - 9);
    306         c += (d ^ a ^ b) + X[6] + 0x6ed9eba1;
    307         c = c << 11 | c >>> (32 - 11);
    308         b += (c ^ d ^ a) + X[14] + 0x6ed9eba1;
    309         b = b << 15 | b >>> (32 - 15);
    310         a += (b ^ c ^ d) + X[1] + 0x6ed9eba1;
    311         a = a << 3 | a >>> (32 - 3);
    312         d += (a ^ b ^ c) + X[9] + 0x6ed9eba1;
    313         d = d << 9 | d >>> (32 - 9);
    314         c += (d ^ a ^ b) + X[5] + 0x6ed9eba1;
    315         c = c << 11 | c >>> (32 - 11);
    316         b += (c ^ d ^ a) + X[13] + 0x6ed9eba1;
    317         b = b << 15 | b >>> (32 - 15);
    318         a += (b ^ c ^ d) + X[3] + 0x6ed9eba1;
    319         a = a << 3 | a >>> (32 - 3);
    320         d += (a ^ b ^ c) + X[11] + 0x6ed9eba1;
    321         d = d << 9 | d >>> (32 - 9);
    322         c += (d ^ a ^ b) + X[7] + 0x6ed9eba1;
    323         c = c << 11 | c >>> (32 - 11);
    324         b += (c ^ d ^ a) + X[15] + 0x6ed9eba1;
    325         b = b << 15 | b >>> (32 - 15);
    326
    327         //Update state.
    328         a += aa;
    329         b += bb;
    330         c += cc;
    331         d += dd;
    332     }
    333 }