Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-25 Thread Valerie Peng
On Fri, 14 May 2021 00:33:12 GMT, Valerie Peng  wrote:

>> This change updates SunJCE provider as below:
>> - updated existing AESWrap support with AES/KW/NoPadding cipher 
>> transformation. 
>> - added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.
>> 
>> Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed 
>> to KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil 
>> class. The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded 
>> classes which extend FeedbackCipher and used in KeyWrapCipher class. To 
>> minimize data copying, AESKeyWrap and AESKeyWrapPadded will do the crypto 
>> operation over the same input buffer which is allocated and managed by 
>> KeyWrapCipher class. 
>> 
>> Also note that existing AESWrap impl does not take IV. However, the 
>> corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
>> both KW and KWP.
>> 
>> Thanks,
>> Valerie
>
> Valerie Peng has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains seven commits:
> 
>  - Merge master into JDK-8248268
>  - Minor update to address review comments.
>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>KWParameters and KWPParameters.
>  - Refactor code to reduce code duplication
>Address review comments
>Add more test vectors
>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>AES/KWP/NoPadding
>  - Restored Iv algorithm parameters impl.
>  - 8248268: Support KWP in addition to KW
>
>Updated existing AESWrap support with AES/KW/NoPadding cipher
>transformation. Added support for AES/KWP/NoPadding and
>AES/KW/PKCS5Padding support to SunJCE provider.

Current impl takes account into RFC 3394 (Sept 2002), RFC 5649 (Aug 2009), NIST 
800-38F (Dec 2012) and PKCS#11 v3.0 Current Mech Spec (June 2020) and tries to 
support them all. If solely basing on RFC 3394/5649, then AES KW and KWP cipher 
should just supports key wrap/unwrap but not enc/dec. The main reason that I 
added the support for alternative iv and enc/dec is more for NIST 800-38F which 
states that KW/KWP can be used for general data protection as well and PKCS#11 
v3.0 which lists 3 mechanisms mapping to java's AES using KW, AES using KW and 
PKCS5Padding and AES using KWP. These 3 mechanisms supports all 4, i.e. 
enc/dec/wrap/unwrap, as well custom IVs (8-byte for KW and 4-byte for KWP). 
Naming can be a very subjective matter and putting it aside, I don't see why KW 
and KWP should not allow custom IVs? Isn't hardcoded values less secure or 
fragile in general?

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-24 Thread Valerie Peng
On Sat, 22 May 2021 01:02:50 GMT, Xue-Lei Andrew Fan  wrote:

>> Valerie Peng has updated the pull request with a new target base due to a 
>> merge or a rebase. The pull request now contains seven commits:
>> 
>>  - Merge master into JDK-8248268
>>  - Minor update to address review comments.
>>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>>KWParameters and KWPParameters.
>>  - Refactor code to reduce code duplication
>>Address review comments
>>Add more test vectors
>>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>>AES/KWP/NoPadding
>>  - Restored Iv algorithm parameters impl.
>>  - 8248268: Support KWP in addition to KW
>>
>>Updated existing AESWrap support with AES/KW/NoPadding cipher
>>transformation. Added support for AES/KWP/NoPadding and
>>AES/KW/PKCS5Padding support to SunJCE provider.
>
> src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java line 
> 176:
> 
>> 174: return ConstructKeys.constructPublicKey(encoding, 
>> keyAlgorithm);
>> 175: default:
>> 176: throw new RuntimeException("Unsupported key type");
> 
> Good improvement to thrown an exception rather than return "null"!
> 
> Is NoSuchAlgorithmException fitted better the specification?  See also the 
> comment in  KeyWrapCipher.engineUnwrap().

Yes, will change.

> src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java line 
> 710:
> 
>> 708: outLen = helperDecrypt(dataBuf, dataIdx);
>> 709: return ConstructKeys.constructKey(dataBuf, 0, outLen,
>> 710: wrappedKeyAlgorithm, wrappedKeyType);
> 
> Per the specification of engineUnwrap,  maybe, the 
> ConstructKeys.constructKey() implementation could throw 
> NoSuchAlgorithmException if wrappedKeyType is unknown.  See the common in the 
> the ConstructKeys.constructKey() implementation.

Sure, makes sense.

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-24 Thread Michael StJohns

Some more general comments - related to the restructuring.

In AESKeyWrap at 152-155 - that check probably should be moved to W().   
KWP should do the formatting prior to passing the data to W().  Also at 
185-187 - move that to W_INV().


AESKeyWrap at 158 - shouldn't you be returning the cipher text length?  
That's what the comment in FeedbackCipher says.  W() should probably be 
returning the final length.


