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 import org.apache.harmony.crypto.internal.nls.Messages; 24 25 /** 26 * The algorithm parameter specification for the <a 27 * href="http://www.ietf.org/rfc/rfc2040.txt">RC5</a> algorithm. 28 */ 29 public class RC5ParameterSpec implements AlgorithmParameterSpec { 30 31 private final int version; 32 private final int rounds; 33 private final int wordSize; 34 private final byte[] iv; 35 36 /** 37 * Creates a new <code>RC5ParameterSpec</code> instance with the specified 38 * version, round count an word size (in bits). 39 * 40 * @param version 41 * the version. 42 * @param rounds 43 * the round count. 44 * @param wordSize 45 * the word size (in bits). 46 */ 47 public RC5ParameterSpec(int version, int rounds, int wordSize) { 48 this.version = version; 49 this.rounds = rounds; 50 this.wordSize = wordSize; 51 this.iv = null; 52 } 53 54 /** 55 * Creates a new <code>RC5ParameterSpec</code> instance with the specified 56 * version, round count, word size (in bits) and an <i>initialization 57 * vector</i>. 58 * <p> 59 * The size of the <i>initialization vector</i> must be at least 60 * <code>2 * (wordSize / 8)</code> bytes which are copied to protect them 61 * against modification. 62 * 63 * @param version 64 * the version. 65 * @param rounds 66 * the round count. 67 * @param wordSize 68 * the word size (in bits). 69 * @param iv 70 * the initialization vector. 71 * @throws IllegalArgumentException 72 * if the initialization vector is null or shorter than <code>2 73 * * (wordSize / 8)</code>. 74 */ 75 public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv) { 76 if (iv == null) { 77 throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$ 78 } 79 if (iv.length < 2 * (wordSize / 8)) { 80 throw new IllegalArgumentException( 81 Messages.getString("crypto.32")); //$NON-NLS-1$ 82 } 83 this.version = version; 84 this.rounds = rounds; 85 this.wordSize = wordSize; 86 this.iv = new byte[2*(wordSize/8)]; 87 System.arraycopy(iv, 0, this.iv, 0, 2*(wordSize/8)); 88 } 89 90 /** 91 * Creates a new <code>RC5ParameterSpec</code> instance with the specified 92 * version, round count, wordSize (in bits), an <i>initialization vector</i> 93 * and an offset. 94 * <p> 95 * The size of the <i>initialization vector</i> must be at least 96 * <code>offset + (2 * (wordSize / 8))</code> bytes. The bytes starting at 97 * <code>offset</code> are copied to protect them against modification. 98 * 99 * @param version 100 * the version. 101 * @param rounds 102 * the round count. 103 * @param wordSize 104 * the word size (in bits). 105 * @param iv 106 * the initialization vector. 107 * @param offset 108 * the offset in the initialization vector. 109 * @throws IllegalArgumentException 110 * if the initialization vector is null of shorter than 111 * <code>offset + (2 * (wordSize / 8))</code>. 112 * @throws ArrayIndexOutOfBoundsException 113 * if <code>offset</code> is negative. 114 */ 115 public RC5ParameterSpec(int version, int rounds, 116 int wordSize, byte[] iv, int offset) { 117 if (iv == null) { 118 throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$ 119 } 120 if (offset < 0) { 121 throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.33")); //$NON-NLS-1$ 122 } 123 if (iv.length - offset < 2 * (wordSize / 8)) { 124 throw new IllegalArgumentException( 125 Messages.getString("crypto.34")); //$NON-NLS-1$ 126 } 127 this.version = version; 128 this.rounds = rounds; 129 this.wordSize = wordSize; 130 this.iv = new byte[offset+2*(wordSize/8)]; 131 System.arraycopy(iv, offset, this.iv, 0, 2*(wordSize/8)); 132 } 133 134 /** 135 * Returns the version. 136 * 137 * @return the version. 138 */ 139 public int getVersion() { 140 return version; 141 } 142 143 /** 144 * Returns the round count. 145 * 146 * @return the round count. 147 */ 148 public int getRounds() { 149 return rounds; 150 } 151 152 /** 153 * Returns the word size (in bits). 154 * 155 * @return the word size (in bits). 156 */ 157 public int getWordSize() { 158 return wordSize; 159 } 160 161 /** 162 * Returns a copy of the initialization vector. 163 * 164 * @return a copy of the initialization vector, or null if none specified. 165 */ 166 public byte[] getIV() { 167 if (iv == null) { 168 return null; 169 } 170 byte[] result = new byte[iv.length]; 171 System.arraycopy(iv, 0, result, 0, iv.length); 172 return result; 173 } 174 175 /** 176 * Compares the specified object with this <code>RC5ParameterSpec</code> 177 * instance. 178 * 179 * @param obj 180 * the object to compare. 181 * @return true if version, round count, word size and initializaion vector 182 * of both objects are equal, otherwise false. 183 */ 184 @Override 185 public boolean equals(Object obj) { 186 if (obj == this) { 187 return true; 188 } 189 if (!(obj instanceof RC5ParameterSpec)) { 190 return false; 191 } 192 RC5ParameterSpec ps = (RC5ParameterSpec) obj; 193 return (version == ps.version) 194 && (rounds == ps.rounds) 195 && (wordSize == ps.wordSize) 196 && (Arrays.equals(iv, ps.iv)); 197 } 198 199 /** 200 * Returns the hash code of this <code>RC5ParameterSpec</code> instance. 201 * 202 * @return the hash code. 203 */ 204 @Override 205 public int hashCode() { 206 int result = version + rounds + wordSize; 207 if (iv == null) { 208 return result; 209 } 210 for (byte element : iv) { 211 result += element & 0xFF; 212 } 213 return result; 214 } 215 } 216 217