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
29extern "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 */
49struct 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 */
59const 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 */
65const 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 */
72typedef 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 */
84void 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 */
92EseAppResult 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 */
100EseAppResult 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 */
111EseAppResult 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 */
125EseAppResult 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
135EseAppResult 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 */
144EseAppResult 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 */
157EseAppResult 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 */
169EseAppResult 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 */
176EseAppResult 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 */
183EseAppResult 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 */
190EseAppResult 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 */
199EseAppResult ese_boot_reset_locks(struct EseBootSession *session);
200
201#ifdef __cplusplus
202}  /* extern "C" */
203#endif
204
205#endif  /* ESE_APP_BOOT_H_ */
206