• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, 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 //! v1 storage response
17 
18 use super::{LargeSecretInfo, LeafContents, LeafId, Path, TreeHash, TreeHashes, TreeParams, U32};
19 use crate::util::{serde_enums, serde_fields, serde_zerocopy, SerdeOption};
20 use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
21 
22 /// The response from the storage daemon.
23 pub struct StorageResponse {
24     /// Header info that is serialized contiguously.
25     pub header: StorageResponseHeader,
26 
27     /// The operation-specific data for a storage response.
28     pub op_data: StorageResponseData,
29 }
30 
31 /// The header for [`StorageResponse`].
32 #[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
33 #[repr(C)]
34 pub struct StorageResponseHeader {
35     /// The status of executing the request; check this first.
36     pub status: ResponseStatus,
37 
38     /// The current root hash for the tree.
39     pub root_hash: TreeHash,
40 }
41 
42 /// The response when getting the status of PinWeaver.
43 #[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
44 #[repr(C)]
45 pub struct GetStatusResponse {
46     /// The parameters for the hash tree, as understood by the storage daemon.
47     pub tree_params: TreeParams,
48 }
49 
50 /// The status of a storage daemon operation.
51 #[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
52 #[repr(transparent)]
53 pub struct ResponseStatus(u8);
54 
55 #[allow(non_upper_case_globals)]
56 impl ResponseStatus {
57     /// Success.
58     pub const Ok: Self = Self(0);
59 
60     /// An unknown internal error occurred.
61     pub const ErrUnknown: Self = Self(1);
62 }
63 
64 /// The response when initializing PinWeaver on disk.
65 #[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
66 #[repr(C)]
67 pub struct InitializeResponse {
68     /// The total number of leaves in this tree.
69     pub num_hashes: U32,
70 }
71 
72 /// The response when starting an operation in PinWeaver.
73 pub struct StartOpResponse {
74     /// The path of the currently operating leaf.
75     pub path: Path,
76 
77     /// The current tree hashes for the specified leaf.
78     pub tree_hashes: TreeHashes,
79 
80     /// The response data specific to this operation.
81     pub op_data: StartOpResponseData,
82 }
83 
84 /// The response when committing an operation in PinWeaver.
85 pub struct CommitOpResponse {
86     /// The path of the leaf that was just updated.
87     pub path: Path,
88 
89     /// The response data specific to this operation.
90     pub op_data: CommitOpResponseData,
91 }
92 
93 serde_enums! {
94     /// The operation-specific data for a storage response.
95     pub enum StorageResponseData {
96         /// The response when getting the status of PinWeaver.
97         GetStatus(GetStatusResponse) = 0,
98 
99         /// The response when initializing PinWeaver.
100         Initialize(InitializeResponse) = 1,
101 
102         /// The response when starting an operation in PinWeaver.
103         StartOp(StartOpResponse) = 2,
104 
105         /// The response when committing an operation in PinWeaver.
106         CommitOp(CommitOpResponse) = 3,
107     }
108 
109     /// The suboperation-specific data for a start-operation response.
110     pub enum StartOpResponseData {
111         /// The response when starting insert of a new leaf.
112         Insert(StartInsertResponseData) = 0,
113 
114         /// The response when starting removal of a leaf.
115         Remove(StartRemoveResponseData) = 1,
116 
117         /// The response when starting to authenticate the low-entropy secret in a leaf.
118         TryAuth(StartTryAuthResponseData) = 2,
119     }
120 
121     /// The suboperation-specific data for a commit-operation response.
122     pub enum CommitOpResponseData {
123         /// This suboperation has no more specific data.
124         None = 0,
125 
126         /// The response when committing that a leaf replacement has finished the insert stage.
127         ///
128         /// An insert that replaces a leaf takes place in multiple stages:
129         ///
130         /// 1. Start the insert of a new leaf.
131         /// 2. Insert the leaf in the GSC.
132         /// 3. Commit the insert of that leaf to disk, and transition to the removal stage.
133         /// 4. Remove the replaced leaf in the GSC.
134         /// 5. Commit the removal of the replaced leaf to disk.
135         ///
136         /// This is the response to stage 3, containing info about the leaf to delete.
137         InsertReplace(RemoveHashes) = 1,
138 
139         /// Info about the next leaf to delete.
140         RemoveBulk(CommitRemoveBulkResponseData) = 2,
141     }
142 
143     /// Info about the next leaf to delete after committing the delete of a leaf.
144     pub enum CommitRemoveBulkResponseData {
145         /// Finished with bulk removal.
146         Finished = 0,
147 
148         /// There are more bulk removals to perform.
149         Continue(ContinueRemoveBulkResponse) = 1,
150     }
151 }
152 
153 /// The response when starting insert of a new leaf.
154 pub struct StartInsertResponseData {
155     /// The leaf path that is being replaced and will be deleted, if any.
156     pub replacing_path: SerdeOption<Path>,
157 }
158 
159 /// The response when starting removal of a leaf.
160 #[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
161 #[repr(C)]
162 pub struct StartRemoveResponseData {
163     /// The HMAC of the leaf to remove.
164     pub leaf_hmac: TreeHash,
165 }
166 
167 /// The response when starting to authenticate the low-entropy secret in a leaf.
168 pub struct StartTryAuthResponseData {
169     /// The size of the high-entropy secret stored by the client in bytes.
170     pub secret_size: u32,
171 
172     /// The encrypted leaf contents stored on disk.
173     pub leaf_contents: LeafContents,
174 
175     /// Info necessary to access a larger key than can fit in `leaf_contents`.
176     /// A large key is only used when `secret_size > 32`.
177     pub large_key_info: SerdeOption<LargeSecretInfo>,
178 }
179 
180 /// Header for [`ContinueRemoveBulkResponse`].
181 #[derive(FromBytes, KnownLayout, Immutable, IntoBytes)]
182 #[repr(C)]
183 pub struct ContinueRemoveBulkResponseHeader {
184     /// The next leaf to remove as part of this bulk removal.
185     pub id: LeafId,
186 
187     /// The path of that leaf.
188     pub path: Path,
189 }
190 
191 /// Response when committing the bulk removal of one leaf,
192 /// and there are more leaves to remove.
193 pub struct ContinueRemoveBulkResponse {
194     /// Header info that is serialized contiguously.
195     pub header: ContinueRemoveBulkResponseHeader,
196 
197     /// Tree info about this leaf necessary to do the deletion.
198     pub hashes: RemoveHashes,
199 }
200 
201 /// Response when a leaf should be removed after a commit operation.
202 pub struct RemoveHashes {
203     /// The HMAC for the leaf to remove removed.
204     pub leaf_hmac: TreeHash,
205 
206     /// The tree hashes for the leaf to remove.
207     pub tree_hashes: TreeHashes,
208 }
209 
210 serde_fields! {
211     StorageResponse { header, op_data },
212     StartOpResponse { path, tree_hashes, op_data },
213     CommitOpResponse { path, op_data },
214     StartInsertResponseData { replacing_path },
215     StartTryAuthResponseData { secret_size, leaf_contents, large_key_info },
216     ContinueRemoveBulkResponse { header, hashes },
217     RemoveHashes { leaf_hmac, tree_hashes },
218 }
219 
220 serde_zerocopy!(
221     StorageResponseHeader,
222     GetStatusResponse,
223     InitializeResponse,
224     StartRemoveResponseData,
225     ContinueRemoveBulkResponseHeader,
226 );
227