Skip to content

Commit

Permalink
Use FIPS approved APIs to generate RSA key pairs (#303)
Browse files Browse the repository at this point in the history
* Use FIPS approved APIs to generate RSA key pairs
* Update CHANGELOG.md
* Update version numbers to 2.1.0
  • Loading branch information
amirhosv authored May 30, 2023
1 parent 190b1ad commit 1adb7e0
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 26 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 2.1.0 (not released yet)

### Minor changes
* Support AlgorithmParameters for EC [PR 274]
* Support KeyGenerator for AES [PR 279]
* Register LibCryptoRng by default in non-FIPS mode [PR 286]
* Use FIPS approved API of AWS-LC for RSA key generation in FIPS mode [PR 301]
* Include AWS-LC's self tests as part of ACCP's self tests [PR 283]

### Patches
* Fixed bug in output buffer size check [PR 297]
* Improved the performance of AES-GCM [PRs 296, 298, 300, 302]
* Added code formatting and style checking to the build scripts [PRs 287, 292]
* Renamed branches on GitHub

## 2.0.0

### Overview
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ plugins {
}

group = 'software.amazon.cryptools'
version = '2.0.0'
version = '2.1.0'
ext.isFips = Boolean.getBoolean('FIPS')
ext.isLegacyBuild = Boolean.getBoolean('LEGACY_BUILD')

Expand Down
26 changes: 13 additions & 13 deletions csrc/rsa_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ JNIEXPORT jlong JNICALL Java_com_amazon_corretto_crypto_provider_RsaGen_generate
try {
raii_env env(pEnv);

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

if (1 != RSA_generate_key_ex(r, bits, bne, NULL)) {
throw_openssl("Unable to generate key");
}

if (FIPS_mode() == 1) {
// We should be using RSA_generate_key_fips, but since RSA_generate_key_fips doesn't allow
// bit lengths greater than 4096 and public exponents other than F4, we use RSA_generate_key_ex
// and explicitly check FIPS related conditions. This is done to ensure that ACCP built in FIPS mode
// is compatible with BC-FIPS.
if (RSA_check_fips(r) != 1) {
throw_openssl("RSA_check_fips failed");
// RSA_generate_key_fips performs extra checks so there is no need
// to run post generation checks. This API generates keys with
// public exponent F4; we ignore the public exponent here, but in
// the Java layer, we check that the public exponent passed is F4.
if (RSA_generate_key_fips(r, bits, NULL) != 1) {
throw_openssl("Unable to generate key");
}
} else {
BigNumObj bne;
jarr2bn(env, pubExp, bne);

if (RSA_generate_key_ex(r, bits, bne, NULL) != 1) {
throw_openssl("Unable to generate key");
}

if (checkConsistency && RSA_check_key(r) != 1) {
throw_openssl("Key failed consistency check");
}
Expand Down
2 changes: 1 addition & 1 deletion examples/gradle-kt-dsl/lib/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
val accpVersion = "2.0.0"
val accpVersion = "2.1.0"

plugins {
// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
Expand Down
6 changes: 3 additions & 3 deletions src/com/amazon/corretto/crypto/provider/RsaGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ public void initialize(int keysize, SecureRandom rnd) throws InvalidParameterExc
private static RSAKeyGenParameterSpec validateParameter(final RSAKeyGenParameterSpec spec)
throws InvalidAlgorithmParameterException {

// Similar to BC-FIPS, ACCP only disallows public exponents less than F4.
if (Loader.FIPS_BUILD && spec.getPublicExponent().compareTo(RSAKeyGenParameterSpec.F4) <= -1) {
// In FIPS mode, ACCP only allows public exponents F4.
if (Loader.FIPS_BUILD && !RSAKeyGenParameterSpec.F4.equals(spec.getPublicExponent())) {
throw new InvalidAlgorithmParameterException(
"For FIPS builds, public exponent cannot be less that F4");
"For FIPS builds, public exponent must be equal to F4");
}

if (spec.getKeysize() < MIN_KEY_SIZE) {
Expand Down
43 changes: 35 additions & 8 deletions tst/com/amazon/corretto/crypto/provider/test/RsaGenTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider;
import com.amazon.corretto.crypto.provider.RuntimeCryptoException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
Expand Down Expand Up @@ -145,16 +146,42 @@ public void test4096() throws GeneralSecurityException {
}

@Test
public void test5120_with_customE() throws GeneralSecurityException {
public void test5120() throws GeneralSecurityException {
final KeyPairGenerator generator = getGenerator();
generator.initialize(5120);
if (TestUtil.isFips()) {
assertThrows(RuntimeCryptoException.class, () -> generator.generateKeyPair());
} else {
final KeyPair keyPair = generator.generateKeyPair();
final RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
final RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();
assertEquals(5120, pubKey.getModulus().bitLength());
assertEquals(RSAKeyGenParameterSpec.F4, pubKey.getPublicExponent());
assertConsistency(pubKey, privKey);
}
}

@Test
public void test_customE() throws GeneralSecurityException {
final int[] bitLens = {4096, 5120};
final BigInteger customE = RSAKeyGenParameterSpec.F4.add(BigInteger.valueOf(2));
final KeyPairGenerator generator = getGenerator();
generator.initialize(new RSAKeyGenParameterSpec(5120, customE));
final KeyPair keyPair = generator.generateKeyPair();
final RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
final RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();
assertEquals(5120, pubKey.getModulus().bitLength());
assertEquals(customE, pubKey.getPublicExponent());
assertConsistency(pubKey, privKey);

for (int bitLen : bitLens) {
if (TestUtil.isFips()) {
assertThrows(
InvalidAlgorithmParameterException.class,
() -> generator.initialize(new RSAKeyGenParameterSpec(5120, customE)));
} else {
generator.initialize(new RSAKeyGenParameterSpec(bitLen, customE));
final KeyPair keyPair = generator.generateKeyPair();
final RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
final RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();
assertEquals(bitLen, pubKey.getModulus().bitLength());
assertEquals(customE, pubKey.getPublicExponent());
assertConsistency(pubKey, privKey);
}
}
}

@Test
Expand Down

0 comments on commit 1adb7e0

Please sign in to comment.