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      */
RC5ParameterSpec(int version, int rounds, int wordSize)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      */
RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv)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      */
RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv, int offset)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      */
getVersion()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      */
getRounds()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      */
getWordSize()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      */
getIV()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      */
equals(Object obj)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      */
hashCode()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 }
204