Home | History | Annotate | Download | only in app
      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