Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/KeyWrap/NISTWrapKAT.java
41161 views
/*1* Copyright (c) 2004, 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*/2223/*24* @test25* @bug 5008156 824826826* @run testng NISTWrapKAT27* @summary Verify that the AES-Key-Wrap and AES-Key-Wrap-Pad ciphers28* work as expected using NIST test vectors.29* @author Valerie Peng30*/31import java.security.Key;32import java.security.AlgorithmParameters;33import javax.crypto.*;34import javax.crypto.spec.*;35import java.util.Arrays;36import java.math.BigInteger;37import org.testng.annotations.DataProvider;38import org.testng.annotations.Test;39import org.testng.Assert;4041public class NISTWrapKAT {4243private static final String KEK =44"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";45private static final String DATA =46"00112233445566778899aabbccddeeff000102030405060708090a0b0c0d0e0f";47// from RFC 3394 sec448private static String KW_AES128_128 =49"1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5";50private static String KW_AES192_128 =51"96778b25ae6ca435f92b5b97c050aed2468ab8a17ad84e5d";52private static String KW_AES192_192 =53"031d33264e15d33268f24ec260743edce1c6c7ddee725a936ba814915c6762d2";54private static String KW_AES256_128 =55"64e8c3f9ce0f5ba263e9777905818a2a93c8191e7d6e8ae7";56private static String KW_AES256_192 =57"a8f9bc1612c68b3ff6e6f4fbe30e71e4769c8b80a32cb8958cd5d17d6b254da1";58private static String KW_AES256_256 =59"28c9f404c4b810f4cbccb35cfb87f8263f5786e2d80ed326cbc7f0e71a99f43bfb988b9b7a02dd21";6061private static String KWP_AES128_56 = "1B1D4BC2A90B1FA389412B3D40FECB20";62private static String KWP_AES128_112 =63"EA0BFDE8AF063E8918E811A05D2A4C23A367B45315716B5B";64private static String KWP_AES192_56 = "87CE2C5C2D7196E09381056B319D91E9";65private static String KWP_AES192_112 =66"900484950F84EB6ED74CE81DCDACA26E72BB29D4A6F7AC74";67private static String KWP_AES192_168 =68"A402348F1956DB968FDDFD8976420F9DDEB7183CF16B91B0AEB74CAB196C343E";69private static String KWP_AES256_56 = "809BB1864A18938529E97EFCD9544E9A";70private static String KWP_AES256_112 =71"C68168173F141E6D5767611574A941259090DA78D7DF9DF7";72private static String KWP_AES256_168 =73"308D49692B5F8CF638D54BB4B985633504237329964C76EBB3F669870A708DBC";74private static String KWP_AES256_224 =75"0942747DB07032A3F04CDB2E7DE1CBA038F92BC355393AE9A0E4AE8C901912AC3D3AF0F16D240607";76// from RFC 5649 sec677private static String KEK2 = "5840DF6E29B02AF1AB493B705BF16EA1AE8338F4DCC176A8";7879private static byte[] toBytes(String hex, int hexLen) {80if (hexLen < hex.length()) {81hex = hex.substring(0, hexLen);82} else {83hexLen = hex.length();84}85int outLen = hexLen >> 1;86BigInteger temp = new BigInteger(hex, 16);87byte[] val = temp.toByteArray();88if (val.length == outLen) {89return val;90} else {91byte[] out = new byte[outLen];92if (val.length < outLen) {93// enlarge94System.arraycopy(val, 0, out, outLen - val.length, val.length);95} else {96// truncate97System.arraycopy(val, val.length - outLen, out, 0, outLen);98}99return out;100}101}102103@DataProvider104public Object[][] testData() {105return new Object[][] {106{ "AESWrap", KEK, 16, DATA, 16, KW_AES128_128 },107{ "AESWrap", KEK, 24, DATA, 16, KW_AES192_128 },108{ "AESWrap", KEK, 24, DATA, 24, KW_AES192_192 },109{ "AESWrap", KEK, 32, DATA, 16, KW_AES256_128 },110{ "AESWrap", KEK, 32, DATA, 24, KW_AES256_192 },111{ "AESWrap", KEK, 32, DATA, 32, KW_AES256_256 },112{ "AESWrap_128", KEK, 16, DATA, 16, KW_AES128_128 },113{ "AESWrap_192", KEK, 24, DATA, 16, KW_AES192_128 },114{ "AESWrap_256", KEK, 32, DATA, 16, KW_AES256_128 },115{ "AES/KW/NoPadding", KEK, 16, DATA, 16, KW_AES128_128 },116{ "AES/KW/NoPadding", KEK, 24, DATA, 16, KW_AES192_128 },117{ "AES/KW/NoPadding", KEK, 24, DATA, 24, KW_AES192_192 },118{ "AES/KW/NoPadding", KEK, 32, DATA, 16, KW_AES256_128 },119{ "AES/KW/NoPadding", KEK, 32, DATA, 24, KW_AES256_192 },120{ "AES/KW/NoPadding", KEK, 32, DATA, 32, KW_AES256_256 },121{ "AESWrapPad", KEK, 16, DATA, 7, KWP_AES128_56 },122{ "AESWrapPad", KEK, 16, DATA, 14, KWP_AES128_112 },123{ "AESWrapPad", KEK, 24, DATA, 7, KWP_AES192_56 },124{ "AESWrapPad", KEK, 24, DATA, 14, KWP_AES192_112 },125{ "AESWrapPad", KEK, 24, DATA, 21, KWP_AES192_168 },126{ "AESWrapPad", KEK, 32, DATA, 7, KWP_AES256_56 },127{ "AESWrapPad", KEK, 32, DATA, 14, KWP_AES256_112 },128{ "AESWrapPad", KEK, 32, DATA, 21, KWP_AES256_168 },129{ "AESWrapPad", KEK, 32, DATA, 28, KWP_AES256_224 },130{ "AESWrapPad_128", KEK, 16, DATA, 7, KWP_AES128_56 },131{ "AESWrapPad_192", KEK, 24, DATA, 7, KWP_AES192_56 },132{ "AESWrapPad_256", KEK, 32, DATA, 7, KWP_AES256_56 },133{ "AES/KWP/NoPadding", KEK, 16, DATA, 7, KWP_AES128_56 },134{ "AES/KWP/NoPadding", KEK, 16, DATA, 14, KWP_AES128_112 },135{ "AES/KWP/NoPadding", KEK, 24, DATA, 7, KWP_AES192_56 },136{ "AES/KWP/NoPadding", KEK, 24, DATA, 14, KWP_AES192_112 },137{ "AES/KWP/NoPadding", KEK, 24, DATA, 21, KWP_AES192_168 },138{ "AES/KWP/NoPadding", KEK, 32, DATA, 7, KWP_AES256_56 },139{ "AES/KWP/NoPadding", KEK, 32, DATA, 14, KWP_AES256_112 },140{ "AES/KWP/NoPadding", KEK, 32, DATA, 21, KWP_AES256_168 },141{ "AES/KWP/NoPadding", KEK, 32, DATA, 28, KWP_AES256_224 },142{ "AES/KWP/NoPadding", KEK2, 24, "466F7250617369", 7,143"AFBEB0F07DFBF5419200F2CCB50BB24F" },144{ "AES/KWP/NoPadding", KEK2, 24,145"C37B7E6492584340BED12207808941155068F738", 20,146"138BDEAA9B8FA7FC61F97742E72248EE5AE6AE5360D1AE6A5F54F373FA543B6A" },147// some more test vectors for KW and KWP148// from csrc.nist.gov/groups/STM/cavp/documents/mac/kwtestvectors.zip149{ "AES/KW/NoPadding", "7575da3a93607cc2bfd8cec7aadfd9a6", 16,150"42136d3c384a3eeac95a066fd28fed3f", 16,151"031f6bd7e61e643df68594816f64caa3f56fabea2548f5fb" },152{ "AES/KW/NoPadding", "e5d058e7f1c22c016c4e1cc9b26b9f8f", 16,153"7f604e9b8d39d3c91e193fe6f196c1e3da6211a7c9a33b8873b64b138d1803" +154"e4", 32,155"60b9f8ac797c56e01e9b5f84d65816a980777869f67991a0e6dc19b8cd75c9" +156"b54db4a38456bbd6f3" },157{ "AES/KW/NoPadding", "67ae4270bcdd31e8326b7e7f94c80276", 16,158"57e748b62fbc37ba25e904ee973d01b136cf7c1d0c8c5c87", 24,159"96cec0e3272a21faa550a857957aa38ce3c1cf06f0dd9f5b5c5c422cef6c69" +160"a1" },161{ "AES/KW/NoPadding", "d7aa53aefad65cd95b57c8eee7b0a906", 16,162"4a8daee6774751fc4489e837b8f7fba6896c70bb3d5e53053c92eb58046ee4" +163"a7002e542311253b97", 40,164"84ebd38cf06c674dcf186977de4a40c6dde3e7f49361a43420a887d2931b29" +165"c23e2db72e95e4107001da925181bb7097" },166{ "AES/KW/NoPadding", "98311985c4661d7e811ee56070e6fecf", 16,167"18840c96813864ef3093b48cdde6ac5d78248b96d4a2cd1f15f0b56f98213d" +168"bf87e1ccad04e0d4f1954c233ea3e48fdad8f2b1156e54e19e3b5f4a66d2e9" +169"149032b876c51249165fe8c28e112a685b2d228a8ac308017574274af36a4e" +170"a3877bcc9850bafe8fc0e0a712faca0dea98396f9143bc5819fe4933a806e9" +171"b965133e3c695a45f0fbd6961798c400d7477287df64798b651e0d3009c13f" +172"7a2246c28f983509b9e5339919f2cdffcdfc550693cba9491c00334c4a62d8" +173"78c4d0ca57b1104bc0174968ea8e3730b9e68db49678b23cd508ebe3e12e94" +174"b0ad3791023a8ef95473f0b32f906738f34e94e45a4480ad768072e1853adb" +175"63996b9ac27a1dade70804b82290a2274c6dcc3ccd40a8b38a56a5eb03f590" +176"75de015e8f9096f53549f6374e02da947fb849287a447f757cc340b6bded71" +177"d480988b6d2fcd984fba841470519830304667fef0a577b4cf84f76aef9deb" +178"84dde36abfbd76673c17113dbea7a3e24bf9b57a8fd17173a1ef91497b732b" +179"3fa8889bed58a503a0d3e20bc27ec4dbf5d13a93cbad05495e3df15e1fe34a" +180"3a6d6f648ea4aa60b2f114f30944ae593675dac2db188f90a3c483fb82cec0" +181"f0d295544d798b62cdcb51c6c036af1a341d78babf87b92609c1d866e311a4" +182"6abccc8ba8c6a41420359bb061d7e752c0ed25990eef57c9f9e190572203f8" +183"c473edf8cfc8c26d34e37240f45ded97", 512,184"625aea9122b7b57b9f36446f9053acc42c6435a7f69d91b41547026f833291" +185"d488e477c7ccba698c143633a304f463d6af4a3e72c189234fcfc360013e65" +186"b07b7f7a36c529d3fdbbdbd6224bf100c14bc5354893b44790f54c739a2b1f" +187"5bda82d70fb600ed9b0606dbddea52e508b492b72d8779856274aaaaddc0a3" +188"edb6cfc788b603101bedfcc3f44baa62336bd950c2e349d5daf04f2e23ec26" +189"28893d214e277569c565e5e6aa8b72ffa14118a3b57f814b4deb179980b5ee" +190"efa4fd93f1751850466e929be537801babc2120f3ff1ffe5fea813ec7788ea" +191"f43f5ef657e5af48395c3ad11aaf741549090b58670695f7c95c68e00576ca" +192"18ef0313f2b4b757219fc8db3dc2db28721d6f912547ebfebcd96935c3100a" +193"a4e4df9955acae1b4e2c10df1166d46c4285ab631c6d2ce58ad3ae99c07c01" +194"9dcd15958694055281ccd6f803af290431f188cc4c429e84a4c30fd9c63968" +195"dfd0951c417efb71921c207de172a9546bdd3e2bb35b45e140892c649f88c3" +196"1a438f864e801a69f8010aa3d77a26601a7a89067c81b0f7e70d8e82f21f88" +197"c7d0bb0c8ca0db875d6c3f8c6f6d709bbb31c7da2e31f3571daa2c5ab13bfc" +198"16624cf35abd526e84269fb45bbd2fcd8c383d6fbb700bc4b5205b3ef8c432" +199"3dc0d9e0370e56a3d1e5e76aa4de082e4c2a0afd092845bd5dab52a4594318" +200"1461b76e3984b95f48bea80a94944241d04b5634c86274e7" },201{ "AES/KWP/NoPadding", "6decf10a1caf8e3b80c7a4be8c9c84e8", 16,202"49", 1, "01a7d657fc4a5b216f261cca4d052c2b" },203{ "AES/KWP/NoPadding", "a8e06da625a65b25cf5030826830b661", 16,204"43acff293120dd5d", 8, "b6f967616dd8d772e9fea295a456dba7" },205{ "AES/KWP/NoPadding", "7865e20f3c21659ab4690b629cdf3cc4", 16,206"bd6843d420378dc896", 9,207"41eca956d4aa047eb5cf4efe659661e74db6f8c564e23500" },208{ "AES/KWP/NoPadding", "be96dc195ec034d616486ed70e97fe83", 16,209"85b5437b6335ebba7635903a4493d12a77d9357a9e0dbc013456d85f1d3201",21031,211"974769b3a7b4d5d32985f87fddf9990631e5610fbfb278387b58b1f48e05c7" +212"7d2fb7575c5169eb0e" },213{ "AES/KWP/NoPadding", "0e54956a24c7d4a343f90269fb18a17f", 16,214"817ddabdc5d215eee233adff97e92193c6beec52a71340477f70243a794ce9" +215"54af51e356c9940e4ab198f0e68c543355f65ad179cb2d60dd369eaeb9ed14" +216"1fb18c9e4054ac7fdc83506896990a4d20833d2d6e9a34938796ee67c9d7d2" +217"3058544a4a35f2954103ce443a95a7e785602075ca0a73da37899e4568106b" +218"b2dbf1f901377d4d3380c70fa5175ebc550481ac6f15986a4407fde5c23ff3" +219"17e37544c0a25f87117506597db5bb79850c86247b73a5d0090417d63e4c25" +220"7ea0220c2c04db07a34f0ab7954e1dfa2007a1466795c4d0c2aa09ca3986c0" +221"28185b43a466526594afc9c891c263a7c608304bc1957c9873f544dc71e6f8" +222"47c48d32026ed03b2333825452ee7e12a50e1cd7d678319264c65f78001996" +223"d37fae7f9861fbd21cb506c2f8a3b0ee53c7debe17111b6e3f78a5c5677857" +224"b082c2c4943dfd1edf6337fea98a44fc25928361156ef38d865948b979cf6f" +225"4b46bd2119f12f0891cef7fc9d0638fd105fc05f9968d16948d1cb820751e8" +226"2e44cb68e99d4f072ffd1577da6c0631b5827bec7e1b9ec72d18b74cf5f233" +227"e85013c1668ceb5d7a1f5e0f016b0ff726a0a9d41e2cea8e14a2f56492b146" +228"06d3fafd8ac141335f39f90d56863735628e8f17be90e100ef0785f3cd57db" +229"8b9d89a6b2189dc2ea00c285d2657983f8bd7883c215477e67a55556401f1d" +230"8b27d4e0d541c7fb7ace370c2e428884", 512,231"876f3e53ba9cf4f6a521ac198bc813d0ede0f862ab6082e3e0a06ad82b4f27" +232"9582f7c43bb63574608446bc2a05f401a68f74086cf2776b4b3df6b3679c2e" +233"dfb91c024db54c6831e0752ae6f86c7596462de905ee0be908c1b9d043ecaf" +234"e2ad1cbddb904e18ebc9b7a107031be3a87059516a3d1257812d9c801b0b9f" +235"21539e70c47150c128d87c5e58fa6e4371aedde69c7b5cd16b73ac42267632" +236"8131f3ac48c602bb6e0741805aad9d23b33b3523b86cf0588cdf9dc6c4d5f9" +237"fa43d88ca17976eaf48fb37a41a598266da04144373df5631cc5126341c200" +238"a0c8499b29ae96e6e6e6c2bdf8d8903da62bf8ddae970569b695240e77f8ac" +239"5b191da5034008b6ef21936858e69bac372bbafd8794f6b03711503c187552" +240"8a9348681844edb199a0664d740f0f0b1f866c4248c80fe8b5700a3c4134cd" +241"ddb17676e0cd37d6d81831a0f4adfba071bb0935502480eccd48b28be5954e" +242"a6c7d873b51b8bd2b709c5b6132ed31296510915073c18f7012f0eff6a9aad" +243"5340a19fd5e372d35260b718d9e4807b1954c24e6a4fd48e4dbb8f395474e9" +244"9ab577367d2ab5ccaa18c947331047dc3986e213a878b41089aa221019dad4" +245"191a4feefd095f8606c2700a46d71cbb13efb6957df925ec26071c04d04d5a" +246"94e138e5fc5d1f059236aad76208077dcc607b1dd2086f9c04e33f955822b4" +247"57eecd68bd5f24836ecedbac675e6ed93d8a787cb57ad68e" },248};249}250251@Test(dataProvider = "testData")252public void testKeyWrap(String algo, String key, int keyLen,253String data, int dataLen, String expected) throws Exception {254System.out.println("Testing " + algo + " Cipher with wrapping " +255dataLen + "-byte key with " + 8*keyLen + "-bit KEK");256int allowed = Cipher.getMaxAllowedKeyLength("AES");257if (keyLen > allowed) {258System.out.println("=> skip, exceeds max allowed size " + allowed);259return;260}261Cipher c1 = Cipher.getInstance(algo, "SunJCE");262Cipher c2 = Cipher.getInstance(algo, "SunJCE");263Cipher c3 = Cipher.getInstance(algo, "SunJCE");264265byte[] keyVal = toBytes(key, keyLen << 1);266byte[] dataVal = toBytes(data, dataLen << 1);267268SecretKey cipherKey = new SecretKeySpec(keyVal, "AES");269SecretKey toBeWrappedKey = new SecretKeySpec(dataVal, "AES");270271c1.init(Cipher.WRAP_MODE, cipherKey);272IvParameterSpec ivSpec = new IvParameterSpec(c1.getIV());273c2.init(Cipher.WRAP_MODE, cipherKey, ivSpec);274AlgorithmParameters params = AlgorithmParameters.getInstance("AES");275params.init(ivSpec);276c3.init(Cipher.WRAP_MODE, cipherKey, params);277278// first test WRAP with known values279byte[] wrapped = c1.wrap(toBeWrappedKey);280byte[] wrapped2 = c2.wrap(toBeWrappedKey);281byte[] wrapped3 = c3.wrap(toBeWrappedKey);282283byte[] expectedVal = toBytes(expected, expected.length());284285if (!Arrays.equals(wrapped, expectedVal) ||286!Arrays.equals(wrapped2, expectedVal) ||287!Arrays.equals(wrapped3, expectedVal)) {288throw new Exception("Wrap test failed; got different result");289}290291// then test UNWRAP and compare with the initial values292c1.init(Cipher.UNWRAP_MODE, cipherKey);293ivSpec = new IvParameterSpec(c1.getIV());294c2.init(Cipher.UNWRAP_MODE, cipherKey, ivSpec);295params = AlgorithmParameters.getInstance("AES");296params.init(ivSpec);297c3.init(Cipher.UNWRAP_MODE, cipherKey, params);298299Key unwrapped = c1.unwrap(wrapped, "AES", Cipher.SECRET_KEY);300Key unwrapped2 = c2.unwrap(wrapped, "AES", Cipher.SECRET_KEY);301Key unwrapped3 = c3.unwrap(wrapped, "AES", Cipher.SECRET_KEY);302303if (!Arrays.equals(unwrapped.getEncoded(), dataVal) ||304!Arrays.equals(unwrapped2.getEncoded(), dataVal) ||305!Arrays.equals(unwrapped3.getEncoded(), dataVal)) {306throw new Exception("Unwrap failed; got different result");307}308}309310@Test(dataProvider = "testData")311public void testEnc(String algo, String key, int keyLen, String data, int dataLen, String expected)312throws Exception {313System.out.println("Testing " + algo + " Cipher with enc " +314dataLen + "-byte data with " + 8*keyLen + "-bit KEK");315int allowed = Cipher.getMaxAllowedKeyLength("AES");316if (keyLen > allowed) {317System.out.println("=> skip, exceeds max allowed size " + allowed);318return;319}320Cipher c1 = Cipher.getInstance(algo, "SunJCE");321Cipher c2 = Cipher.getInstance(algo, "SunJCE");322Cipher c3 = Cipher.getInstance(algo, "SunJCE");323324byte[] keyVal = toBytes(key, keyLen << 1);325byte[] dataVal = toBytes(data, dataLen << 1);326327SecretKey cipherKey = new SecretKeySpec(keyVal, "AES");328c1.init(Cipher.ENCRYPT_MODE, cipherKey);329IvParameterSpec ivSpec = new IvParameterSpec(c1.getIV());330c2.init(Cipher.ENCRYPT_MODE, cipherKey, ivSpec);331AlgorithmParameters params = AlgorithmParameters.getInstance("AES");332params.init(ivSpec);333c3.init(Cipher.ENCRYPT_MODE, cipherKey, params);334335// first test encryption with known values336byte[] ct11 = c1.update(dataVal);337byte[] ct12 = c1.doFinal();338byte[] ct2 = c1.doFinal(dataVal);339byte[] ct22 = c2.doFinal(dataVal);340byte[] ct32 = c3.doFinal(dataVal);341342byte[] expectedVal = toBytes(expected, expected.length());343344if (ct11 != null || !Arrays.equals(ct12, ct2) ||345!Arrays.equals(ct2, expectedVal) ||346!Arrays.equals(ct22, expectedVal) ||347!Arrays.equals(ct32, expectedVal)) {348throw new Exception("Encryption failed; got different result");349}350351// then test decryption and compare with the initial values352c1.init(Cipher.DECRYPT_MODE, cipherKey);353ivSpec = new IvParameterSpec(c1.getIV());354c2.init(Cipher.DECRYPT_MODE, cipherKey, ivSpec);355params = AlgorithmParameters.getInstance("AES");356params.init(ivSpec);357c3.init(Cipher.DECRYPT_MODE, cipherKey, params);358359byte[] pt11 = c1.update(ct12);360byte[] pt12 = c1.doFinal();361byte[] pt2 = c1.doFinal(ct2);362byte[] pt22 = c2.doFinal(ct2);363byte[] pt32 = c3.doFinal(ct2);364365if (pt11 != null || !Arrays.equals(pt12, pt2) ||366!Arrays.equals(pt2, dataVal) || !Arrays.equals(pt22, dataVal) ||367!Arrays.equals(pt32, dataVal)) {368throw new Exception("Decryption failed; got different result");369}370}371}372373374