The length of the final ciphertext data should be 8 bytes longer than 
the plaintext. decryptFinal() seems to do the right thing by decreasing 
the length returned.   But again - shouldn't that be the purview of W_INV()?


The call in KeyWrapCipher.engineGetOutputSize() should probably also be 
passed into KWUtil rather than being  done in KeyWrapCipher.  And the 
more I look at this, the more I think that all of the engineUpdate 
operations should throw UnsupportedOperationException - it would 
certainly simplify the logic.  That would make the call return either  
inputLength + 8 or inputLength - 8 depending on mode.


KWUtil.W() - should probably check that in.length >= inLen + 8 and throw 
a ShortBufferException if not.


Would it be useful to add a comment in KeyWrapCipher that  warns 
maintainers that  AESKeyWrap(Padded).encryptFinal() and decryptFinal() 
uses the input buffer as the output buffer? That's a reasonable approach 
for decryption, but I'm wondering if you might want to support in-place 
encryption as there's no spec prohibition requiring data to be held 
until the encryption is complete.


Mike









On 5/24/2021 7:01 PM, Valerie Peng wrote:

On Fri, 21 May 2021 20:44:57 GMT, Xue-Lei Andrew Fan  wrote:


Valerie Peng has updated the pull request with a new target base due to a merge 
or a rebase. The pull request now contains seven commits:

  - Merge master into JDK-8248268
  - Minor update to address review comments.
  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
KWParameters and KWPParameters.
  - Refactor code to reduce code duplication
Address review comments
Add more test vectors
  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
AES/KWP/NoPadding
  - Restored Iv algorithm parameters impl.
  - 8248268: Support KWP in addition to KW

Updated existing AESWrap support with AES/KW/NoPadding cipher

transformation. Added support for AES/KWP/NoPadding and
AES/KW/PKCS5Padding support to SunJCE provider.

src/java.base/share/classes/com/sun/crypto/provider/AESParameters.java line 50:


48:
49: public AESParameters() {
50: core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE, 4, 8);

A cipher object may not take different IV sizes at the same time.  I was just 
wondering how it could be used in practice.  Maybe something like:


AlgorithmParameters algParams = AlgorithmParameters.getInstance("AES");
algParams.init(ivParameterSpec);

The IV parameter is given with the init() method.  Then, it may be not 
necessary to construct the BlockCipherParamsCore object will all potential IV 
sizes.  See the comments in BlockCipherParamsCore.

Cipher objects normally takes just one iv size. BlockCipherParamsCore is used 
by various impls of AlgorithmParametersSpi class which may be used with 
different block cipher algorithms. The iv parameter is given with the 
AlgorithmParametersSpi.init() method and invalid iv will lead to exceptions. 
Since there are iv size checks built in BlockCipherParamsCore already, it seems 
safer to relax the check a bit for AES (4 and 8 for KWP and KW). The other 
choice is to just remove the size check from BlockCipherParamsCore for AES 
algorithm, but then we'd not be able to reject invalid iv lengths as before.


src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java 
line 52:


50: private byte[] iv = null;
51:
52: private int[] moreSizes = null;

The moreSizes is not used other than the init() method field.  It may be not 
easy to check the specific size if we cache all supported sized in the object.  
For example, if the required IV size if 8 bytes, it may be a problem about how 
to make sure the iv size is 8 bytes exactly for a specific algorithm.

Maybe, we could just have a ivSize filed.  The default value is block_size, 
which coupe be set with the init(ivParameterSpec) method.


 
 private int ivSize;
 ...
BlockCipherParamsCore(int blkSize) {
block_size = blkSize;
ivSize = blkSize;
 }
 ...
void init(AlgorithmParameterSpec paramSpec) {
 ivSize = ...;  // reset IV size.
 }

 // use ivSize while encoding and decoding.

The problem with this is that this assumes that the specified paramSpec 
argument of the init() method is always valid.

-

PR: https://git.openjdk.java.net/jdk/pull/2404





Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-24 Thread Valerie Peng
On Sat, 22 May 2021 00:45:27 GMT, Xue-Lei Andrew Fan  wrote:

