xref: /aosp_15_r20/external/tink/java_src/src/main/java/com/google/crypto/tink/config/internal/TinkFipsUtil.java (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 package com.google.crypto.tink.config.internal;
17 
18 import java.lang.reflect.Method;
19 import java.util.concurrent.atomic.AtomicBoolean;
20 import java.util.logging.Logger;
21 
22 /**
23  * Static methods for checking if Tink was built in FIPS mode and to check for algorithm
24  * compatibility.
25  */
26 public final class TinkFipsUtil {
27   private static final Logger logger = Logger.getLogger(TinkFipsUtil.class.getName());
28 
29   // Is true if the FIPS restrictions have been enabled at runtime.
30   private static final AtomicBoolean isRestrictedToFips = new AtomicBoolean(false);
31 
32   /** The status of FIPS compatibility of an algorithm. */
33   public enum AlgorithmFipsCompatibility {
34     /** The algorithm is not FIPS compatible */
35     ALGORITHM_NOT_FIPS {
36       @Override
isCompatible()37       public boolean isCompatible() {
38         // Non-FIPS algorithms are only allowed if Tink is not built in FIPS-only mode.
39         return !useOnlyFips();
40       }
41     },
42     /** The algorithm has a FIPS validated implementation if BoringCrypto is available. */
43     ALGORITHM_REQUIRES_BORINGCRYPTO {
44       @Override
isCompatible()45       public boolean isCompatible() {
46         // If Tink is not in FIPS-only mode, then no restrictions are necessary. In FIPS-only mode
47         // this returns True if BoringCrypto is available.
48         return !useOnlyFips() || fipsModuleAvailable();
49       }
50     };
51 
isCompatible()52     public abstract boolean isCompatible();
53   }
54 
setFipsRestricted()55   public static void setFipsRestricted() {
56     isRestrictedToFips.set(true);
57   }
58 
59   /**
60    * This method is only exposed for tests and should not be used to disable the FIPS restrictions.
61    */
unsetFipsRestricted()62   public static void unsetFipsRestricted() {
63     isRestrictedToFips.set(false);
64   }
65 
useOnlyFips()66   public static boolean useOnlyFips() {
67     return TinkFipsStatus.useOnlyFips() || isRestrictedToFips.get();
68   }
69 
fipsModuleAvailable()70   public static boolean fipsModuleAvailable() {
71     return checkConscryptIsAvailableAndUsesFipsBoringSsl();
72   }
73 
checkConscryptIsAvailableAndUsesFipsBoringSsl()74   static Boolean checkConscryptIsAvailableAndUsesFipsBoringSsl() {
75     try {
76       Class<?> cls = Class.forName("org.conscrypt.Conscrypt");
77       Method isBoringSslFIPSBuild = cls.getMethod("isBoringSslFIPSBuild");
78       return (Boolean) isBoringSslFIPSBuild.invoke(null);
79     } catch (Exception e) {
80       // For older versions of Conscrypt we get a NoSuchMethodException. But no matter what goes
81       // wrong, we cannot guarantee that Conscrypt uses BoringCrypto, so we will return false.
82       logger.info("Conscrypt is not available or does not support checking for FIPS build.");
83       return false;
84     }
85   }
86 
TinkFipsUtil()87   private TinkFipsUtil() {}
88 
89 }
90