Class OomGcRetryTest


  • public class OomGcRetryTest
    extends java.lang.Object
    Validates the retry-after-GC path of the library across the native JCA subsystems.

    When a native operation runs out of native memory, the library calls System.gc() once and retries the operation, so that the native resources of unreachable crypto objects are released before the operation fails. The BON constant com.microej.security.retryAfterGcOnNativeOom enables this path (it is enabled by default).

    Each test fills the native heap with objects of the same kind as the operation under test, drops the Java references without calling System.gc(), runs the operation and compares the result with a published test vector (NIST SP 800-38A, FIPS 180-2, RFC 4231, RFC 7914). A correct result, not the absence of an exception, proves that the retry path ran: the operation could only get its native memory back from the collected objects. An ECDSA signature carries a random nonce and has no reference value: the EC tests verify the signature with the public key instead.

    The pressure is built by allocating until the native heap refuses the allocation, so the test adapts to the size of the native heap of the port. The pressure objects are of the same kind as the operation under test because a bucket allocator only reuses memory within one size class. On a port whose native heap cannot be exhausted within the configured bound, the test reports that it is inconclusive and passes, unless the pressure is declared required.

    Every operation under test runs in EnsureAsync, to check that the blocking native call yields to other threads. The pressure allocations do not: they are not the operation under test and their number is large.

    Configurable properties (prefixed by com.microej.crypto.test.):

    • oomgcretry.pressure.max: upper bound on the number of pressure objects allocated before giving up on exhausting the native heap (default: 1024),
    • oomgcretry.pressure.required: when true, a test fails when the native heap is not exhausted within the bound, instead of reporting that it is inconclusive (default: false),
    • oomgcretry.repeat.outer: number of pressure-and-operate iterations per test (default: 5).
    • Constructor Detail

      • OomGcRetryTest

        public OomGcRetryTest()
    • Method Detail

      • testSha256DigestUnderNativePressure

        public void testSha256DigestUnderNativePressure()
                                                 throws java.lang.Exception
        Validates a SHA-256 digest under native heap pressure.

        The pressure objects are SHA-256 digest contexts. Asserts the digest value matches the FIPS 180-2 example.

        Throws:
        java.lang.Exception - on any error
      • testAesCbcCipherUnderNativePressure

        public void testAesCbcCipherUnderNativePressure()
                                                 throws java.lang.Exception
        Validates an AES/CBC cipher under native heap pressure.

        The pressure objects are initialized AES/CBC cipher contexts. Asserts the ciphertext matches the NIST SP 800-38A F.2.1 example.

        Throws:
        java.lang.Exception - on any error
      • testHmacSha256UnderNativePressure

        public void testHmacSha256UnderNativePressure()
                                               throws java.lang.Exception
        Validates an HmacSHA256 MAC under native heap pressure.

        The pressure objects are initialized HmacSHA256 contexts. Asserts the MAC value matches the RFC 4231 test case 1.

        Throws:
        java.lang.Exception - on any error
      • testEcSignatureUnderNativePressure

        public void testEcSignatureUnderNativePressure()
                                                throws java.lang.Exception
        Validates an EC key import through KeyFactory and an ECDSA sign and verify under native heap pressure.

        An EC P-256 key pair is generated once before the pressure loop. The pressure objects are EC private keys imported from the PKCS#8 encoding of that key pair. Each iteration re-imports the private key, signs the test data with the re-imported key and verifies the signature with the original public key, with fresh pressure before each of the three steps.

        Throws:
        java.lang.Exception - on any error
      • testPbkdf2UnderNativePressure

        public void testPbkdf2UnderNativePressure()
                                           throws java.lang.Exception
        Validates a PBKDF2WithHmacSHA256 key derivation under native heap pressure.

        The pressure objects are derived secret keys. Asserts the derived key bytes match the RFC 7914 test vector.

        Throws:
        java.lang.Exception - on any error
      • testSecureRandomUnderNativePressure

        public void testSecureRandomUnderNativePressure()
                                                 throws java.lang.Exception
        Validates SecureRandom under native heap pressure.

        The pressure objects are secure random generators that produced at least one byte, so their native generator is allocated. Asserts the output buffer is not all zeros, which holds with overwhelming probability for 32 bytes.

        Throws:
        java.lang.Exception - on any error
      • testEcKeyPairGeneratorUnderNativePressure

        public void testEcKeyPairGeneratorUnderNativePressure()
                                                       throws java.lang.Exception
        Validates an EC P-256 key pair generation under native heap pressure.

        The pressure objects are EC private keys imported through KeyFactory, which hold the same kind of native key as a generated key pair and are faster to produce. A generated key pair has no reference value, so the test proves the pair is fresh and consistent instead: a signature made with its private key verifies with its public key, and its public key differs from the one of the previous iteration.

        Throws:
        java.lang.Exception - on any error