>> Valerie Peng has updated the pull request with a new target base due to a 
>> merge or a rebase. The pull request now contains seven commits:
>> 
>>  - Merge master into JDK-8248268
>>  - Minor update to address review comments.
>>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>>KWParameters and KWPParameters.
>>  - Refactor code to reduce code duplication
>>Address review comments
>>Add more test vectors
>>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>>AES/KWP/NoPadding
>>  - Restored Iv algorithm parameters impl.
>>  - 8248268: Support KWP in addition to KW
>>
>>Updated existing AESWrap support with AES/KW/NoPadding cipher
>>transformation. Added support for AES/KWP/NoPadding and
>>AES/KW/PKCS5Padding support to SunJCE provider.
>
> src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java line 
> 190:
> 
>> 188: return constructKey(encoding, keyAlgorithm, keyType);
>> 189: } else {
>> 190: byte[] encoding2 = Arrays.copyOfRange(encoding, ofs, 
>> ofs + len);
> 
> The array will be copied again in the X509EncodedKeySpec and 
> PKCS8EncodedKeySpec.  It is out of this scope, but it may be a performance 
> improvement if adding X509EncodedKeySpec and PKCS8EncodedKeySpec constructors 
> that accept array offset, so that the array copy here could be avoid.

Right, maybe there is no constructor which takes offset and length due to 
trying to avoid the cost of validating them. I recall seeing other *Spec 
classes whose list of constructors are similar to 
X509EncodedKeySpec/PKCS8EncodedKeySpec as well.

> src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java line 
> 192:
> 
>> 190: byte[] encoding2 = Arrays.copyOfRange(encoding, ofs, 
>> ofs + len);
>> 191: try {
>> 192: return constructKey(encoding2, keyAlgorithm, 
>> keyType);
> 
> The two constructKey methods are depended on each other.  It may improve the 
> readability if only having one-way dependence, by moving the switch-block 
> logic from the former constructKey() to the later one.
> 
> 
>  static final Key constructKey(byte[] encoding, String keyAlgorithm,
>int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
> return constructKey(encoding, 0. encoding.length, keyAlgorithm, keyType);
> }
> 
> 
> With this re-org, the array copy could be avoid if the key type is unknown.

Yes, I will refactor the two constructKey() methods as you suggested.

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-24 Thread Valerie Peng
On Fri, 21 May 2021 20:44:57 GMT, Xue-Lei Andrew Fan  wrote:

>> Valerie Peng has updated the pull request with a new target base due to a 
>> merge or a rebase. The pull request now contains seven commits:
>> 
>>  - Merge master into JDK-8248268
>>  - Minor update to address review comments.
>>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>>KWParameters and KWPParameters.
>>  - Refactor code to reduce code duplication
>>Address review comments
>>Add more test vectors
>>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>>AES/KWP/NoPadding
>>  - Restored Iv algorithm parameters impl.
>>  - 8248268: Support KWP in addition to KW
>>
>>Updated existing AESWrap support with AES/KW/NoPadding cipher
>>transformation. Added support for AES/KWP/NoPadding and
>>AES/KW/PKCS5Padding support to SunJCE provider.
>
> src/java.base/share/classes/com/sun/crypto/provider/AESParameters.java line 
> 50:
> 
>> 48: 
>> 49: public AESParameters() {
>> 50: core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE, 4, 
>> 8);
> 
> A cipher object may not take different IV sizes at the same time.  I was just 
> wondering how it could be used in practice.  Maybe something like:
> 
> 
> AlgorithmParameters algParams = AlgorithmParameters.getInstance("AES");
> algParams.init(ivParameterSpec);
> 
> The IV parameter is given with the init() method.  Then, it may be not 
> necessary to construct the BlockCipherParamsCore object will all potential IV 
> sizes.  See the comments in BlockCipherParamsCore.

Cipher objects normally takes just one iv size. BlockCipherParamsCore is used 
by various impls of AlgorithmParametersSpi class which may be used with 
different block cipher algorithms. The iv parameter is given with the 
AlgorithmParametersSpi.init() method and invalid iv will lead to exceptions. 
Since there are iv size checks built in BlockCipherParamsCore already, it seems 
safer to relax the check a bit for AES (4 and 8 for KWP and KW). The other 
choice is to just remove the size check from BlockCipherParamsCore for AES 
algorithm, but then we'd not be able to reject invalid iv lengths as before.

> src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java
>  line 52:
> 
>> 50: private byte[] iv = null;
>> 51: 
>> 52: private int[] moreSizes = null;
> 
> The moreSizes is not used other than the init() method field.  It may be not 
> easy to check the specific size if we cache all supported sized in the 
> object.  For example, if the required IV size if 8 bytes, it may be a problem 
> about how to make sure the iv size is 8 bytes exactly for a specific 
> algorithm.
> 
> Maybe, we could just have a ivSize filed.  The default value is block_size, 
> which coupe be set with the init(ivParameterSpec) method.
> 
> 
> 
> private int ivSize;
> ...
>BlockCipherParamsCore(int blkSize) {
>block_size = blkSize;
>ivSize = blkSize;
> }
> ...
>void init(AlgorithmParameterSpec paramSpec) {
> ivSize = ...;  // reset IV size.
> }
> 
> // use ivSize while encoding and decoding.

The problem with this is that this assumes that the specified paramSpec 
argument of the init() method is always valid.

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-24 Thread Valerie Peng
On Fri, 21 May 2021 19:15:49 GMT, Xue-Lei Andrew Fan  wrote:

>> Valerie Peng has updated the pull request with a new target base due to a 
>> merge or a rebase. The pull request now contains seven commits:
>> 
>>  - Merge master into JDK-8248268
>>  - Minor update to address review comments.
>>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>>KWParameters and KWPParameters.
>>  - Refactor code to reduce code duplication
>>Address review comments
>>Add more test vectors
>>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>>AES/KWP/NoPadding
>>  - Restored Iv algorithm parameters impl.
>>  - 8248268: Support KWP in addition to KW
>>
>>Updated existing AESWrap support with AES/KW/NoPadding cipher
>>transformation. Added support for AES/KWP/NoPadding and
>>AES/KW/PKCS5Padding support to SunJCE provider.
>
> src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java
>  line 81:
> 
>> 79: expectedLen + " bytes long");
>> 80: }
>> 81: iv = tmpIv.clone();
> 
> The moreSizes is not used after initialization.  The iv/tmpIv could be a 
> value other than the block_size.   The getEncoded() method would use the iv 
> value for the encoding.  While in the decoding method init(byte[]) method, 
> the IV sizes other block_size is not considered, and IOE will be thrown.  
> Could this be a problem?

