Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BouncyCastle FIPs Support #99

Closed
johnwalker opened this issue Feb 12, 2019 · 7 comments
Closed

BouncyCastle FIPs Support #99

johnwalker opened this issue Feb 12, 2019 · 7 comments
Assignees

Comments

@johnwalker
Copy link
Contributor

Can the Encryption SDK for Java be used with BouncyCastle FIPs?

@mattsb42-aws
Copy link
Member

Yes[1]. Something that would be great to add to our CI is to run all of our tests with different JCE backends, much like we currently do with different JDKs.

[1] 99% certain. I'm pretty sure we've had people use it with that before.

@mattsb42-aws
Copy link
Member

I stand corrected. #41 is blocking this.

@SalusaSecondus
Copy link
Contributor

I wired in BC-FIPS for test purposes by using the following diff. (ACCP is used as BC-FIPS pulls tons of entropy from /dev/random by default, and thus blocks.) There are some test failures we still need to figure out, but nothing too worrisome. All decryption test vectors successfully pass. Most of the failures are from tests using features/functionality outside of the standard FIPS 140-2 area.

diff --git a/pom.xml b/pom.xml
index 3a2f2d3..561930a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,8 +48,8 @@

         <dependency>
             <groupId>org.bouncycastle</groupId>
-            <artifactId>bcprov-ext-jdk15on</artifactId>
-            <version>1.61</version>
+            <artifactId>bc-fips</artifactId>
+            <version>1.0.1</version>
         </dependency>

         <dependency>
@@ -73,6 +73,12 @@
             <scope>test</scope>
         </dependency>

+<dependency>
+  <groupId>software.amazon.cryptools</groupId>
+  <artifactId>AmazonCorrettoCryptoProvider</artifactId>
+  <version>LATEST</version>
+  <classifier>linux-x86_64</classifier>
+</dependency>

         <dependency>
             <groupId>com.google.code.findbugs</groupId>
diff --git a/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java b/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java
index fecd733..e51e8dd 100644
--- a/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java
+++ b/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java
@@ -84,8 +84,56 @@ import com.amazonaws.encryptionsdk.model.EncryptionMaterialsRequest;
  * safety to advanced developers. The great majority of users should be able to just use the
  * provided type parameters or the {@code ?} wildcard.
  */
