# Overview

MicroEJ Foundation Library testsuite for `ej.api:crypto`.

# Test suite Configuration
Setup the following system properties to override default values in the following tests.

Note: In PQT configuration file or in test suite properties add the prefix `microej.testsuite.properties.microej.java.property.` to the following properties:

### Skipping one test method

The MicroEJ JUnit runner skips a test method when the system property `tests.<ClassSimpleName>.<method>.skip` is `true`, and reports it as skipped. For example, in a VEE Port test suite properties file:

```
microej.java.property.tests.ExternalKeyStoreTest.testSetKeyEntryWithUnencodableCertificateKeepsPreviousEntry.skip=true
```

A skipped method hides a failure of the backend it covers. Use it for a method the backend cannot satisfy by design, and say why in the properties file.

### AESCipherTest Properties

For test `testMultiPartCipherAndResetOnDoFinalNoPadding`:
- `com.microej.crypto.test.cipher.transformation`: The default value is `AES/CTR/NoPadding`.
- `com.microej.crypto.test.cipher.key`: The default value is `ACD1DDB17E69A9A7C8158C38068DDBD621425E83AB2AE8A061713F994AB676DA`.
- `com.microej.crypto.test.cipher.iv`: The default value is `lCq77sYlhcLXGobTC6mqmg==`.
- `com.microej.crypto.test.cipher.plaintext`: The default value is `0102030405060708090A0B0C0D0E0F10`.
- `com.microej.crypto.test.cipher.ciphertext.onepass`: the expected ciphertext block when running the encryption using configured cipher transformation using configured key/iv on the configured plaintext. (defaults to `DEE3778CB54C83495C0FF5745067D99E`).
- `com.microej.crypto.test.cipher.ciphertext.twopass`: the expected ciphertext block when running a second block of encryption on the same configured plaintext. (defaults to `346C62B683745806F68E20775F7C3FD8`).
- `com.microej.crypto.test.cipher.ciphertext.threepass`: the expected ciphertext block when running a third block of encryption on the same configured plaintext. (defaults to `58EA9CB3CDDCC4471A56F3069FCF5910`).

### Algorithm Lists

Global lists, read by every test of the algorithm family:

- `com.microej.crypto.test.ec.curves`: list of comma separated EC curve names supported by the platform, exercised by `KeyPairGeneratorTest`, `SignatureTest`, `CertificateTest` and `CertificateDataTest`.
  - Default value: `secp256r1, secp384r1, secp521r1`.
  - Possible values: `secp192r1, secp224r1, secp256k1, secp256r1, secp384r1, secp521r1`, the curves the test suite holds test material for. No other curve can be listed. The three curves absent from the default list were removed from recent JDKs. A VEE Port whose backend supports them adds them to its list.
- `com.microej.crypto.test.rsa.keysizes`: list of comma separated RSA key sizes in bits supported by the platform, exercised by `KeyPairGeneratorTest`, `RSACipherTest`, `SignatureTest`, `CertificateTest` and `CertificateDataTest`.
  - Default value: `1024, 2048, 3072, 4096`.
  - Possible values: the same as the default value, the key sizes the test suite holds test material for. No other size can be listed.

Key pair generation lists, to skip a slow key size or curve in `KeyPairGeneratorTest` only, the one class that generates keys (the other classes load the key pairs of the test material). Each one defaults to its global list when not set or empty, and can only list values of that global list:

- `com.microej.crypto.test.keypairgen.ec.curves`: curves generated by `KeyPairGeneratorTest`.
- `com.microej.crypto.test.keypairgen.rsa.keysizes`: RSA key sizes generated by `KeyPairGeneratorTest`.

A global list must not be empty: a VEE Port whose backend does not support a family at all excludes its test classes instead.

### ExternalKeyStoreTest Properties

For properties description, see [ExternalKeyStoreTest.java](src/test/java/com/microej/crypto/test/ExternalKeyStoreTest.java).

- `com.microej.crypto.test.ExternalKeyStoreTest.keystore.type`
- `com.microej.crypto.test.ExternalKeyStoreTest.keystore.password`
- `com.microej.crypto.test.ExternalKeyStoreTest.keystore.size`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.extractable`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.import.algorithms`: list of comma separated algorithms of the private keys the import tests set through `setKeyEntry`, among `RSA` and `EC`. For each one the tests set the committed key of the first configured RSA key size or EC curve, its certificate, and the same key encrypted with the key store password. The default value is `RSA, EC`, also when the property is empty. A VEE Port whose backend imports one family lists that family.
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.tmp.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.password`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.signature.algorithm`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.signature.data`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.keyagreement.algorithm`
- `com.microej.crypto.test.ExternalKeyStoreTest.privatekey.keyagreement.secret`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.extractable`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.data`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.algorithm`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.tmp.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.import.loops`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.password`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.cipher.transformation`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.cipher.payload`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.cipher.iv`
- `com.microej.crypto.test.ExternalKeyStoreTest.secretkey.cipher.encrypted`
- `com.microej.crypto.test.ExternalKeyStoreTest.certificate.data`
- `com.microej.crypto.test.ExternalKeyStoreTest.certificate.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.certificate.tmp.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.certificatechain.alias`
- `com.microej.crypto.test.ExternalKeyStoreTest.certificatechain.length`
- `com.microej.crypto.test.ExternalKeyStoreTest.getcertificate.repeat`

### OomGcRetryTest Properties