Right, good catch, I will fix it.

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-22 Thread Michael StJohns

On 5/22/2021 1:57 PM, Xue-Lei Andrew Fan wrote:

On Fri, 14 May 2021 00:33:12 GMT, Valerie Peng  wrote:


This change updates SunJCE provider as below:
- updated existing AESWrap support with AES/KW/NoPadding cipher transformation.
- added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.

Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed to 
KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil class. 
The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded classes 
which extend FeedbackCipher and used in KeyWrapCipher class. To minimize data 
copying, AESKeyWrap and AESKeyWrapPadded will do the crypto operation over the 
same input buffer which is allocated and managed by KeyWrapCipher class.

Also note that existing AESWrap impl does not take IV. However, the 
corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
both KW and KWP.

Thanks,
Valerie

Valerie Peng has updated the pull request with a new target base due to a merge 
or a rebase. The pull request now contains seven commits:

  - Merge master into JDK-8248268
  - Minor update to address review comments.
  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
KWParameters and KWPParameters.
  - Refactor code to reduce code duplication
Address review comments
Add more test vectors
  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
AES/KWP/NoPadding
  - Restored Iv algorithm parameters impl.
  - 8248268: Support KWP in addition to KW

Updated existing AESWrap support with AES/KW/NoPadding cipher

transformation. Added support for AES/KWP/NoPadding and
AES/KW/PKCS5Padding support to SunJCE provider.

Good points, Mike!  Thank you!


_Mailing list message from [Michael StJohns](mailto:mstjo...@comcast.net) on 
[security-dev](mailto:security-...@mail.openjdk.java.net):_

src/java.base/share/classes/com/sun/crypto/provider/AESParameters.java line 50:

48:
49: public AESParameters() {
50: core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE, 4, 8);
A cipher object may not take different IV sizes at the same time.  I was just 
wondering how it could be used in practice.  Maybe something like:

The mode is KW - it has a fixed length 8 byte non-iv integrity tag.???
KWP is a special case of KW where there's still an 8 byte tag, but part
of it is interpreted by KWP to figure out how much padding was
included.?? KW (AKA RFC3394) permits user (actually specification
specified) IV values.? KWP (aka RFC5649) does not.


Hm, I missed this point.  KW (RFC 3394) supports Alternative IV (AIV), while 
KWP is just a case about how to construct the alternative IV for KWP operations.


Yes.  Sorry if I wasn't clearer in earlier emails.




I'd treat KWP as a final (in the Java final sense) extension to KW with
a fixed AIV flag value and a defined interpretation for the 8 byte AIV
tag.? E.g. if you try to specify an IV for KWP, it should fail.?? If
someone else wants to do something like KWP or even twiddle with the 4
byte AIV, let them do their own KW wrap around - which they should be
able to do that via the KW/NoPadding model by specifying their own AIV.?
That should improve interoperability by preventing some monkey see
monkey do errors.


I agreed.  Maybe, we could do:
1. Support Alternative IV for KW, for the flexibility as described in section 
2.2.3.2 of RFC 3394.


I think that's acceptable.  Hmm... is it possible to make the set ICV 
call protected rather than public?   Generally, the defined ICVs match 
up with specific algorithm OIDS.  You shouldn't see a third one unless 
someone defines a brand new variant.  But you want to make it possible 
for someone to do an extension.



