Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0da7c097 authored by Shikha Panwar's avatar Shikha Panwar Committed by Gerrit Code Review
Browse files

Merge changes from topic "sk_hal" into main

* changes:
  VTS test for ISecretkeeper
  Secretkeeper implementation: in-HAL/nonsecure impl
  Introduce Secretkeeper HAL interface
parents 3fb1cdda a6eaf55d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -302,6 +302,14 @@
            <instance>default</instance>
        </interface>
    </hal>
    <hal format="aidl" optional="true">
        <name>android.hardware.security.secretkeeper</name>
        <version>1</version>
        <interface>
            <name>ISecretkeeper</name>
            <instance>nonsecure</instance>
        </interface>
    </hal>
    <hal format="aidl" optional="true" updatable-via-apex="true">
        <name>android.hardware.security.keymint</name>
        <version>1-3</version>
+36 −0
Original line number Diff line number Diff line
// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}

aidl_interface {
    name: "android.hardware.security.secretkeeper",
    vendor_available: true,
    srcs: ["android/hardware/security/secretkeeper/*.aidl"],
    stability: "vintf",
    backend: {
        ndk: {
            enabled: true,
        },
        rust: {
            enabled: true,
            apex_available: [
                "//apex_available:platform",
                "com.android.virt",
            ],
        },
    },
}
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
///////////////////////////////////////////////////////////////////////////////

// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
//     the interface (from the latest frozen version), the build system will
//     prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.

package android.hardware.security.secretkeeper;
@VintfStability
interface ISecretkeeper {
  byte[] processSecretManagementRequest(in byte[] request);
}
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.security.secretkeeper;

@VintfStability
/**
 * Secretkeeper service definition.
 *
 * An ISecretkeeper instance provides secure storage of secrets on behalf of other components in
 * Android, in particular for protected virtual machine instances. From the perspective of security
 * privilege, Secretkeeper must be implemented in an environment with privilege higher than any of
 * its clients. Since AVF based protected Virtual Machines are one set of its clients, the
 * implementation of ISecretkeeper should live in a secure environment, such as:
 * - A trusted execution environment such as ARM TrustZone.
 * - A completely separate, purpose-built and certified secure CPU.
 *
 * TODO(b/291224769): Extend the HAL interface to include:
 * 1. Session setup api: This is used to perform cryptographic operations that allow shared keys to
 * be exchanged between session participants, typically (but not necessarily) a pVM instance and
 * Secretkeeper. This session setup is based on public key cryptography.
 * 2. Dice policy operation - These allow sealing of the secrets with a class of Dice chains.
 * Typical operations are (securely) updating the dice policy sealing the Secrets above. These
 * operations are core to AntiRollback protected secrets - ie, ensuring secrets of a pVM are only
 * accessible to same or higher versions of the images.
 * 3. Maintenance api: This is required for removing the Secretkeeper entries for obsolete pvMs.
 */
interface ISecretkeeper {
    /**
     * processSecretManagementRequest method is used for interacting with the Secret Management API
     *
     * Secret Management API: The clients can use this API to store (& get) 32 bytes of data.
     * The API is a CBOR based protocol, which follows request/response model.
     * See SecretManagement.cddl for the API spec.
     *
     * Further, the requests (from client) & responses (from service) must be encrypted into
     * ProtectedRequestPacket & ProtectedResponsePacket using symmetric keys agreed between
     * the client & service. This cryptographic protection is required because the messages are
     * ferried via Android, which is allowed to be outside the TCB of clients (for example protected
     * Virtual Machines). For this, service (& client) must implement a key exchange protocol, which
     * is critical for establishing the secure channel.
     *
     * Secretkeeper database should guarantee the following properties:
     * 1. Confidentiality: No entity (of security privilege lower than Secretkeeper) should
     *    be able to get a client's data in clear.
     *
     * 2. Integrity: The data is protected against malicious Android OS tampering with database.
     *    ie, if Android (userspace & kernel) tampers with the client's secret, the Secretkeeper
     *    service must be able to detect it & return error when clients requests for their secrets.
     *    Note: the integrity requirements also include Antirollback protection ie, reverting the
     *    database into an old state should be detected.
     *
     * 3. The data is persistent across device boot.
     *    Note: Denial of service is not in scope. A malicious Android may be able to delete data,
     *    but for ideal Android, the data should be persistent.
     *
     * @param CBOR-encoded ProtectedRequestPacket. See SecretManagement.cddl for its definition.
     * @return CBOR-encoded ProtectedResponsePacket. See SecretManagement.cddl for its definition
     */
    byte[] processSecretManagementRequest(in byte[] request);
}
+116 −0
Original line number Diff line number Diff line
; CDDL for the Secret Management API.
; Also see processSecretManagementRequest method in ISecretkeeper.aidl

; ProtectedRequestPacket is used by client for accessing Secret Management API
; in Secretkeeper service. The service returns ProtectedResponsePacket of the corresponding type.

