blob: aa7b492188efbc5f2f69399df86c6f9c39dafb8b [file] [log] [blame]
/*
* Copyright (C) 2020 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.keymint;
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.secureclock.TimeStampToken;
/** @hide */
@VintfStability
@SensitiveData
interface IKeyMintOperation {
/**
* Provides additional authentication data (AAD) to a cryptographic operation begun with
* begin(), provided in the input argument. This method only applies to AEAD modes. This
* method may be called multiple times, supplying the AAD in chunks, but may not be called after
* update() is called. If updateAad() is called after update(), it must return
* ErrorCode::INVALID_TAG.
*
* If the operation is in an invalid state (was aborted or had an error) update() must return
* ErrorCode::INVALID_OPERATION_HANDLE.
*
* If this method returns an error code other than ErrorCode::OK, the operation is aborted and
* the operation handle must be invalidated. Any future use of this object must return
* ErrorCode::INVALID_OPERATION_HANDLE.
*
* == Authorization Enforcement ==
*
* Key authorization enforcement is performed primarily in begin(). The one exception is the
* case where the key has:
*
* o One or more Tag::USER_SECURE_IDs, and
*
* o Does not have a Tag::AUTH_TIMEOUT
*
* In this case, the key requires an authorization per operation, and the update method must
* receive a non-null and valid HardwareAuthToken. For the auth token to be valid, all of the
* following has to be true:
*
* o The HMAC field must validate correctly.
*
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
* the secure ID values in the token.
*
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
*
* o The challenge field in the auth token must contain the value returned from
* IKeyMintDevice::begin(), given by the challenge field of the BeginResult structure.
*
* If any of these conditions are not met, updateAad() must return
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
*
* The caller must provide the auth token on every call to updateAad(), update() and finish().
*
*
* For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
* decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
* be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
* it must process all but the tag length and buffer the possible tag data for processing during
* finish().
*
* @param input Additional Authentication Data to be processed.
*
* @param authToken Authentication token, if provided.
*
* @param timeStampToken timestamp token, certifies the freshness of an auth token in case
* the security domain of this KeyMint instance has a different clock than the
* authenticator issuing the auth token.
*
* @return error Returns ErrorCode encountered in keymint as service specific errors. See the
* ErrorCode enum in ErrorCode.aidl.
*/
void updateAad(in byte[] input, in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken timeStampToken);
/**
* Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
* with begin().
*
* If operation is in an invalid state (was aborted or had an error) update() must return
* ErrorCode::INVALID_OPERATION_HANDLE.
*
* Implementations may choose how much data to return as a result of the update. This is
* only relevant for encryption and decryption operations, because signing returns no data
* until finish. It is recommended to return data as early as possible, rather than buffer it.
*
* If this method returns an error code other than ErrorCode::OK, the operation is aborted and
* the operation handle must be invalidated. Any future use of the handle, with this method,
* finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
*
* == Authorization Enforcement ==
*
* Key authorization enforcement is performed primarily in IKeyMintDevice::begin(). The one
* exception is the case where the key has:
*
* o One or more Tag::USER_SECURE_IDs, and
*
* o Does not have a Tag::AUTH_TIMEOUT
*
* In this case, the key requires an authorization per operation, and the update method must
* receive a non-empty and valid HardwareAuthToken. For the auth token to be valid, all of the
* following has to be true:
*
* o The HMAC field must validate correctly.
*
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
* the secure ID values in the token.
*
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
*
* o The challenge field in the auth token must contain the challenge value contained in the
* BeginResult returned from IKeyMintDevice::begin().
*
* If any of these conditions are not met, update() must return
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
*
* The caller must provide the auth token on every call to update() and finish().
*
* -- RSA keys --
*
* For signing operations with Digest::NONE, this method must accept the entire block to be
* signed in a single update. It may not consume only a portion of the block in these cases.
* However, the caller may choose to provide the data in multiple updates, and update() must
* accept the data this way as well. If the caller provides more data to sign than can be used
* (length of data exceeds RSA key size), update() must return ErrorCode::INVALID_INPUT_LENGTH.
*
* -- ECDSA keys --
*
* For signing operations with Digest::NONE, this method must accept the entire block to be
* signed in a single update. This method may not consume only a portion of the block.
* However, the caller may choose to provide the data in multiple updates and update() must
* accept the data this way as well. If the caller provides more data to sign than can be used,
* the data is silently truncated. (This differs from the handling of excess data provided in
* similar RSA operations. The reason for this is compatibility with legacy clients.)
*
* -- AES keys --
*
* For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
* decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
* be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
* it must process all but the tag length and buffer the possible tag data for processing during
* finish().
*
* @param input Data to be processed. Note that update() may or may not consume all of the data
* provided. See return value.
*
* @param authToken Authentication token. Can be nullable if not provided.
*
* @param timeStampToken certifies the freshness of an auth token in case the security domain of
* this KeyMint instance has a different clock than the authenticator issuing the auth
* token.
*
* @return error Returns ErrorCode encountered in keymint as service specific errors. See the
* ErrorCode enum in ErrorCode.aidl.
*
* @return byte[] The output data, if any.
*/
byte[] update(in byte[] input, in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken timeStampToken);
/**
* Finalizes a cryptographic operation begun with begin() and invalidates the operation.
*
* This method is the last one called in an operation, so all processed data must be returned.
*
* Whether it completes successfully or returns an error, this method finalizes the operation.
* Any future use of the operation, with finish(), update(), or abort(), must return
* ErrorCode::INVALID_OPERATION_HANDLE.
*
* Signing operations return the signature as the output.
*
* == Authorization enforcement ==
*
* Key authorization enforcement is performed primarily in begin(). The exceptions are
* authorization per operation keys and confirmation-required keys.
*
* Authorization per operation keys are the case where the key has one or more
* Tag::USER_SECURE_IDs, and does not have a Tag::AUTH_TIMEOUT. In this case, the key requires
* an authorization per operation, and the finish method must receive a non-empty and valid
* authToken. For the auth token to be valid, all of the following has to be true:
*
* o The HMAC field must validate correctly.
*
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
* the secure ID values in the token.
*
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
*
* o The challenge field in the auth token must contain the operation challenge.
*
* If any of these conditions are not met, update() must return
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
*
* The caller must provide the auth token on every call to update() and finish().
*
* Confirmation-required keys are keys that were generated with
* Tag::TRUSTED_CONFIRMATION_REQUIRED. For these keys, when doing a signing operation the
* caller must pass a KeyParameter Tag::CONFIRMATION_TOKEN to finish(). Implementations must
* check the confirmation token by computing the 32-byte HMAC-SHA256 over all of the
* to-be-signed data, prefixed with the 18-byte UTF-8 encoded string "confirmation token". If
* the computed value does not match the Tag::CONFIRMATION_TOKEN parameter, finish() must not
* produce a signature and must return ErrorCode::NO_USER_CONFIRMATION.
*
* -- RSA keys --
*
* Some additional requirements, depending on the padding mode:
*
* o PaddingMode::NONE. For unpadded signing and encryption operations, if the provided data is
* shorter than the key, the data must be zero-padded on the left before signing/encryption.
* If the data is the same length as the key, but numerically larger, finish() must return
* ErrorCode::INVALID_ARGUMENT. For decryption operations, the data must be exactly as long
* as the key. Otherwise, return ErrorCode::INVALID_INPUT_LENGTH.
*
* o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match
* the size of the PSS digest selected. The digest specified with Tag::DIGEST in params
* on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask
* generation function and SHA1 must be used as the MGF1 digest algorithm.
*
* -- ECDSA keys --
*
* If the data provided for undigested signing is too long, truncate it.
*
* -- AES keys --
*
* Some additional conditions, depending on block mode:
*
* o BlockMode::ECB or BlockMode::CBC. If padding is PaddingMode::NONE and the data length is
* not a multiple of the AES block size, finish() must return
* ErrorCode::INVALID_INPUT_LENGTH. If padding is PaddingMode::PKCS7, pad the data per the
* PKCS#7 specification, including adding an additional padding block if the data is a
* multiple of the block length.
*
* o BlockMode::GCM. During encryption, after processing all plaintext, compute the tag
* (Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption,
* process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, finish()
* must return ErrorCode::VERIFICATION_FAILED.
*
* @param input Data to be processed, per the parameters established in the call to begin().
* finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
*
* @param signature The signature to be verified if the purpose specified in the begin() call
* was KeyPurpose::VERIFY.
*
* @param authToken Authentication token. Can be nullable if not provided.
*
* @param timestampToken certifies the freshness of an auth token in case the security domain of
* this KeyMint instance has a different clock than the authenticator issuing the auth
* token.
*
* @param confirmationToken is the confirmation token required by keys with
* Tag::TRUSTED_CONFIRMATION_REQUIRED.
*
* @return The output data, if any.
*/
byte[] finish(in @nullable byte[] input, in @nullable byte[] signature,
in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken timestampToken,
in @nullable byte[] confirmationToken);
/**
* Aborts a cryptographic operation begun with IKeyMintDevice::begin(), freeing all internal
* resources. If an operation was finalized, calling updateAad, update, finish, or abort yields
* ErrorCode::INVALID_OPERATION_HANDLE. An operation is finalized if finish or abort was called
* on it, or if updateAad or update returned an ErrorCode.
*
* @return error See the ErrorCode enum in ErrorCode.aidl.
*/
void abort();
}