2. Use default IV if no AIV specified for KW, as described in section 2.2.3.1 
of RFC 3394.

Works.  Or see the above.

3. Use a fixed IV for KWP, as described in section 3of RFC 5649.

Yes.



This is sort of one reason I was arguing for AES/KW/KWPPadding rather
than AES/KWP/NoPadding.


I thought of the "AES/KW/KWPPadding" style as well.  The "AES/KWP/NoPadding" looks a 
little bit weird to me because there is padding while we call it with "NoPadding".

KWP is not exactly like the traditional AES/CBC/PKCS5Padding, where the 
components could be treated separately.  The padding scheme of KWP impact the 
IV as well.  So it was arguable to me.


We keep referring to it as an IV  - but it isn't - it's an Integrity 
Check Value.  Unlike an IV, it doesn't inform the decryption stage, it's 
only checked after the decryption is complete.  (E.g. in a mode with an 
IV, you need to know the IV before you encrypt and before you decrypt).  
Then there's this from Section 6.3 of SP800-38F.



Let S = ICV2|| [len(P)/8]32 || P|| PAD



Step 5 of the KWP-AE algorithm basically passes the A65959A6 value 
pre-prepended to the pad length both pre-pended to the padded data 
through to W().


The equivalent for KW-AE is step 2 

Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-22 Thread Xue-Lei Andrew Fan
On Fri, 14 May 2021 00:33:12 GMT, Valerie Peng  wrote:

>> This change updates SunJCE provider as below:
>> - updated existing AESWrap support with AES/KW/NoPadding cipher 
>> transformation. 
>> - added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.
>> 
>> Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed 
>> to KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil 
>> class. The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded 
>> classes which extend FeedbackCipher and used in KeyWrapCipher class. To 
>> minimize data copying, AESKeyWrap and AESKeyWrapPadded will do the crypto 
>> operation over the same input buffer which is allocated and managed by 
>> KeyWrapCipher class. 
>> 
>> Also note that existing AESWrap impl does not take IV. However, the 
>> corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
>> both KW and KWP.
>> 
>> Thanks,
>> Valerie
>
> Valerie Peng has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains seven commits:
> 
>  - Merge master into JDK-8248268
>  - Minor update to address review comments.
>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>KWParameters and KWPParameters.
>  - Refactor code to reduce code duplication
>Address review comments
>Add more test vectors
>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>AES/KWP/NoPadding
>  - Restored Iv algorithm parameters impl.
>  - 8248268: Support KWP in addition to KW
>
>Updated existing AESWrap support with AES/KW/NoPadding cipher
>transformation. Added support for AES/KWP/NoPadding and
>AES/KW/PKCS5Padding support to SunJCE provider.

Good points, Mike!  Thank you!

> _Mailing list message from [Michael StJohns](mailto:mstjo...@comcast.net) on 
> [security-dev](mailto:security-...@mail.openjdk.java.net):_
> > src/java.base/share/classes/com/sun/crypto/provider/AESParameters.java line 
> > 50:
> > > 48:
> > > 49: public AESParameters() {
> > > 50: core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE, 
> > > 4, 8);
> > > A cipher object may not take different IV sizes at the same time.  I was 
> > > just wondering how it could be used in practice.  Maybe something like:
> 
> The mode is KW - it has a fixed length 8 byte non-iv integrity tag.???
> KWP is a special case of KW where there's still an 8 byte tag, but part
> of it is interpreted by KWP to figure out how much padding was
> included.?? KW (AKA RFC3394) permits user (actually specification
> specified) IV values.? KWP (aka RFC5649) does not.
> 
Hm, I missed this point.  KW (RFC 3394) supports Alternative IV (AIV), while 
KWP is just a case about how to construct the alternative IV for KWP operations.

> I'd treat KWP as a final (in the Java final sense) extension to KW with
> a fixed AIV flag value and a defined interpretation for the 8 byte AIV
> tag.? E.g. if you try to specify an IV for KWP, it should fail.?? If
> someone else wants to do something like KWP or even twiddle with the 4
> byte AIV, let them do their own KW wrap around - which they should be
> able to do that via the KW/NoPadding model by specifying their own AIV.?
> That should improve interoperability by preventing some monkey see
> monkey do errors.
> 

I agreed.  Maybe, we could do:
1. Support Alternative IV for KW, for the flexibility as described in section 
2.2.3.2 of RFC 3394.
2. Use default IV if no AIV specified for KW, as described in section 2.2.3.1 
of RFC 3394.
3. Use a fixed IV for KWP, as described in section 3of RFC 5649.

