1 /*
   2  * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.crypto.spec;
  27 
  28 import java.security.spec.AlgorithmParameterSpec;
  29 
  30 /**
  31  * This class specifies the parameters used with the
  32  * <a href="http://tools.ietf.org/html/rfc2040"><i>RC5</i></a>
  33  * algorithm.
  34  *
  35  * <p> The parameters consist of a version number, a rounds count, a word
  36  * size, and optionally an initialization vector (IV) (only in feedback mode).
  37  *
  38  * <p> This class can be used to initialize a <code>Cipher</code> object that
  39  * implements the <i>RC5</i> algorithm as supplied by
  40  * <a href="http://www.rsa.com">RSA Security LLC</a>,
  41  * or any parties authorized by RSA Security.
  42  *
  43  * @author Jan Luehe
  44  *
  45  * @since 1.4
  46  */
  47 public class RC5ParameterSpec implements AlgorithmParameterSpec {
  48 
  49     private byte[] iv = null;
  50     private int version;
  51     private int rounds;
  52     private int wordSize; // the word size in bits
  53 
  54     /**
  55      * Constructs a parameter set for RC5 from the given version, number of
  56      * rounds and word size (in bits).
  57      *
  58      * @param version the version.
  59      * @param rounds the number of rounds.
  60      * @param wordSize the word size in bits.
  61      */
  62     public RC5ParameterSpec(int version, int rounds, int wordSize) {
  63         this.version = version;
  64         this.rounds = rounds;
  65         this.wordSize = wordSize;
  66     }
  67 
  68     /**
  69      * Constructs a parameter set for RC5 from the given version, number of
  70      * rounds, word size (in bits), and IV.
  71      *
  72      * <p> Note that the size of the IV (block size) must be twice the word
  73      * size. The bytes that constitute the IV are those between
  74      * <code>iv[0]</code> and <code>iv[2*(wordSize/8)-1]</code> inclusive.
  75      *
  76      * @param version the version.
  77      * @param rounds the number of rounds.
  78      * @param wordSize the word size in bits.
  79      * @param iv the buffer with the IV. The first <code>2*(wordSize/8)
  80      * </code> bytes of the buffer are copied to protect against subsequent
  81      * modification.
  82      * @exception IllegalArgumentException if <code>iv</code> is
  83      * <code>null</code> or {@code (iv.length < 2 * (wordSize / 8))}
  84      */
  85     public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv) {
  86         this(version, rounds, wordSize, iv, 0);
  87     }
  88 
  89     /**
  90      * Constructs a parameter set for RC5 from the given version, number of
  91      * rounds, word size (in bits), and IV.
  92      *
  93      * <p> The IV is taken from <code>iv</code>, starting at
  94      * <code>offset</code> inclusive.
  95      * Note that the size of the IV (block size), starting at
  96      * <code>offset</code> inclusive, must be twice the word size.
  97      * The bytes that constitute the IV are those between
  98      * <code>iv[offset]</code> and <code>iv[offset+2*(wordSize/8)-1]</code>
  99      * inclusive.
 100      *
 101      * @param version the version.
 102      * @param rounds the number of rounds.
 103      * @param wordSize the word size in bits.
 104      * @param iv the buffer with the IV. The first <code>2*(wordSize/8)
 105      * </code> bytes of the buffer beginning at <code>offset</code>
 106      * inclusive are copied to protect against subsequent modification.
 107      * @param offset the offset in <code>iv</code> where the IV starts.
 108      * @exception IllegalArgumentException if <code>iv</code> is
 109      * <code>null</code> or
 110      * {@code (iv.length - offset < 2 * (wordSize / 8))}
 111      */
 112     public RC5ParameterSpec(int version, int rounds, int wordSize,
 113                             byte[] iv, int offset) {
 114         this.version = version;
 115         this.rounds = rounds;
 116         this.wordSize = wordSize;
 117         if (iv == null) throw new IllegalArgumentException("IV missing");
 118         int blockSize = (wordSize / 8) * 2;
 119         if (iv.length - offset < blockSize) {
 120             throw new IllegalArgumentException("IV too short");
 121         }
 122         this.iv = new byte[blockSize];
 123         System.arraycopy(iv, offset, this.iv, 0, blockSize);
 124     }
 125 
 126     /**
 127      * Returns the version.
 128      *
 129      * @return the version.
 130      */
 131     public int getVersion() {
 132         return this.version;
 133     }
 134 
 135     /**
 136      * Returns the number of rounds.
 137      *
 138      * @return the number of rounds.
 139      */
 140     public int getRounds() {
 141         return this.rounds;
 142     }
 143 
 144     /**
 145      * Returns the word size in bits.
 146      *
 147      * @return the word size in bits.
 148      */
 149     public int getWordSize() {
 150         return this.wordSize;
 151     }
 152 
 153     /**
 154      * Returns the IV or null if this parameter set does not contain an IV.
 155      *
 156      * @return the IV or null if this parameter set does not contain an IV.
 157      * Returns a new array each time this method is called.
 158      */
 159     public byte[] getIV() {
 160         return (iv == null? null:iv.clone());
 161     }
 162 
 163    /**
 164      * Tests for equality between the specified object and this
 165      * object. Two RC5ParameterSpec objects are considered equal if their
 166      * version numbers, number of rounds, word sizes, and IVs are equal.
 167      * (Two IV references are considered equal if both are <tt>null</tt>.)
 168      *
 169      * @param obj the object to test for equality with this object.
 170      *
 171      * @return true if the objects are considered equal, false if
 172      * <code>obj</code> is null or otherwise.
 173      */
 174     public boolean equals(Object obj) {
 175         if (obj == this) {
 176             return true;
 177         }
 178         if (!(obj instanceof RC5ParameterSpec)) {
 179             return false;
 180         }
 181         RC5ParameterSpec other = (RC5ParameterSpec) obj;
 182 
 183         return ((version == other.version) &&
 184                 (rounds == other.rounds) &&
 185                 (wordSize == other.wordSize) &&
 186                 java.util.Arrays.equals(iv, other.iv));
 187     }
 188 
 189     /**
 190      * Calculates a hash code value for the object.
 191      * Objects that are equal will also have the same hashcode.
 192      */
 193     public int hashCode() {
 194         int retval = 0;
 195         if (iv != null) {
 196             for (int i = 1; i < iv.length; i++) {
 197                 retval += iv[i] * i;
 198             }
 199         }
 200         retval += (version + rounds + wordSize);
 201         return retval;
 202     }
 203 }