1package org.bouncycastle.jcajce.provider.symmetric; 2 3// BEGIN android-removed 4// import java.security.AlgorithmParameters; 5// import java.security.InvalidAlgorithmParameterException; 6// END android-removed 7import java.security.SecureRandom; 8// BEGIN android-removed 9// import java.security.spec.AlgorithmParameterSpec; 10// END android-removed 11import java.security.spec.InvalidKeySpecException; 12import java.security.spec.KeySpec; 13 14import javax.crypto.SecretKey; 15import javax.crypto.spec.DESedeKeySpec; 16// BEGIN android-removed 17// import javax.crypto.spec.IvParameterSpec; 18// END android-removed 19import javax.crypto.spec.SecretKeySpec; 20 21import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 22import org.bouncycastle.crypto.KeyGenerationParameters; 23import org.bouncycastle.crypto.engines.DESedeEngine; 24import org.bouncycastle.crypto.engines.DESedeWrapEngine; 25// BEGIN android-removed 26// import org.bouncycastle.crypto.engines.RFC3211WrapEngine; 27// END android-removed 28import org.bouncycastle.crypto.generators.DESedeKeyGenerator; 29import org.bouncycastle.crypto.macs.CBCBlockCipherMac; 30// BEGIN android-removed 31// import org.bouncycastle.crypto.macs.CFBBlockCipherMac; 32// import org.bouncycastle.crypto.macs.CMac; 33// END android-removed 34import org.bouncycastle.crypto.modes.CBCBlockCipher; 35import org.bouncycastle.crypto.paddings.ISO7816d4Padding; 36import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; 37// BEGIN android-removed 38// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; 39// END android-removed 40import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; 41import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; 42import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; 43import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; 44import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; 45import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; 46import org.bouncycastle.jce.provider.BouncyCastleProvider; 47 48public final class DESede 49{ 50 private DESede() 51 { 52 } 53 54 static public class ECB 55 extends BaseBlockCipher 56 { 57 public ECB() 58 { 59 super(new DESedeEngine()); 60 } 61 } 62 63 static public class CBC 64 extends BaseBlockCipher 65 { 66 public CBC() 67 { 68 super(new CBCBlockCipher(new DESedeEngine()), 64); 69 } 70 } 71 72 // BEGIN android-removed 73 // /** 74 // * DESede CFB8 75 // */ 76 // public static class DESedeCFB8 77 // extends BaseMac 78 // { 79 // public DESedeCFB8() 80 // { 81 // super(new CFBBlockCipherMac(new DESedeEngine())); 82 // } 83 // } 84 // END android-removed 85 86 /** 87 * DESede64 88 */ 89 public static class DESede64 90 extends BaseMac 91 { 92 public DESede64() 93 { 94 super(new CBCBlockCipherMac(new DESedeEngine(), 64)); 95 } 96 } 97 98 /** 99 * DESede64with7816-4Padding 100 */ 101 public static class DESede64with7816d4 102 extends BaseMac 103 { 104 public DESede64with7816d4() 105 { 106 super(new CBCBlockCipherMac(new DESedeEngine(), 64, new ISO7816d4Padding())); 107 } 108 } 109 110 public static class CBCMAC 111 extends BaseMac 112 { 113 public CBCMAC() 114 { 115 super(new CBCBlockCipherMac(new DESedeEngine())); 116 } 117 } 118 119 // BEGIN android-removed 120 // static public class CMAC 121 // extends BaseMac 122 // { 123 // public CMAC() 124 // { 125 // super(new CMac(new DESedeEngine())); 126 // } 127 // } 128 // END android-removed 129 130 public static class Wrap 131 extends BaseWrapCipher 132 { 133 public Wrap() 134 { 135 super(new DESedeWrapEngine()); 136 } 137 } 138 139 // BEGIN android-removed 140 // public static class RFC3211 141 // extends BaseWrapCipher 142 // { 143 // public RFC3211() 144 // { 145 // super(new RFC3211WrapEngine(new DESedeEngine()), 8); 146 // } 147 // } 148 // END android-removed 149 150 /** 151 * DESede - the default for this is to generate a key in 152 * a-b-a format that's 24 bytes long but has 16 bytes of 153 * key material (the first 8 bytes is repeated as the last 154 * 8 bytes). If you give it a size, you'll get just what you 155 * asked for. 156 */ 157 public static class KeyGenerator 158 extends BaseKeyGenerator 159 { 160 private boolean keySizeSet = false; 161 162 public KeyGenerator() 163 { 164 super("DESede", 192, new DESedeKeyGenerator()); 165 } 166 167 protected void engineInit( 168 int keySize, 169 SecureRandom random) 170 { 171 super.engineInit(keySize, random); 172 keySizeSet = true; 173 } 174 175 protected SecretKey engineGenerateKey() 176 { 177 if (uninitialised) 178 { 179 engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize)); 180 uninitialised = false; 181 } 182 183 // 184 // if no key size has been defined generate a 24 byte key in 185 // the a-b-a format 186 // 187 if (!keySizeSet) 188 { 189 byte[] k = engine.generateKey(); 190 191 System.arraycopy(k, 0, k, 16, 8); 192 193 return new SecretKeySpec(k, algName); 194 } 195 else 196 { 197 return new SecretKeySpec(engine.generateKey(), algName); 198 } 199 } 200 } 201 202 /** 203 * generate a desEDE key in the a-b-c format. 204 */ 205 public static class KeyGenerator3 206 extends BaseKeyGenerator 207 { 208 public KeyGenerator3() 209 { 210 super("DESede3", 192, new DESedeKeyGenerator()); 211 } 212 } 213 214 /** 215 * PBEWithSHAAnd3-KeyTripleDES-CBC 216 */ 217 static public class PBEWithSHAAndDES3Key 218 extends BaseBlockCipher 219 { 220 public PBEWithSHAAndDES3Key() 221 { 222 super(new CBCBlockCipher(new DESedeEngine())); 223 } 224 } 225 226 /** 227 * PBEWithSHAAnd2-KeyTripleDES-CBC 228 */ 229 static public class PBEWithSHAAndDES2Key 230 extends BaseBlockCipher 231 { 232 public PBEWithSHAAndDES2Key() 233 { 234 super(new CBCBlockCipher(new DESedeEngine())); 235 } 236 } 237 238 // BEGIN android-removed 239 // public static class AlgParamGen 240 // extends BaseAlgorithmParameterGenerator 241 // { 242 // protected void engineInit( 243 // AlgorithmParameterSpec genParamSpec, 244 // SecureRandom random) 245 // throws InvalidAlgorithmParameterException 246 // { 247 // throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation."); 248 // } 249 // 250 // protected AlgorithmParameters engineGenerateParameters() 251 // { 252 // byte[] iv = new byte[8]; 253 // 254 // if (random == null) 255 // { 256 // random = new SecureRandom(); 257 // } 258 // 259 // random.nextBytes(iv); 260 // 261 // AlgorithmParameters params; 262 // 263 // try 264 // { 265 // params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME); 266 // params.init(new IvParameterSpec(iv)); 267 // } 268 // catch (Exception e) 269 // { 270 // throw new RuntimeException(e.getMessage()); 271 // } 272 // 273 // return params; 274 // } 275 // } 276 // END android-removed 277 278 static public class KeyFactory 279 extends BaseSecretKeyFactory 280 { 281 public KeyFactory() 282 { 283 super("DESede", null); 284 } 285 286 protected KeySpec engineGetKeySpec( 287 SecretKey key, 288 Class keySpec) 289 throws InvalidKeySpecException 290 { 291 if (keySpec == null) 292 { 293 throw new InvalidKeySpecException("keySpec parameter is null"); 294 } 295 if (key == null) 296 { 297 throw new InvalidKeySpecException("key parameter is null"); 298 } 299 300 if (SecretKeySpec.class.isAssignableFrom(keySpec)) 301 { 302 return new SecretKeySpec(key.getEncoded(), algName); 303 } 304 else if (DESedeKeySpec.class.isAssignableFrom(keySpec)) 305 { 306 byte[] bytes = key.getEncoded(); 307 308 try 309 { 310 if (bytes.length == 16) 311 { 312 byte[] longKey = new byte[24]; 313 314 System.arraycopy(bytes, 0, longKey, 0, 16); 315 System.arraycopy(bytes, 0, longKey, 16, 8); 316 317 return new DESedeKeySpec(longKey); 318 } 319 else 320 { 321 return new DESedeKeySpec(bytes); 322 } 323 } 324 catch (Exception e) 325 { 326 throw new InvalidKeySpecException(e.toString()); 327 } 328 } 329 330 throw new InvalidKeySpecException("Invalid KeySpec"); 331 } 332 333 protected SecretKey engineGenerateSecret( 334 KeySpec keySpec) 335 throws InvalidKeySpecException 336 { 337 if (keySpec instanceof DESedeKeySpec) 338 { 339 DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec; 340 return new SecretKeySpec(desKeySpec.getKey(), "DESede"); 341 } 342 343 return super.engineGenerateSecret(keySpec); 344 } 345 } 346 347 public static class Mappings 348 extends AlgorithmProvider 349 { 350 private static final String PREFIX = DESede.class.getName(); 351 private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2 352 353 public Mappings() 354 { 355 } 356 357 public void configure(ConfigurableProvider provider) 358 { 359 provider.addAlgorithm("Cipher.DESEDE", PREFIX + "$ECB"); 360 // BEGIN android-removed 361 // provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC"); 362 // END android-removed 363 provider.addAlgorithm("Cipher.DESEDEWRAP", PREFIX + "$Wrap"); 364 // BEGIN android-changed 365 provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWRAP"); 366 // END android-changed 367 // BEGIN android-removed 368 // provider.addAlgorithm("Cipher.DESEDERFC3211WRAP", PREFIX + "$RFC3211"); 369 // END android-removed 370 371 if (provider.hasAlgorithm("MessageDigest", "SHA-1")) 372 { 373 provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key"); 374 // BEGIN android-removed 375 // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES3Key"); 376 // provider.addAlgorithm("Cipher.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$OldPBEWithSHAAndDES3Key"); 377 // END android-removed 378 provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key"); 379 // BEGIN android-removed 380 // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key"); 381 // END android-removed 382 provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); 383 provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"); 384 provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); 385 provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); 386 provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"); 387 } 388 389 provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator"); 390 // BEGIN android-removed 391 // provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3"); 392 // provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator"); 393 // END android-removed 394 395 provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory"); 396 397 // BEGIN android-removed 398 // provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC"); 399 // provider.addAlgorithm("Mac.DESEDEMAC", PREFIX + "$CBCMAC"); 400 // provider.addAlgorithm("Alg.Alias.Mac.DESEDE", "DESEDEMAC"); 401 // 402 // provider.addAlgorithm("Mac.DESEDEMAC/CFB8", PREFIX + "$DESedeCFB8"); 403 // provider.addAlgorithm("Alg.Alias.Mac.DESEDE/CFB8", "DESEDEMAC/CFB8"); 404 // 405 // provider.addAlgorithm("Mac.DESEDEMAC64", PREFIX + "$DESede64"); 406 // provider.addAlgorithm("Alg.Alias.Mac.DESEDE64", "DESEDEMAC64"); 407 // 408 // provider.addAlgorithm("Mac.DESEDEMAC64WITHISO7816-4PADDING", PREFIX + "$DESede64with7816d4"); 409 // provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING"); 410 // provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING"); 411 // provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING"); 412 // END android-removed 413 414 provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters"); 415 provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE"); 416 417 // BEGIN android-removed 418 // provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE", PREFIX + "$AlgParamGen"); 419 // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE"); 420 // END android-removed 421 } 422 } 423} 424