Skip to content

Commit 78be334

Browse files
author
Valerie Peng
committed
8242332: Add SHA3 support to SunPKCS11 provider
Reviewed-by: xuelei
1 parent c4339c3 commit 78be334

25 files changed

+1037
-619
lines changed

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,8 @@
4141

4242
/**
4343
* MessageDigest implementation class. This class currently supports
44-
* MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512.
44+
* MD2, MD5, SHA-1, SHA-2 family (SHA-224, SHA-256, SHA-384, and SHA-512)
45+
* and SHA-3 family (SHA3-224, SHA3-256, SHA3-384, and SHA3-512) of digests.
4546
*
4647
* Note that many digest operations are on fairly small amounts of data
4748
* (less than 100 bytes total). For example, the 2nd hashing in HMAC or
@@ -104,16 +105,20 @@ final class P11Digest extends MessageDigestSpi implements Cloneable,
104105
break;
105106
case (int)CKM_SHA224:
106107
case (int)CKM_SHA512_224:
108+
case (int)CKM_SHA3_224:
107109
digestLength = 28;
108110
break;
109111
case (int)CKM_SHA256:
110112
case (int)CKM_SHA512_256:
113+
case (int)CKM_SHA3_256:
111114
digestLength = 32;
112115
break;
113116
case (int)CKM_SHA384:
117+
case (int)CKM_SHA3_384:
114118
digestLength = 48;
115119
break;
116120
case (int)CKM_SHA512:
121+
case (int)CKM_SHA3_512:
117122
digestLength = 64;
118123
break;
119124
default:

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java

Lines changed: 157 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,9 @@
3636

3737
/**
3838
* KeyGenerator implementation class. This class currently supports
39-
* DES, DESede, AES, ARCFOUR, and Blowfish.
39+
* DES, DESede, AES, ARCFOUR, Blowfish, Hmac using MD5, SHA, SHA-2 family
40+
* (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256), and SHA-3
41+
* family (SHA3-224, SHA3-256, SHA3-384, SHA3-512) of digests.
4042
*
4143
* @author Andreas Sterbenz
4244
* @since 1.5
@@ -65,6 +67,48 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
6567
// are supported.
6668
private boolean supportBothKeySizes;
6769

70+
// for determining if the specified key size is valid
71+
private final CK_MECHANISM_INFO range;
72+
73+
// utility method for query the native key sizes and enforcing the
74+
// java-specific lower limit; returned values are in bits
75+
private static CK_MECHANISM_INFO getSupportedRange(Token token,
76+
long mech) throws ProviderException {
77+
// No need to query for fix-length algorithms
78+
if (mech == CKM_DES_KEY_GEN || mech == CKM_DES2_KEY_GEN ||
79+
mech == CKM_DES3_KEY_GEN) {
80+
return null;
81+
}
82+
83+
// Explicitly disallow keys shorter than 40-bits for security
84+
int lower = 40;
85+
int upper = Integer.MAX_VALUE;
86+
try {
87+
CK_MECHANISM_INFO info = token.getMechanismInfo(mech);
88+
if (info != null) {
89+
boolean isBytes = ((mech != CKM_GENERIC_SECRET_KEY_GEN
90+
&& mech != CKM_RC4_KEY_GEN) || info.iMinKeySize < 8);
91+
lower = Math.max(lower, (isBytes?
92+
Math.multiplyExact(info.iMinKeySize, 8) :
93+
info.iMinKeySize));
94+
// NSS CKM_GENERIC_SECRET_KEY_GEN mech info is not precise;
95+
// its upper limit is too low and does not match its impl
96+
if (mech == CKM_GENERIC_SECRET_KEY_GEN &&
97+
info.iMaxKeySize <= 32) {
98+
// ignore and leave upper limit at MAX_VALUE;
99+
} else if (info.iMaxKeySize != Integer.MAX_VALUE) {
100+
upper = (isBytes?
101+
Math.multiplyExact(info.iMaxKeySize, 8) :
102+
info.iMaxKeySize);
103+
}
104+
}
105+
} catch (PKCS11Exception p11e) {
106+
// Should never happen
107+
throw new ProviderException("Cannot retrieve mechanism info", p11e);
108+
}
109+
return new CK_MECHANISM_INFO(lower, upper, 0 /* flags not used */);
110+
}
111+
68112
/**
69113
* Utility method for checking if the specified key size is valid
70114
* and within the supported range. Return the significant key size
@@ -78,8 +122,15 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
78122
* @throws ProviderException if this mechanism isn't supported by SunPKCS11
79123
* or underlying native impl.
80124
*/
125+
// called by P11SecretKeyFactory to check key size
81126
static int checkKeySize(long keyGenMech, int keySize, Token token)
82127
throws InvalidAlgorithmParameterException, ProviderException {
128+
CK_MECHANISM_INFO range = getSupportedRange(token, keyGenMech);
129+
return checkKeySize(keyGenMech, keySize, range);
130+
}
131+
132+
private static int checkKeySize(long keyGenMech, int keySize,
133+
CK_MECHANISM_INFO range) throws InvalidAlgorithmParameterException {
83134
int sigKeySize;
84135
switch ((int)keyGenMech) {
85136
case (int)CKM_DES_KEY_GEN:
@@ -102,52 +153,38 @@ static int checkKeySize(long keyGenMech, int keySize, Token token)
102153
break;
103154
default:
104155
// Handle all variable-key-length algorithms here
105-
CK_MECHANISM_INFO info = null;
106-
try {
107-
info = token.getMechanismInfo(keyGenMech);
108-
} catch (PKCS11Exception p11e) {
109-
// Should never happen
110-
throw new ProviderException
111-
("Cannot retrieve mechanism info", p11e);
112-
}
113-
if (info == null) {
114-
// XXX Unable to retrieve the supported key length from
115-
// the underlying native impl. Skip the checking for now.
116-
return keySize;
117-
}
118-
// PKCS#11 defines these to be in number of bytes except for
119-
// RC4 which is in bits. However, some PKCS#11 impls still use
120-
// bytes for all mechs, e.g. NSS. We try to detect this
121-
// inconsistency if the minKeySize seems unreasonably small.
122-
int minKeySize = info.iMinKeySize;
123-
int maxKeySize = info.iMaxKeySize;
124-
if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
125-
minKeySize = Math.multiplyExact(minKeySize, 8);
126-
if (maxKeySize != Integer.MAX_VALUE) {
127-
maxKeySize = Math.multiplyExact(maxKeySize, 8);
128-
}
129-
}
130-
// Explicitly disallow keys shorter than 40-bits for security
131-
if (minKeySize < 40) minKeySize = 40;
132-
if (keySize < minKeySize || keySize > maxKeySize) {
156+
if (range != null && keySize < range.iMinKeySize
157+
|| keySize > range.iMaxKeySize) {
133158
throw new InvalidAlgorithmParameterException
134-
("Key length must be between " + minKeySize +
135-
" and " + maxKeySize + " bits");
159+
("Key length must be between " + range.iMinKeySize +
160+
" and " + range.iMaxKeySize + " bits");
136161
}
137162
if (keyGenMech == CKM_AES_KEY_GEN) {
138163
if ((keySize != 128) && (keySize != 192) &&
139164
(keySize != 256)) {
140165
throw new InvalidAlgorithmParameterException
141-
("AES key length must be " + minKeySize +
142-
(maxKeySize >= 192? ", 192":"") +
143-
(maxKeySize >= 256? ", or 256":"") + " bits");
166+
("AES key length must be 128, 192, or 256 bits");
144167
}
145168
}
146169
sigKeySize = keySize;
147170
}
148171
return sigKeySize;
149172
}
150173

