Summary
-------
Support additional pseudo random functions (PRFs) and encryption schemes. Provide better fail-fast error checking during initialization.
Problem
-------
JDK-8076999 outlined multiple processing issues with PBES2-based `AlgorithmParameters`. Some of these issues were fixed as part of JDK-8202837, but one issue (additional algorithm support) remained unaddressed. During the fix for this remaining issue, other problems were uncovered in the state machine for PBES2-based `AlgorithmParameters` initialization which necessitated further behavioral changes.
Solution
--------
The solution has multiple components:
### Additional PRF and Cipher support:
Currently `AlgorithmParameters` only supports the following combinations of pseudorandom functions (PRFs) and Ciphers:
| PRFs | Ciphers |
|:------------|:----------------|
| HmacSHA1 | AES_128 |
| HmacSHA224 | AES_256 |
| HmacSHA256 | |
| HmacSHA384 | |
| HmacSHA512 | |
These strings are used to create a standard name used with `AlgorithmParameters` of the form `PBEWith<prf>And<cipher>` (e.g. PBEWithHmacSHA256AndAES_256). When initialized via the `init(byte[])` method, only those DER encodings that advertise the above PRFs and Ciphers can be successfully processed.
This fix will now allow the SunJCE provider's `AlgorithmParameters` PBES2 implementation to accept encodings that advertise the HmacSHA512/224 and HmacSHA512/256 PRFs and the following additional ciphers: AES_192, DES, DESede (Triple-DES), RC2, and RC5. These algorithms all have `AlgorithmParameterSpec` classes designed for them and are detailed in [RFC 8018.][rfc8018]
In addition, we will be adding a new SunJCE `AlgorithmParameters` implementation for RC5 parameters, using the standard name "RC5". The parameters are described in [RFC 2040][rfc2040] and [RFC 8018][rfc8018].
Accepting these new algorithms in the PBES2 parameter encodings only covers the PBES2 parameters themselves. It does not guarantee PBE `Cipher` or `SecretKeyFactory` support in the SunJCE provider. The `AlgorithmParameters` object may be used with other JCE providers' Cipher and/or SecretKeyFactory implementations.
### Standard Names
We are proposing two new AlgorithmParameters standard names in the SunJCE provider:
| Name | Description |
|:--------------------|:------------------------------|
| RC5 | The `RC5_CBC_Parameters` as described in [RFC 2040][rfc2040] and [RFC 8018][rfc8018] |
| PBES2 | A generic PBES2 `AlgorithmParameters` object |
The algorithm string "PBES2" can be used to instantiate a generic PBES2-based `AlgorithmParameters` object that can accept DER-encodings with the any of the supported PRFs and Ciphers listed above.
### Improved Initialization Fail-Fast Behavior
There are two ways to instantiate PBES2-based `AlgorithmParameters` objects. The first is by a generic name "PBES2". The second is via a fully-qualified name indicating the PRF and encryption scheme (e.g. PBEWithHmacSHA256AndAES_128). Initialization can happen either by providing DER encoded parameter data as a byte array or via an `AlgorithmParameterSpec`. The current interactions between instantiation and initialization methods allowed certain combinations to cause incompatibilities that were not caught at initialization time, and would only happen when later used by the consumer of the AlgorithmParameters object. The following section details how this will be corrected.
### Consistency Between Fully-Qualified Name and Encoding
In the current implementation it is possible to create the object using a string such as "PBEWithHmacSHA256AndAES_128", but initialize it with DER encodings using a different PRF and/or encryption scheme. The proposed changes will cause an `IOException` to be thrown on the `init` methods that take DER encodings when either the PRF or encryption scheme OIDs do not match the requested types in the `getInstance()` call. These init methods already throw IOException on decoding errors, but this behavioral change makes the SunJCE implementation adhere more strictly to the specification by requiring better consistency between the requested and received algorithm types in the encoding.
### Consistency Between Fully-Qualified Algorithm Name and Provided AlgorithmParameterSpec
Another method of initialization can happen through the submission of an `AlgorithmParameterSpec` (specifically a `javax.crypto.spec.PBEParameterSpec`). The PBES2 Cipher may itself have additional configuration options provided to it via `PBEParameterSpec.getParameterSpec()`.
Currently, there is no checking performed to ensure that the `AlgorithmParameterSpec` retrieved by `PBEParameterSpec.getParameterSpec()` matches the type appropriate for the Cipher. The proposed change will now check the Cipher `AlgorithmParameterSpec` to make sure it is the correct type. Failure to use the correct class or derived subclass from that type will cause `InvalidParameterSpecException` to be thrown. The table below shows a sample fully qualified name and its corresponding Cipher's 'AlgorithmParameterSpec' type:
| Encryption Scheme | AlgorithmParameterSpec |
|:--------------------|:----------------------|
| PBEWithSHA256AndAES_128 | javax.crypto.spec.IvParameterSpec |
| PBEWithSHA256AndAES_192 | javax.crypto.spec.IvParameterSpec |
| PBEWithSHA256AndAES_256 | javax.crypto.spec.IvParameterSpec |
| PBEWithSHA256AndDES | javax.crypto.spec.IvParameterSpec |
| PBEWithSHA256AndDESede | javax.crypto.spec.IvParameterSpec |
| PBEWithSHA256AndRC2_<nn>| javax.crypto.spec.RC2ParameterSpec |
| PBEWithSHA256AndRC5_<nn> | javax.crypto.spec.RC5ParameterSpec |
Because there are multiple encryption schemes that use the same `AlgorithmParameterSpec` concrete class, the generic "PBES2" standard name cannot be used to instantiate the PBES2 `AlgorithmParameters` object if `init(AlgorithmParameterSpec)` is used. If this is attempted, `InvalidParameterSpecException` will be thrown.
In addition to type enforcement, when the `init(AlgorithmParameterSpec)` method is used the contents of the `AlgorithmParameterSpec` will be tested to make sure the values are consistent with the algorithm they are configuring. For instance, if AES is selected, a provided `IvParameterSpec` will have the output length from the `getIV()` method tested to make sure it is 16 bytes.
Specification
-------------
`RC5`: Standard name for the RC5_CBC_Parameters encoding as an `AlgorithmParameters` object.
`PBES2`: Standard name for generic PBES2 `AlgorithmParameters` encodings.
[rfc2040]: https://tools.ietf.org/html/rfc2040
[rfc8018]: https://tools.ietf.org/html/rfc8018