> This is sort of one reason I was arguing for AES/KW/KWPPadding rather
> than AES/KWP/NoPadding.
> 

I thought of the "AES/KW/KWPPadding" style as well.  The "AES/KWP/NoPadding" 
looks a little bit weird to me because there is padding while we call it with 
"NoPadding".

KWP is not exactly like the traditional AES/CBC/PKCS5Padding, where the 
components could be treated separately.  The padding scheme of KWP impact the 
IV as well.  So it was arguable to me.

Finally I feel better of the "AES/KWP/NoPadding" when I read the NIST SP title 
again, "Recommendation for Block Cipher Modes of Operation: Methods for Key 
Wrapping".  Maybe, it is an industry accepted notation to treat KWP as a block 
cipher mode.

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-22 Thread Michael StJohns

In line

On 5/21/2021 5:01 PM, Xue-Lei Andrew Fan wrote:

On Fri, 14 May 2021 00:33:12 GMT, Valerie Peng  wrote:


This change updates SunJCE provider as below:
- updated existing AESWrap support with AES/KW/NoPadding cipher transformation.
- added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.

Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed to 
KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil class. 
The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded classes 
which extend FeedbackCipher and used in KeyWrapCipher class. To minimize data 
copying, AESKeyWrap and AESKeyWrapPadded will do the crypto operation over the 
same input buffer which is allocated and managed by KeyWrapCipher class.

Also note that existing AESWrap impl does not take IV. However, the 
corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
both KW and KWP.

Thanks,
Valerie

Valerie Peng has updated the pull request with a new target base due to a merge 
or a rebase. The pull request now contains seven commits:

  - Merge master into JDK-8248268
  - Minor update to address review comments.
  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
KWParameters and KWPParameters.
  - Refactor code to reduce code duplication
Address review comments
Add more test vectors
  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
AES/KWP/NoPadding
  - Restored Iv algorithm parameters impl.
  - 8248268: Support KWP in addition to KW

Updated existing AESWrap support with AES/KW/NoPadding cipher

transformation. Added support for AES/KWP/NoPadding and
AES/KW/PKCS5Padding support to SunJCE provider.

src/java.base/share/classes/com/sun/crypto/provider/AESParameters.java line 50:


48:
49: public AESParameters() {
50: core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE, 4, 8);

A cipher object may not take different IV sizes at the same time.  I was just 
wondering how it could be used in practice.  Maybe something like:


The mode is KW - it has a fixed length 8 byte non-iv integrity tag.    
KWP is a special case of KW where there's still an 8 byte tag, but part 
of it is interpreted by KWP to figure out how much padding was 
included.   KW (AKA RFC3394) permits user (actually specification 
specified) IV values.  KWP (aka RFC5649) does not.


I'd treat KWP as a final (in the Java final sense) extension to KW with 
a fixed AIV flag value and a defined interpretation for the 8 byte AIV 
tag.  E.g. if you try to specify an IV for KWP, it should fail.   If 
someone else wants to do something like KWP or even twiddle with the 4 
byte AIV, let them do their own KW wrap around - which they should be 
able to do that via the KW/NoPadding model by specifying their own AIV.  
That should improve interoperability by preventing some monkey see 
monkey do errors.


This is sort of one reason I was arguing for AES/KW/KWPPadding rather 
than AES/KWP/NoPadding.



Mike






AlgorithmParameters algParams = AlgorithmParameters.getInstance("AES");
algParams.init(ivParameterSpec);

The IV parameter is given with the init() method.  Then, it may be not 
necessary to construct the BlockCipherParamsCore object will all potential IV 
sizes.  See the comments in BlockCipherParamsCore.

src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java 
line 52:


50: private byte[] iv = null;
51:
52: private int[] moreSizes = null;

The moreSizes is not used other than the init() method field.  It may be not 
easy to check the specific size if we cache all supported sized in the object.  
For example, if the required IV size if 8 bytes, it may be a problem about how 
to make sure the iv size is 8 bytes exactly for a specific algorithm.

Maybe, we could just have a ivSize filed.  The default value is block_size, 
which coupe be set with the init(ivParameterSpec) method.


 
 private int ivSize;
 ...
BlockCipherParamsCore(int blkSize) {
block_size = blkSize;
ivSize = blkSize;
 }
 ...
void init(AlgorithmParameterSpec paramSpec) {
 ivSize = ...;  // reset IV size.
 }

 // use ivSize while encoding and decoding.

src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java 
line 81:


79: expectedLen + " bytes long");
80: }
81: iv = tmpIv.clone();