+
+import org.bouncycastle.crypto.util.BasicEntropySourceProvider;
+import java.security.SecureRandom;
 @SuppressWarnings("WeakerAccess") // this is a public API
 public class AwsCrypto {
+    /**
+     * Provides non-blocking entropy to BouncyCastle (non-FIPS mode).
+     */
+    public static final class FastEntropySourceProvider extends BasicEntropySourceProvider {
+        private static final java.util.List<String> PREFERRED_SOURCES = java.util.Arrays.asList(
+                                                                           "NIST800-90A/AES-CTR-256", "NativePRNGNonBlocking", "Windows-PRNG");
+
+        public FastEntropySourceProvider() {
+            super(selectSecureRandom(), true);
+        }
+
+        private static SecureRandom selectSecureRandom() {
+            if (com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider.isRdRandSupported()) {
+               System.out.println("Using AesCtrDrbg");
+               return new com.amazon.corretto.crypto.provider.AesCtrDrbg();
+            } else {
+                for (final String algorithm : PREFERRED_SOURCES) {
+                    try {
+                        final SecureRandom rng = SecureRandom.getInstance(algorithm);
+                       System.out.println("Using " + algorithm);
+                        return rng;
+                    } catch (final Exception ex) {
+                        // Expected
+                    }
+                }
+                throw new AssertionError("No acceptable EntropySource found.");
+            }
+        }
+    }
+
+    static {
+       try {
+           System.setProperty("org.bouncycastle.drbg.entropysource", FastEntropySourceProvider.class.getName());
+           System.out.println("Default provider for GCM is* " + javax.crypto.Cipher.getInstance("AES/GCM/NoPadding").getProvider());
+           System.err.println("Default provider for GCM is* " + javax.crypto.Cipher.getInstance("AES/GCM/NoPadding").getProvider());
+
+           org.bouncycastle.crypto.CryptoServicesRegistrar.setSecureRandom(
+                                                                           org.bouncycastle.crypto.fips.FipsDRBG.SHA512_HMAC.fromEntropySource
+                                                                           (new FastEntropySourceProvider()).build(null, true));
+            java.security.Security.insertProviderAt(new org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider(), 1);
+       } catch (final Exception ex) {
+           throw new AssertionError(ex);
+       }
+    }
+
     private static final Map<String, String> EMPTY_MAP = Collections.emptyMap();

     /**

WesleyRosenblum added a commit that referenced this issue Oct 23, 2019
*Issue #, if available:* #99

*Description of changes:*

These changes allow for the unit tests to pass when the FIPS validated Bouncy Castle provider is explicitly set.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

# Check any applicable:
- [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files.
WesleyRosenblum added a commit that referenced this issue Oct 23, 2019
*Issue #, if available:* #99

*Description of changes:*

These changes allow for the unit tests to pass when the FIPS validated Bouncy Castle provider is explicitly set.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

# Check any applicable:
- [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files.
@WesleyRosenblum
Copy link
Contributor

Tests are now passing with FIPS certified Bouncy Castle

@ravinirmal10
Copy link

@WesleyRosenblum @SalusaSecondus - I am planning to use BC FIPS for aws-encryption-sdk.

I can see that pom.xml file of aws-encryption-sdk is having dependency of bcprov-ext-jdk15on jar, based on that it seems that if I want to use bc-fips then I need to copy the aws-encryption-sdk package and replace bcprov-ext-jdk15on to bc-fips in pom.xml. Basically I don't want to copy the package and want to use aws-encryption-sdk with BC-FIPS directly as a dependency in my project.

@WesleyRosenblum
Copy link
Contributor

Hi @ravinirmal10,

The dependency on bcprov-ext-jdk15on is only needed for the AWS Encryption SDK to serialize and deserialize cryptographic objects, not for the underlying cryptography. From the Getting Started section of the README:

The AWS Encryption SDK for Java uses Bouncy Castle to serialize and deserialize cryptographic objects. It does not explicitly use Bouncy Castle (or any other JCA Provider) for the underlying cryptography. Instead, it uses the platform default, which you can configure or override as documented in the Java Cryptography Architecture (JCA) Reference Guide.
...
Beginning in version 1.6.1, the AWS Encryption SDK also works with Bouncy Castle FIPS (groupId: org.bouncycastle, artifactId: bc-fips) as an alternative to non-FIPS Bouncy Castle. For help installing and configuring Bouncy Castle FIPS properly, see BC FIPS documentation, in particular, User Guides and Security Policy.

To summarize, you do not need to modify the pom.xml of the AWS Encryption SDK. You may add Bouncy Castle FIPS as a dependency of your own software, and install it as mentioned in the BC FIPS documentation. Let me know if you have any further questions.

Thanks!
Wesley

@ravinirmal10
Copy link

ravinirmal10 commented Dec 24, 2020

@WesleyRosenblum - Thanks for your quick response, I am able to use aws-encryption-sdk with Bouncy Castle FIPS by adding bc-fips dependency in my project.

Please note when I tried to use aws-encryption-sdk with Bouncy Castle FIPS by adding bc-fips & aws-encryption-sdk dependency in my project I saw aws-encryption-sdk-java-2.0.0.jar, bc-fips-1.0.2.jar and bcprov-ext-jdk15on-1.65.jar files were present in the class path and on server startup I could see below exception:

Caused by: java.lang.NoSuchFieldError: id_alg_AEADChaCha20Poly1305
	at org.bouncycastle.jcajce.provider.symmetric.ChaCha$Mappings.configure(Unknown Source) ~[bcprov-ext-jdk15on-1.65.jar:1.65.00.0]
	at org.bouncycastle.jce.provider.BouncyCastleProvider.loadAlgorithms(Unknown Source) ~[bcprov-ext-jdk15on-1.65.jar:1.65.00.0]
	at org.bouncycastle.jce.provider.BouncyCastleProvider.setup(Unknown Source) ~[bcprov-ext-jdk15on-1.65.jar:1.65.00.0]
	at org.bouncycastle.jce.provider.BouncyCastleProvider.access$000(Unknown Source) ~[bcprov-ext-jdk15on-1.65.jar:1.65.00.0]
	at org.bouncycastle.jce.provider.BouncyCastleProvider$1.run(Unknown Source) ~[bcprov-ext-jdk15on-1.65.jar:1.65.00.0]
	at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_181]
	at org.bouncycastle.jce.provider.BouncyCastleProvider.<init>(Unknown Source) ~[bcprov-ext-jdk15on-1.65.jar:1.65.00.0]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_181]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_181]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_181]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_181]
	at java.lang.Class.newInstance(Class.java:442) ~[?:1.8.0_181]

Then I have to manually exclude bcprov-ext-jdk15on-1.65.jar from build.gradle file of my project in order to solve the issue, the reason was because bc-fips-1.0.2.jar and bcprov-ext-jdk15on-1.65.jar both files were present in the class path and they were colliding with each other.

Thanks,
Ravi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants