Skip to content

Intermittant failure generating RSA key "ICC_RSA_generate_key() failed" #1052

@jasonkatonica

Description

@jasonkatonica

RSA key generations have failed on rare occasions in various testing scenarios.

I was able to recreate the failure using the following test:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class RSAKeyGenStressTest {
    
    private static final int NUM_THREADS = 16;
    private static final int ITERATIONS_PER_THREAD = 100000;
    private static final AtomicInteger successCount = new AtomicInteger(0);

    public static void main(String[] args) {
        System.out.println("================================");
        System.out.println("RSA Key Generation Stress Test");
        System.out.println("================================");
        System.out.println("Threads: " + NUM_THREADS);
        System.out.println("Iterations per thread: " + ITERATIONS_PER_THREAD);
        System.out.println("================================");
        System.out.println();
        
        try {
            Class<?> providerClass = Class.forName("com.ibm.crypto.plus.provider.OpenJCEPlusFIPS");
            java.security.Provider provider = (java.security.Provider) providerClass.getDeclaredConstructor().newInstance();
            Security.addProvider(provider);
            System.out.println("Loaded provider: " + provider.getName());
        } catch (Exception e) {
            System.err.println("ERROR: Could not load OpenJCEPlusFIPS provider: " + e.getMessage());
            System.exit(-1);
        }

        System.out.println("\nStarting stress test...\n");
        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
        CountDownLatch latch = new CountDownLatch(NUM_THREADS);
        
        for (int t = 0; t < NUM_THREADS; t++) {
            final int threadId = t;
            executor.submit(() -> {
                try {
                    runTest(threadId);
                } finally {
                    latch.countDown();
                }
            });
        }
        
        try {
            latch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("Test interrupted");
        }
        executor.shutdown();
        System.out.println("\n================================");
        System.out.println("Test Results:");
        System.out.println("================================");
        System.out.println("Successes: " + successCount.get());
        System.out.println("\nAll key generations succeeded");
        System.out.println("================================");
        System.exit(-1);
    }

    private static void runTest(int threadId) {
        KeyPairGenerator kpg = null;
        try {
            kpg = KeyPairGenerator.getInstance("RSA", "OpenJCEPlusFIPS");
        } catch (Exception e) {
            System.err.println("Failed to get RSA instance.");
            System.exit(-1);
        }

        for (int i = 0; i < ITERATIONS_PER_THREAD; i++) {
            try {
                KeyPair keyPair = kpg.generateKeyPair();
                
                if (keyPair == null || keyPair.getPrivate() == null || keyPair.getPublic() == null) {
                    System.err.println("Error empty key.");
                    System.exit(-1);
                } else {
                    successCount.incrementAndGet();
                    if (successCount.get() % 100 == 0) {
                        System.out.println("Progress: " + successCount.get() + " keys generated...");
                    }
                }
                
            } catch (Exception e) {
                System.err.println("FAILURE generating key.");
                System.err.println("Exception: " + e.getClass().getName() + ": " + e.getMessage());
                e.printStackTrace(System.err);
                System.exit(-1);
            }
        }
    }
}

With enough time the failure can be observed on MacOS:

...
...
...
Progress: 1226100 keys generated...
Progress: 1226200 keys generated...
Progress: 1226300 keys generated...
FAILURE generating key.
Exception: java.security.ProviderException: Failure in generateKeyPair
java.security.ProviderException: Failure in generateKeyPair
        at openjceplus/com.ibm.crypto.plus.provider.OpenJCEPlusFIPS.providerException(OpenJCEPlusFIPS.java:935)
        at openjceplus/com.ibm.crypto.plus.provider.RSAKeyPairGenerator.generateKeyPair(RSAKeyPairGenerator.java:125)
        at openjceplus/com.ibm.crypto.plus.provider.RSAKeyPairGenerator$Legacy.generateKeyPair(RSAKeyPairGenerator.java:129)
        at java.base/java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:723)
        at RSAKeyGenStressTest.runTest(RSAKeyGenStressTest.java:81)
        at RSAKeyGenStressTest.lambda$main$0(RSAKeyGenStressTest.java:47)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:328)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
        at java.base/java.lang.Thread.run(Thread.java:1485)
Caused by: com.ibm.crypto.plus.provider.ock.OCKException: ICC_RSA_generate_key() failed
        at openjceplus/com.ibm.crypto.plus.provider.ock.NativeInterface.RSAKEY_generate(Native Method)
        at openjceplus/com.ibm.crypto.plus.provider.ock.RSAKey.generateKeyPair(RSAKey.java:41)
        at openjceplus/com.ibm.crypto.plus.provider.RSAKeyPairGenerator.generateKeyPair(RSAKeyPairGenerator.java:119)
        ... 9 more

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions