1 /* 2 * Copyright (C) 2022 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 #pragma once 18 19 #include <stdbool.h> 20 #include <stddef.h> 21 #include <stdint.h> 22 #include <sys/cdefs.h> 23 24 #include "vm_main.h" 25 26 __BEGIN_DECLS 27 28 typedef struct AIBinder AIBinder; 29 30 /** 31 * Introduced in API 35. 32 * Remote attestation result if the attestation succeeds. 33 */ 34 typedef struct AVmAttestationResult AVmAttestationResult; 35 36 /** 37 * Introduced in API 35. 38 * Remote attestation status types returned from remote attestation functions. 39 */ 40 typedef enum AVmAttestationStatus : int32_t { 41 /** The remote attestation completes successfully. */ 42 ATTESTATION_OK = 0, 43 44 /** The challenge size is not between 0 and 64. */ 45 ATTESTATION_ERROR_INVALID_CHALLENGE = -10001, 46 47 /** Failed to attest the VM. Please retry at a later time. */ 48 ATTESTATION_ERROR_ATTESTATION_FAILED = -10002, 49 50 /** Remote attestation is not supported in the current environment. */ 51 ATTESTATION_ERROR_UNSUPPORTED = -10003, 52 } AVmAttestationStatus; 53 54 /** 55 * Introduced in API 36. 56 * Status type used to indicate error while accessing RollbackProtectedSecret. 57 */ 58 typedef enum AVmAccessRollbackProtectedSecretStatus : int32_t { 59 /** 60 * Relevant Entry not found. This can happen either due to no value was ever written or because 61 * it was deleted by host. 62 */ 63 AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ENTRY_NOT_FOUND = -1, 64 /** Requested access size is not supported by the implementation */ 65 AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_BAD_SIZE = -2, 66 /** Access failed, this could be due to lacking support from Hardware */ 67 AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ACCESS_FAILED = -3, 68 } AVmAccessRollbackProtectedSecretStatus; 69 70 /** 71 * Notifies the host that the payload is ready. 72 * 73 * If the host app has set a `VirtualMachineCallback` for the VM, its 74 * `onPayloadReady` method will be called. 75 * 76 * Note that subsequent calls to this function after the first have no effect; 77 * `onPayloadReady` is never called more than once. 78 */ 79 void AVmPayload_notifyPayloadReady(void); 80 81 /** 82 * Runs a binder RPC server, serving the supplied binder service implementation on the given vsock 83 * port. 84 * 85 * If and when the server is ready for connections (it is listening on the port), `on_ready` is 86 * called to allow appropriate action to be taken - e.g. to notify clients that they may now 87 * attempt to connect with `AVmPayload_notifyPayloadReady`. 88 * 89 * Note that this function does not return. The calling thread joins the binder 90 * thread pool to handle incoming messages. 91 * 92 * \param service the service to bind to the given port. 93 * \param port vsock port. 94 * \param on_ready the callback to execute once the server is ready for connections. If not null the 95 * callback will be called at most once. 96 * \param param parameter to be passed to the `on_ready` callback. 97 */ 98 __attribute__((noreturn)) void AVmPayload_runVsockRpcServer( 99 AIBinder* _Nonnull service, uint32_t port, 100 void (*_Nullable on_ready)(void* _Nullable param), void* _Nullable param); 101 102 /** 103 * Returns all or part of a 32-byte secret that is bound to this unique VM 104 * instance and the supplied identifier. The secret can be used e.g. as an 105 * encryption key. 106 * 107 * Every VM has a secret that is derived from a device-specific value known to 108 * the hypervisor, the code that runs in the VM and its non-modifiable 109 * configuration; it is not made available to the host OS. 110 * 111 * This function performs a further derivation from the VM secret and the 112 * supplied identifier. As long as the VM identity doesn't change the same value 113 * will be returned for the same identifier, even if the VM is stopped & 114 * restarted or the device rebooted. 115 * 116 * If multiple secrets are required for different purposes, a different 117 * identifier should be used for each. The identifiers otherwise are arbitrary 118 * byte sequences and do not need to be kept secret; typically they are 119 * hardcoded in the calling code. 120 * 121 * The secret is linked to the instance & will be created for a new instance. 122 * Callers should check `AVmPayload_isNewInstance()` to meaningfully use the secret. 123 * For ex, decryption of any old data is meaningless with the returned secret of a new 124 * VM instance with fresh keys. 125 * 126 * \param identifier identifier of the secret to return. 127 * \param identifier_size size of the secret identifier. 128 * \param secret pointer to size bytes where the secret is written. 129 * \param size number of bytes of the secret to get, <= 32. 130 */ 131 void AVmPayload_getVmInstanceSecret(const void* _Nonnull identifier, size_t identifier_size, 132 void* _Nonnull secret, size_t size); 133 134 /** 135 * Gets the path to the APK contents. It is a directory, under which are 136 * the unzipped contents of the APK containing the payload, all read-only 137 * but accessible to the payload. 138 * 139 * \return the path to the APK contents. The returned string should not be 140 * deleted or freed by the application. The string remains valid for the 141 * lifetime of the VM. 142 */ 143 const char* _Nonnull AVmPayload_getApkContentsPath(void); 144 145 /** 146 * Gets the path to the encrypted persistent storage for the VM, if any. This is 147 * a directory under which any files or directories created will be stored on 148 * behalf of the VM by the host app. All data is encrypted using a key known 149 * only to the VM, so the host cannot decrypt it, but may delete it. 150 * 151 * \return the path to the encrypted storage directory, or NULL if no encrypted 152 * storage was requested in the VM configuration. If non-null the returned 153 * string should not be deleted or freed by the application and remains valid 154 * for the lifetime of the VM. 155 */ 156 const char* _Nullable AVmPayload_getEncryptedStoragePath(void); 157 158 /** 159 * Requests the remote attestation of the client VM. 160 * 161 * The challenge will be included in the certificate chain in the attestation result, 162 * serving as proof of the freshness of the result. 163 * 164 * \param challenge A pointer to the challenge buffer. 165 * \param challenge_size size of the challenge. The maximum supported challenge size is 166 * 64 bytes. The status ATTESTATION_ERROR_INVALID_CHALLENGE will be returned if 167 * an invalid challenge is passed. 168 * \param result The remote attestation result will be filled here if the attestation 169 * succeeds. The result remains valid until it is freed with 170 * `AVmPayload_freeAttestationResult`. 171 * 172 * \return ATTESTATION_OK upon successful attestation. 173 */ 174 AVmAttestationStatus AVmPayload_requestAttestation(const void* _Nonnull challenge, 175 size_t challenge_size, 176 AVmAttestationResult* _Nullable* _Nonnull result) 177 __INTRODUCED_IN(__ANDROID_API_V__); 178 179 /** 180 * Converts the return value from `AVmPayload_requestAttestation` to a text string 181 * representing the status code. 182 * 183 * \return a constant string value representing the status code. The string should not 184 * be deleted or freed by the application and remains valid for the lifetime of the VM. 185 */ 186 const char* _Nonnull AVmAttestationStatus_toString(AVmAttestationStatus status) 187 __INTRODUCED_IN(__ANDROID_API_V__); 188 189 /** 190 * Frees all the data owned by the provided attestation result, including the result itself. 191 * 192 * Callers should ensure to invoke this API only once on a valid attestation result 193 * returned by `AVmPayload_requestAttestation` to avoid undefined behavior. 194 * 195 * \param result A pointer to the attestation result. 196 */ 197 void AVmAttestationResult_free(AVmAttestationResult* _Nullable result) 198 __INTRODUCED_IN(__ANDROID_API_V__); 199 200 /** 201 * Reads the DER-encoded ECPrivateKey structure specified in [RFC 5915 s3] for the 202 * EC P-256 private key from the provided attestation result. 203 * 204 * \param result A pointer to the attestation result filled in 205 * `AVmPayload_requestAttestation` when the attestation succeeds. 206 * \param data A pointer to the memory where the private key will be written 207 * (can be null if size is 0). 208 * \param size The maximum number of bytes that can be written to the data buffer. 209 * If `size` is smaller than the total size of the private key, the key data will be 210 * truncated to this `size`. 211 * 212 * \return The total size of the private key. 213 * 214 * [RFC 5915 s3]: https://datatracker.ietf.org/doc/html/rfc5915#section-3 215 */ 216 size_t AVmAttestationResult_getPrivateKey(const AVmAttestationResult* _Nonnull result, 217 void* _Nullable data, size_t size) 218 __INTRODUCED_IN(__ANDROID_API_V__); 219 220 /** 221 * Signs the given message using ECDSA P-256, the message is first hashed with SHA-256 and 222 * then it is signed with the attested EC P-256 private key in the attestation result. 223 * 224 * \param result A pointer to the attestation result filled in 225 * `AVmPayload_requestAttestation` when the attestation succeeds. 226 * \param message A pointer to the message buffer. 227 * \param message_size size of the message. 228 * \param data A pointer to the memory where the signature will be written 229 * (can be null if size is 0). The signature is a DER-encoded ECDSASignature structure 230 * detailed in the [RFC 6979]. 231 * \param size The maximum number of bytes that can be written to the data buffer. 232 * If `size` is smaller than the total size of the signature, the signature will be 233 * truncated to this `size`. 234 * 235 * \return The size of the signature, or the size needed if the supplied buffer is too small. 236 * 237 * [RFC 6979]: https://datatracker.ietf.org/doc/html/rfc6979 238 */ 239 size_t AVmAttestationResult_sign(const AVmAttestationResult* _Nonnull result, 240 const void* _Nonnull message, size_t message_size, 241 void* _Nullable data, size_t size) 242 __INTRODUCED_IN(__ANDROID_API_V__); 243 244 /** 245 * Gets the number of certificates in the certificate chain. 246 * 247 * The certificate chain consists of a sequence of DER-encoded X.509 certificates that form 248 * the attestation key's certificate chain. It starts with a leaf certificate covering the attested 249 * public key and ends with a root certificate. 250 * 251 * \param result A pointer to the attestation result obtained from `AVmPayload_requestAttestation` 252 * when the attestation succeeds. 253 * 254 * \return The number of certificates in the certificate chain. 255 */ 256 size_t AVmAttestationResult_getCertificateCount(const AVmAttestationResult* _Nonnull result) 257 __INTRODUCED_IN(__ANDROID_API_V__); 258 259 /** 260 * Retrieves the certificate at the given `index` from the certificate chain in the provided 261 * attestation result. 262 * 263 * The certificate chain consists of a sequence of DER-encoded X.509 certificates that form 264 * the attestation key's certificate chain. It starts with a leaf certificate covering the attested 265 * public key and ends with a root certificate. 266 * 267 * \param result A pointer to the attestation result obtained from `AVmPayload_requestAttestation` 268 * when the attestation succeeds. 269 * \param index Index of the certificate to retrieve. The `index` must be within the range of 270 * [0, number of certificates). The number of certificates can be obtained with 271 * `AVmAttestationResult_getCertificateCount`. 272 * \param data A pointer to the memory where the certificate will be written 273 * (can be null if size is 0). 274 * \param size The maximum number of bytes that can be written to the data buffer. If `size` 275 * is smaller than the total size of the certificate, the certificate will be 276 * truncated to this `size`. 277 * 278 * \return The total size of the certificate at the given `index`. 279 */ 280 size_t AVmAttestationResult_getCertificateAt(const AVmAttestationResult* _Nonnull result, 281 size_t index, void* _Nullable data, size_t size) 282 __INTRODUCED_IN(__ANDROID_API_V__); 283 /** 284 * Writes up to n bytes from buffer starting at `buf`, on behalf of the payload, to rollback 285 * detectable storage. The data is written from the start. The number of bytes written may be less 286 * than n if, for example, the underlying storage has size constraints. This stored data is 287 * confidential to the VM instance. 288 * 289 * \param buf A pointer to data to be written. This should have the size of at least n bytes. 290 * \param n The maximum number of bytes to be filled in `buf`. 291 * 292 * \return On success, the number of bytes written is returned. On error, appropriate 293 * AVmAccessRollbackProtectedSecretStatus (negative number) is returned. 294 */ 295 296 int32_t AVmPayload_writeRollbackProtectedSecret(const void* _Nonnull buf, size_t n) 297 __INTRODUCED_IN(36); 298 /** 299 * Read the first n bytes of payload's data in rollback detectable storage into `buf`. 300 * 301 * \param buf A pointer to buffer where the requested data is written. This should have the size of 302 * at least n bytes. 303 * \param n The maximum number of bytes to be read. 304 * 305 * \return On success, the number of bytes that would have been written to `buf` if n was 306 * sufficiently large. On error, appropriate AVmAccessRollbackProtectedSecretStatus(a negative 307 * number) is returned. 308 */ 309 int32_t AVmPayload_readRollbackProtectedSecret(void* _Nullable buf, size_t n) __INTRODUCED_IN(36); 310 311 /** 312 * Checks whether the VM instance is new - i.e., if this is the first run of an instance. 313 * This is an indication of fresh new VM secrets. Payload can use this to setup the fresh 314 * instance if needed. 315 * 316 * \return true if this is the first run of an instance, false otherwise. 317 */ 318 bool AVmPayload_isNewInstance(void) __INTRODUCED_IN(36); 319 320 __END_DECLS 321