• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 /*
3  * Copyright 2016 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.org.conscrypt.java.security;
19 
20 import static java.nio.charset.StandardCharsets.UTF_8;
21 
22 import java.io.BufferedReader;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.Arrays;
29 import java.util.List;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32 
33 /**
34  * @hide This class is not part of the Android public SDK API
35  */
36 public class CpuFeatures {
CpuFeatures()37     private CpuFeatures() {}
38 
isAESHardwareAccelerated()39     public static boolean isAESHardwareAccelerated() {
40         List<String> features = getListFromCpuinfo("Features");
41         if (features != null && features.contains("aes")) {
42             return true;
43         }
44 
45         List<String> flags = getListFromCpuinfo("flags");
46         if (flags != null && flags.contains("aes")) {
47             return true;
48         }
49 
50         features = getCpuFeaturesMac();
51         if (features != null && features.contains("aes")) {
52             return true;
53         }
54 
55         // If we're in an emulated ABI, Conscrypt's NativeCrypto might bridge to
56         // a library that has accelerated AES instructions. See if Conscrypt
57         // detects that condition.
58         Class<?> nativeCrypto = findNativeCrypto();
59         if (nativeCrypto != null) {
60             try {
61                 Method EVP_has_aes_hardware =
62                         nativeCrypto.getDeclaredMethod("EVP_has_aes_hardware");
63                 EVP_has_aes_hardware.setAccessible(true);
64                 return ((Integer) EVP_has_aes_hardware.invoke(null)) == 1;
65             } catch (NoSuchMethodException ignored) {
66             } catch (SecurityException ignored) {
67             } catch (IllegalAccessException ignored) {
68             } catch (IllegalArgumentException ignored) {
69             } catch (InvocationTargetException e) {
70                 throw new IllegalArgumentException(e);
71             }
72         }
73 
74         return false;
75     }
76 
findNativeCrypto()77     private static Class<?> findNativeCrypto() {
78         for (String packageName : new String[]{"com.android.com.android.org.conscrypt", "com.android.org.conscrypt"}) {
79             String name = packageName + ".NativeCrypto";
80             try {
81                 return Class.forName(name);
82             } catch (ClassNotFoundException e) {
83                 // Try the next one.
84             }
85         }
86         return null;
87     }
88 
getFieldFromCpuinfo(String field)89     private static String getFieldFromCpuinfo(String field) {
90         try {
91             @SuppressWarnings("DefaultCharset")
92             BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"));
93             Pattern p = Pattern.compile(field + "\\s*:\\s*(.*)");
94 
95             try {
96                 String line;
97                 while ((line = br.readLine()) != null) {
98                     Matcher m = p.matcher(line);
99                     if (m.matches()) {
100                         return m.group(1);
101                     }
102                 }
103             } finally {
104                 br.close();
105             }
106         } catch (IOException ignored) {
107             // Ignored.
108         }
109 
110         return null;
111     }
112 
getListFromCpuinfo(String fieldName)113     private static List<String> getListFromCpuinfo(String fieldName) {
114         String features = getFieldFromCpuinfo(fieldName);
115         if (features == null)
116             return null;
117 
118         return Arrays.asList(features.split("\\s"));
119     }
120 
getCpuFeaturesMac()121     private static List<String> getCpuFeaturesMac() {
122         try {
123             StringBuilder output = new StringBuilder();
124             Process proc = Runtime.getRuntime().exec("sysctl -a");
125             if (proc.waitFor() == 0) {
126                 BufferedReader reader =
127                         new BufferedReader(new InputStreamReader(proc.getInputStream(), UTF_8));
128 
129                 final String linePrefix = "machdep.cpu.features:";
130 
131                 String line;
132                 while ((line = reader.readLine()) != null) {
133                     line = line.toLowerCase();
134                     if (line.startsWith(linePrefix)) {
135                         // Strip the line prefix from the results.
136                         output.append(line.substring(linePrefix.length())).append(' ');
137                     }
138                 }
139                 if (output.length() > 0) {
140                     String outputString = output.toString();
141                     String[] parts = outputString.split("\\s+");
142                     return Arrays.asList(parts);
143                 }
144             }
145         } catch (Exception ignored) {
146             // Ignored.
147         }
148 
149         return null;
150     }
151 }
152