Home | History | Annotate | Download | only in spec
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package javax.crypto.spec;
     19 
     20 import java.security.spec.AlgorithmParameterSpec;
     21 import java.util.Arrays;
     22 
     23 /**
     24  * The algorithm parameter specification for the <a
     25  * href="http://www.ietf.org/rfc/rfc2040.txt">RC5</a> algorithm.
     26  */
     27 public class RC5ParameterSpec implements AlgorithmParameterSpec {
     28 
     29     private final int version;
     30     private final int rounds;
     31     private final int wordSize;
     32     private final byte[] iv;
     33 
     34     /**
     35      * Creates a new <code>RC5ParameterSpec</code> instance with the specified
     36      * version, round count an word size (in bits).
     37      *
     38      * @param version
     39      *            the version.
     40      * @param rounds
     41      *            the round count.
     42      * @param wordSize
     43      *            the word size (in bits).
     44      */
     45     public RC5ParameterSpec(int version, int rounds, int wordSize) {
     46         this.version = version;
     47         this.rounds = rounds;
     48         this.wordSize = wordSize;
     49         this.iv = null;
     50     }
     51 
     52     /**
     53      * Creates a new <code>RC5ParameterSpec</code> instance with the specified
     54      * version, round count, word size (in bits) and an <i>initialization
     55      * vector</i>.
     56      * <p>
     57      * The size of the <i>initialization vector</i> must be at least
     58      * <code>2 * (wordSize / 8)</code> bytes which are copied to protect them
     59      * against modification.
     60      *
     61      * @param version
     62      *            the version.
     63      * @param rounds
     64      *            the round count.
     65      * @param wordSize
     66      *            the word size (in bits).
     67      * @param iv
     68      *            the initialization vector.
     69      * @throws IllegalArgumentException
     70      *             if the initialization vector is null or shorter than <code>2
     71      *             * (wordSize / 8)</code>.
     72      */
     73     public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv) {
     74         if (iv == null) {
     75             throw new IllegalArgumentException("iv == null");
     76         }
     77         if (iv.length < 2 * (wordSize / 8)) {
     78             throw new IllegalArgumentException("iv.length < 2 * (wordSize / 8)");
     79         }
     80         this.version = version;
     81         this.rounds = rounds;
     82         this.wordSize = wordSize;
     83         this.iv = new byte[2*(wordSize/8)];
     84         System.arraycopy(iv, 0, this.iv, 0, 2*(wordSize/8));
     85     }
     86 
     87     /**
     88      * Creates a new <code>RC5ParameterSpec</code> instance with the specified
     89      * version, round count, wordSize (in bits), an <i>initialization vector</i>
     90      * and an offset.
     91      * <p>
     92      * The size of the <i>initialization vector</i> must be at least
     93      * <code>offset + (2 * (wordSize / 8))</code> bytes. The bytes starting at
     94      * <code>offset</code> are copied to protect them against modification.
     95      *
     96      * @param version
     97      *            the version.
     98      * @param rounds
     99      *            the round count.
    100      * @param wordSize
    101      *            the word size (in bits).
    102      * @param iv
    103      *            the initialization vector.
    104      * @param offset
    105      *            the offset in the initialization vector.
    106      * @throws IllegalArgumentException
    107      *             if the initialization vector is null of shorter than
    108      *             <code>offset + (2 * (wordSize / 8))</code>.
    109      * @throws ArrayIndexOutOfBoundsException
    110      *             if <code>offset</code> is negative.
    111      */
    112     public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv, int offset) {
    113         if (iv == null) {
    114             throw new IllegalArgumentException("iv == null");
    115         }
    116         if (offset < 0) {
    117             throw new ArrayIndexOutOfBoundsException("offset < 0: " + offset);
    118         }
    119         if (iv.length - offset < 2 * (wordSize / 8)) {
    120             throw new IllegalArgumentException("iv.length - offset < 2 * (wordSize / 8)");
    121         }
    122         this.version = version;
    123         this.rounds = rounds;
    124         this.wordSize = wordSize;
    125         this.iv = new byte[offset+2*(wordSize/8)];
    126         System.arraycopy(iv, offset, this.iv, 0, 2*(wordSize/8));
    127     }
    128 
    129     /**
    130      * Returns the version.
    131      *
    132      * @return the version.
    133      */
    134     public int getVersion() {
    135         return version;
    136     }
    137 
    138     /**
    139      * Returns the round count.
    140      *
    141      * @return the round count.
    142      */
    143     public int getRounds() {
    144         return rounds;
    145     }
    146 
    147     /**
    148      * Returns the word size (in bits).
    149      *
    150      * @return the word size (in bits).
    151      */
    152     public int getWordSize() {
    153         return wordSize;
    154     }
    155 
    156     /**
    157      * Returns a copy of the initialization vector.
    158      *
    159      * @return a copy of the initialization vector, or null if none specified.
    160      */
    161     public byte[] getIV() {
    162         if (iv == null) {
    163             return null;
    164         }
    165         byte[] result = new byte[iv.length];
    166         System.arraycopy(iv, 0, result, 0, iv.length);
    167         return result;
    168     }
    169 
    170     /**
    171      * Compares the specified object with this <code>RC5ParameterSpec</code>
    172      * instance.
    173      *
    174      * @param obj
    175      *            the object to compare.
    176      * @return true if version, round count, word size and initializaion vector
    177      *         of both objects are equal, otherwise false.
    178      */
    179     @Override
    180     public boolean equals(Object obj) {
    181         if (obj == this) {
    182             return true;
    183         }
    184         if (!(obj instanceof RC5ParameterSpec)) {
    185             return false;
    186         }
    187         RC5ParameterSpec ps = (RC5ParameterSpec) obj;
    188         return (version == ps.version)
    189             && (rounds == ps.rounds)
    190             && (wordSize == ps.wordSize)
    191             && (Arrays.equals(iv, ps.iv));
    192     }
    193 
    194     /**
    195      * Returns the hash code of this <code>RC5ParameterSpec</code> instance.
    196      *
    197      * @return the hash code.
    198      */
    199     @Override
    200     public int hashCode() {
    201         int result = version + rounds + wordSize;
    202         if (iv == null) {
    203             return result;
    204         }
    205         for (byte element : iv) {
    206             result += element & 0xFF;
    207         }
    208         return result;
    209     }
    210 }
    211