1 /* 2 * Copyright (c) 2013, 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 if (failed) { 134 throw new Exception("Test failed"); 135 } 136 } 137 138 /* 139 * Test with one byte, the max bytes, and the max + 1 bytes allowed by 140 * the RSA key size and the digest algorithm 141 */ 142 static void test(OAEPParameterSpec spec) throws Exception { 143 int dlen = 0; 144 String algo; 145 146 // For default OAEPParameterSpec case (SHA1) 147 if (spec == null) { 148 dlen = 20; 149 algo = "Default"; 150 } else { 151 // Use the digest algorith provided in the spec 152 algo = spec.getDigestAlgorithm(); 153 if (algo.equals("MD5")) { 154 dlen = 16; 155 } else if (algo.equals("SHA1")) { 156 dlen = 20; 157 } else if (algo.equals("SHA-224")) { 158 dlen = 28; 159 } else if (algo.equals("SHA-256")) { 160 dlen = 32; 161 } else if (algo.equals("SHA-384")) { 162 dlen = 48; 163 } else if (algo.equals("SHA-512")) { 164 dlen = 64; 165 } 166 } 167 168 // OAEP maximum length for a given digest algorith & RSA key length 169 int max = ((publicKey.getModulus().bitLength() / 8) - (2 * dlen) - 2); 170 171 // Test with data length of 1 172 try { 173 testEncryptDecrypt(spec, 1); 174 } catch (Exception e) { 175 System.out.println(algo + " failed with data length of 1"); 176 e.printStackTrace(); 177 failed = true; 178 } 179 180 // Test with data length of maximum allowed 181 try { 182 testEncryptDecrypt(spec, max); 183 } catch (Exception e) { 184 System.out.println(algo + " failed with data length of " + max); 185 e.printStackTrace(); 186 failed = true; 187 } 188 189 // Test with data length of maximum allowed + 1 190 try { 191 testEncryptDecrypt(spec, max + 1); 192 throw new Exception(); 193 } catch (IllegalBlockSizeException ie) { 194 // expected to fail 195 } catch (Exception e) { 196 System.err.println(algo + " failed with data length of " + 197 (max + 1)); 198 e.printStackTrace(); 199 failed = true; 200 201 } 202 } 203 204 private static void testEncryptDecrypt(OAEPParameterSpec spec, 205 int dataLength) throws Exception { 206 207 System.out.print("Testing OAEP with hash "); 208 if (spec != null) { 209 System.out.print(spec.getDigestAlgorithm() + " and MGF " + 210 ((MGF1ParameterSpec)spec.getMGFParameters()). 211 getDigestAlgorithm()); 212 } else { 213 System.out.print("Default"); 214 } 215 System.out.println(", " + dataLength + " bytes"); 216 217 Cipher c = Cipher.getInstance("RSA/ECB/OAEPPadding", cp); 218 if (spec != null) { 219 c.init(Cipher.ENCRYPT_MODE, publicKey, spec); 220 } else { 221 c.init(Cipher.ENCRYPT_MODE, publicKey); 222 } 223 224 byte[] data = new byte[dataLength]; 225 byte[] enc = c.doFinal(data); 226 if (spec != null) { 227 c.init(Cipher.DECRYPT_MODE, privateKey, spec); 228 } else { 229 c.init(Cipher.DECRYPT_MODE, privateKey); 230 } 231 byte[] dec = c.doFinal(enc); 232 if (Arrays.equals(data, dec) == false) { 233 throw new Exception("Data does not match"); 234 } 235 } 236 }