Skip to content

Commit

Permalink
Round RSA key sizes up when generating (#321)
Browse files Browse the repository at this point in the history
* Round RSA key sizes up when generating

* Add documentation and address feedback

* Only increase bitlength to closest multiple

Co-authored-by: Will Childs-Klein <willck93@gmail.com>

---------

Co-authored-by: Greg Rubin <ga_rubin@apple.com>
Co-authored-by: Will Childs-Klein <willck93@gmail.com>
  • Loading branch information
3 people authored Aug 15, 2023
1 parent 44a7892 commit 2a1b77f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
8 changes: 8 additions & 0 deletions DIFFERENCES.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ ACCP cannot make any promises that its default key sizes match the defaults of *
Because no providers have guarantees around the uninitialized behavior of `KeyPairGenerators` it is generally fragile for your application to use a `KeyPairGenerator` without initialization.
For this reason, even if you don't use ACCP, we recommend that you always call the [KeyPairGenerator.initialize(AlgorithmParameterSpec params)](https://docs.oracle.com/javase/8/docs/api/java/security/KeyPairGenerator.html#initialize-java.security.spec.AlgorithmParameterSpec-) prior to generating a key pair.

## Supported RSA key sizes for generation.
Aws-lc (our underlying cryptographic implementation) does not support generating arbitrary RSA key sizes.
Specifically, it requires that [bit-lengths are a multiple of 128](https://github.com/aws/aws-lc/blob/25260d785f6e2eaf3c5f5dce83cf92c272f0a8b1/crypto/fipsmodule/rsa/rsa_impl.c#L1168-L1171).
For better compatibility with applications, when in *non-FIPS mode*, ACCP will round bit-lengths up to the nearest multiple of 128.
This way we will not throw exceptions at runtime and will give our callers at least as much security as requested.
This is different from the default JDK provider which will attempt to generate a key of the exact requested bit-length.
In FIPS mode will will only return keys of the exact requested length.

## Elliptic Curve KeyPairGeneration by curve size
Neither the JCE nor the default OpenJDK provider for Elliptic Curve Cryptography (SunEC) specify the effect of calling `KeyPairGenerator.initialize(int keysize)` with an arbitrary value.
This behavior is fully specified only for values of 192, 224, 256, 384, and 521.
Expand Down
8 changes: 8 additions & 0 deletions csrc/rsa_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ JNIEXPORT jlong JNICALL Java_com_amazon_corretto_crypto_provider_RsaGen_generate
throw_openssl("Unable to generate key");
}
} else {
// AWS-LC requires that the bitlength be a multiple of 128 and will round down.
// We want to guarantee that we return a key of at least the requested strength and so must
// round up. We only do this in the non-FIPS branch because in FIPS mode we want to do
// exactly what the application requests.
if (bits % 128 != 0) {
bits += 128 - (bits % 128);
}

BigNumObj bne;
jarr2bn(env, pubExp, bne);

Expand Down
18 changes: 18 additions & 0 deletions tst/com/amazon/corretto/crypto/provider/test/RsaGenTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;

import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider;
import com.amazon.corretto.crypto.provider.RuntimeCryptoException;
Expand Down Expand Up @@ -133,6 +134,23 @@ public void test3072() throws GeneralSecurityException {
assertConsistency(pubKey, privKey);
}

// We want to ensure that when we ask for a strange keylength we get something of at least that
// strength.
@Test
public void test3073() throws GeneralSecurityException {
assumeFalse(
AmazonCorrettoCryptoProvider.INSTANCE.isFips(),
"Keysize of 3073 is not supported with FIPS");
final KeyPairGenerator generator = getGenerator();
generator.initialize(3073);
final KeyPair keyPair = generator.generateKeyPair();
final RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
final RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();
assertTrue(3073 <= pubKey.getModulus().bitLength());
assertEquals(RSAKeyGenParameterSpec.F4, pubKey.getPublicExponent());
assertConsistency(pubKey, privKey);
}

@Test
public void test4096() throws GeneralSecurityException {
final KeyPairGenerator generator = getGenerator();
Expand Down

0 comments on commit 2a1b77f

Please sign in to comment.