1 package org.bouncycastle.jcajce.provider.symmetric; 2 3 import java.io.IOException; 4 import java.security.spec.AlgorithmParameterSpec; 5 import java.security.spec.InvalidKeySpecException; 6 import java.security.spec.InvalidParameterSpecException; 7 import java.security.spec.KeySpec; 8 9 import javax.crypto.SecretKey; 10 import javax.crypto.spec.PBEKeySpec; 11 import javax.crypto.spec.PBEParameterSpec; 12 13 import org.bouncycastle.asn1.ASN1Encoding; 14 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 15 import org.bouncycastle.asn1.ASN1Primitive; 16 // BEGIN android-removed 17 // import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 18 // END android-removed 19 import org.bouncycastle.asn1.pkcs.PBKDF2Params; 20 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 21 import org.bouncycastle.crypto.CipherParameters; 22 import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; 23 import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; 24 import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters; 25 import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory; 26 import org.bouncycastle.jcajce.provider.symmetric.util.PBE; 27 import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; 28 import org.bouncycastle.jcajce.spec.PBKDF2KeySpec; 29 30 public class PBEPBKDF2 31 { PBEPBKDF2()32 private PBEPBKDF2() 33 { 34 35 } 36 37 // BEGIN android-removed 38 // public static class AlgParams 39 // extends BaseAlgorithmParameters 40 // { 41 // PBKDF2Params params; 42 // 43 // protected byte[] engineGetEncoded() 44 // { 45 // try 46 // { 47 // return params.getEncoded(ASN1Encoding.DER); 48 // } 49 // catch (IOException e) 50 // { 51 // throw new RuntimeException("Oooops! " + e.toString()); 52 // } 53 // } 54 55 // protected byte[] engineGetEncoded( 56 // String format) 57 // { 58 // if (this.isASN1FormatString(format)) 59 // { 60 // return engineGetEncoded(); 61 // } 62 // 63 // return null; 64 // } 65 // 66 // protected AlgorithmParameterSpec localEngineGetParameterSpec( 67 // Class paramSpec) 68 // throws InvalidParameterSpecException 69 // { 70 // if (paramSpec == PBEParameterSpec.class) 71 // { 72 // return new PBEParameterSpec(params.getSalt(), 73 // params.getIterationCount().intValue()); 74 // } 75 // 76 // throw new InvalidParameterSpecException("unknown parameter spec passed to PBKDF2 PBE parameters object."); 77 // } 78 // 79 // protected void engineInit( 80 // AlgorithmParameterSpec paramSpec) 81 // throws InvalidParameterSpecException 82 // { 83 // if (!(paramSpec instanceof PBEParameterSpec)) 84 // { 85 // throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PBKDF2 PBE parameters algorithm parameters object"); 86 // } 87 // 88 // PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec; 89 // 90 // this.params = new PBKDF2Params(pbeSpec.getSalt(), 91 // pbeSpec.getIterationCount()); 92 // } 93 // 94 // protected void engineInit( 95 // byte[] params) 96 // throws IOException 97 // { 98 // this.params = PBKDF2Params.getInstance(ASN1Primitive.fromByteArray(params)); 99 // } 100 // 101 // protected void engineInit( 102 // byte[] params, 103 // String format) 104 // throws IOException 105 // { 106 // if (this.isASN1FormatString(format)) 107 // { 108 // engineInit(params); 109 // return; 110 // } 111 // 112 // throw new IOException("Unknown parameters format in PBKDF2 parameters object"); 113 // } 114 // 115 // protected String engineToString() 116 // { 117 // return "PBKDF2 Parameters"; 118 // } 119 // } 120 // END android-removed 121 122 public static class BasePBKDF2 123 extends BaseSecretKeyFactory 124 { 125 private int scheme; 126 // BEGIN ANDROID-ADDED 127 private int keySizeInBits; 128 private int ivSizeInBits; 129 // END ANDROID-ADDED 130 private int defaultDigest; 131 BasePBKDF2(String name, int scheme)132 public BasePBKDF2(String name, int scheme) 133 { 134 this(name, scheme, SHA1); 135 } 136 137 // BEGIN ANDROID-CHANGED 138 // Was: public BasePBKDF2(String name, int scheme, int defaultDigest) BasePBKDF2( String name, int scheme, int digest, int keySizeInBits, int ivSizeInBits)139 private BasePBKDF2( 140 String name, int scheme, int digest, int keySizeInBits, int ivSizeInBits) 141 // END ANDROID-CHANGED 142 { 143 super(name, PKCSObjectIdentifiers.id_PBKDF2); 144 145 this.scheme = scheme; 146 // BEGIN ANDROID-ADDED 147 this.keySizeInBits = keySizeInBits; 148 this.ivSizeInBits = ivSizeInBits; 149 // END ANDROID-ADDED 150 this.defaultDigest = digest; 151 } 152 153 // BEGIN android-added BasePBKDF2(String name, int scheme, int digest)154 private BasePBKDF2(String name, int scheme, int digest) { 155 this(name, scheme, digest, 0, 0); 156 } 157 // END android-added 158 engineGenerateSecret( KeySpec keySpec)159 protected SecretKey engineGenerateSecret( 160 KeySpec keySpec) 161 throws InvalidKeySpecException 162 { 163 if (keySpec instanceof PBEKeySpec) 164 { 165 PBEKeySpec pbeSpec = (PBEKeySpec)keySpec; 166 167 // BEGIN ANDROID-ADDED 168 // Allow to specify a key using only the password. The key will be generated later 169 // when other parameters are known. 170 if (pbeSpec.getSalt() == null 171 && pbeSpec.getIterationCount() == 0 172 && pbeSpec.getKeyLength() == 0 173 && pbeSpec.getPassword().length > 0 174 && keySizeInBits != 0) { 175 return new BCPBEKey( 176 this.algName, this.algOid, scheme, defaultDigest, keySizeInBits, 177 ivSizeInBits, pbeSpec, 178 // cipherParameters, to be generated when the PBE parameters are known. 179 null); 180 } 181 // END ANDROID-ADDED 182 183 if (pbeSpec.getSalt() == null) 184 { 185 throw new InvalidKeySpecException("missing required salt"); 186 } 187 188 if (pbeSpec.getIterationCount() <= 0) 189 { 190 throw new InvalidKeySpecException("positive iteration count required: " 191 + pbeSpec.getIterationCount()); 192 } 193 194 if (pbeSpec.getKeyLength() <= 0) 195 { 196 throw new InvalidKeySpecException("positive key length required: " 197 + pbeSpec.getKeyLength()); 198 } 199 200 if (pbeSpec.getPassword().length == 0) 201 { 202 throw new IllegalArgumentException("password empty"); 203 } 204 205 if (pbeSpec instanceof PBKDF2KeySpec) 206 { 207 PBKDF2KeySpec spec = (PBKDF2KeySpec)pbeSpec; 208 209 int digest = getDigestCode(spec.getPrf().getAlgorithm()); 210 int keySize = pbeSpec.getKeyLength(); 211 int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version. 212 CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); 213 214 return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); 215 } 216 else 217 { 218 int digest = defaultDigest; 219 int keySize = pbeSpec.getKeyLength(); 220 int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version. 221 CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize); 222 223 return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param); 224 } 225 } 226 227 throw new InvalidKeySpecException("Invalid KeySpec"); 228 } 229 230 getDigestCode(ASN1ObjectIdentifier algorithm)231 private int getDigestCode(ASN1ObjectIdentifier algorithm) 232 throws InvalidKeySpecException 233 { 234 // BEGIN android-removed 235 // if (algorithm.equals(CryptoProObjectIdentifiers.gostR3411Hmac)) 236 // { 237 // return GOST3411; 238 // } 239 // else 240 // END android-removed 241 if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA1)) 242 { 243 return SHA1; 244 } 245 else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA256)) 246 { 247 return SHA256; 248 } 249 else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA224)) 250 { 251 return SHA224; 252 } 253 else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA384)) 254 { 255 return SHA384; 256 } 257 else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA512)) 258 { 259 return SHA512; 260 } 261 262 throw new InvalidKeySpecException("Invalid KeySpec: unknown PRF algorithm " + algorithm); 263 } 264 } 265 266 // BEGIN android-removed 267 // public static class PBKDF2withUTF8 268 // extends BasePBKDF2 269 // { 270 // public PBKDF2withUTF8() 271 // { 272 // super("PBKDF2", PKCS5S2_UTF8); 273 // } 274 // } 275 // 276 // public static class PBKDF2withSHA224 277 // extends BasePBKDF2 278 // { 279 // public PBKDF2withSHA224() 280 // { 281 // super("PBKDF2", PKCS5S2_UTF8, SHA224); 282 // } 283 // } 284 // 285 // public static class PBKDF2withSHA256 286 // extends BasePBKDF2 287 // { 288 // public PBKDF2withSHA256() 289 // { 290 // super("PBKDF2", PKCS5S2_UTF8, SHA256); 291 // } 292 // } 293 // 294 // public static class PBKDF2withSHA384 295 // extends BasePBKDF2 296 // { 297 // public PBKDF2withSHA384() 298 // { 299 // super("PBKDF2", PKCS5S2_UTF8, SHA384); 300 // } 301 // } 302 // 303 // public static class PBKDF2withSHA512 304 // extends BasePBKDF2 305 // { 306 // public PBKDF2withSHA512() 307 // { 308 // super("PBKDF2", PKCS5S2_UTF8, SHA512); 309 // } 310 // } 311 // 312 // public static class PBKDF2with8BIT 313 // extends BasePBKDF2 314 // { 315 // public PBKDF2with8BIT() 316 // { 317 // super("PBKDF2", PKCS5S2); 318 // } 319 // } 320 321 // BEGIN android-added 322 public static class BasePBKDF2WithHmacSHA1 extends BasePBKDF2 { BasePBKDF2WithHmacSHA1(String name, int scheme)323 public BasePBKDF2WithHmacSHA1(String name, int scheme) 324 { 325 super(name, scheme, SHA1); 326 } 327 } 328 329 public static class PBKDF2WithHmacSHA1UTF8 330 extends BasePBKDF2WithHmacSHA1 331 { PBKDF2WithHmacSHA1UTF8()332 public PBKDF2WithHmacSHA1UTF8() 333 { 334 super("PBKDF2WithHmacSHA1", PKCS5S2_UTF8); 335 } 336 } 337 338 public static class PBKDF2WithHmacSHA18BIT 339 extends BasePBKDF2WithHmacSHA1 340 { PBKDF2WithHmacSHA18BIT()341 public PBKDF2WithHmacSHA18BIT() 342 { 343 super("PBKDF2WithHmacSHA1And8bit", PKCS5S2); 344 } 345 } 346 347 public static class BasePBKDF2WithHmacSHA224 extends BasePBKDF2 { BasePBKDF2WithHmacSHA224(String name, int scheme)348 public BasePBKDF2WithHmacSHA224(String name, int scheme) 349 { 350 super(name, scheme, SHA224); 351 } 352 } 353 354 public static class PBKDF2WithHmacSHA224UTF8 355 extends BasePBKDF2WithHmacSHA224 356 { PBKDF2WithHmacSHA224UTF8()357 public PBKDF2WithHmacSHA224UTF8() 358 { 359 super("PBKDF2WithHmacSHA224", PKCS5S2_UTF8); 360 } 361 } 362 363 public static class BasePBKDF2WithHmacSHA256 extends BasePBKDF2 { BasePBKDF2WithHmacSHA256(String name, int scheme)364 public BasePBKDF2WithHmacSHA256(String name, int scheme) 365 { 366 super(name, scheme, SHA256); 367 } 368 } 369 370 public static class PBKDF2WithHmacSHA256UTF8 371 extends BasePBKDF2WithHmacSHA256 372 { PBKDF2WithHmacSHA256UTF8()373 public PBKDF2WithHmacSHA256UTF8() 374 { 375 super("PBKDF2WithHmacSHA256", PKCS5S2_UTF8); 376 } 377 } 378 379 380 public static class BasePBKDF2WithHmacSHA384 extends BasePBKDF2 { BasePBKDF2WithHmacSHA384(String name, int scheme)381 public BasePBKDF2WithHmacSHA384(String name, int scheme) 382 { 383 super(name, scheme, SHA384); 384 } 385 } 386 387 public static class PBKDF2WithHmacSHA384UTF8 388 extends BasePBKDF2WithHmacSHA384 389 { PBKDF2WithHmacSHA384UTF8()390 public PBKDF2WithHmacSHA384UTF8() 391 { 392 super("PBKDF2WithHmacSHA384", PKCS5S2_UTF8); 393 } 394 } 395 396 public static class BasePBKDF2WithHmacSHA512 extends BasePBKDF2 { BasePBKDF2WithHmacSHA512(String name, int scheme)397 public BasePBKDF2WithHmacSHA512(String name, int scheme) 398 { 399 super(name, scheme, SHA512); 400 } 401 } 402 403 public static class PBKDF2WithHmacSHA512UTF8 404 extends BasePBKDF2WithHmacSHA512 405 { PBKDF2WithHmacSHA512UTF8()406 public PBKDF2WithHmacSHA512UTF8() 407 { 408 super("PBKDF2WithHmacSHA512", PKCS5S2_UTF8); 409 } 410 } 411 412 public static class PBEWithHmacSHA1AndAES_128 413 extends BasePBKDF2 { PBEWithHmacSHA1AndAES_128()414 public PBEWithHmacSHA1AndAES_128() { 415 super("PBEWithHmacSHA1AndAES_128", PKCS5S2_UTF8, SHA1, 128, 128); 416 } 417 } 418 419 public static class PBEWithHmacSHA224AndAES_128 420 extends BasePBKDF2 { PBEWithHmacSHA224AndAES_128()421 public PBEWithHmacSHA224AndAES_128() { 422 super("PBEWithHmacSHA224AndAES_128", PKCS5S2_UTF8, SHA224, 128, 128); 423 } 424 } 425 426 public static class PBEWithHmacSHA256AndAES_128 427 extends BasePBKDF2 { PBEWithHmacSHA256AndAES_128()428 public PBEWithHmacSHA256AndAES_128() { 429 super("PBEWithHmacSHA256AndAES_128", PKCS5S2_UTF8, SHA256, 128, 128); 430 } 431 } 432 433 public static class PBEWithHmacSHA384AndAES_128 434 extends BasePBKDF2 { PBEWithHmacSHA384AndAES_128()435 public PBEWithHmacSHA384AndAES_128() { 436 super("PBEWithHmacSHA384AndAES_128", PKCS5S2_UTF8, SHA384, 128, 128); 437 } 438 } 439 440 public static class PBEWithHmacSHA512AndAES_128 441 extends BasePBKDF2 { PBEWithHmacSHA512AndAES_128()442 public PBEWithHmacSHA512AndAES_128() { 443 super("PBEWithHmacSHA512AndAES_128", PKCS5S2_UTF8, SHA512, 128, 128); 444 } 445 } 446 447 448 public static class PBEWithHmacSHA1AndAES_256 449 extends BasePBKDF2 { PBEWithHmacSHA1AndAES_256()450 public PBEWithHmacSHA1AndAES_256() { 451 super("PBEWithHmacSHA1AndAES_256", PKCS5S2_UTF8, SHA1, 256, 128); 452 } 453 } 454 455 public static class PBEWithHmacSHA224AndAES_256 456 extends BasePBKDF2 { PBEWithHmacSHA224AndAES_256()457 public PBEWithHmacSHA224AndAES_256() { 458 super("PBEWithHmacSHA224AndAES_256", PKCS5S2_UTF8, SHA224, 256, 128); 459 } 460 } 461 462 public static class PBEWithHmacSHA256AndAES_256 463 extends BasePBKDF2 { PBEWithHmacSHA256AndAES_256()464 public PBEWithHmacSHA256AndAES_256() { 465 super("PBEWithHmacSHA256AndAES_256", PKCS5S2_UTF8, SHA256, 256, 128); 466 } 467 } 468 469 public static class PBEWithHmacSHA384AndAES_256 470 extends BasePBKDF2 { PBEWithHmacSHA384AndAES_256()471 public PBEWithHmacSHA384AndAES_256() { 472 super("PBEWithHmacSHA384AndAES_256", PKCS5S2_UTF8, SHA384, 256, 128); 473 } 474 } 475 476 public static class PBEWithHmacSHA512AndAES_256 477 extends BasePBKDF2 { PBEWithHmacSHA512AndAES_256()478 public PBEWithHmacSHA512AndAES_256() { 479 super("PBEWithHmacSHA512AndAES_256", PKCS5S2_UTF8, SHA512, 256, 128); 480 } 481 } 482 // END android-added 483 484 public static class Mappings 485 extends AlgorithmProvider 486 { 487 private static final String PREFIX = PBEPBKDF2.class.getName(); 488 Mappings()489 public Mappings() 490 { 491 } 492 configure(ConfigurableProvider provider)493 public void configure(ConfigurableProvider provider) 494 { 495 // BEGIN android-comment 496 // Context: many of these services used to be in 497 // com.android.org.bouncycastle.jcajce.provider.digest,SHA1, duplicated with respect to here. This 498 // class (PBEPBKDF2) wasn't present in Android until the upgrade to 1.56. Android added 499 // some other of these services in SHA1 (for fixed key sizes). Then the duplicate 500 // algorithms were removed upstream from SHA1 in 501 // b5634e3155e7fd8688599d3eef8e4f3c8a1db078 502 // . As a result, when adapting BouncyCastle 1.56 from upstream, the Android code that 503 // had been added to SHA1 was moved here, and the rest of the services provided by this 504 // class were commented. 505 // BEGIN android-removed 506 // provider.addAlgorithm("AlgorithmParameters.PBKDF2", PREFIX + "$AlgParams"); 507 // provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2"); 508 // provider.addAlgorithm("SecretKeyFactory.PBKDF2", PREFIX + "$PBKDF2withUTF8"); 509 // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1", "PBKDF2"); 510 // END android-removed 511 // BEGIN android-changed 512 // Was: provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1ANDUTF8", "PBKDF2"); 513 provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WithHmacSHA1AndUTF8", "PBKDF2WithHmacSHA1"); 514 // END android-changed 515 // BEGin android-removed 516 // provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2"); 517 // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHASCII", PREFIX + "$PBKDF2with8BIT"); 518 // END android-removed 519 // BEGIN android-changed 520 // Was: 521 // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITH8BIT", "PBKDF2WITHASCII"); 522 // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1AND8BIT", "PBKDF2WITHASCII"); 523 provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2with8BIT", "PBKDF2WithHmacSHA1And8BIT"); 524 // END android-changed 525 // BEGIN android-added 526 provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2withASCII", "PBKDF2WithHmacSHA1And8BIT"); 527 // BEGIN android-removed 528 // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA224", PREFIX + "$PBKDF2withSHA224"); 529 // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA256", PREFIX + "$PBKDF2withSHA256"); 530 // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA384", PREFIX + "$PBKDF2withSHA384"); 531 // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA512", PREFIX + "$PBKDF2withSHA512"); 532 // END android-removed 533 // BEGIN android-added 534 provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1", PREFIX + "$PBKDF2WithHmacSHA1UTF8"); 535 provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA224", PREFIX + "$PBKDF2WithHmacSHA224UTF8"); 536 provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA256", PREFIX + "$PBKDF2WithHmacSHA256UTF8"); 537 provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA384", PREFIX + "$PBKDF2WithHmacSHA384UTF8"); 538 provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA512", PREFIX + "$PBKDF2WithHmacSHA512UTF8"); 539 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_128", PREFIX + "$PBEWithHmacSHA1AndAES_128"); 540 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_128", PREFIX + "$PBEWithHmacSHA224AndAES_128"); 541 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_128", PREFIX + "$PBEWithHmacSHA256AndAES_128"); 542 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_128", PREFIX + "$PBEWithHmacSHA384AndAES_128"); 543 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_128", PREFIX + "$PBEWithHmacSHA512AndAES_128"); 544 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_256", PREFIX + "$PBEWithHmacSHA1AndAES_256"); 545 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_256", PREFIX + "$PBEWithHmacSHA224AndAES_256"); 546 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_256", PREFIX + "$PBEWithHmacSHA256AndAES_256"); 547 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_256", PREFIX + "$PBEWithHmacSHA384AndAES_256"); 548 provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256"); 549 provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT"); 550 // END android-added 551 } 552 } 553 } 554