1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8020081 8022669 27 * @summary encryption/decryption test for using OAEPPadding with 28 * OAEPParameterSpec specified and not specified during a Cipher.init(). 29 * @author Anthony Scarpino 30 */ 31 32 import java.util.Arrays; 33 34 import java.security.Security; 35 import java.security.Provider; 36 import java.security.KeyPair; 37 import java.security.KeyPairGenerator; 38 import java.security.interfaces.RSAPrivateKey; 39 import java.security.interfaces.RSAPublicKey; 40 import java.security.spec.MGF1ParameterSpec; 41 42 import javax.crypto.Cipher; 43 import javax.crypto.spec.OAEPParameterSpec; 44 import javax.crypto.IllegalBlockSizeException; 45 import javax.crypto.spec.PSource; 46 47 48 public class TestOAEPPadding { 49 private static RSAPrivateKey privateKey; 50 private static RSAPublicKey publicKey; 51 static Provider cp; 52 static boolean failed = false; 53 54 public static void main(String args[]) throws Exception { 55 cp = Security.getProvider("SunJCE"); 56 System.out.println("Testing provider " + cp.getName() + "..."); 57 Provider kfp = Security.getProvider("SunRsaSign"); 58 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", kfp); 59 kpg.initialize(2048); 60 KeyPair kp = kpg.generateKeyPair(); 61 privateKey = (RSAPrivateKey)kp.getPrivate(); 62 publicKey = (RSAPublicKey)kp.getPublic(); 63 64 // Test using a spec with each digest algorithm case 65 // MD5 66 test(new OAEPParameterSpec("MD5", "MGF1", 67 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 68 test(new OAEPParameterSpec("MD5", "MGF1", 69 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 70 test(new OAEPParameterSpec("MD5", "MGF1", 71 MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); 72 test(new OAEPParameterSpec("MD5", "MGF1", 73 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 74 test(new OAEPParameterSpec("MD5", "MGF1", 75 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 76 // SHA1 77 test(new OAEPParameterSpec("SHA1", "MGF1", 78 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 79 test(new OAEPParameterSpec("SHA1", "MGF1", 80 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 81 test(new OAEPParameterSpec("SHA1", "MGF1", 82 MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); 83 test(new OAEPParameterSpec("SHA1", "MGF1", 84 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 85 test(new OAEPParameterSpec("SHA1", "MGF1", 86 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 87 // For default OAEPParameterSpec case (SHA1) 88 test(null); 89 // SHA-224 90 test(new OAEPParameterSpec("SHA-224", "MGF1", 91 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 92 test(new OAEPParameterSpec("SHA-224", "MGF1", 93 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 94 test(new OAEPParameterSpec("SHA-224", "MGF1", 95 MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); 96 test(new OAEPParameterSpec("SHA-224", "MGF1", 97 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 98 test(new OAEPParameterSpec("SHA-224", "MGF1", 99 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 100 // SHA-256 101 test(new OAEPParameterSpec("SHA-256", "MGF1", 102 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 103 test(new OAEPParameterSpec("SHA-256", "MGF1", 104 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 105 test(new OAEPParameterSpec("SHA-256", "MGF1", 106 MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); 107 test(new OAEPParameterSpec("SHA-256", "MGF1", 108 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 109 test(new OAEPParameterSpec("SHA-256", "MGF1", 110 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 111 // SHA-384 112 test(new OAEPParameterSpec("SHA-384", "MGF1", 113 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 114 test(new OAEPParameterSpec("SHA-384", "MGF1", 115 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 116 test(new OAEPParameterSpec("SHA-384", "MGF1", 117 MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); 118 test(new OAEPParameterSpec("SHA-384", "MGF1", 119 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 120 test(new OAEPParameterSpec("SHA-384", "MGF1", 121 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 122 // SHA-512 123 test(new OAEPParameterSpec("SHA-512", "MGF1", 124 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 125 test(new OAEPParameterSpec("SHA-512", "MGF1", 126 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 127 test(new OAEPParameterSpec("SHA-512", "MGF1", 128 MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); 129 test(new OAEPParameterSpec("SHA-512", "MGF1", 130 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 131 test(new OAEPParameterSpec("SHA-512", "MGF1", 132 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 133 // SHA-512/224 and SHA-512/256 134 test(new OAEPParameterSpec("SHA-512/224", "MGF1", 135 MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); 136 test(new OAEPParameterSpec("SHA-512/224", "MGF1", 137 MGF1ParameterSpec.SHA512_224, PSource.PSpecified.DEFAULT)); 138 test(new OAEPParameterSpec("SHA-512/256", "MGF1", 139 MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); 140 test(new OAEPParameterSpec("SHA-512/256", "MGF1", 141 MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); 142 143 if (failed) { 144 throw new Exception("Test failed"); 145 } 146 } 147 148 /* 149 * Test with one byte, the max bytes, and the max + 1 bytes allowed by 150 * the RSA key size and the digest algorithm 151 */ 152 static void test(OAEPParameterSpec spec) throws Exception { 153 int dlen = 0; 154 String algo; 155 156 // For default OAEPParameterSpec case (SHA1) 157 if (spec == null) { 158 dlen = 20; 159 algo = "Default"; 160 } else { 161 // Use the digest algorith provided in the spec 162 algo = spec.getDigestAlgorithm(); 163 if (algo.equals("MD5")) { 164 dlen = 16; 165 } else if (algo.equals("SHA1")) { 166 dlen = 20; 167 } else if (algo.equals("SHA-224") || algo.equals("SHA-512/224")) { 168 dlen = 28; 169 } else if (algo.equals("SHA-256") || algo.equals("SHA-512/256")) { 170 dlen = 32; 171 } else if (algo.equals("SHA-384")) { 172 dlen = 48; 173 } else if (algo.equals("SHA-512")) { 174 dlen = 64; 175 } 176 } 177 178 // OAEP maximum length for a given digest algorith & RSA key length 179 int max = ((publicKey.getModulus().bitLength() / 8) - (2 * dlen) - 2); 180 181 // Test with data length of 1 182 try { 183 testEncryptDecrypt(spec, 1); 184 } catch (Exception e) { 185 System.out.println(algo + " failed with data length of 1"); 186 e.printStackTrace(); 187 failed = true; 188 } 189 190 // Test with data length of maximum allowed 191 try { 192 testEncryptDecrypt(spec, max); 193 } catch (Exception e) { 194 System.out.println(algo + " failed with data length of " + max); 195 e.printStackTrace(); 196 failed = true; 197 } 198 199 // Test with data length of maximum allowed + 1 200 try { 201 testEncryptDecrypt(spec, max + 1); 202 throw new Exception(); 203 } catch (IllegalBlockSizeException ie) { 204 // expected to fail 205 } catch (Exception e) { 206 System.err.println(algo + " failed with data length of " + 207 (max + 1)); 208 e.printStackTrace(); 209 failed = true; 210 211 } 212 } 213 214 private static void testEncryptDecrypt(OAEPParameterSpec spec, 215 int dataLength) throws Exception { 216 217 System.out.print("Testing OAEP with hash "); 218 if (spec != null) { 219 System.out.print(spec.getDigestAlgorithm() + " and MGF " + 220 ((MGF1ParameterSpec)spec.getMGFParameters()). 221 getDigestAlgorithm()); 222 } else { 223 System.out.print("Default"); 224 } 225 System.out.println(", " + dataLength + " bytes"); 226 227 Cipher c = Cipher.getInstance("RSA/ECB/OAEPPadding", cp); 228 if (spec != null) { 229 c.init(Cipher.ENCRYPT_MODE, publicKey, spec); 230 } else { 231 c.init(Cipher.ENCRYPT_MODE, publicKey); 232 } 233 234 byte[] data = new byte[dataLength]; 235 byte[] enc = c.doFinal(data); 236 if (spec != null) { 237 c.init(Cipher.DECRYPT_MODE, privateKey, spec); 238 } else { 239 c.init(Cipher.DECRYPT_MODE, privateKey); 240 } 241 byte[] dec = c.doFinal(enc); 242 if (Arrays.equals(data, dec) == false) { 243 throw new Exception("Data does not match"); 244 } 245 } 246 }