The moreSizes is not used after initialization.  The iv/tmpIv could be a value 
other than the block_size.   The getEncoded() method would use the iv value for 
the encoding.  While in the decoding method init(byte[]) method, the IV sizes 
other block_size is not considered, and IOE will be thrown.  Could this be a 
problem?

-

PR: https://git.openjdk.java.net/jdk/pull/2404





Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-21 Thread Xue-Lei Andrew Fan
On Fri, 14 May 2021 00:33:12 GMT, Valerie Peng  wrote:

>> This change updates SunJCE provider as below:
>> - updated existing AESWrap support with AES/KW/NoPadding cipher 
>> transformation. 
>> - added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.
>> 
>> Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed 
>> to KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil 
>> class. The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded 
>> classes which extend FeedbackCipher and used in KeyWrapCipher class. To 
>> minimize data copying, AESKeyWrap and AESKeyWrapPadded will do the crypto 
>> operation over the same input buffer which is allocated and managed by 
>> KeyWrapCipher class. 
>> 
>> Also note that existing AESWrap impl does not take IV. However, the 
>> corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
>> both KW and KWP.
>> 
>> Thanks,
>> Valerie
>
> Valerie Peng has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains seven commits:
> 
>  - Merge master into JDK-8248268
>  - Minor update to address review comments.
>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>KWParameters and KWPParameters.
>  - Refactor code to reduce code duplication
>Address review comments
>Add more test vectors
>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>AES/KWP/NoPadding
>  - Restored Iv algorithm parameters impl.
>  - 8248268: Support KWP in addition to KW
>
>Updated existing AESWrap support with AES/KW/NoPadding cipher
>transformation. Added support for AES/KWP/NoPadding and
>AES/KW/PKCS5Padding support to SunJCE provider.

src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java line 176:

> 174: return ConstructKeys.constructPublicKey(encoding, 
> keyAlgorithm);
> 175: default:
> 176: throw new RuntimeException("Unsupported key type");

Good improvement to thrown an exception rather than return "null"!

Is NoSuchAlgorithmException fitted better the specification?  See also the 
comment in  KeyWrapCipher.engineUnwrap().

src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java line 190:

