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