1 /* 2 * Copyright (C) 2017 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 * See the README.md in the parent (../../..) directory. 17 */ 18 19 #ifndef ESE_APP_BOOT_H_ 20 #define ESE_APP_BOOT_H_ 1 21 22 #include "../../../../../libese/include/ese/ese.h" 23 #include "../../../../../libese/include/ese/log.h" 24 #include "../../../../../libese-sysdeps/include/ese/sysdeps.h" 25 26 #include "../../../../include/ese/app/result.h" 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /** 33 * EseBootSession carries the necessary start for interfacing 34 * with the methods below. 35 * 36 * Its usage follows a lifecycle like: 37 * 38 * EseAppResult res; 39 * EseBootSession session; 40 * ese_boot_session_init(&session); 41 * res = ese_boot_session_open(ese, &session); 42 * if (res != ESE_APP_RESULT_OK) { 43 * ... handle error (especially cooldown) ... 44 * } 45 * ... ese_boot_* ... 46 * ese_boot_session_close(&session); 47 * 48 */ 49 struct EseBootSession { 50 struct EseInterface *ese; 51 bool active; 52 uint8_t channel_id; 53 }; 54 55 /** 56 * The Storage applet supports up to 8 64-bit storage slots for storing 57 * rollback protection indices. 58 */ 59 const uint8_t kEseBootRollbackSlotCount = 8; 60 /** 61 * When using the LOCK_OWNER, a key, or other relevant value, must be supplied. 62 * It may be at most OWNER_LOCK_METADATA_SIZE as defined in 63 * card/src/com/android/verifiedboot/storage/Storage.java. 64 */ 65 const uint16_t kEseBootOwnerKeyMax = 2048; 66 67 /* Keep in sync with card/src/com/android/verifiedboot/storage/Storage.java */ 68 /** 69 * This enum reflects the types of Locks that are supported by 70 * the ese_boot_lock_* calls. 71 */ 72 typedef enum { 73 kEseBootLockIdCarrier = 0, 74 kEseBootLockIdDevice, 75 kEseBootLockIdBoot, 76 kEseBootLockIdOwner, 77 kEseBootLockIdMax = kEseBootLockIdOwner, 78 } EseBootLockId; 79 80 81 /** 82 * Initializes a pre-allocated |session| for use. 83 */ 84 void ese_boot_session_init(struct EseBootSession *session); 85 86 /** 87 * Configures a communication session with the Storage applet using a logical 88 * channel on an already open |ese| object. 89 * 90 * @returns ESE_APP_RESULT_OK on success. 91 */ 92 EseAppResult ese_boot_session_open(struct EseInterface *ese, struct EseBootSession *session); 93 94 /** 95 * Shuts down the logical channel with the Storage applet and invalidates 96 * the |session| internal state. 97 * 98 * @returns ESE_APP_RESULT_OK on success. 99 */ 100 EseAppResult ese_boot_session_close(struct EseBootSession *session); 101 102 /** 103 * Retrieves the uint8_t value stored for the lock specified by |lockId|. 104 * On success, the value is stored in |lockVal|. If the byte is 0x0, then 105 * the lock is cleared (or unlocked). If it is any non-zero value, then it 106 * is locked. Any specific byte value may have additional meaning to the 107 * caller. 108 * 109 * @returns ESE_APP_RESULT_OK if |lockVal| contains a valid byte. 110 */ 111 EseAppResult ese_boot_lock_get(struct EseBootSession *session, EseBootLockId lockId, uint8_t *lockVal); 112 /** 113 * Retrieves extended lock data for the lock specified by |lockId|. 114 * 115 * |maxSize| specifies how many bytes may be written to |lockData|. |dataLen| 116 * will be updated to hold the length of the data received from the applet on 117 * success. 118 * 119 * The first byte of |lockData| will be the lock's value. The remaining bytes 120 * are the associated metadata. See the README.md for more details 121 * on each lock's behavior. 122 * 123 * @returns ESE_APP_RESULT_OK on success. 124 */ 125 EseAppResult ese_boot_lock_xget( 126 struct EseBootSession *session, EseBootLockId lockId, uint8_t *lockData, 127 uint16_t maxSize, uint16_t *dataLen); 128 129 /** 130 * Sets the lock specified by |lockId| to |lockVal|. 131 * 132 * @returns ESE_APP_RESULT_OK on success. 133 */ 134 135 EseAppResult ese_boot_lock_set(struct EseBootSession *session, EseBootLockId lockId, uint8_t lockVal); 136 /** 137 * Sets the lock and its metadata specified by |lockId| and |lockData|, 138 * respectively. |dataLen| indicates the length of |lockData|. 139 * 140 * The first byte of |lockData| will be treated as the new value for the lock. 141 * 142 * @returns ESE_APP_RESULT_OK on success. 143 */ 144 EseAppResult ese_boot_lock_xset(struct EseBootSession *session, EseBootLockId lockId, const uint8_t *lockData, uint16_t dataLen); 145 146 /** 147 * Performs a test of the carrier unlock code by allowing the caller to specify 148 * a fake internal nonce value, fake internal device data, as well as an actual 149 * unlock token (made up of a nonce and signature). 150 * 151 * @returns ESE_APP_RESULT_OK on success. On failure, it is worthwhile to 152 * check the upper two bytes in the result code if the lower two bytes 153 * are ESE_APP_RESULT_ERROR_APPLET as it will provide an error 154 * specific to the code path. These applet codes are not (yet) 155 * considered API and should be relied on for debugging. 156 */ 157 EseAppResult ese_boot_carrier_lock_test(struct EseBootSession *session, const uint8_t *testdata, uint16_t len); 158 159 /** 160 * Transitions the applet from "factory" mode to "production" mode. 161 * This can only be done if the bootloader gpio has not been cleared. 162 * 163 * When not in production mode, the applet will ignore the bootloader gpio 164 * and allow for all the locks to be provisioned. Once |mode| is set 165 * to true, LOCK_CARRIER can not be "lock"ed once cleared and any locks 166 * that depend on being in the bootloader (gpio not cleared) will respect 167 * that value. 168 */ 169 EseAppResult ese_boot_set_production(struct EseBootSession *session, bool production_mode); 170 171 /** 172 * Debugging helper that emits the internal value of production, bootloader gpio, 173 * and lock initialization and storage. It is not insecure in the field, but 174 * it is not expected to be needed during normal operation. 175 */ 176 EseAppResult ese_boot_get_state(struct EseBootSession *session, uint8_t *state, uint16_t maxSize); 177 178 /** 179 * Stores |value| in the specified |slot| in the applet. 180 * 181 * @returns ESE_APP_RESULT_OK on success 182 */ 183 EseAppResult ese_boot_rollback_index_write(struct EseBootSession *session, uint8_t slot, uint64_t value); 184 185 /** 186 * Reads a uint64_t from |slot| into |value|. 187 * 188 * @returns ESE_APP_RESULT_OK on success. 189 */ 190 EseAppResult ese_boot_rollback_index_read(struct EseBootSession *session, uint8_t slot, uint64_t *value); 191 192 193 /** 194 * Resets all lock state -- including internal metadata. 195 * This should only be called in factory or under test. 196 * 197 * @returns ESE_APP_RESULT_OK on success. 198 */ 199 EseAppResult ese_boot_reset_locks(struct EseBootSession *session); 200 201 #ifdef __cplusplus 202 } /* extern "C" */ 203 #endif 204 205 #endif /* ESE_APP_BOOT_H_ */ 206