Skip to content

Commit afbb1cb

Browse files
Restrict RSA paddings allowed through OpenJCEPlusFIPS
This change adds attributes in the RSA service registration in the OpenJCEPlusFIPS provider to only support OAEP paddings. It, also, update the engineSetPadding() method to only allow OAEP paddings to be set when the FIPS provider is used. Tests are updated accordingly to skip invalid padding tests when running with OpenJCEPlusFIPS. A temporary flag that allows the use of other paddings with OpenJCEPlusFIPS is introduced to facilitate migration of users utilizing the previous behaviour. The flag to be set to revert this behaviour is -Dcom.ibm.openjceplusfips.allowNonOAEP=true. Signed-off-by: Kostas Tsiounis <kostas.tsiounis@ibm.com>
1 parent 9688edd commit afbb1cb

File tree

5 files changed

+64
-24
lines changed

5 files changed

+64
-24
lines changed

src/main/java/com/ibm/crypto/plus/provider/OpenJCEPlusFIPS.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public final class OpenJCEPlusFIPS extends OpenJCEPlusProvider {
2424

2525
private static final boolean printFipsDeveloperModeWarning = Boolean.parseBoolean(System.getProperty("openjceplus.fips.devmodewarn", "true"));
2626

27+
private static final boolean allowNonOAEPFIPS = Boolean.parseBoolean(System.getProperty("com.ibm.openjceplusfips.allowNonOAEP", "false"));
28+
2729
private static final String info = "OpenJCEPlusFIPS Provider implements the following:\n" +
2830

2931
"Algorithm parameter : AES, DiffieHellman, DSA, EC, GCM, OAEP, RSAPSS\n"
@@ -208,8 +210,21 @@ private void registerAlgorithms(Provider jce) {
208210
"com.ibm.crypto.plus.provider.AESCipher", aliases));
209211

210212
aliases = null;
213+
Map<String, String> rsaAttr = new HashMap<>();
214+
215+
String supportedPaddings = "OAEPPADDING"
216+
+ "|OAEPWITHSHA1ANDMGF1PADDING"
217+
+ "|OAEPWITHSHA-1ANDMGF1PADDING";
218+
if (allowNonOAEPFIPS) {
219+
supportedPaddings += "|NOPADDING|PKCS1PADDING";
220+
}
221+
rsaAttr.put("SupportedModes", "ECB");
222+
rsaAttr.put("SupportedPaddings", supportedPaddings);
223+
rsaAttr.put("SupportedKeyClasses",
224+
"java.security.interfaces.RSAPublicKey" +
225+
"|java.security.interfaces.RSAPrivateKey");
211226
putService(new OpenJCEPlusService(jce, "Cipher", "RSA", "com.ibm.crypto.plus.provider.RSA",
212-
aliases));
227+
aliases, rsaAttr));
213228