; ProtectedRequestPacket & ProtectedResponsePacket are encrypted wrappers
; on RequestPacket & ResponsePacket using symmetric keys agreed between Secretkeeper & clients
; (these are referred to as KeySourceToSink & KeySinkToSource)
;
; The API operation required is encoded using 'Opcode', the arguments using 'Params'
; and returned values as 'Result'.

ProtectedRequestPacket =
        ProtectedGetVersionRequest / ProtectedStoreSecretRequest / ProtectedGetSecretRequest
ProtectedResponsePacket =
        ProtectedGetVersionResponse / ProtectedStoreSecretResponse / ProtectedGetSecretResponse

ProtectedGetVersionRequest = ProtectedRequestPacket<GetVersionRequestPacket>
ProtectedGetVersionResponse = ProtectedResponsePacket<GetVersionResponsePacket>
ProtectedStoreSecretRequest = ProtectedRequestPacket<StoreSecretRequestPacket>
ProtectedStoreSecretResponse = ProtectedResponsePacket<StoreSecretResponsePacket>
ProtectedGetSecretRequest = ProtectedRequestPacket<GetSecretRequestPacket>
ProtectedGetSecretResponse = ProtectedResponsePacket<GetSecretResponsePacket>

GetVersionRequestPacket = RequestPacket<GetVersionOpcode, GetVersionParams>
GetVersionResponsePacket = ResponsePacket<GetVersionResult>
StoreSecretRequestPacket = RequestPacket<StoreSecretOpcode, StoreSecretParams>
StoreSecretResponsePacket = ResponsePacket<StoreSecretResult>
GetSecretRequestPacket = RequestPacket<GetOpcode, GetSecretParams>
GetSecretResponsePacket = ResponsePacket<GetSecretResult>

RequestPacket<Opcode, Params> = [
    Opcode,
    Params
]
ResponsePacket<Result> = ResponsePacketError / ResponsePacketSuccess<Result>

ResponsePacketSuccess = [
    0,                          ; Indicates successful Response
    result : Result
]
ResponsePacketError = [
    error_code: ErrorCode,      ; Indicate the error
    error_message: tstr         ; Additional human-readable context
]

Opcode = &(
    GetVersionOpcode: 1,     ; Get version of the SecretManagement API
    StoreSecretOpcode: 2,          ; Store a secret
    GetSecretOpcode: 3,            ; Get the secret
)

GetVersionParams = ()
GetVersionResult = (version : uint)

StoreSecretParams = (
    id : bstr .size 64              ; Unique identifier of the secret
    secret : bstr .size 32,
    sealing_policy : bstr .cbor DicePolicy,    ; See DicePolicy.cddl for definition of DicePolicy
)
StoreSecretResult = ()

GetSecretParams = (
    id : bstr .size 64              ; Unique identifier of the secret
    ; Use this to update the sealing policy associated with a secret during GetSecret operation.
    updated_sealing_policy : bstr .cbor DicePolicy / nil,
)
GetSecretResult = (secret : bstr .size 32)


ProtectedRequestPacket<Payload, Key> = CryptoPayload<Payload, KeySourceToSink>
ProtectedResponsePacket<Payload, Key> = ProtectedResponseError
                                    / ProtectedResponseSuccess<Payload>

ProtectedResponseSuccess<Payload> = [
    0,                                ; Indicates successful crypto operations. Note: Payload
                                                    ; may contain Error from functional layer.
    message: CryptoPayload<Payload, KeySinkToSource>         ; message is the encrypted payload
]

ProtectedResponseError = [
    error_code: CryptoErrorCode,           ; Indicates the error. This is in cleartext & will be
                                           ; visible to Android. These are errors from crypto
                                           ; layer & indicates the request could not even be read
    message: tstr                          ; Additional human-readable context
]

CryptoPayload<Payload, Key> = [         ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
    protected: bstr .cbor {
        1 : 3,                  ; Algorithm: AES-GCM mode w/ 256-bit key, 128-bit tag
        4 : bstr                ; key identifier, uniquely identifies the session
                                ; TODO(b/291228560): Refer to the Key Exchange spec.
    },
    unprotected: {
        5 : bstr .size 12          ; IV
    },
    ciphertext : bstr     ; AES-GCM-256(Key, bstr .cbor Payload)
                          ; AAD for the encryption is CBOR-serialized
                          ; Enc_structure (RFC 9052 s5.3) with empty external_aad.
]

; TODO(b/291224769): Create a more exhaustive set of CryptoErrorCode
CryptoErrorCode = &(
    CryptoErrorCode_SessionExpired: 1,
)

; TODO(b/291224769): Create a more exhaustive set of ErrorCodes
ErrorCode = &(
    ; Use this as if no other error code can be used.
    ErrorCode_UnexpectedServerError: 1,
    ; Indicate the Request was malformed & hence couldnt be served.
    ErrorCode_RequestMalformed: 2,
)

; INCLUDE DicePolicy.cddl for: DicePolicy
 No newline at end of file
Loading