For properties description, see [OomGcRetryTest.java](src/test/java/com/microej/crypto/test/OomGcRetryTest.java).

- `com.microej.crypto.test.oomgcretry.pressure.max`: upper bound on the number of objects allocated to exhaust the native heap. The default value is `1024`.
- `com.microej.crypto.test.oomgcretry.pressure.required`: when `true`, a test fails when the native heap is not exhausted within the bound. The default value is `false`, the test then reports that it is inconclusive and passes.
- `com.microej.crypto.test.oomgcretry.repeat.outer`: number of pressure-and-operate iterations per test. The default value is `5`.

### SecureRandomTest Properties

- `com.microej.crypto.test.securerandom.iterations.divisor`: divisor applied to the count of every long generation loop (10 000 to 1 500 000 iterations at nominal count). The default value is `1`. Set it on a Simulator or a slow backend to shorten the class; a device validation leaves it unset, since a large divisor weakens the statistical checks.

### Authenticated cipher properties

- `cipher.auth.<i>.tagLength`: authentication tag length in bits of the `<i>`th authenticated transformation. The default value is `128`.
  - NIST SP 800-38D caps the GCM tag at 128 bits. This value is unrelated to the key size; passing one for the other is only harmless when both happen to be 128.
- `cipher.auth.tagLengths`: list of comma separated tag lengths in bits that the encrypt and decrypt round trip is run at. The default value is `96, 104, 112, 120, 128`.
  - Possible values: the tag lengths SP 800-38D lists for general use. A VEE Port whose backend accepts only some of them shortens the list.

### AESNistVectorsTest Properties

- `com.microej.crypto.test.cipher.aes.keysizes`: list of comma separated AES key sizes to check against the NIST SP 800-38A vectors. The default value is `128, 192, 256`.
  - Possible values: `128, 192, 256`, the sizes the standard publishes vectors for. A VEE Port whose backend lacks one of them shortens the list.

### Date

- `date`: the date the test suite runs at, as `YYYY-MM-DD`. The default value is `2030-01-01`.

  A target whose clock is not set boots in 1970, outside the validity window of every certificate the suite loads,
  and the certificate tests then fail for a reason unrelated to the backend. Each test class that loads a
  certificate sets this date first. On a platform that does not let an application set its time, the tests run at
  the current time of the platform instead. A plain JVM is one such platform. A Linux VEE Port is another when its
  executable runs without the privilege to set the system clock (`CAP_SYS_TIME`).

  A replacement value must stay after November 2023 and before November 2053: the suite holds one certificate that
  must read as not yet valid and several that must read as valid, and only that window satisfies both.

### KeyGeneratorTest Properties

- `keygen.aes.keysizes`: list of comma separated key sizes for AES algorithm supported by the platform. The default value is `128, 192, 256`.

# Test material

The key pairs, certificates, signatures and key stores the tests load live in `src/test/resources`.
Two scripts generate all of them:

| Script | Generates | Needs |
| --- | --- | --- |
| `src/test/resources/_generate.sh` | the key pairs, the self-signed certificates, `data4096.bin` and its signatures, and the private keys in encrypted PKCS#8 form | OpenSSL 3.5 or later |
| `../pki/generate-pki.sh` | the certificate path chain `certpathvalidator/A.crt` to `H.crt`, the key store `test-keystore.p12`, and the values `ExternalKeyStoreTest` expects from its keys (`test-keystore-*.bin`) | OpenSSL 3.5 or later, JDK 17 or later |

Each script rewrites every file it owns on each run and keeps nothing that is already present, because a
certificate, a signature or an expected value only matches the key it was produced from. Running a script
therefore replaces its whole set and the committed files change; commit the result as one change.

`test-keystore.p12` is also the key store that the VEE Ports provision their backend from. Keep its aliases and
key types when changing `generate-pki.sh`.

## Regenerate the Key Store and Its Secrets

`ExternalKeyStoreTest` checks that a VEE Port can use keys that its backend stores, for example in a secure element.
Before the test runs, the VEE Port loads the keys of `test-keystore.p12` into its backend.
The test then makes the backend use two of these keys, and compares each result with a value computed in advance:

- The backend encrypts a fixed message with the AES key `test-secret`. The test compares the encrypted message with `test-keystore-aes-cbc.bin`.
- The backend computes an ECDH shared secret from the private key `test-entity` and the public key of the certificate `test-trusted-cert`. The test compares it with `test-keystore-ecdh.bin`.

The two `.bin` files depend on the keys.
When the keys change, the two files must change too, or the test fails.
`generate-pki.sh` creates the keys and the two files together.
To run it:

1. Install OpenSSL 3.5 or later and JDK 17 or later.
   The script takes `keytool` and `java` from `JAVA_HOME` when it is set.
2. Run `sh pki/generate-pki.sh` from the root of the repository.
   On Windows, run it in Git Bash with `MSYS_NO_PATHCONV=1` set.
3. Commit the regenerated files of `src/test/resources` as one change.
   The script also regenerates the `certpathvalidator` chain.
4. Load the new `test-keystore.p12` into the backend of each VEE Port again.
   The old keys do not match the new values.

# Usage

# Requirements

# Dependencies

_All dependencies are retrieved transitively by Gradle_.

# Source

N/A.

# Restrictions

None.

---

_Copyright 2018-2026 MicroEJ Corp. All rights reserved._  
_Use of this source code is governed by a BSD-style license that can be found with this software._  
_Build: 7E4D1F7C_
