View Javadoc
1   /*
2    * Copyright (c) 1998, 2013, 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://www.ietf.org/rfc/rfc2040.txt"><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.rsasecurity.com">RSA Security Inc.</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 }