diff --git a/ta_services/secure_key_services/Makefile b/ta_services/secure_key_services/Makefile new file mode 100644 index 00000000000..fa405f76b3b --- /dev/null +++ b/ta_services/secure_key_services/Makefile @@ -0,0 +1,9 @@ +# The UUID for the Trusted Application +BINARY=fd02c9da-306c-48c7-a49c-bbd827ae86ee + +-include $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk + +ifeq ($(wildcard $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk), ) +clean: + @echo 'Note: $$(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk not found, cannot clean TA' +endif diff --git a/ta_services/secure_key_services/include/sks_ta.h b/ta_services/secure_key_services/include/sks_ta.h new file mode 100644 index 00000000000..934a39c428b --- /dev/null +++ b/ta_services/secure_key_services/include/sks_ta.h @@ -0,0 +1,779 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2017-2018, Linaro Limited + */ + +#ifndef __SKS_TA_H__ +#define __SKS_TA_H__ + +#include +#include +#include + +#define TA_SKS_UUID { 0xfd02c9da, 0x306c, 0x48c7, \ + { 0xa4, 0x9c, 0xbb, 0xd8, 0x27, 0xae, 0x86, 0xee } } + +/* SKS trusted application version information */ +#define SKS_VERSION_ID0 0 +#define SKS_VERSION_ID1 0 + +/* + * SKS_CMD_PING Acknowledge TA presence and return TA version info + * + * Optinal invocation parameter: + * + * [out] memref[2] = [ + * 32bit version0 value, + * 32bit version1 value + * ] + */ +#define SKS_CMD_PING 0x00000000 + +/* + * SKS_CMD_CK_SLOT_LIST - Get the table of the valid slot IDs + * + * [out] memref[2] = 32bit array slot_ids[slot counts] + * + * The TA instance may represent several PKCS#11 slots and associated tokens. + * This command relates the PKCS#11 API function C_GetSlotList and return the + * valid IDs recognized by the trusted application. + */ +#define SKS_CMD_CK_SLOT_LIST 0x00000001 + +/* + * SKS_CMD_CK_SLOT_INFO - Get cryptoki structured slot information + * + * [in] memref[0] = 32bit slot ID + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = (struct sks_ck_slot_info)info + * + * The TA instance may represent several PKCS#11 slots and associated tokens. + * This command relates the PKCS#11 API function C_GetSlotInfo and return the + * information about the target slot. + */ +#define SKS_CMD_CK_SLOT_INFO 0x00000002 + +#define SKS_SLOT_DESC_SIZE 64 +#define SKS_SLOT_MANUFACTURER_SIZE 32 +#define SKS_SLOT_VERSION_SIZE 2 + +struct sks_slot_info { + uint8_t slotDescription[SKS_SLOT_DESC_SIZE]; + uint8_t manufacturerID[SKS_SLOT_MANUFACTURER_SIZE]; + uint32_t flags; + uint8_t hardwareVersion[SKS_SLOT_VERSION_SIZE]; + uint8_t firmwareVersion[SKS_SLOT_VERSION_SIZE]; +}; + +/* + * Values for sks_token_info::flags. + * SKS_CKFS_ corresponds to cryptoki flag CKF_ related to slot flags. + */ +#define SKS_CKFS_TOKEN_PRESENT (1U << 0) +#define SKS_CKFS_REMOVABLE_DEVICE (1U << 1) +#define SKS_CKFS_HW_SLOT (1U << 2) + +/* + * SKS_CMD_CK_TOKEN_INFO - Get cryptoki structured token information + * + * [in] memref[0] = 32bit slot ID + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = (struct sks_ck_token_info)info + * + * The TA instance may represent several PKCS#11 slots and associated tokens. + * This command relates the PKCS#11 API function C_GetTokenInfo and return the + * information about the target represented token. + */ +#define SKS_CMD_CK_TOKEN_INFO 0x00000003 + +#define SKS_TOKEN_LABEL_SIZE 32 +#define SKS_TOKEN_MANUFACTURER_SIZE 32 +#define SKS_TOKEN_MODEL_SIZE 16 +#define SKS_TOKEN_SERIALNUM_SIZE 16 + +struct sks_token_info { + uint8_t label[SKS_TOKEN_LABEL_SIZE]; + uint8_t manufacturerID[SKS_TOKEN_MANUFACTURER_SIZE]; + uint8_t model[SKS_TOKEN_MODEL_SIZE]; + uint8_t serialNumber[SKS_TOKEN_SERIALNUM_SIZE]; + uint32_t flags; + uint32_t ulMaxSessionCount; + uint32_t ulSessionCount; + uint32_t ulMaxRwSessionCount; + uint32_t ulRwSessionCount; + uint32_t ulMaxPinLen; + uint32_t ulMinPinLen; + uint32_t ulTotalPublicMemory; + uint32_t ulFreePublicMemory; + uint32_t ulTotalPrivateMemory; + uint32_t ulFreePrivateMemory; + uint8_t hardwareVersion[2]; + uint8_t firmwareVersion[2]; + uint8_t utcTime[16]; +}; + +/* + * Values for sks_token_info::flags. + * SKS_CKFT_ corresponds to cryptoki CKF_ related to token flags. + */ +#define SKS_CKFT_RNG (1U << 0) +#define SKS_CKFT_WRITE_PROTECTED (1U << 1) +#define SKS_CKFT_LOGIN_REQUIRED (1U << 2) +#define SKS_CKFT_USER_PIN_INITIALIZED (1U << 3) +#define SKS_CKFT_RESTORE_KEY_NOT_NEEDED (1U << 4) +#define SKS_CKFT_CLOCK_ON_TOKEN (1U << 5) +#define SKS_CKFT_PROTECTED_AUTHENTICATION_PATH (1U << 6) +#define SKS_CKFT_DUAL_CRYPTO_OPERATIONS (1U << 7) +#define SKS_CKFT_TOKEN_INITIALIZED (1U << 8) +#define SKS_CKFT_USER_PIN_COUNT_LOW (1U << 9) +#define SKS_CKFT_USER_PIN_FINAL_TRY (1U << 10) +#define SKS_CKFT_USER_PIN_LOCKED (1U << 11) +#define SKS_CKFT_USER_PIN_TO_BE_CHANGED (1U << 12) +#define SKS_CKFT_SO_PIN_COUNT_LOW (1U << 13) +#define SKS_CKFT_SO_PIN_FINAL_TRY (1U << 14) +#define SKS_CKFT_SO_PIN_LOCKED (1U << 15) +#define SKS_CKFT_SO_PIN_TO_BE_CHANGED (1U << 16) +#define SKS_CKFT_ERROR_STATE (1U << 17) + +/* + * SKS_CMD_CK_MECHANISM_IDS - Get list of the supported mechanisms + * + * [in] memref[0] = 32bit slot ID + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = 32bit array mechanism IDs + * + * This commands relates to the PKCS#11 API function C_GetMechanismList. + */ +#define SKS_CMD_CK_MECHANISM_IDS 0x00000004 + +/* + * SKS_CMD_CK_MECHANISM_INFO - Get information on a specific mechanism + * + * [in] memref[0] = [ + * 32bit slot ID, + * 32bit mechanism ID + * ] + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = (struct sks_mecha_info)info + * + * This commands relates to the PKCS#11 API function C_GetMechanismInfo. + */ +#define SKS_CMD_CK_MECHANISM_INFO 0x00000005 + +struct sks_mechanism_info { + uint32_t min_key_size; + uint32_t max_key_size; + uint32_t flags; +}; + +/* + * Values for sks_mechanism_info::flags. + * SKS_CKFM_ strictly matches cryptoki CKF_ related to mechanism flags. + */ +#define SKS_CKFM_HW (1U << 0) +#define SKS_CKFM_ENCRYPT (1U << 8) +#define SKS_CKFM_DECRYPT (1U << 9) +#define SKS_CKFM_DIGEST (1U << 10) +#define SKS_CKFM_SIGN (1U << 11) +#define SKS_CKFM_SIGN_RECOVER (1U << 12) +#define SKS_CKFM_VERIFY (1U << 13) +#define SKS_CKFM_VERIFY_RECOVER (1U << 14) +#define SKS_CKFM_GENERATE (1U << 15) +#define SKS_CKFM_GENERATE_PAIR (1U << 16) +#define SKS_CKFM_WRAP (1U << 17) +#define SKS_CKFM_UNWRAP (1U << 18) +#define SKS_CKFM_DERIVE (1U << 19) + +/* + * SKS_CMD_CK_INIT_TOKEN - Initialize PKCS#11 token + * + * [in] memref[0] = [ + * 32bit slot ID, + * 32bit pin length, + * 8bit array pin[pin length], + * 8bit array label[32] + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * This commands relates to the PKCS#11 API function C_InitToken(). + */ +#define SKS_CMD_CK_INIT_TOKEN 0x00000006 + +/* + * SKS_CMD_CK_INIT_PIN - Initialize PKCS#11 token PIN + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit pin length, + * 8bit array pin[pin length] + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * This commands relates to the PKCS#11 API function C_InitPIN(). + */ +#define SKS_CMD_CK_INIT_PIN 0x00000007 + +/* + * SKS_CMD_CK_SET_PIN - Set PKCS#11 token PIN + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit old_pin_length, + * 8bit array old_pin[old_pin_length], + * 32bit new_pin_length, + * 8bit array new_pin[new_pin_length] + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * This commands relates to the PKCS#11 API function C_SetPIN() + */ +#define SKS_CMD_CK_SET_PIN 0x00000008 + +/* + * SKS_CMD_CK_OPEN_RO_SESSION - Open read-only session + * + * [in] memref[0] = 32bit slot ID + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[0] = 32bit session handle + * + * This commands relates to the PKCS#11 API function C_OpenSession() for a + * read-only session. + */ +#define SKS_CMD_CK_OPEN_RO_SESSION 0x00000009 + +/* + * SKS_CMD_CK_OPEN_RW_SESSION - Open read/write session + * + * [in] memref[0] = 32bit slot + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[0] = 32bit session handle + * + * This commands relates to the PKCS#11 API function C_OpenSession() for a + * read/Write session. + */ +#define SKS_CMD_CK_OPEN_RW_SESSION 0x0000000a + +/* + * SKS_CMD_CK_CLOSE_SESSION - Close an opened session + * + * [in] memref[0] = 32bit session handle + * [out] memref[0] = 32bit fine grain retrun code + * + * This commands relates to the PKCS#11 API function C_CloseSession(). + */ +#define SKS_CMD_CK_CLOSE_SESSION 0x0000000b + +/* + * SKS_CMD_CK_SESSION_INFO - Get Cryptoki information on a session + * + * [in] memref[0] = 32bit session handle + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = (struct sks_ck_session_info)info + * + * This commands relates to the PKCS#11 API function C_GetSessionInfo(). + */ +#define SKS_CMD_CK_SESSION_INFO 0x0000000c + +struct sks_session_info { + uint32_t slot_id; + uint32_t state; + uint32_t flags; + uint32_t error_code; +}; + +/* + * SKS_CMD_CK_CLOSE_ALL_SESSIONS - Close all client sessions on slot/token + * + * [in] memref[0] = 32bit slot + * [out] memref[0] = 32bit fine grain retrun code + * + * This commands relates to the PKCS#11 API function C_CloseAllSessions(). + */ +#define SKS_CMD_CK_CLOSE_ALL_SESSIONS 0x0000000d + +/* + * SKS_CMD_IMPORT_OBJECT - Import a raw object in the session or token + * + * [in] memref[0] = [ + * 32bit session handle, + * (struct sks_object_head)attribs + attributes data + * ] + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = 32bit object handle + * + * This commands relates to the PKCS#11 API function C_CreateObject(). + */ +#define SKS_CMD_IMPORT_OBJECT 0x0000000e + +/** + * Serialization of object attributes + */ + +/* + * sks_object_head - Header of object whose data are serialized in memory + * + * An object in made of several attributes. Attributes are store one next to + * the other with byte alignment as serialized byte arrays. Appended + * attributes byte arrays are prepend with this header structure that + * defines the number of attribute items and the overall byte size of the + * attrs byte array. + * + * @attrs_size - byte size of whole byte array attrs[] + * @attrs_count - number of attribute items stored in attrs[] + * @attrs - then starts the attributes data + */ +struct sks_object_head { + uint32_t attrs_size; + uint32_t attrs_count; + uint8_t attrs[]; +}; + +/* + * Attribute reference in the TA ABI. Each attribute start with the header + * structure followed by the attribute value, its byte size being defined + * in the attribute header. + * + * @id - the 32bit identificator of the attribute, see SKS_CKA_ + * @size - the 32bit value attribute byte size + * @data - then starts the attribute value + */ +struct sks_attr_head { + uint32_t id; + uint32_t size; + uint8_t data[]; +}; + +/* + * SKS_CMD_DESTROY_OBJECT - Destroy an object + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit object handle + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * This commands relates to the PKCS#11 API function C_DestroyObject(). + */ +#define SKS_CMD_DESTROY_OBJECT 0x0000000f + +/* + * SKS_CMD_ENCRYPT_INIT - Initialize enryption processing + * SKS_CMD_DECRYPT_INIT - Initialize decryption processing + * + * [in] memref[0] = [ + * 32bit session handle, + * (struct sks_attr_head)mechanism + mechanism parameters + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * These commands relate to the PKCS#11 API functions C_EncryptInit() and + * C_DecryptInit. + */ +#define SKS_CMD_ENCRYPT_INIT 0x00000010 +#define SKS_CMD_DECRYPT_INIT 0x00000011 + +/* + * SKS_CMD_ENCRYPT_UPDATE - Update encryption processing + * SKS_CMD_DECRYPT_UPDATE - Update decryption processing + * + * [in] memref[0] = 32bit session handle + * [in] memref[1] = input data to be processed + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = output processed data + * + * These commands relate to the PKCS#11 API functions C_EncryptUpdate() and + * C_DecryptUpdate. + */ +#define SKS_CMD_ENCRYPT_UPDATE 0x00000012 +#define SKS_CMD_DECRYPT_UPDATE 0x00000013 + +/* + * SKS_CMD_ENCRYPT_FINAL - Finalize encryption processing + * SKS_CMD_DECRYPT_FINAL - Finalize decryption processing + * + * [in] memref[0] = 32bit session handle + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = output processed data + * + * These commands relate to the PKCS#11 API functions C_EncryptFinal() and + * C_DecryptFinal. + */ +#define SKS_CMD_ENCRYPT_FINAL 0x00000014 +#define SKS_CMD_DECRYPT_FINAL 0x00000015 + +/* + * SKS_CMD_GENERATE_SYMM_KEY - Generate a symmetric key + * + * [in] memref[0] = [ + * 32bit session handle, + * (struct sks_attr_head)mechanism + mechanism parameters, + * (struct sks_object_head)attribs + attributes data + * ] + * [in] memref[1] = input data to be processed + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = 32bit key handle + * + * This command relates to the PKCS#11 API functions C_GenerateKey(). + */ +#define SKS_CMD_GENERATE_SYMM_KEY 0x00000016 + +/* + * SKS_CMD_SIGN_INIT - Initialize a signature computation processing + * SKS_CMD_VERIFY_INIT - Initialize a signature verification processing + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit key handle, + * (struct sks_attr_head)mechanism + mechanism parameters, + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * These commands relate to the PKCS#11 API functions C_SignInit() and + * C_VerifyInit. + */ +#define SKS_CMD_SIGN_INIT 0x00000017 +#define SKS_CMD_VERIFY_INIT 0x00000018 + +/* + * SKS_CMD_SIGN_UPDATE - Update a signature computation processing + * SKS_CMD_VERIFY_UPDATE - Update a signature verification processing + * + * [in] memref[0] = 32bit session handle + * [in] memref[1] = input data to be processed + * [out] memref[0] = 32bit fine grain retrun code + * + * These commands relate to the PKCS#11 API functions C_SignUpdate() and + * C_VerifyUpdate. + */ +#define SKS_CMD_SIGN_UPDATE 0x00000019 +#define SKS_CMD_VERIFY_UPDATE 0x0000001a + +/* + * SKS_CMD_SIGN_FINAL - Finalize a signature computation processing + * SKS_CMD_VERIFY_FINAL - Finalize a signature verification processing + * + * [in] memref[0] = 32bit session handle + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = output processed data + * + * These commands relate to the PKCS#11 API functions C_SignFinal() and + * C_VerifyFinal. + */ +#define SKS_CMD_SIGN_FINAL 0x0000001b +#define SKS_CMD_VERIFY_FINAL 0x0000001c + +/* + * SKS_CMD_FIND_OBJECTS_INIT - Initialize a objects search + * + * [in] memref[0] = [ + * 32bit session handle, + * (struct sks_object_head)attribs + attributes data + * ] + * [out] memref[0] = 32bit fine grain retrun code + * + * This command relates to the PKCS#11 API function C_FindOjectsInit(). + */ +#define SKS_CMD_FIND_OBJECTS_INIT 0x0000001d + +/* + * SKS_CMD_FIND_OBJECTS - Get handles of matching objects + * + * [in] memref[0] = 32bit session handle + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = 32bit array object_handle_array[N] + * + * This command relates to the PKCS#11 API function C_FindOjects(). + * The size of object_handle_array depends output buffer size + * provided by the client. + */ +#define SKS_CMD_FIND_OBJECTS 0x0000001e + +/* + * SKS_CMD_FIND_OBJECTS_FINAL - Finalize current objects search + * + * [in] memref[0] = 32bit session handle + * [out] memref[0] = 32bit fine grain retrun code + * + * This command relates to the PKCS#11 API function C_FindOjectsFinal(). + */ +#define SKS_CMD_FIND_OBJECTS_FINAL 0x0000001f + +/* + * SKS_CMD_GET_OBJECT_SIZE - Get size used by object in the TEE + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit key handle + * ] + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = 32bit object_byte_size + */ +#define SKS_CMD_GET_OBJECT_SIZE 0x00000020 + +/* + * SKS_CMD_GET_ATTRIBUTE_VALUE - Get the value of object attribute(s) + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit object handle, + * (struct sks_object_head)attribs + attributes data + * ] + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = (struct sks_object_head)attribs + attributes data + */ +#define SKS_CMD_GET_ATTRIBUTE_VALUE 0x00000021 + +/* + * SKS_CMD_SET_ATTRIBUTE_VALUE - Set the value for object attribute(s) + * + * [in] memref[0] = [ + * 32bit session handle, + * 32bit object handle, + * (struct sks_object_head)attribs + attributes data + * ] + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = (struct sks_object_head)attribs + attributes data + */ +#define SKS_CMD_SET_ATTRIBUTE_VALUE 0x00000022 + +/* + * SKS_CMD_DERIVE_KEY - Derive a key from already provisioned parent key + * + * [in] memref[0] = [ + * 32bit session handle, + * (struct sks_attr_head)mechanism + mechanism parameters, + * 32bit key handle, + * (struct sks_object_head)attribs + attributes data + * ] + * [out] memref[0] = 32bit fine grain retrun code + * [out] memref[2] = 32bit object handle + */ +#define SKS_CMD_DERIVE_KEY 0x00000023 + +/* + * Command return codes + * SKS_CKR_ relates cryptoki CKR_ in meaning if not in value. + */ +#define SKS_CKR_OK 0x00000000 +#define SKS_CKR_GENERAL_ERROR 0x00000001 +#define SKS_CKR_DEVICE_MEMORY 0x00000002 +#define SKS_CKR_ARGUMENT_BAD 0x00000003 +#define SKS_CKR_BUFFER_TOO_SMALL 0x00000004 +#define SKS_CKR_FUNCTION_FAILED 0x00000005 +#define SKS_CKR_SIGNATURE_INVALID 0x00000007 +#define SKS_CKR_ATTRIBUTE_TYPE_INVALID 0x00000008 +#define SKS_CKR_ATTRIBUTE_VALUE_INVALID 0x00000009 +#define SKS_CKR_OBJECT_HANDLE_INVALID 0x0000000a +#define SKS_CKR_KEY_HANDLE_INVALID 0x0000000b +#define SKS_CKR_MECHANISM_INVALID 0x0000000c +#define SKS_CKR_SESSION_HANDLE_INVALID 0x0000000d +#define SKS_CKR_SLOT_ID_INVALID 0x0000000e +#define SKS_CKR_MECHANISM_PARAM_INVALID 0x0000000f +#define SKS_CKR_TEMPLATE_INCONSISTENT 0x00000010 +#define SKS_CKR_TEMPLATE_INCOMPLETE 0x00000011 +#define SKS_CKR_PIN_INCORRECT 0x00000012 +#define SKS_CKR_PIN_LOCKED 0x00000013 +#define SKS_CKR_PIN_EXPIRED 0x00000014 +#define SKS_CKR_PIN_INVALID 0x00000015 +#define SKS_CKR_PIN_LEN_RANGE 0x00000016 +#define SKS_CKR_SESSION_EXISTS 0x00000017 +#define SKS_CKR_SESSION_READ_ONLY 0x00000018 +#define SKS_CKR_SESSION_READ_WRITE_SO_EXISTS 0x00000019 +#define SKS_CKR_OPERATION_ACTIVE 0x0000001a +#define SKS_CKR_KEY_FUNCTION_NOT_PERMITTED 0x0000001b +#define SKS_CKR_OPERATION_NOT_INITIALIZED 0x0000001c +/* Statuc without strict equivalence in cryptoki */ +#define SKS_NOT_FOUND 0x00001000 +#define SKS_NOT_IMPLEMENTED 0x00001001 + +/* Attribute specific values */ +#define SKS_UNDEFINED_ID ((uint32_t)0xFFFFFFFF) +#define SKS_FALSE 0 +#define SKS_TRUE 1 + +/* + * Attribute identificators + * Valid values for struct sks_reference::id + * + * SKS_ATTR_ corresponds to cryptoki CKA_. + * Value range [0 63] is reserved to boolean value attributes. + */ +#define SKS_BOOLPROPS_BASE 0x00000000 +#define SKS_CKA_TOKEN 0x00000000 +#define SKS_CKA_PRIVATE 0x00000001 +#define SKS_CKA_TRUSTED 0x00000002 +#define SKS_CKA_SENSITIVE 0x00000003 +#define SKS_CKA_ENCRYPT 0x00000004 +#define SKS_CKA_DECRYPT 0x00000005 +#define SKS_CKA_WRAP 0x00000006 +#define SKS_CKA_UNWRAP 0x00000007 +#define SKS_CKA_SIGN 0x00000008 +#define SKS_CKA_SIGN_RECOVER 0x00000009 +#define SKS_CKA_VERIFY 0x0000000a +#define SKS_CKA_VERIFY_RECOVER 0x0000000b +#define SKS_CKA_DERIVE 0x0000000c +#define SKS_CKA_EXTRACTABLE 0x0000000d +#define SKS_CKA_LOCAL 0x0000000e +#define SKS_CKA_NEVER_EXTRACTABLE 0x0000000f +#define SKS_CKA_ALWAYS_SENSITIVE 0x00000010 +#define SKS_CKA_MODIFIABLE 0x00000011 +#define SKS_CKA_COPYABLE 0x00000012 +#define SKS_CKA_DESTROYABLE 0x00000013 +#define SKS_CKA_ALWAYS_AUTHENTICATE 0x00000014 +#define SKS_CKA_WRAP_WITH_TRUSTED 0x00000015 +#define SKS_BOOLPROPS_LAST 0x0000003F + +#define SKS_CKA_LABEL 0x00000040 +#define SKS_CKA_VALUE 0x00000041 +#define SKS_CKA_VALUE_LEN 0x00000042 +#define SKS_CKA_WRAP_TEMPLATE 0x00000043 +#define SKS_CKA_UNWRAP_TEMPLATE 0x00000044 +#define SKS_CKA_DERIVE_TEMPLATE 0x00000045 +#define SKS_CKA_START_DATE 0x00000046 +#define SKS_CKA_END_DATE 0x00000047 +#define SKS_CKA_OBJECT_ID 0x00000048 +#define SKS_CKA_APPLICATION 0x00000049 +#define SKS_CKA_MECHANISM_TYPE 0x0000004a +#define SKS_CKA_ID 0x0000004b +#define SKS_CKA_ALLOWED_MECHANISMS 0x0000004c +#define SKS_CKA_CLASS 0x0000004d +#define SKS_CKA_KEY_TYPE 0x0000004e + +/* + * Valid values for attribute SKS_CKA_CLASS + * SKS_CKO_ corresponds to cryptoki CKO_. + */ +#define SKS_CKO_SECRET_KEY 0x000 +#define SKS_CKO_PUBLIC_KEY 0x001 +#define SKS_CKO_PRIVATE_KEY 0x002 +#define SKS_CKO_OTP_KEY 0x003 +#define SKS_CKO_CERTIFICATE 0x004 +#define SKS_CKO_DATA 0x005 +#define SKS_CKO_DOMAIN_PARAMETERS 0x006 +#define SKS_CKO_HW_FEATURE 0x007 +#define SKS_CKO_MECHANISM 0x008 + +/* + * Valid values for attribute SKS_CKA_KEY_TYPE + * SKS_CKK_ corresponds to cryptoki CKK_ related to symmetric keys + */ +#define SKS_CKK_AES 0x000 +#define SKS_CKK_GENERIC_SECRET 0x001 +#define SKS_CKK_MD5_HMAC 0x002 +#define SKS_CKK_SHA_1_HMAC 0x003 +#define SKS_CKK_SHA224_HMAC 0x004 +#define SKS_CKK_SHA256_HMAC 0x005 +#define SKS_CKK_SHA384_HMAC 0x006 +#define SKS_CKK_SHA512_HMAC 0x007 + +/* + * Valid values for attribute SKS_CKA_MECHANISM_TYPE + * SKS_CKM_ corresponds to cryptoki CKM_. + */ +#define SKS_CKM_AES_ECB 0x000 +#define SKS_CKM_AES_CBC 0x001 +#define SKS_CKM_AES_CBC_PAD 0x002 +#define SKS_CKM_AES_CTS 0x003 +#define SKS_CKM_AES_CTR 0x004 +#define SKS_CKM_AES_GCM 0x005 +#define SKS_CKM_AES_CCM 0x006 +#define SKS_CKM_AES_GMAC 0x007 +#define SKS_CKM_AES_CMAC 0x008 +#define SKS_CKM_AES_CMAC_GENERAL 0x009 +#define SKS_CKM_AES_ECB_ENCRYPT_DATA 0x00a +#define SKS_CKM_AES_CBC_ENCRYPT_DATA 0x00b +#define SKS_CKM_AES_KEY_GEN 0x00c +#define SKS_CKM_GENERIC_SECRET_KEY_GEN 0x00d +#define SKS_CKM_MD5_HMAC 0x00e +#define SKS_CKM_SHA_1_HMAC 0x00f +#define SKS_CKM_SHA224_HMAC 0x010 +#define SKS_CKM_SHA256_HMAC 0x011 +#define SKS_CKM_SHA384_HMAC 0x012 +#define SKS_CKM_SHA512_HMAC 0x013 +#define SKS_CKM_AES_XCBC_MAC 0x014 +/* SKS added IDs for operation without cryptoki mechanism ID defined */ +#define SKS_PROCESSING_IMPORT 0x1000 +#define SKS_PROCESSING_COPY 0x1001 + +/* + * Processing parameters + * + * These can hardly be described by ANSI-C structures since some field of the + * structure have a size specify by a previous field. Therefore the format of + * the parameter binary data for each supported processing is define here from + * this comment rather than using C structures. Processing parameters are used + * as argument the C_EncryptInit and friends using the struct sks_reference + * format where field 'type' is the SKS processing ID and field 'size' is the + * parameter byte size. Below is shown the head struct sks_reference fields + * and the trailling data (the effective parameters binary blob). + * + * AES ECB + * head: 32bit type = SKS_CKM_AES_ECB + * 32bit params byte size = 0 + * + * AES CBC, CBC_NOPAD and CTS + * head: 32bit type = SKS_CKM_AES_CBC + * or SKS_CKM_AES_CBC_PAD + * or SKS_CKM_AES_CTS + * 32bit params byte size = 16 + * params: 16byte IV + * + * AES CTR + * head: 32bit type = SKS_CKM_AES_CTR + * 32bit params byte size = 20 + * params: 32bit counter bit increment + * 16byte IV + * + * AES GCM + * head: 32bit type = SKS_CKM_AES_GCM + * 32bit params byte size + * params: 32bit IV_byte_size + * byte array: IV (IV_byte_size bytes) + * 32bit AAD_byte_size + * byte array: AAD data (AAD_byte_size bytes) + * 32bit tag bit size + * + * AES CCM + * head: 32bit type = SKS_CKM_AES_CCM + * 32bit params byte size + * params: 32bit data_byte_size + * 32bit nonce_byte_size + * byte array: nonce data (nonce_byte_size bytes) + * 32bit AAD_byte_size + * byte array: AAD data (AAD_byte_size bytes) + * 32bit MAC byte size + * + * AES GMAC + * head: 32bit type = SKS_CKM_AES_GMAC + * 32bit params byte size = 12 + * params: 12byte IV + + * AES CMAC with general length + * head: 32bit type = SKS_CKM_AES_CMAC_GENERAL + * 32bit params byte size = 12 + * params: 32bit byte size of the output CMAC data + * + * AES CMAC fixed size (16byte CMAC) + * head: 32bit type = SKS_CKM_AES_CMAC_GENERAL + * 32bit size = 0 + * + * AES derive by ECB + * head: 32bit type = SKS_CKM_AES_ECB_ENCRYPT_DATA + * 32bit params byte size + * params: 32bit byte size of the data to encrypt + * byte array: data to encrypt + * + * AES derive by CBC + * head: 32bit type = SKS_CKM_AES_CBC_ENCRYPT_DATA + * 32bit params byte size + * params: 16byte IV + * 32bit byte size of the data to encrypt + * byte array: data to encrypt + * + * AES and generic secret generation + * head: 32bit type = SKS_CKM_AES_KEY_GEN + * or SKS_CKM_GENERIC_SECRET_KEY_GEN + * 32bit size = 0 + */ + +#endif /*__SKS_TA_H__*/ diff --git a/ta_services/secure_key_services/src/entry.c b/ta_services/secure_key_services/src/entry.c new file mode 100644 index 00000000000..3f607966389 --- /dev/null +++ b/ta_services/secure_key_services/src/entry.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2017-2018, Linaro Limited + */ + +#include +#include +#include +#include + +#include "sks_helpers.h" + +TEE_Result TA_CreateEntryPoint(void) +{ + return TEE_SUCCESS; +} + +void TA_DestroyEntryPoint(void) +{ +} + +TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types, + TEE_Param __unused params[4], + void **session) +{ + *session = NULL; + + return TEE_SUCCESS; +} + +void TA_CloseSessionEntryPoint(void *session __unused) +{ +} + +static uint32_t entry_ping(TEE_Param *ctrl, TEE_Param *in, TEE_Param *out) +{ + uint32_t *ver; + + if (ctrl || in) + return SKS_BAD_PARAM; + + if (!out) + return SKS_OK; + + if (out->memref.size < 2 * sizeof(uint32_t)) + return SKS_SHORT_BUFFER; + + ver = (uint32_t *)out->memref.buffer; + *ver = SKS_VERSION_ID0; + *(ver + 1) = SKS_VERSION_ID1; + + return SKS_OK; +} + +/* + * Entry point for SKS TA commands + * + * ABI: param#0 is control buffer with serialized arguments. + * param#1 is the input data buffer + * param#2 is the output data buffer (also used to return handles) + * param#3 is not used + * + * Param#0 ctrl, if defined is an in/out buffer, is used to send back to + * the client a Cryptoki status ID that superseeds the TEE result code which + * will be force to TEE_SUCCESS. Note that some Cryptoki error status are + * sent straight through TEE result code. See sks2tee_noerr(). + */ +TEE_Result TA_InvokeCommandEntryPoint(void *session __unused, uint32_t cmd, + uint32_t ptypes, + TEE_Param params[TEE_NUM_PARAMS]) +{ + TEE_Param *ctrl = NULL; + TEE_Param *in = NULL; + TEE_Param *out = NULL; + TEE_Result res; + uint32_t rc; + + if (TEE_PARAM_TYPE_GET(ptypes, 0) == TEE_PARAM_TYPE_MEMREF_INPUT || + TEE_PARAM_TYPE_GET(ptypes, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) + ctrl = ¶ms[0]; + else if (TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_NONE) + goto bad_types; + + if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) + in = ¶ms[1]; + else if (TEE_PARAM_TYPE_GET(ptypes, 1) != TEE_PARAM_TYPE_NONE) + goto bad_types; + + if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) + out = ¶ms[2]; + else if (TEE_PARAM_TYPE_GET(ptypes, 2) != TEE_PARAM_TYPE_NONE) + goto bad_types; + + if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) + goto bad_types; + + DMSG("%s ctrl %" PRIu32 "@%p, in %" PRIu32 "@%p, out %" PRIu32 "@%p", + sks2str_skscmd(cmd), + ctrl ? ctrl->memref.size : 0, ctrl ? ctrl->memref.buffer : 0, + in ? in->memref.size : 0, in ? in->memref.buffer : 0, + out ? out->memref.size : 0, out ? out->memref.buffer : 0); + + switch (cmd) { + case SKS_CMD_PING: + rc = entry_ping(ctrl, in, out); + break; + + default: + EMSG("Command ID 0x%x is not supported", cmd); + return TEE_ERROR_NOT_SUPPORTED; + } + + if (TEE_PARAM_TYPE_GET(ptypes, 0) == TEE_PARAM_TYPE_MEMREF_INOUT && + ctrl->memref.size >= sizeof(uint32_t)) { + + TEE_MemMove(ctrl->memref.buffer, &rc, sizeof(uint32_t)); + ctrl->memref.size = sizeof(uint32_t); + + res = sks2tee_noerr(rc); + } else { + res = sks2tee_error(rc); + } + + DMSG("SKS TA exit: %s rc 0x%08" PRIu32 "/%s", + sks2str_skscmd(cmd), rc, sks2str_rc(rc)); + + return res; + +bad_types: + DMSG("Bad parameter types used at SKS TA entry:"); + DMSG("- parameter #0: formated input request buffer or none"); + DMSG("- parameter #1: processed input data buffer or none"); + DMSG("- parameter #2: processed output data buffer or none"); + DMSG("- parameter #3: none"); + return TEE_ERROR_BAD_PARAMETERS; +} diff --git a/ta_services/secure_key_services/src/sks_helpers.c b/ta_services/secure_key_services/src/sks_helpers.c new file mode 100644 index 00000000000..07c8f4f6b47 --- /dev/null +++ b/ta_services/secure_key_services/src/sks_helpers.c @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2017-2018, Linaro Limited + */ + +#include +#include +#include + +#include "sks_helpers.h" + +struct string_id { + uint32_t id; + const char *string; +}; + +#define SKS_ID(_id) { .id = _id, .string = #_id } + +struct attr_size { + uint32_t id; + uint32_t size; + const char *string; +}; + +#if CFG_TEE_TA_LOG_LEVEL > 0 +#define SKS_ID_SZ(_id, _size) { .id = _id, .string = #_id, .size = _size } +#else +#define SKS_ID_SZ(_id, _size) { .id = _id, .size = _size } +#endif + +static const struct attr_size attr_ids[] = { + SKS_ID_SZ(SKS_CKA_CLASS, 4), + SKS_ID_SZ(SKS_CKA_KEY_TYPE, 4), + SKS_ID_SZ(SKS_CKA_VALUE, 0), + SKS_ID_SZ(SKS_CKA_VALUE_LEN, 4), + SKS_ID_SZ(SKS_CKA_WRAP_TEMPLATE, 0), + SKS_ID_SZ(SKS_CKA_UNWRAP_TEMPLATE, 0), + SKS_ID_SZ(SKS_CKA_DERIVE_TEMPLATE, 0), + SKS_ID_SZ(SKS_CKA_START_DATE, 4), + SKS_ID_SZ(SKS_CKA_END_DATE, 4), + SKS_ID_SZ(SKS_CKA_OBJECT_ID, 0), + SKS_ID_SZ(SKS_CKA_APPLICATION, 0), + SKS_ID_SZ(SKS_CKA_MECHANISM_TYPE, 4), + SKS_ID_SZ(SKS_CKA_ID, 0), + SKS_ID_SZ(SKS_CKA_ALLOWED_MECHANISMS, 0), + /* Below are boolean attribs */ + SKS_ID_SZ(SKS_CKA_TOKEN, 1), + SKS_ID_SZ(SKS_CKA_PRIVATE, 1), + SKS_ID_SZ(SKS_CKA_TRUSTED, 1), + SKS_ID_SZ(SKS_CKA_SENSITIVE, 1), + SKS_ID_SZ(SKS_CKA_ENCRYPT, 1), + SKS_ID_SZ(SKS_CKA_DECRYPT, 1), + SKS_ID_SZ(SKS_CKA_WRAP, 1), + SKS_ID_SZ(SKS_CKA_UNWRAP, 1), + SKS_ID_SZ(SKS_CKA_SIGN, 1), + SKS_ID_SZ(SKS_CKA_SIGN_RECOVER, 1), + SKS_ID_SZ(SKS_CKA_VERIFY, 1), + SKS_ID_SZ(SKS_CKA_VERIFY_RECOVER, 1), + SKS_ID_SZ(SKS_CKA_DERIVE, 1), + SKS_ID_SZ(SKS_CKA_EXTRACTABLE, 1), + SKS_ID_SZ(SKS_CKA_LOCAL, 1), + SKS_ID_SZ(SKS_CKA_NEVER_EXTRACTABLE, 1), + SKS_ID_SZ(SKS_CKA_ALWAYS_SENSITIVE, 1), + SKS_ID_SZ(SKS_CKA_MODIFIABLE, 1), + SKS_ID_SZ(SKS_CKA_COPYABLE, 1), + SKS_ID_SZ(SKS_CKA_DESTROYABLE, 1), + SKS_ID_SZ(SKS_CKA_ALWAYS_AUTHENTICATE, 1), + SKS_ID_SZ(SKS_CKA_WRAP_WITH_TRUSTED, 1), + /* Specific SKS attribute IDs */ + SKS_ID_SZ(SKS_UNDEFINED_ID, 0), +}; + +#if CFG_TEE_TA_LOG_LEVEL > 0 +static const char __maybe_unused unknown[] = ""; + +static const struct string_id __maybe_unused string_cmd[] = { + SKS_ID(SKS_CMD_PING), + SKS_ID(SKS_CMD_CK_SLOT_LIST), + SKS_ID(SKS_CMD_CK_SLOT_INFO), + SKS_ID(SKS_CMD_CK_TOKEN_INFO), + SKS_ID(SKS_CMD_CK_MECHANISM_IDS), + SKS_ID(SKS_CMD_CK_MECHANISM_INFO), + SKS_ID(SKS_CMD_CK_INIT_TOKEN), + SKS_ID(SKS_CMD_CK_INIT_PIN), + SKS_ID(SKS_CMD_CK_SET_PIN), + SKS_ID(SKS_CMD_CK_OPEN_RO_SESSION), + SKS_ID(SKS_CMD_CK_OPEN_RW_SESSION), + SKS_ID(SKS_CMD_CK_CLOSE_SESSION), + SKS_ID(SKS_CMD_CK_SESSION_INFO), + SKS_ID(SKS_CMD_CK_CLOSE_ALL_SESSIONS), + SKS_ID(SKS_CMD_IMPORT_OBJECT), + SKS_ID(SKS_CMD_DESTROY_OBJECT), + SKS_ID(SKS_CMD_ENCRYPT_INIT), + SKS_ID(SKS_CMD_DECRYPT_INIT), + SKS_ID(SKS_CMD_ENCRYPT_UPDATE), + SKS_ID(SKS_CMD_DECRYPT_UPDATE), + SKS_ID(SKS_CMD_ENCRYPT_FINAL), + SKS_ID(SKS_CMD_DECRYPT_FINAL), + SKS_ID(SKS_CMD_GENERATE_SYMM_KEY), + SKS_ID(SKS_CMD_SIGN_INIT), + SKS_ID(SKS_CMD_VERIFY_INIT), + SKS_ID(SKS_CMD_SIGN_UPDATE), + SKS_ID(SKS_CMD_VERIFY_UPDATE), + SKS_ID(SKS_CMD_SIGN_FINAL), + SKS_ID(SKS_CMD_VERIFY_FINAL), + SKS_ID(SKS_CMD_FIND_OBJECTS_INIT), + SKS_ID(SKS_CMD_FIND_OBJECTS), + SKS_ID(SKS_CMD_FIND_OBJECTS_FINAL), + SKS_ID(SKS_CMD_GET_OBJECT_SIZE), + SKS_ID(SKS_CMD_GET_ATTRIBUTE_VALUE), + SKS_ID(SKS_CMD_SET_ATTRIBUTE_VALUE), +}; + +static const struct string_id __maybe_unused string_rc[] = { + SKS_ID(SKS_CKR_OK), + SKS_ID(SKS_CKR_GENERAL_ERROR), + SKS_ID(SKS_CKR_DEVICE_MEMORY), + SKS_ID(SKS_CKR_ARGUMENT_BAD), + SKS_ID(SKS_CKR_BUFFER_TOO_SMALL), + SKS_ID(SKS_CKR_FUNCTION_FAILED), + SKS_ID(SKS_CKR_SIGNATURE_INVALID), + SKS_ID(SKS_CKR_ATTRIBUTE_TYPE_INVALID), + SKS_ID(SKS_CKR_ATTRIBUTE_VALUE_INVALID), + SKS_ID(SKS_CKR_OBJECT_HANDLE_INVALID), + SKS_ID(SKS_CKR_KEY_HANDLE_INVALID), + SKS_ID(SKS_CKR_MECHANISM_INVALID), + SKS_ID(SKS_CKR_SESSION_HANDLE_INVALID), + SKS_ID(SKS_CKR_SLOT_ID_INVALID), + SKS_ID(SKS_CKR_MECHANISM_PARAM_INVALID), + SKS_ID(SKS_CKR_TEMPLATE_INCONSISTENT), + SKS_ID(SKS_CKR_TEMPLATE_INCOMPLETE), + SKS_ID(SKS_CKR_PIN_INCORRECT), + SKS_ID(SKS_CKR_PIN_LOCKED), + SKS_ID(SKS_CKR_PIN_EXPIRED), + SKS_ID(SKS_CKR_PIN_INVALID), + SKS_ID(SKS_CKR_PIN_LEN_RANGE), + SKS_ID(SKS_CKR_SESSION_EXISTS), + SKS_ID(SKS_CKR_SESSION_READ_ONLY), + SKS_ID(SKS_CKR_SESSION_READ_WRITE_SO_EXISTS), + SKS_ID(SKS_CKR_OPERATION_ACTIVE), + SKS_ID(SKS_CKR_KEY_FUNCTION_NOT_PERMITTED), + SKS_ID(SKS_CKR_OPERATION_NOT_INITIALIZED), + SKS_ID(SKS_NOT_FOUND), + SKS_ID(SKS_NOT_IMPLEMENTED), +}; + +static const struct string_id __maybe_unused string_slot_flags[] = { + SKS_ID(SKS_CKFS_TOKEN_PRESENT), + SKS_ID(SKS_CKFS_REMOVABLE_DEVICE), + SKS_ID(SKS_CKFS_HW_SLOT), +}; + +static const struct string_id __maybe_unused string_token_flags[] = { + SKS_ID(SKS_CKFT_RNG), + SKS_ID(SKS_CKFT_WRITE_PROTECTED), + SKS_ID(SKS_CKFT_LOGIN_REQUIRED), + SKS_ID(SKS_CKFT_USER_PIN_INITIALIZED), + SKS_ID(SKS_CKFT_RESTORE_KEY_NOT_NEEDED), + SKS_ID(SKS_CKFT_CLOCK_ON_TOKEN), + SKS_ID(SKS_CKFT_PROTECTED_AUTHENTICATION_PATH), + SKS_ID(SKS_CKFT_DUAL_CRYPTO_OPERATIONS), + SKS_ID(SKS_CKFT_TOKEN_INITIALIZED), + SKS_ID(SKS_CKFT_USER_PIN_COUNT_LOW), + SKS_ID(SKS_CKFT_USER_PIN_FINAL_TRY), + SKS_ID(SKS_CKFT_USER_PIN_LOCKED), + SKS_ID(SKS_CKFT_USER_PIN_TO_BE_CHANGED), + SKS_ID(SKS_CKFT_SO_PIN_COUNT_LOW), + SKS_ID(SKS_CKFT_SO_PIN_FINAL_TRY), + SKS_ID(SKS_CKFT_SO_PIN_LOCKED), + SKS_ID(SKS_CKFT_SO_PIN_TO_BE_CHANGED), + SKS_ID(SKS_CKFT_ERROR_STATE), +}; + +static const struct string_id __maybe_unused string_class[] = { + SKS_ID(SKS_CKO_SECRET_KEY), + SKS_ID(SKS_CKO_PUBLIC_KEY), + SKS_ID(SKS_CKO_PRIVATE_KEY), + SKS_ID(SKS_CKO_OTP_KEY), + SKS_ID(SKS_CKO_CERTIFICATE), + SKS_ID(SKS_CKO_DATA), + SKS_ID(SKS_CKO_DOMAIN_PARAMETERS), + SKS_ID(SKS_CKO_HW_FEATURE), + SKS_ID(SKS_CKO_MECHANISM), + SKS_ID(SKS_UNDEFINED_ID) +}; + +static const struct string_id __maybe_unused string_key_type[] = { + SKS_ID(SKS_CKK_AES), + SKS_ID(SKS_CKK_GENERIC_SECRET), + SKS_ID(SKS_CKK_MD5_HMAC), + SKS_ID(SKS_CKK_SHA_1_HMAC), + SKS_ID(SKS_CKK_SHA224_HMAC), + SKS_ID(SKS_CKK_SHA256_HMAC), + SKS_ID(SKS_CKK_SHA384_HMAC), + SKS_ID(SKS_CKK_SHA512_HMAC), + SKS_ID(SKS_UNDEFINED_ID) +}; + +static const struct string_id __maybe_unused string_processing[] = { + SKS_ID(SKS_CKM_AES_ECB), + SKS_ID(SKS_CKM_AES_CBC), + SKS_ID(SKS_CKM_AES_CBC_PAD), + SKS_ID(SKS_CKM_AES_CTR), + SKS_ID(SKS_CKM_AES_GCM), + SKS_ID(SKS_CKM_AES_CCM), + SKS_ID(SKS_CKM_AES_CTS), + SKS_ID(SKS_CKM_AES_GMAC), + SKS_ID(SKS_CKM_AES_CMAC), + SKS_ID(SKS_CKM_AES_CMAC_GENERAL), + SKS_ID(SKS_CKM_AES_ECB_ENCRYPT_DATA), + SKS_ID(SKS_CKM_AES_CBC_ENCRYPT_DATA), + SKS_ID(SKS_CKM_AES_KEY_GEN), + SKS_ID(SKS_CKM_GENERIC_SECRET_KEY_GEN), + SKS_ID(SKS_CKM_MD5_HMAC), + SKS_ID(SKS_CKM_SHA_1_HMAC), + SKS_ID(SKS_CKM_SHA224_HMAC), + SKS_ID(SKS_CKM_SHA256_HMAC), + SKS_ID(SKS_CKM_SHA384_HMAC), + SKS_ID(SKS_CKM_SHA512_HMAC), + SKS_ID(SKS_CKM_AES_XCBC_MAC), + SKS_ID(SKS_UNDEFINED_ID) +}; + +/* Processing IDs not exported in the TA API */ +static const struct string_id __maybe_unused string_internal_processing[] = { + SKS_ID(SKS_PROCESSING_IMPORT), + SKS_ID(SKS_PROCESSING_COPY), +}; + +static const struct string_id __maybe_unused string_proc_flags[] = { + SKS_ID(SKS_CKFM_HW), + SKS_ID(SKS_CKFM_ENCRYPT), + SKS_ID(SKS_CKFM_DECRYPT), + SKS_ID(SKS_CKFM_DIGEST), + SKS_ID(SKS_CKFM_SIGN), + SKS_ID(SKS_CKFM_SIGN_RECOVER), + SKS_ID(SKS_CKFM_VERIFY), + SKS_ID(SKS_CKFM_VERIFY_RECOVER), + SKS_ID(SKS_CKFM_GENERATE), + SKS_ID(SKS_CKFM_GENERATE_PAIR), + SKS_ID(SKS_CKFM_WRAP), + SKS_ID(SKS_CKFM_UNWRAP), + SKS_ID(SKS_CKFM_DERIVE), +}; +#endif /*CFG_TEE_TA_LOG_LEVEL*/ + +/* + * Helper functions to analyse SKS identifiers + */ + +size_t sks_attr_is_class(uint32_t attribute_id) +{ + if (attribute_id == SKS_CKA_CLASS) + return sizeof(uint32_t); + else + return 0; +} + +size_t sks_attr_is_type(uint32_t attribute_id) +{ + switch (attribute_id) { + case SKS_CKA_KEY_TYPE: + case SKS_CKA_MECHANISM_TYPE: + return sizeof(uint32_t); + default: + return 0; + } +} + +bool sks_class_has_type(uint32_t class) +{ + switch (class) { + case SKS_CKO_CERTIFICATE: + case SKS_CKO_PUBLIC_KEY: + case SKS_CKO_PRIVATE_KEY: + case SKS_CKO_SECRET_KEY: + case SKS_CKO_MECHANISM: + case SKS_CKO_HW_FEATURE: + return 1; + default: + return 0; + } +} + +bool sks_attr_class_is_key(uint32_t class) +{ + switch (class) { + case SKS_CKO_SECRET_KEY: + case SKS_CKO_PUBLIC_KEY: + case SKS_CKO_PRIVATE_KEY: + return 1; + default: + return 0; + } +} + +/* Returns shift position or -1 on error */ +int sks_attr2boolprop_shift(uint32_t attr) +{ + COMPILE_TIME_ASSERT(SKS_BOOLPROPS_BASE == 0); + + if (attr > SKS_BOOLPROPS_LAST) + return -1; + + return attr; +} + +/* + * Conversion between SKS and GPD TEE return codes + */ + +TEE_Result sks2tee_error(uint32_t rv) +{ + switch (rv) { + case SKS_CKR_OK: + return TEE_SUCCESS; + + case SKS_CKR_ARGUMENT_BAD: + return TEE_ERROR_BAD_PARAMETERS; + + case SKS_CKR_DEVICE_MEMORY: + return TEE_ERROR_OUT_OF_MEMORY; + + case SKS_CKR_BUFFER_TOO_SMALL: + return TEE_ERROR_SHORT_BUFFER; + + default: + return TEE_ERROR_GENERIC; + } +} + +TEE_Result sks2tee_noerr(uint32_t rc) +{ + switch (rc) { + case SKS_CKR_ARGUMENT_BAD: + return TEE_ERROR_BAD_PARAMETERS; + + case SKS_CKR_DEVICE_MEMORY: + return TEE_ERROR_OUT_OF_MEMORY; + + case SKS_CKR_BUFFER_TOO_SMALL: + return TEE_ERROR_SHORT_BUFFER; + + case SKS_CKR_GENERAL_ERROR: + return TEE_ERROR_GENERIC; + + default: + return TEE_SUCCESS; + } +} + +uint32_t tee2sks_error(TEE_Result res) +{ + switch (res) { + case TEE_SUCCESS: + return SKS_CKR_OK; + + case TEE_ERROR_BAD_PARAMETERS: + return SKS_CKR_ARGUMENT_BAD; + + case TEE_ERROR_OUT_OF_MEMORY: + return SKS_CKR_DEVICE_MEMORY; + + case TEE_ERROR_SHORT_BUFFER: + return SKS_CKR_BUFFER_TOO_SMALL; + + case TEE_ERROR_MAC_INVALID: + return SKS_CKR_SIGNATURE_INVALID; + + default: + return SKS_CKR_GENERAL_ERROR; + } +} + +bool valid_sks_attribute_id(uint32_t id, uint32_t size) +{ + size_t n; + + for (n = 0; n < ARRAY_SIZE(attr_ids); n++) { + if (id != attr_ids[n].id) + continue; + + /* Check size matches if provided */ + return !size || size == attr_ids[n].size; + } + + return false; +} + +#if CFG_TEE_TA_LOG_LEVEL > 0 +/* + * Convert a SKS ID into its label string + */ +const char *sks2str_attr(uint32_t id) +{ + size_t n; + + for (n = 0; n < ARRAY_SIZE(attr_ids); n++) { + if (id != attr_ids[n].id) + continue; + + /* Skip SKS_ prefix */ + return (char *)attr_ids[n].string + strlen("SKS_CKA_"); + } + + return unknown; +} + +static const char *id2str(uint32_t id, const struct string_id *table, + size_t count, const char *prefix) +{ + size_t n; + const char *str = NULL; + + for (n = 0; n < count; n++) { + if (id != table[n].id) + continue; + + str = table[n].string; + + /* Skip prefix provided matches found */ + if (prefix && !TEE_MemCompare(str, prefix, strlen(prefix))) + str += strlen(prefix); + + return str; + } + + return unknown; +} + +#define ID2STR(id, table, prefix) \ + id2str(id, table, ARRAY_SIZE(table), prefix) + +const char *sks2str_class(uint32_t id) +{ + return ID2STR(id, string_class, "SKS_CKO_"); +} + +const char *sks2str_type(uint32_t id, uint32_t class) +{ + switch (class) { + case SKS_CKO_SECRET_KEY: + case SKS_CKO_PUBLIC_KEY: + case SKS_CKO_PRIVATE_KEY: + return sks2str_key_type(id); + default: + return unknown; + } +} +const char *sks2str_key_type(uint32_t id) +{ + return ID2STR(id, string_key_type, "SKS_CKK_"); +} + +const char *sks2str_boolprop(uint32_t id) +{ + if (id < 64) + return sks2str_attr(id); + + return unknown; +} + +const char *sks2str_proc(uint32_t id) +{ + const char *str = ID2STR(id, string_internal_processing, "SKS_PROC_"); + + if (str != unknown) + return str; + + return ID2STR(id, string_processing, "SKS_CKM_"); +} + +const char *sks2str_proc_flag(uint32_t id) +{ + return ID2STR(id, string_proc_flags, "SKS_CKFM_"); +} + +const char *sks2str_rc(uint32_t id) +{ + return ID2STR(id, string_rc, "SKS_CKR_"); +} + +const char *sks2str_skscmd(uint32_t id) +{ + return ID2STR(id, string_cmd, NULL); +} + +const char *sks2str_slot_flag(uint32_t id) +{ + return ID2STR(id, string_slot_flags, "SKS_CKFS_"); +} + +const char *sks2str_token_flag(uint32_t id) +{ + return ID2STR(id, string_token_flags, "SKS_CKFT_"); +} +#endif /*CFG_TEE_TA_LOG_LEVEL*/ diff --git a/ta_services/secure_key_services/src/sks_helpers.h b/ta_services/secure_key_services/src/sks_helpers.h new file mode 100644 index 00000000000..666783207b4 --- /dev/null +++ b/ta_services/secure_key_services/src/sks_helpers.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2017-2018, Linaro Limited + */ + +#ifndef __SKS_HELPERS_H +#define __SKS_HELPERS_H + +#include +#include +#include +#include + +/* Short aliases for return code */ +#define SKS_OK SKS_CKR_OK +#define SKS_ERROR SKS_CKR_GENERAL_ERROR +#define SKS_MEMORY SKS_CKR_DEVICE_MEMORY +#define SKS_BAD_PARAM SKS_CKR_ARGUMENT_BAD +#define SKS_SHORT_BUFFER SKS_CKR_BUFFER_TOO_SMALL +#define SKS_FAILED SKS_CKR_FUNCTION_FAILED + +/* + * Helper functions to analyse CK fields + */ +bool valid_sks_attribute_id(uint32_t id, uint32_t size); + +size_t sks_attr_is_class(uint32_t attribute_id); +size_t sks_attr_is_type(uint32_t attribute_id); +bool sks_class_has_boolprop(uint32_t class); +bool sks_class_has_type(uint32_t class); +bool sks_attr_class_is_key(uint32_t class); +int sks_attr2boolprop_shift(uint32_t attr); + +/* + * Convert SKS retrun code into a GPD TEE result ID when matching. + * If not, return a TEE success (_noerr) or generic error (_error). + */ +TEE_Result sks2tee_noerr(uint32_t rv); +TEE_Result sks2tee_error(uint32_t rv); +uint32_t tee2sks_error(TEE_Result res); + +/* Id-to-string conversions when CFG_TEE_TA_LOG_LEVEL > 0 */ +const char *sks2str_attr(uint32_t id); +const char *sks2str_class(uint32_t id); +const char *sks2str_type(uint32_t id, uint32_t class); +const char *sks2str_key_type(uint32_t id); +const char *sks2str_boolprop(uint32_t id); +const char *sks2str_proc(uint32_t id); +const char *sks2str_proc_flag(uint32_t id); +const char *sks2str_slot_flag(uint32_t id); +const char *sks2str_token_flag(uint32_t id); +const char *sks2str_rc(uint32_t id); +const char *sks2str_skscmd(uint32_t id); + +#endif /*__CK_HELPERS_H*/ diff --git a/ta_services/secure_key_services/src/sub.mk b/ta_services/secure_key_services/src/sub.mk new file mode 100644 index 00000000000..bf561113cbe --- /dev/null +++ b/ta_services/secure_key_services/src/sub.mk @@ -0,0 +1,2 @@ +srcs-y += entry.c +srcs-y += sks_helpers.c diff --git a/ta_services/secure_key_services/src/user_ta_header_defines.h b/ta_services/secure_key_services/src/user_ta_header_defines.h new file mode 100644 index 00000000000..d234ce5a6a2 --- /dev/null +++ b/ta_services/secure_key_services/src/user_ta_header_defines.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2017-2018, Linaro Limited + */ + +#ifndef USER_TA_HEADER_DEFINES_H +#define USER_TA_HEADER_DEFINES_H + +#include + +#define TA_UUID TA_SKS_UUID + +#define TA_FLAGS (TA_FLAG_SINGLE_INSTANCE | \ + TA_FLAG_MULTI_SESSION | \ + TA_FLAG_EXEC_DDR | \ + TA_FLAG_INSTANCE_KEEP_ALIVE) + +#define TA_STACK_SIZE (2 * 1024) +#define TA_DATA_SIZE (16 * 1024) + +#define TA_CURRENT_TA_EXT_PROPERTIES \ + { "gp.ta.version", USER_TA_PROP_TYPE_U32, &(const uint32_t){ 0x0000 } } + +#endif /*USER_TA_HEADER_DEFINES_H*/ diff --git a/ta_services/secure_key_services/sub.mk b/ta_services/secure_key_services/sub.mk new file mode 100644 index 00000000000..ae78d611bad --- /dev/null +++ b/ta_services/secure_key_services/sub.mk @@ -0,0 +1,3 @@ +global-incdirs-y += include +global-incdirs-y += src +subdirs-y += src