1 /* 2 * Copyright 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libcore.java.security; 18 19 import java.io.BufferedReader; 20 import java.io.FileReader; 21 import java.io.IOException; 22 import java.lang.reflect.InvocationTargetException; 23 import java.lang.reflect.Method; 24 import java.util.Arrays; 25 import java.util.List; 26 import java.util.regex.Matcher; 27 import java.util.regex.Pattern; 28 29 public class CpuFeatures { 30 private CpuFeatures() { 31 } 32 33 public static boolean isAESHardwareAccelerated() { 34 List<String> features = getListFromCpuinfo("Features"); 35 if (features != null && features.contains("aes")) { 36 return true; 37 } 38 39 List<String> flags = getListFromCpuinfo("flags"); 40 if (flags != null && flags.contains("aes")) { 41 return true; 42 } 43 44 // If we're in an emulated ABI, Conscrypt's NativeCrypto might bridge to 45 // a library that has accelerated AES instructions. See if Conscrypt 46 // detects that condition. 47 try { 48 Class<?> nativeCrypto = Class.forName("com.android.org.conscrypt.NativeCrypto"); 49 Method EVP_has_aes_hardware = nativeCrypto.getDeclaredMethod("EVP_has_aes_hardware"); 50 EVP_has_aes_hardware.setAccessible(true); 51 return ((Integer) EVP_has_aes_hardware.invoke(null)) == 1; 52 } catch (ClassNotFoundException | NoSuchMethodException | SecurityException 53 | IllegalAccessException | IllegalArgumentException ignored) { 54 } catch (InvocationTargetException e) { 55 throw new IllegalArgumentException(e); 56 } 57 58 return false; 59 } 60 61 private static String getFieldFromCpuinfo(String field) { 62 try { 63 BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo")); 64 Pattern p = Pattern.compile(field + "\\s*:\\s*(.*)"); 65 66 try { 67 String line; 68 while ((line = br.readLine()) != null) { 69 Matcher m = p.matcher(line); 70 if (m.matches()) { 71 return m.group(1); 72 } 73 } 74 } finally { 75 br.close(); 76 } 77 } catch (IOException ignored) { 78 } 79 80 return null; 81 } 82 83 private static List<String> getListFromCpuinfo(String fieldName) { 84 String features = getFieldFromCpuinfo(fieldName); 85 if (features == null) 86 return null; 87 88 return Arrays.asList(features.split("\\s")); 89 } 90 } 91