214229
aliases = new String[] {"AESWrap"};
215230
putService(new OpenJCEPlusService(jce, "Cipher", "AES/KW/NoPadding",

src/main/java/com/ibm/crypto/plus/provider/RSA.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ public final class RSA extends CipherSpi {
4747

4848
private static final boolean doTypeChecking;
4949
private static final String DO_TYPE_CHECKING = "com.ibm.crypto.provider.DoRSATypeChecking";
50+
private static final boolean allowNonOAEPFIPS;
51+
private static final String ALLOW_NON_OAEP_FIPS = "com.ibm.openjceplusfips.allowNonOAEP";
5052

5153
private final static byte[] B0 = new byte[0];
5254

5355
static {
5456
doTypeChecking = Boolean.parseBoolean(System.getProperty(DO_TYPE_CHECKING, "true"));
57+
allowNonOAEPFIPS = Boolean.parseBoolean(System.getProperty(ALLOW_NON_OAEP_FIPS, "false"));
5558
}
5659

5760
public RSA(OpenJCEPlusProvider provider) {
@@ -358,24 +361,30 @@ private void checkOAEPParameters(OAEPParameterSpec spec)
358361

359362
@Override
360363
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
361-
if (mode == null || mode.matches(" |ECB|SSL")) {
364+
if (mode == null || mode.matches("ECB")) {
362365
return;
363366
}
364367
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
365368
}
366369

367370
@Override
368371
protected void engineSetPadding(String padding) throws NoSuchPaddingException {
369-
if (padding.equalsIgnoreCase("NoPadding")) {
370-
this.padding = RSAPadding.NoPadding;
371-
} else if (padding.equalsIgnoreCase("PKCS1Padding")) {
372-
this.padding = RSAPadding.PKCS1Padding;
373-
} else if (padding.equalsIgnoreCase("OAEPPadding")
372+
if (padding.equalsIgnoreCase("OAEPPadding")
374373
|| padding.equalsIgnoreCase("OAEPWithSHA-1AndMGF1Padding")
375374
|| padding.equalsIgnoreCase("OAEPWithSHA1AndMGF1Padding")) {
376375
this.padding = RSAPadding.OAEPPadding;
377376
} else {
378-
throw new NoSuchPaddingException("Padding: " + padding + " not implemented");
377+
if (provider.isFIPS() && !allowNonOAEPFIPS) {
378+
throw new NoSuchPaddingException("Padding: " + padding + " not supported through FIPS provider");
379+
} else {
380+
if (padding.equalsIgnoreCase("NoPadding")) {
381+
this.padding = RSAPadding.NoPadding;
382+
} else if (padding.equalsIgnoreCase("PKCS1Padding")) {
383+
this.padding = RSAPadding.PKCS1Padding;
384+
} else {
385+
throw new NoSuchPaddingException("Padding: " + padding + " not implemented");
386+
}
387+
}
379388
}
380389
}
381390

src/test/java/ibm/jceplus/junit/base/BaseTestRSA.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.junit.jupiter.api.Test;
4444
import static org.junit.jupiter.api.Assertions.assertTrue;
4545
import static org.junit.jupiter.api.Assertions.fail;
46+
import static org.junit.jupiter.api.Assumptions.assumeFalse;
4647

4748
public class BaseTestRSA extends BaseTestCipher {
4849

@@ -197,26 +198,36 @@ public void plainKeyCipher(String alg, int mode, Key key, String in, String out,
197198

198199
@Test
199200
public void testRSACipher_PKCS1Padding() throws Exception {
201+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
202+
200203
encryptDecrypt("RSA/ECB/PKCS1Padding");
201204
}
202205

203206
@Test
204207
public void testRSACipher_NoPadding() throws Exception {
208+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
209+
205210
encryptDecrypt("RSA/ECB/NoPadding");
206211
}
207212

208213
@Test
209214
public void testRSACipher_ECB_PKCS1Padding() throws Exception {
215+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
216+
210217
encryptDecrypt("RSA/ECB/PKCS1Padding");
211218
}
212219

213220
@Test
214221
public void testRSACipher_ECB_NoPadding() throws Exception {
222+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
223+
215224
encryptDecrypt("RSA/ECB/NoPadding");
216225
}
217226

218227
@Test
219228
public void testRSACipher_ECB_ZeroPadding() throws Exception {
229+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
230+
220231
encryptDecrypt("RSA/ECB/ZeroPadding");
221232
}
222233

@@ -230,11 +241,6 @@ public void testRSACipherForSSL() throws Exception {
230241
encryptDecrypt("RSAforSSL");
231242
}
232243

233-
@Test
234-
public void testRSACipher_SSL_PKCS1Padding() throws Exception {
235-
encryptDecrypt("RSA/SSL/PKCS1Padding");
236-
}
237-
238244
@Test
239245
public void testRSACipherWithOAEPPadding() throws Exception {
240246
byte[] message = getMessage_OAEP_SHA1();
@@ -312,25 +318,22 @@ public void testRSAShortBuffer() throws Exception {
312318

313319
@Test
314320
public void testRSAShortBuffer2() throws Exception {
321+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
322+
315323
String algorithm = "RSA/ECB/NoPadding";
316324
int outputByteLength = 64;
317325
int finalOffset = 65;
318326

319327
try {
320-
321328
Cipher cipher = Cipher.getInstance(algorithm, getProviderName());
322329

323330
if (cipher.equals(null))
324331
System.out.println("The cipher was null.");
325332

326333
cipher.init(Cipher.ENCRYPT_MODE, rsaPub);
327-
328334
byte[] newplainText2 = new byte[outputByteLength];
329-
330335
cipher.doFinal(newplainText2, finalOffset);
331-
332336
fail("Expected ShortBufferException did not occur");
333-
334337
} catch (ShortBufferException ex) {
335338
assertTrue(true);
336339
}
@@ -360,6 +363,7 @@ public void testRSABadPadding() throws Exception {
360363

361364
@Test
362365
public void testRSAIllegalMode() throws Exception {
366+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
363367

364368
// Test RSA Cipher
365369
Cipher cp = Cipher.getInstance("RSA/ECB/PKCS1Padding", getProviderName());
@@ -376,7 +380,6 @@ public void testRSAIllegalMode() throws Exception {
376380

377381
boolean success = decryptResultsMatch(cp.getAlgorithm(), plainText, newPlainText);
378382
assertTrue(success, "Decrypted text does not match expected");
379-
380383
}
381384

382385
@Test
@@ -386,26 +389,36 @@ public void testRSACipher_getParams() throws Exception {
386389

387390
@Test
388391
public void testRSACipher_PKCS1Padding_getParams() throws Exception {
392+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
393+
389394
checkGetParamsNull("RSA/ECB/PKCS1Padding");
390395
}
391396

392397
@Test
393398
public void testRSACipher_NoPadding_getParams() throws Exception {
399+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
400+
394401
checkGetParamsNull("RSA/ECB/NoPadding");
395402
}
396403

397404
@Test
398405
public void testRSACipher_ECB_PKCS1Padding_getParams() throws Exception {
406+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
407+
399408
checkGetParamsNull("RSA/ECB/PKCS1Padding");
400409
}
401410

402411
@Test
403412
public void testRSACipher_ECB_NoPadding_getParams() throws Exception {
413+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
414+
404415
checkGetParamsNull("RSA/ECB/NoPadding");
405416
}
406417

407418
@Test
408419
public void testRSACipher_ECB_ZeroPadding_getParams() throws Exception {
420+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
421+
409422
checkGetParamsNull("RSA/ECB/ZeroPadding");
410423
}
411424

@@ -419,11 +432,6 @@ public void testRSACipherForSSL_getParams() throws Exception {
419432
checkGetParamsNull("RSAforSSL");
420433
}
421434

422-
@Test
423-
public void testRSACipher_SSL_PKCS1Padding_getParams() throws Exception {
424-
checkGetParamsNull("RSA/SSL/PKCS1Padding");
425-
}
426-
427435
@Test
428436
public void testRSACipherWithOAEPPadding_getParams() throws Exception {
429437
checkGetParamsNotNull("RSA/ECB/OAEPPadding");

src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInterop.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.junit.jupiter.api.Test;
3131
import static org.junit.jupiter.api.Assertions.assertTrue;
3232
import static org.junit.jupiter.api.Assertions.fail;
33+
import static org.junit.jupiter.api.Assumptions.assumeFalse;
3334

3435
public class BaseTestRSAKeyInterop extends BaseTestJunit5Interop {
3536

@@ -475,6 +476,7 @@ public void testSignPlusAndVerifyJCECrt() {
475476

476477
@Test
477478
public void testEncryptPlusDecryptJCE() {
479+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
478480

479481
try {
480482

@@ -514,6 +516,8 @@ public void testEncryptPlusDecryptJCE() {
514516

515517
@Test
516518
public void testEncryptJCEDecryptPlus() {
519+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
520+
517521
byte[] msgBytes = ("This is a short message".getBytes());
518522
//long message to be encrypted and decrypted using RSA public and Private key;" +
519523
// "encrypt with JCE and decrypt with JCEPlus and vice versa").getBytes();

src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInteropBC.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.junit.jupiter.api.Test;
3131
import static org.junit.jupiter.api.Assertions.assertTrue;
3232
import static org.junit.jupiter.api.Assertions.fail;
33+
import static org.junit.jupiter.api.Assumptions.assumeFalse;
3334

3435
public class BaseTestRSAKeyInteropBC extends BaseTestJunit5Interop {
3536

@@ -500,6 +501,7 @@ public void testSignPlusAndVerifyBCCrt() {
500501

501502
@Test
502503
public void testEncryptPlusDecryptBC() {
504+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
503505

504506
try {
505507

@@ -543,6 +545,8 @@ public void testEncryptPlusDecryptBC() {
543545

544546
@Test
545547
public void testEncryptBCDecryptPlus() {
548+
assumeFalse("OpenJCEPlusFIPS".equals(getProviderName()));
549+
546550
byte[] msgBytes = ("This is a short message".getBytes());
547551
//long message to be encrypted and decrypted using RSA public and Private key;" +
548552
// "encrypt with BC and decrypt with BCPlus and vice versa").getBytes();

0 commit comments

Comments
 (0)