1 /* 2 * Copyright (C) 2020 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 com.android.server.biometrics; 18 19 import static java.nio.ByteOrder.LITTLE_ENDIAN; 20 21 import android.hardware.keymaster.HardwareAuthToken; 22 import android.hardware.keymaster.Timestamp; 23 24 import java.nio.ByteOrder; 25 26 /** 27 * Utilities for converting between old and new HardwareAuthToken types. See 28 * {@link HardwareAuthToken}. 29 */ 30 public class HardwareAuthTokenUtils { toByteArray(HardwareAuthToken hat)31 public static byte[] toByteArray(HardwareAuthToken hat) { 32 final byte[] array = new byte[69]; 33 34 // Version, first byte. Used in hw_auth_token.h but not HardwareAuthToken 35 array[0] = 0; 36 37 // Challenge, 1:8. 38 writeLong(hat.challenge, array, 1 /* offset */); 39 40 // UserId, 9:16. 41 writeLong(hat.userId, array, 9 /* offset */); 42 43 // AuthenticatorId, 17:24. 44 writeLong(hat.authenticatorId, array, 17 /* offset */); 45 46 // AuthenticatorType, 25:28. 47 writeInt(flipIfNativelyLittle(hat.authenticatorType), array, 25 /* offset */); 48 49 // Timestamp, 29:36. 50 writeLong(flipIfNativelyLittle(hat.timestamp.milliSeconds), array, 29 /* offset */); 51 52 // MAC, 37:69. Byte array. 53 System.arraycopy(hat.mac, 0 /* srcPos */, array, 37 /* destPos */, hat.mac.length); 54 55 return array; 56 } 57 toHardwareAuthToken(byte[] array)58 public static HardwareAuthToken toHardwareAuthToken(byte[] array) { 59 final HardwareAuthToken hardwareAuthToken = new HardwareAuthToken(); 60 61 // First byte is version, which doesn't not exist in HardwareAuthToken anymore 62 // Next 8 bytes is the challenge. 63 hardwareAuthToken.challenge = getLong(array, 1 /* offset */); 64 65 // Next 8 bytes is the userId 66 hardwareAuthToken.userId = getLong(array, 9 /* offset */); 67 68 // Next 8 bytes is the authenticatorId. 69 hardwareAuthToken.authenticatorId = getLong(array, 17 /* offset */); 70 71 // Next 4 bytes is the authenticatorType. 72 hardwareAuthToken.authenticatorType = flipIfNativelyLittle(getInt(array, 25 /* offset */)); 73 74 // Next 8 bytes is the timestamp. 75 final Timestamp timestamp = new Timestamp(); 76 timestamp.milliSeconds = flipIfNativelyLittle(getLong(array, 29 /* offset */)); 77 hardwareAuthToken.timestamp = timestamp; 78 79 // Last 32 bytes is the mac, 37:69 80 hardwareAuthToken.mac = new byte[32]; 81 System.arraycopy(array, 37 /* srcPos */, 82 hardwareAuthToken.mac, 83 0 /* destPos */, 84 32 /* length */); 85 86 return hardwareAuthToken; 87 } 88 flipIfNativelyLittle(long l)89 private static long flipIfNativelyLittle(long l) { 90 if (LITTLE_ENDIAN == ByteOrder.nativeOrder()) { 91 return Long.reverseBytes(l); 92 } 93 return l; 94 } 95 flipIfNativelyLittle(int i)96 private static int flipIfNativelyLittle(int i) { 97 if (LITTLE_ENDIAN == ByteOrder.nativeOrder()) { 98 return Integer.reverseBytes(i); 99 } 100 return i; 101 } 102 writeLong(long l, byte[] dest, int offset)103 private static void writeLong(long l, byte[] dest, int offset) { 104 dest[offset + 0] = (byte) l; 105 dest[offset + 1] = (byte) (l >> 8); 106 dest[offset + 2] = (byte) (l >> 16); 107 dest[offset + 3] = (byte) (l >> 24); 108 dest[offset + 4] = (byte) (l >> 32); 109 dest[offset + 5] = (byte) (l >> 40); 110 dest[offset + 6] = (byte) (l >> 48); 111 dest[offset + 7] = (byte) (l >> 56); 112 } 113 writeInt(int i, byte[] dest, int offset)114 private static void writeInt(int i, byte[] dest, int offset) { 115 dest[offset + 0] = (byte) i; 116 dest[offset + 1] = (byte) (i >> 8); 117 dest[offset + 2] = (byte) (i >> 16); 118 dest[offset + 3] = (byte) (i >> 24); 119 } 120 getLong(byte[] array, int offset)121 private static long getLong(byte[] array, int offset) { 122 long result = 0; 123 // Lowest bit is LSB 124 for (int i = 0; i < 8; i++) { 125 result += (long) ((array[i + offset] & 0xffL) << (8 * i)); 126 } 127 return result; 128 } 129 getInt(byte[] array, int offset)130 private static int getInt(byte[] array, int offset) { 131 int result = 0; 132 // Lowest bit is LSB 133 for (int i = 0; i < 4; i++) { 134 result += (int) (((int) array[i + offset] & 0xff) << (8 * i)); 135 } 136 return result; 137 } 138 } 139