> 188: return constructKey(encoding, keyAlgorithm, keyType);
> 189: } else {
> 190: byte[] encoding2 = Arrays.copyOfRange(encoding, ofs, ofs 
> + len);

The array will be copied again in the X509EncodedKeySpec and 
PKCS8EncodedKeySpec.  It is out of this scope, but it may be a performance 
improvement if adding X509EncodedKeySpec and PKCS8EncodedKeySpec constructors 
that accept array offset, so that the array copy here could be avoid.

src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java line 192:

> 190: byte[] encoding2 = Arrays.copyOfRange(encoding, ofs, ofs 
> + len);
> 191: try {
> 192: return constructKey(encoding2, keyAlgorithm, 
> keyType);

The two constructKey methods are depended on each other.  It may improve the 
readability if only having one-way dependence, by moving the switch-block logic 
from the former constructKey() to the later one.


 static final Key constructKey(byte[] encoding, String keyAlgorithm,
   int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
return constructKey(encoding, 0. encoding.length, keyAlgorithm, keyType);
}


With this re-org, the array copy could be avoid if the key type is unknown.

src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java line 710:

> 708: outLen = helperDecrypt(dataBuf, dataIdx);
> 709: return ConstructKeys.constructKey(dataBuf, 0, outLen,
> 710: wrappedKeyAlgorithm, wrappedKeyType);

Per the specification of engineUnwrap,  maybe, the ConstructKeys.constructKey() 
implementation could throw NoSuchAlgorithmException if wrappedKeyType is 
unknown.  See the common in the the ConstructKeys.constructKey() implementation.

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-21 Thread Xue-Lei Andrew Fan
On Fri, 14 May 2021 00:33:12 GMT, Valerie Peng  wrote:

>> This change updates SunJCE provider as below:
>> - updated existing AESWrap support with AES/KW/NoPadding cipher 
>> transformation. 
>> - added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.
>> 
>> Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed 
>> to KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil 
>> class. The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded 
>> classes which extend FeedbackCipher and used in KeyWrapCipher class. To 
>> minimize data copying, AESKeyWrap and AESKeyWrapPadded will do the crypto 
>> operation over the same input buffer which is allocated and managed by 
>> KeyWrapCipher class. 
>> 
>> Also note that existing AESWrap impl does not take IV. However, the 
>> corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
>> both KW and KWP.
>> 
>> Thanks,
>> Valerie
>
> Valerie Peng has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains seven commits:
> 
>  - Merge master into JDK-8248268
>  - Minor update to address review comments.
>  - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
>KWParameters and KWPParameters.
>  - Refactor code to reduce code duplication
>Address review comments
>Add more test vectors
>  - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
>AES/KWP/NoPadding
>  - Restored Iv algorithm parameters impl.
>  - 8248268: Support KWP in addition to KW
>
>Updated existing AESWrap support with AES/KW/NoPadding cipher
>transformation. Added support for AES/KWP/NoPadding and
>AES/KW/PKCS5Padding support to SunJCE provider.

src/java.base/share/classes/com/sun/crypto/provider/AESParameters.java line 50:

> 48: 
> 49: public AESParameters() {
> 50: core = new BlockCipherParamsCore(AESConstants.AES_BLOCK_SIZE, 4, 
> 8);

A cipher object may not take different IV sizes at the same time.  I was just 
wondering how it could be used in practice.  Maybe something like:


AlgorithmParameters algParams = AlgorithmParameters.getInstance("AES");
algParams.init(ivParameterSpec);

The IV parameter is given with the init() method.  Then, it may be not 
necessary to construct the BlockCipherParamsCore object will all potential IV 
sizes.  See the comments in BlockCipherParamsCore.

src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java 
line 52:

> 50: private byte[] iv = null;
> 51: 
> 52: private int[] moreSizes = null;

The moreSizes is not used other than the init() method field.  It may be not 
easy to check the specific size if we cache all supported sized in the object.  
For example, if the required IV size if 8 bytes, it may be a problem about how 
to make sure the iv size is 8 bytes exactly for a specific algorithm.

Maybe, we could just have a ivSize filed.  The default value is block_size, 
which coupe be set with the init(ivParameterSpec) method.



private int ivSize;
...
   BlockCipherParamsCore(int blkSize) {
   block_size = blkSize;
   ivSize = blkSize;
}
...
   void init(AlgorithmParameterSpec paramSpec) {
ivSize = ...;  // reset IV size.
}

// use ivSize while encoding and decoding.

src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java 
line 81:

> 79: expectedLen + " bytes long");
> 80: }
> 81: iv = tmpIv.clone();

The moreSizes is not used after initialization.  The iv/tmpIv could be a value 
other than the block_size.   The getEncoded() method would use the iv value for 
the encoding.  While in the decoding method init(byte[]) method, the IV sizes 
other block_size is not considered, and IOE will be thrown.  Could this be a 
problem?

-

PR: https://git.openjdk.java.net/jdk/pull/2404


Re: RFR: 8248268: Support KWP in addition to KW [v7]

2021-05-13 Thread Valerie Peng
> This change updates SunJCE provider as below:
> - updated existing AESWrap support with AES/KW/NoPadding cipher 
> transformation. 
> - added support for AES/KWP/NoPadding and AES/KW/PKCS5Padding.
> 
> Existing AESWrap impl, i.e. AESWrapCipher class, is re-factored and renamed 
> to KeyWrapCipher class. The W and W_inverse functions are moved to KWUtil 
> class. The KW and KWP support are in the new AESKeyWrap and AESKeyWrapPadded 
> classes which extend FeedbackCipher and used in KeyWrapCipher class. To 
> minimize data copying, AESKeyWrap and AESKeyWrapPadded will do the crypto 
> operation over the same input buffer which is allocated and managed by 
> KeyWrapCipher class. 
> 
> Also note that existing AESWrap impl does not take IV. However, the 
> corresponding PKCS#11 mechanisms do, so I added support for accepting IVs to 
> both KW and KWP.
> 
> Thanks,
> Valerie

Valerie Peng has updated the pull request with a new target base due to a merge 
or a rebase. The pull request now contains seven commits:

 - Merge master into JDK-8248268
 - Minor update to address review comments.
 - Changed AESParameters to allow 4-byte, 8-byte IVs and removed
   KWParameters and KWPParameters.
 - Refactor code to reduce code duplication
   Address review comments
   Add more test vectors
 - Changed AlgorithmParameters impls to register under AES/KW/NoPadding and
   AES/KWP/NoPadding
 - Restored Iv algorithm parameters impl.
 - 8248268: Support KWP in addition to KW
   
   Updated existing AESWrap support with AES/KW/NoPadding cipher
   transformation. Added support for AES/KWP/NoPadding and
   AES/KW/PKCS5Padding support to SunJCE provider.

-

Changes: https://git.openjdk.java.net/jdk/pull/2404/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk=2404=06
  Stats: 2592 lines in 16 files changed: 1930 ins; 555 del; 107 mod
  Patch: https://git.openjdk.java.net/jdk/pull/2404.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/2404/head:pull/2404

PR: https://git.openjdk.java.net/jdk/pull/2404