174+
// check the supplied keysize (in bits) and adjust it based on the given
175+
// range
176+
private static int adjustKeySize(int ks, CK_MECHANISM_INFO mi) {
177+
// adjust to fit within the supported range
178+
if (mi != null) {
179+
if (ks < mi.iMinKeySize) {
180+
ks = mi.iMinKeySize;
181+
} else if (ks > mi.iMaxKeySize) {
182+
ks = mi.iMaxKeySize;
183+
}
184+
}
185+
return ks;
186+
}
187+
151188
P11KeyGenerator(Token token, String algorithm, long mechanism)
152189
throws PKCS11Exception {
153190
super();
@@ -164,50 +201,118 @@ static int checkKeySize(long keyGenMech, int keySize, Token token)
164201
(token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
165202
(token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
166203
}
167-
setDefaultKeySize();
204+
this.range = getSupportedRange(token, mechanism);
205+
setDefault();
168206
}
169207

170-
// set default keysize and also initialize keyType
171-
private void setDefaultKeySize() {
208+
// set default keysize and keyType
209+
private void setDefault() {
210+
significantKeySize = -1;
172211
switch ((int)mechanism) {
173212
case (int)CKM_DES_KEY_GEN:
174213
keySize = 64;
175214
keyType = CKK_DES;
215+
significantKeySize = 56;
176216
break;
177217
case (int)CKM_DES2_KEY_GEN:
178218
keySize = 128;
179219
keyType = CKK_DES2;
220+
significantKeySize = 112;
180221
break;
181222
case (int)CKM_DES3_KEY_GEN:
182223
keySize = 192;
183224
keyType = CKK_DES3;
225+
significantKeySize = 168;
184226
break;
185227
case (int)CKM_AES_KEY_GEN:
186-
keySize = 128;
228+
keySize = adjustKeySize(128, range);
187229
keyType = CKK_AES;
188230
break;
189231
case (int)CKM_RC4_KEY_GEN:
190-
keySize = 128;
232+
keySize = adjustKeySize(128, range);
191233
keyType = CKK_RC4;
192234
break;
193235
case (int)CKM_BLOWFISH_KEY_GEN:
194-
keySize = 128;
236+
keySize = adjustKeySize(128, range);
195237
keyType = CKK_BLOWFISH;
196238
break;
239+
case (int)CKM_SHA_1_KEY_GEN:
240+
keySize = adjustKeySize(160, range);
241+
keyType = CKK_SHA_1_HMAC;
242+
break;
243+
case (int)CKM_SHA224_KEY_GEN:
244+
keySize = adjustKeySize(224, range);
245+
keyType = CKK_SHA224_HMAC;
246+
break;
247+
case (int)CKM_SHA256_KEY_GEN:
248+
keySize = adjustKeySize(256, range);
249+
keyType = CKK_SHA256_HMAC;
250+
break;
251+
case (int)CKM_SHA384_KEY_GEN:
252+
keySize = adjustKeySize(384, range);
253+
keyType = CKK_SHA384_HMAC;
254+
break;
255+
case (int)CKM_SHA512_KEY_GEN:
256+
keySize = adjustKeySize(512, range);
257+
keyType = CKK_SHA512_HMAC;
258+
break;
259+
case (int)CKM_SHA512_224_KEY_GEN:
260+
keySize = adjustKeySize(224, range);
261+
keyType = CKK_SHA512_224_HMAC;
262+
break;
263+
case (int)CKM_SHA512_256_KEY_GEN:
264+
keySize = adjustKeySize(256, range);
265+
keyType = CKK_SHA512_256_HMAC;
266+
break;
267+
case (int)CKM_SHA3_224_KEY_GEN:
268+
keySize = adjustKeySize(224, range);
269+
keyType = CKK_SHA3_224_HMAC;
270+
break;
271+
case (int)CKM_SHA3_256_KEY_GEN:
272+
keySize = adjustKeySize(256, range);
273+
keyType = CKK_SHA3_256_HMAC;
274+
break;
275+
case (int)CKM_SHA3_384_KEY_GEN:
276+
keySize = adjustKeySize(384, range);
277+
keyType = CKK_SHA3_384_HMAC;
278+
break;
279+
case (int)CKM_SHA3_512_KEY_GEN:
280+
keySize = adjustKeySize(512, range);
281+
keyType = CKK_SHA3_512_HMAC;
282+
break;
283+
case (int)CKM_GENERIC_SECRET_KEY_GEN:
284+
if (algorithm.startsWith("Hmac")) {
285+
String digest = algorithm.substring(4);
286+
keySize = adjustKeySize(switch (digest) {
287+
case "MD5" -> 512;
288+
case "SHA1" -> 160;
289+
case "SHA224", "SHA512/224", "SHA3-224" -> 224;
290+
case "SHA256", "SHA512/256", "SHA3-256" -> 256;
291+
case "SHA384", "SHA3-384" -> 384;
292+
case "SHA512", "SHA3-512" -> 512;
293+
default -> {
294+
throw new ProviderException("Unsupported algorithm " +
295+
algorithm);
296+
}
297+
}, range);
298+
} else {
299+
throw new ProviderException("Unsupported algorithm " +
300+
algorithm);
301+
}
302+
keyType = CKK_GENERIC_SECRET;
303+
break;
197304
default:
198305
throw new ProviderException("Unknown mechanism " + mechanism);
199306
}
200-
try {
201-
significantKeySize = checkKeySize(mechanism, keySize, token);
202-
} catch (InvalidAlgorithmParameterException iape) {
203-
throw new ProviderException("Unsupported default key size", iape);
307+
if (significantKeySize == -1) {
308+
significantKeySize = keySize;
204309
}
205310
}
206311

207312
// see JCE spec
208313
protected void engineInit(SecureRandom random) {
209314
token.ensureValid();
210-
setDefaultKeySize();
315+
setDefault();
211316
}
212317

213318
// see JCE spec
@@ -222,7 +327,7 @@ protected void engineInit(int keySize, SecureRandom random) {
222327
token.ensureValid();
223328
int newSignificantKeySize;
224329
try {
225-
newSignificantKeySize = checkKeySize(mechanism, keySize, token);
330+
newSignificantKeySize = checkKeySize(mechanism, keySize, range);
226331
} catch (InvalidAlgorithmParameterException iape) {
227332
throw (InvalidParameterException)
228333
(new InvalidParameterException().initCause(iape));
@@ -254,10 +359,11 @@ protected SecretKey engineGenerateKey() {
254359
try {
255360
session = token.getObjSession();
256361
CK_ATTRIBUTE[] attributes;
257-
switch ((int)keyType) {
258-
case (int)CKK_DES:
259-
case (int)CKK_DES2:
260-
case (int)CKK_DES3:
362+
363+
switch ((int)mechanism) {
364+
case (int)CKM_DES_KEY_GEN:
365+
case (int)CKM_DES2_KEY_GEN:
366+
case (int)CKM_DES3_KEY_GEN:
261367
// fixed length, do not specify CKA_VALUE_LEN
262368
attributes = new CK_ATTRIBUTE[] {
263369
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
@@ -282,5 +388,4 @@ protected SecretKey engineGenerateKey() {
282388
token.releaseSession(session);
283389
}
284390
}
285-
286391
}

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@
3939

4040
/**
4141
* MAC implementation class. This class currently supports HMAC using
42-
* MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 and the SSL3 MAC
43-
* using MD5 and SHA-1.
42+
* MD5, SHA-1, SHA-2 family (SHA-224, SHA-256, SHA-384, and SHA-512),
43+
* SHA-3 family (SHA3-224, SHA3-256, SHA3-384, and SHA3-512), and the
44+
* SSL3 MAC using MD5 and SHA-1.
4445
*
4546
* Note that unlike other classes (e.g. Signature), this does not
4647
* composite various operations if the token only supports part of the
@@ -92,16 +93,20 @@ final class P11Mac extends MacSpi {
9293
break;
9394
case (int)CKM_SHA224_HMAC:
9495
case (int)CKM_SHA512_224_HMAC:
96+
case (int)CKM_SHA3_224_HMAC:
9597
macLength = 28;
9698
break;
9799
case (int)CKM_SHA256_HMAC:
98100
case (int)CKM_SHA512_256_HMAC:
101+
case (int)CKM_SHA3_256_HMAC:
99102
macLength = 32;
100103
break;
101104
case (int)CKM_SHA384_HMAC:
105+
case (int)CKM_SHA3_384_HMAC:
102106
macLength = 48;
103107
break;
104108
case (int)CKM_SHA512_HMAC:
109+
case (int)CKM_SHA3_512_HMAC:
105110
macLength = 64;
106111
break;
107112
case (int)CKM_SSL3_MD5_MAC:

0 commit comments

Comments
 (0)