1 /* 2 * Copyright (C) 2019 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 android.content.integrity; 18 19 import static com.android.internal.util.Preconditions.checkArgument; 20 21 /** 22 * Utils class for simple operations used in integrity module. 23 * 24 * @hide 25 */ 26 public class IntegrityUtils { 27 28 private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); 29 30 /** 31 * Obtain the raw bytes from hex encoded string. 32 * 33 * @throws IllegalArgumentException if {@code hexDigest} is not a valid hex encoding of some 34 * bytes 35 */ getBytesFromHexDigest(String hexDigest)36 public static byte[] getBytesFromHexDigest(String hexDigest) { 37 checkArgument( 38 hexDigest.length() % 2 == 0, 39 "Invalid hex encoding %s: must have even length", hexDigest); 40 41 byte[] rawBytes = new byte[hexDigest.length() / 2]; 42 for (int i = 0; i < rawBytes.length; i++) { 43 int upperNibble = hexDigest.charAt(2 * i); 44 int lowerNibble = hexDigest.charAt(2 * i + 1); 45 rawBytes[i] = (byte) ((hexToDec(upperNibble) << 4) | hexToDec(lowerNibble)); 46 } 47 return rawBytes; 48 } 49 50 /** Obtain hex encoded string from raw bytes. */ getHexDigest(byte[] rawBytes)51 public static String getHexDigest(byte[] rawBytes) { 52 char[] hexChars = new char[rawBytes.length * 2]; 53 54 for (int i = 0; i < rawBytes.length; i++) { 55 int upperNibble = (rawBytes[i] >>> 4) & 0xF; 56 int lowerNibble = rawBytes[i] & 0xF; 57 hexChars[i * 2] = decToHex(upperNibble); 58 hexChars[i * 2 + 1] = decToHex(lowerNibble); 59 } 60 return new String(hexChars); 61 } 62 hexToDec(int hexChar)63 private static int hexToDec(int hexChar) { 64 if (hexChar >= '0' && hexChar <= '9') { 65 return hexChar - '0'; 66 } 67 if (hexChar >= 'a' && hexChar <= 'f') { 68 return hexChar - 'a' + 10; 69 } 70 if (hexChar >= 'A' && hexChar <= 'F') { 71 return hexChar - 'A' + 10; 72 } 73 throw new IllegalArgumentException("Invalid hex char " + hexChar); 74 } 75 decToHex(int dec)76 private static char decToHex(int dec) { 77 if (dec >= 0 && dec < HEX_CHARS.length) { 78 return HEX_CHARS[dec]; 79 } 80 81 throw new IllegalArgumentException("Invalid dec value to be converted to hex digit " + dec); 82 } 83 } 84