blob: 44c4c39bf84c982bfbd2c47ff8a914621359271f [file] [log] [blame]
/*
* Copyright (C) 2014-2015 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.
*/
#pragma once
#include <lk/compiler.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <interface/hwkey/hwkey.h>
#include <trusty_ipc.h>
__BEGIN_CDECLS
typedef handle_t hwkey_session_t;
/**
* hwkey_open() - Opens a trusty hwkey session.
*
* Return: a hwkey_session_t > 0 on success, * or an error code < 0 on
* failure.
*/
long hwkey_open(void);
/**
* hwkey_get_keyslot_data() - Gets the keyslot data referenced by slot_id.
* @session: session handle retrieved from hwkey_open
* @slot_id: string identifier for the requested keyslot
* @data: buffer for retrieved data
* @data_size: pointer to allocated size of data buffer. Updated to actual
* retrieved size if different from allocated size.
*
* Fills *data with result if size is sufficient. If actual size is less than
* data_size, data_size is updated with the * actual returned size.
*
* Return: NO_ERROR on success, error code less than 0 on error. Possible error
* codes include:
* - ERR_NOT_VALID: if input is NULL
* - ERR_IO: if there's an issue communicating with the server
* - ERR_TOO_BIG: if keyslot does not fit in data buffer
* - ERR_NOT_FOUND: if keyslot is not found
*/
long hwkey_get_keyslot_data(hwkey_session_t session,
const char* slot_id,
uint8_t* data,
uint32_t* data_size);
/**
* hwkey_derive() - Derives a cryptographic key based on input values.
* @session: session handle retrieved from hwkey_open
* @kdf_version: key derivation function version. If most recent supported
* version is desired, pass HWKEY_KDF_VERSION_BEST. Actual KDF
* used is written to field as out param.
* @src: the input for the KDF (key-derivation function)
* @dest: The result buffer into which the derived key is written.
* Must be at least *src_buf_len bytes.
* @buf_size: The size of src and dest.
*
* Return: NO_ERROR on success, error code less than 0 on error. Possible error
* codes include:
* - ERR_NOT_VALID: if input is NULL or if kdf_version is not supported
* - ERR_IO: if there's an issue communicating with the server
* - ERR_BAD_LEN: if buf_size is not valid
*
*/
long hwkey_derive(hwkey_session_t session,
uint32_t* kdf_version,
const uint8_t* src,
uint8_t* dest,
uint32_t buf_size);
/**
* struct hwkey_versioned_key_options - Options that control how a versioned
* key will be derived.
* @kdf_version:
* (in/out) the version of the KDF to use. If set to %HWKEY_KDF_VERSION_BEST
* the latest version will be used and will be written back to the struct.
* @shared_key:
* if true, the derived key will be consistent and shared across the entire
* family of devices, given the same input. If false, the derived key will
* be unique to the particular device it was derived on.
* @rollback_version_source:
* specifies whether the @rollback_version must have been committed. If
* %HWKEY_ROLLBACK_COMMITTED_VERSION is specified, the system must guarantee
* that software with a lower rollback version cannot ever run on a future
* boot. (see &enum hwkey_rollback_version_source)
* @os_rollback_version:
* (in/out) the OS rollback version to be incorporated into the key
* derivation. Must be less than or equal to the current Trusty OS rollback
* version from @rollback_version_source. If set to
* %HWKEY_ROLLBACK_VERSION_CURRENT the latest available version will be used
* and will be written back to the struct.
* @context:
* an arbitrary set of bytes incorporated into the key derivation. May have
* an implementation-specific maximum length, but it is guaranteed to accept
* at least 32 bytes. May not be null unless @key_len is zero.
* @context_len:
* length of @context. May not be zero unless @key_len is also zero.
* @key:
* destination of the derived key. Contains the derived key on success. May
* have an implementation-specific maximum length, but it is guaranteed to
* produce at least 32 bytes. May be null if @key_len is zero.
* @key_len:
* length of the @key buffer. @key_len bytes will be derived or an error
* will be returned. May be zero to query the current OS rollback version
* without deriving a key.
*
* Default field semantics (i.e. if zeroed):
* * @kdf_version: %HWKEY_KDF_VERSION_BEST, version used will be passed back in
* this field.
* * @shared_key: Device-unique key
* * @rollback_version_source: %HWKEY_ROLLBACK_COMMITTED_VERSION
* * @os_rollback_version: Version 0
* * @context: Null, i.e. no user-supplied context will be added. If null,
* @context_len and @key_len must be 0.
* * @context_len: 0
* * @key: Null, i.e. no key will be generated, only the current versions may be
* queried. If null, @key_len must be 0.
* * @key_len: 0
*
* Additional fields may be added in the future, e.g. rollback versions for
* additional system components. Additional future fields will not change the
* resulting key when set to zero, so they will not affect existing key
* derivations as long as any unspecified fields in the struct are zeroed.
*/
struct hwkey_versioned_key_options {
uint32_t kdf_version;
bool shared_key;
enum hwkey_rollback_version_source rollback_version_source;
int32_t os_rollback_version;
const uint8_t* context;
size_t context_len;
uint8_t* key;
size_t key_len;
};
/**
* hwkey_derive_versioned() - Derive a versioned, device-specific key from
* provided context.
* @session: session handle retrieved from hwkey_open
* @args: arguments controlling key derivation, see &enum
* hwkey_derive_versioned_key_args.
*
* Derives a versioned key from provided context input. Gates access to keys
* based on the rollback version of Trusty, so that an app may not derive keys
* for future rollback versions. The intent is that after an update, a previous,
* potentially compromised app cannot derive keys tied to the newly updated
* rollback version. These new keys may then be used to re-secure the device
* after the vulnerability has been fixed without danger of unpatched software
* being able to forward compromise the device.
*
* Changing any of the input parameters should result in a completely different
* key being derived. You will need to keep the parameters stable for
* compatibility with previously generated keys. You may need to prefix wrapped
* data blobs with the parameters used for key derivation (os_rollback_version,
* for example) so they can be unwrapped correctly. One exception is that
* different values of key_len may not change all of the derived key material. A
* shorter key may be the prefix of a longer key.
*
* Apps with different UUIDs will derive different keys, even with the same
* parameters.
*
* If @args->shared_key is false, a key unique to the specific device it was
* derived on will be generated. A device unique key should be considered the
* secure default and used if at all possible.
*
* If @args->shared_key is true, this function will generated the same key when
* invoked with the same input parameters across devices in the same family.
* This kind of key is useful when it is necessary to agree on a shared secret
* with a remote server and there is no channel to transfer the secret, e.g.,
* encryption key for OTAed data. Shared keys may not be available on all
* platforms, and are generally less secure than local keys. The definition of a
* device family is vendor-specific. If possible, set @args->shared_key to
* false.
*
* If @args->shared_key is false and @args->os_rollback_version is 0, this
* function will be backwards compatible with the key derivation in
* hwkey_derive(). This allows a client to migrate away from the old
* hwkey_derive() API without changing the derived key output. When backwards
* compatibility is required, @rollback_version_source is ignored and the same
* key is generated regardless of source, since that parameter is not available
* in the hwkey_derive() API.
*
* If @args->os_rollback_version is %HWKEY_ROLLBACK_VERSION_CURRENT and the
* current version is 0, compatibility will be provided as if 0 was passed
* explicitly.
*
* We plan to deprecate and remove hwkey_derive(); on devices that never
* supported hwkey_derive(), the versioned derive API will not support backwards
* compatibility.
*
* Return: NO_ERROR on success, error code less than 0 on error. Possible error
* codes (see &enum hwkey_err):
* * ERR_NOT_VALID - invalid parameters
* * ERR_BAD_LEN - a buffer size was invalid
* * ERR_NOT_IMPLEMENTED - the requested version source or KDF mode is
* not implemented
* * ERR_NOT_FOUND - requested key version does not exist
*/
long hwkey_derive_versioned(hwkey_session_t session,
struct hwkey_versioned_key_options* args);
/**
* hwkey_close() - Closes the session.
*/
void hwkey_close(hwkey_session_t session);
__END_CDECLS