Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/KeyWrap/TestCipherKeyWrapperTest.java
41161 views
/*1* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import static java.lang.System.out;2425import java.lang.Integer;26import java.lang.String;27import java.lang.System;28import java.security.AlgorithmParameters;29import java.security.InvalidAlgorithmParameterException;30import java.security.InvalidKeyException;31import java.security.Key;32import java.security.KeyPair;33import java.security.NoSuchAlgorithmException;34import java.security.KeyPairGenerator;35import java.security.Provider;36import java.security.Security;37import java.security.spec.AlgorithmParameterSpec;38import java.security.spec.InvalidKeySpecException;39import java.util.Arrays;40import java.util.HashMap;41import java.util.Map;42import java.util.Random;4344import javax.crypto.IllegalBlockSizeException;45import javax.crypto.NoSuchPaddingException;46import javax.crypto.SecretKey;47import javax.crypto.Cipher;48import javax.crypto.KeyGenerator;49import javax.crypto.SecretKeyFactory;50import javax.crypto.spec.PBEKeySpec;51import javax.crypto.spec.PBEParameterSpec;5253/*54* @test55* @bug 8048599 824826856* @summary Tests for key wrap and unwrap operations57*/5859public class TestCipherKeyWrapperTest {60private static final String SUN_JCE = "SunJCE";61// Blowfish Variable key length: 32 bits to 448 bits62private static final int BLOWFISH_MIN_KEYSIZE = 32;63private static final int BLOWFISH_MAX_KEYSIZE = 448;64private static final int LINIMITED_KEYSIZE = 128;65private static final String NOPADDING = "NoPaDDing";66private static final String[] PBE_ALGORITHM_AR = { "pbeWithMD5ANDdes",67"PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndTripleDES",68"PBEWithMD5AndTripleDES/CBC/PKCS5Padding", "PBEwithSHA1AndDESede",69"PBEwithSHA1AndDESede/CBC/PKCS5Padding", "PBEwithSHA1AndRC2_40",70"PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", "PBEWithSHA1AndRC2_128",71"PBEWithSHA1andRC2_128/CBC/PKCS5Padding", "PBEWithSHA1AndRC4_40",72"PBEWithsha1AndRC4_40/ECB/NoPadding", "PBEWithSHA1AndRC4_128",73"pbeWithSHA1AndRC4_128/ECB/NoPadding", "PBEWithHmacSHA1AndAES_128",74"PBEWithHmacSHA224AndAES_128", "PBEWithHmacSHA256AndAES_128",75"PBEWithHmacSHA384AndAES_128", "PBEWithHmacSHA512AndAES_128",76"PBEWithHmacSHA1AndAES_256", "PBEWithHmacSHA224AndAES_256",77"PBEWithHmacSHA256AndAES_256", "PBEWithHmacSHA384AndAES_256",78"PBEWithHmacSHA512AndAES_256" };79private static final String[] MODEL_AR = { "ECb", "pCbC", "cbC", "cFB",80"cFB24", "cFB40", "OfB48", "OFB64" };81private static final String[] PADDING_AR = { NOPADDING, "PKCS5Padding" };8283private enum AlgorithmWrapper {84AESWrap("AES", "AESWrap", -1),85AESWrap_128("AES", "AESWrap_128", 128),86AESWrap_192("AES", "AESWrap_192", 192),87AESWrap_256("AES", "AESWrap_256", 256),88AESWrapPad("AES", "AESWrapPad", -1),89AESWrapPad_128("AES", "AESWrapPad_128", 128),90AESWrapPad_192("AES", "AESWrapPad_192", 192),91AESWrapPad_256("AES", "AESWrapPad_256", 256),92DESedeWrap("desede", "DESedeWrap", -1),93NegtiveWrap("AES", "DESedeWrap", -1);9495private final String algorithm;96private final String wrapper;97private final int keySize;9899private AlgorithmWrapper(String algorithm, String wrapper, int kSize) {100this.algorithm = algorithm;101this.wrapper = wrapper;102this.keySize = kSize;103}104105public String getAlgorithm() {106return algorithm;107}108109public String getWrapper() {110return wrapper;111}112113public int getKeySize() {114return keySize;115}116117};118119public static void main(String[] args) throws Exception {120121TestCipherKeyWrapperTest test = new TestCipherKeyWrapperTest();122// AESWrap and DESedeWrap test123for (AlgorithmWrapper algoWrapper : AlgorithmWrapper.values()) {124String algo = algoWrapper.getAlgorithm();125String wrapper = algoWrapper.getWrapper();126try {127int keySize = algoWrapper.getKeySize();128// only run the tests on longer key lengths if unlimited129// version of JCE jurisdiction policy files are installed130if (!(Cipher.getMaxAllowedKeyLength(algo) == Integer.MAX_VALUE)131&& keySize > LINIMITED_KEYSIZE) {132out.println(algo + " will not run if unlimited version of"133+ " JCE jurisdiction policy files are installed");134continue;135}136test.wrapperAesDESedeKeyTest(algo, wrapper, keySize);137if (algoWrapper == AlgorithmWrapper.NegtiveWrap) {138throw new RuntimeException("Expected not throw when algo"139+ " and wrapAlgo are not match:" + algo);140}141} catch (InvalidKeyException e) {142if (algoWrapper == AlgorithmWrapper.NegtiveWrap) {143out.println("Expepted exception when algo"144+ " and wrapAlgo are not match:" + algo);145} else {146throw e;147}148}149}150test.wrapperBlowfishKeyTest();151// PBE and public wrapper test.152String[] publicPrivateAlgos = new String[] { "DiffieHellman", "DSA",153"RSA" };154Provider provider = Security.getProvider(SUN_JCE);155if (provider == null) {156throw new RuntimeException("SUN_JCE provider not exist");157}158159test.wrapperPBEKeyTest(provider);160// Public and private key wrap test161test.wrapperPublicPriviteKeyTest(provider, publicPrivateAlgos);162}163164private void wrapperAesDESedeKeyTest(String algo, String wrapAlgo,165int keySize) throws InvalidKeyException, NoSuchAlgorithmException,166NoSuchPaddingException, IllegalBlockSizeException,167InvalidAlgorithmParameterException {168// Initialization169KeyGenerator kg = KeyGenerator.getInstance(algo);170if (keySize != -1) {171kg.init(keySize);172}173SecretKey key = kg.generateKey();174wrapTest(algo, wrapAlgo, key, key, Cipher.SECRET_KEY, false);175}176177private void wrapperBlowfishKeyTest() throws InvalidKeyException,178NoSuchAlgorithmException, NoSuchPaddingException,179IllegalBlockSizeException, InvalidAlgorithmParameterException {180// how many kinds of padding mode181int padKinds;182// Keysize should be multiple of 8 bytes.183int KeyCutter = 8;184int kSize = BLOWFISH_MIN_KEYSIZE;185String algorithm = "Blowfish";186int maxAllowKeyLength = Cipher.getMaxAllowedKeyLength(algorithm);187boolean unLimitPolicy = maxAllowKeyLength == Integer.MAX_VALUE;188SecretKey key = null;189while (kSize <= BLOWFISH_MAX_KEYSIZE) {190for (String mode : MODEL_AR) {191// PKCS5padding is meaningful only for ECB, CBC, PCBC192if (mode.equalsIgnoreCase(MODEL_AR[0])193|| mode.equalsIgnoreCase(MODEL_AR[1])194|| mode.equalsIgnoreCase(MODEL_AR[2])) {195padKinds = PADDING_AR.length;196} else {197padKinds = 1;198}199// Initialization200KeyGenerator kg = KeyGenerator.getInstance(algorithm);201for (int k = 0; k < padKinds; k++) {202String transformation = algorithm + "/" + mode + "/"203+ PADDING_AR[k];204if (NOPADDING.equals(PADDING_AR[k]) && kSize % 64 != 0) {205out.println(transformation206+ " will not run if input length not multiple"207+ " of 8 bytes when padding is " + NOPADDING);208continue;209}210kg.init(kSize);211key = kg.generateKey();212// only run the tests on longer key lengths if unlimited213// version of JCE jurisdiction policy files are installed214if (!unLimitPolicy && kSize > LINIMITED_KEYSIZE) {215out.println("keyStrength > 128 within " + algorithm216+ " will not run under global policy");217} else {218wrapTest(transformation, transformation, key, key,219Cipher.SECRET_KEY, false);220}221}222}223if (kSize <= LINIMITED_KEYSIZE) {224KeyCutter = 8;225} else {226KeyCutter = 48;227}228kSize += KeyCutter;229}230}231232private void wrapperPBEKeyTest(Provider p) throws InvalidKeySpecException,233InvalidKeyException, NoSuchPaddingException,234IllegalBlockSizeException, InvalidAlgorithmParameterException,235NoSuchAlgorithmException {236for (String alg : PBE_ALGORITHM_AR) {237String baseAlgo = alg.split("/")[0].toUpperCase();238// only run the tests on longer key lengths if unlimited version239// of JCE jurisdiction policy files are installed240241if (Cipher.getMaxAllowedKeyLength(alg) < Integer.MAX_VALUE242&& (baseAlgo.endsWith("TRIPLEDES") || alg243.endsWith("AES_256"))) {244out.println("keyStrength > 128 within " + alg245+ " will not run under global policy");246continue;247}248SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p);249SecretKey key = skf.generateSecret(new PBEKeySpec("Secret Lover"250.toCharArray()));251wrapTest(alg, alg, key, key, Cipher.SECRET_KEY, true);252}253}254255private void wrapperPublicPriviteKeyTest(Provider p, String[] algorithms)256throws NoSuchAlgorithmException, InvalidKeyException,257NoSuchPaddingException, IllegalBlockSizeException,258InvalidAlgorithmParameterException {259for (String algo : algorithms) {260// Key pair generated261System.out.println("Generate key pair (algorithm: " + algo262+ ", provider: " + p.getName() + ")");263KeyPairGenerator kpg = KeyPairGenerator.getInstance(algo);264kpg.initialize(512);265KeyPair kp = kpg.genKeyPair();266// key generated267String algoWrap = "DES";268KeyGenerator kg = KeyGenerator.getInstance(algoWrap, p);269Key key = kg.generateKey();270wrapTest(algo, algoWrap, key, kp.getPrivate(), Cipher.PRIVATE_KEY,271false);272wrapTest(algo, algoWrap, key, kp.getPublic(), Cipher.PUBLIC_KEY,273false);274}275}276277private void wrapTest(String transformation, String wrapAlgo, Key initKey,278Key wrapKey, int keyType, boolean isPBE)279throws NoSuchAlgorithmException, NoSuchPaddingException,280InvalidKeyException, IllegalBlockSizeException,281InvalidAlgorithmParameterException {282String algo = transformation.split("/")[0];283boolean isAESBlowfish = algo.indexOf("AES") != -1284|| algo.indexOf("Blowfish") != -1;285AlgorithmParameters aps = null;286AlgorithmParameterSpec pbeParams = null;287if (isPBE) {288byte[] salt = new byte[8];289int iterCnt = 1000;290new Random().nextBytes(salt);291pbeParams = new PBEParameterSpec(salt, iterCnt);292}293294out.println("Testing " + wrapAlgo + " cipher wrap/unwrap");295// Wrap & UnWrap operation296Cipher wrapCI = Cipher.getInstance(wrapAlgo);297if (isPBE && !isAESBlowfish) {298wrapCI.init(Cipher.WRAP_MODE, initKey, pbeParams);299} else if (isAESBlowfish) {300wrapCI.init(Cipher.WRAP_MODE, initKey);301aps = wrapCI.getParameters();302} else {303wrapCI.init(Cipher.WRAP_MODE, initKey);304}305byte[] keyWrapper = wrapCI.wrap(wrapKey);306if (isPBE && !isAESBlowfish) {307wrapCI.init(Cipher.UNWRAP_MODE, initKey, pbeParams);308} else if (isAESBlowfish) {309wrapCI.init(Cipher.UNWRAP_MODE, initKey, aps);310} else {311wrapCI.init(Cipher.UNWRAP_MODE, initKey);312}313Key unwrappedKey = wrapCI.unwrap(keyWrapper, algo, keyType);314// Comparison315if (!Arrays.equals(wrapKey.getEncoded(), unwrappedKey.getEncoded())) {316out.println("keysize : " + wrapKey.getEncoded().length);317throw new RuntimeException("Comparation failed testing "318+ transformation + ":" + wrapAlgo + ":" + keyType);319}320}321}322323324