From a149dde2bad3873737957469062af7b53cee0359 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 12 Jan 2023 19:29:47 +0100 Subject: [PATCH] E2EE API draft - Key wrapping API - Key agreement/derivation API - Updated encryption API doc Change-Id: Iaa7add5cf102679aa8ad9464fcbea38d52cf9c3f --- src/include/ckmc/ckmc-manager.h | 237 +++++++++++++++++++++++++++++++++++----- src/include/ckmc/ckmc-type.h | 56 +++++++++- 2 files changed, 258 insertions(+), 35 deletions(-) diff --git a/src/include/ckmc/ckmc-manager.h b/src/include/ckmc/ckmc-manager.h index 3797156..22c5918 100644 --- a/src/include/ckmc/ckmc-manager.h +++ b/src/include/ckmc/ckmc-manager.h @@ -875,35 +875,48 @@ int ckmc_remove_alias(const char *alias); /** * @brief Encrypts data using selected key and algorithm. + * * @since_tizen 3.0 + * * @remarks Key identified by @a key_alias should exist. - * @param[in] params Algorithm parameter list handle. See #ckmc_param_list_h and - * #ckmc_algo_type_e for details + * + * @param[in] params Algorithm parameter list handle. See #ckmc_param_list_h and #ckmc_algo_type_e + * for details. Supported algorithms: + * - #CKMC_ALGO_AES_CTR, + * - #CKMC_ALGO_AES_CBC, + * - #CKMC_ALGO_AES_GCM, + * - #CKMC_ALGO_AES_CFB, + * - #CKMC_ALGO_RSA_OAEP * @param[in] key_alias Alias of the key to be used for encryption * @param[in] password The password used in decrypting a key value \n - * If password of the policy is provided in ckmc_save_key(), the same - * password should be provided - * @param[in] decrypted Data to be encrypted. In case of AES algorithm there are no restrictions on the size of data, - * if S/W backend is used. If module uses TEE backend (since Tizen 5.0 on chosen images), - * maximum size of data is implementation-specific and at least 500 kB. - * For RSA the size must be smaller or equal to key size in bytes - 42. + * If password of the policy is provided in ckmc_save_key(), the same password + * should be provided + * @param[in] decrypted Data to be encrypted. In case of AES algorithm there are no restrictions on + * the size of data, if S/W backend is used. If module uses TEE backend (since + * Tizen 5.0 on chosen images), maximum size of data is implementation-specific + * and at least 500 kB. For RSA the size must be smaller or equal to key size + * in bytes - 42. * Example: for 1024 RSA key the maximum data size is 1024/8 - 42 = 86. - * @param[out] ppencrypted Encrypted data (some algorithms may return additional information embedded in encrypted data. - * AES GCM is an example) \n - * The caller is responsible for freeing @a encrypted with ckmc_buffer_free() - * @return @c 0 on success, - * otherwise a negative error value + * @param[out] ppencrypted Encrypted data (some algorithms may return additional information + * embedded in encrypted data. AES GCM is an example) \n + * The caller is responsible for freeing @a encrypted with + * ckmc_buffer_free() + * + * @return @c 0 on success, otherwise a negative error value * @retval #CKMC_ERROR_NONE Successful - * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid - * mandatory algorithm parameter or RSA data too long, decrypted = NULL, + * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid mandatory + * algorithm parameter or RSA data too long, decrypted = NULL, * ppencrypted = NULL) * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) * @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Key decryption failed because password is incorrect - * @retval #CKMC_ERROR_SERVER_ERROR Too big data size or unsupported GCM mode (32 and 64 bit tag lengths not supported on TEE backend) or internal error + * @retval #CKMC_ERROR_SERVER_ERROR Too big data size or unsupported GCM mode (32 and 64 bit tag + * lengths not supported on TEE backend) or internal error + * * @pre User is already logged in and the user key is already loaded into memory in plain text form. + * * @see ckmc_buffer_free() * @see ckmc_param_list_new() * @see ckmc_param_list_free() @@ -919,31 +932,47 @@ int ckmc_encrypt_data(ckmc_param_list_h params, const char *key_alias, const cha /** * @brief Decrypts data using selected key and algorithm. + * * @since_tizen 3.0 + * * @remarks Key identified by @a key_alias should exist. - * @param[in] params Algorithm parameter list handle. You should use the same parameters that were used for encryption. - * See #ckmc_param_list_h and #ckmc_algo_type_e for details + * + * @param[in] params Algorithm parameter list handle. You should use the same parameters that were + * used for encryption. See #ckmc_param_list_h and #ckmc_algo_type_e for details. + * Supported algorithms: + * - #CKMC_ALGO_AES_CTR, + * - #CKMC_ALGO_AES_CBC, + * - #CKMC_ALGO_AES_GCM, + * - #CKMC_ALGO_AES_CFB, + * - #CKMC_ALGO_RSA_OAEP * @param[in] key_alias Alias of the key to be used for encryption * @param[in] password The password used in decrypting a key value \n - * If password of the policy is provided in ckmc_save_key(), the same password should be provided - * @param[in] encrypted Data to be decrypted (some algorithms may require additional information embedded in encrypted data. AES GCM is an example) - * Since Tizen 5.0, on chosen images where module is using TEE backend, data size is limited to at least 500 kB - * (TEE implementation-specific). + * If password of the policy is provided in ckmc_save_key(), the same password + * should be provided + * @param[in] encrypted Data to be decrypted (some algorithms may require additional information + * embedded in encrypted data. AES GCM is an example) Since Tizen 5.0, on + * chosen images where module is using TEE backend, data size is limited to at + * least 500 kB (TEE implementation-specific). * @param[out] ppdecrypted Decrypted data \n - * The caller is responsible for freeing @a decrypted with ckmc_buffer_free() - * @return @c 0 on success, - * otherwise a negative error value + * The caller is responsible for freeing @a decrypted with + * ckmc_buffer_free() + * + * @return @c 0 on success, otherwise a negative error value * @retval #CKMC_ERROR_NONE Successful - * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid - * mandatory algorithm parameter, GCM tag authentication failed, key or data is wrong, - * in case of RSA key is wrong or data too long, encrypted = NULL, ppdecrypted = NULL) + * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid mandatory + * algorithm parameter, GCM tag authentication failed, key or + * data is wrong, in case of RSA key is wrong or data too + * long, encrypted = NULL, ppdecrypted = NULL) * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) * @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Key decryption failed because password is incorrect - * @retval #CKMC_ERROR_SERVER_ERROR Too big data size or unsupported GCM mode (32 and 64 bit tag lengths not supported on TEE backend) or internal error + * @retval #CKMC_ERROR_SERVER_ERROR Too big data size or unsupported GCM mode (32 and 64 bit tag + * lengths not supported on TEE backend) or internal error + * * @pre User is already logged in and the user key is already loaded into memory in plain text form. + * * @see ckmc_buffer_free() * @see ckmc_param_list_new() * @see ckmc_param_list_free() @@ -957,6 +986,156 @@ int ckmc_encrypt_data(ckmc_param_list_h params, const char *key_alias, const cha int ckmc_decrypt_data(ckmc_param_list_h params, const char *key_alias, const char *password, const ckmc_raw_buffer_s encrypted, ckmc_raw_buffer_s **ppdecrypted); +/** + * @brief Unwraps one key with another and stores it inside key manager. + * + * @since_tizen 7.5 + * + * @remarks The wrapping key must be either symmetric (#CKMC_KEY_AES) or private RSA + * (#CKMC_KEY_RSA_PRIVATE). + * @remarks key_type in @a wrapped_key may be set to #CKMC_KEY_NONE as an input. In such case the + * key type is determined inside key manager during storing keys. + * @remarks password in @a wrapped_key must be set to NULL. There's no need to additionally encrypt + * a wrapped key. + * @remarks If password in @a policy is provided, the stored key is additionally encrypted with it. + * @remarks If extractable in @a policy is set to false, the stored key may still be exported in a + * wrapped form. + * + * @param[in] params Algorithm parameter list handle. See #ckmc_param_list_h and #ckmc_algo_type_e + * for details. Supported algorithms: + * - #CKMC_ALGO_AES_CTR, + * - #CKMC_ALGO_AES_CBC, + * - #CKMC_ALGO_AES_GCM, + * - #CKMC_ALGO_AES_CFB, + * - #CKMC_ALGO_RSA_OAEP + * @param[in] wrapping_key_alias The name of the wrapping key. + * @param[in] wrapping_key_password An optional password of the wrapping key + * @param[in] alias The name of a key to be stored + * @param[in] wrapped_key The wrapped key to be unwrapped and stored + * @param[in] policy The policy about how to store a key securely + * + * @return @c 0 on success, otherwise a negative error value + * @retval #CKMC_ERROR_NONE Successful + * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid mandatory + * algorithm parameter, GCM tag authentication failed, + * @a wrapping_key_alias = NULL, @a alias = NULL, + * @a wrapped_key = NULL) + * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) + * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN @a wrapping_key_alias does not exist + * @retval #CKMC_ERROR_DB_ALIAS_EXISTS @a alias already exists + * @retval #CKMC_ERROR_INVALID_FORMAT The format of @a wrapped_key is not valid + * @retval #CKMC_ERROR_DB_ERROR Failed due to a database error + * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Wrapping key decryption failed because + * @a wrapping_key_password is incorrect + * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager + * @retval #CKMC_ERROR_SERVER_ERROR Unknown error + * + * @pre User is already logged in and the user key is already loaded into memory in plain text form. + * + * @see ckmc_export_wrapped_key() + * @see #ckmc_key_s + * @see #ckmc_param_list_h + * @see #ckmc_policy_s + */ +int ckmc_import_wrapped_key(const ckmc_param_list_h params, + const char *wrapping_key_alias, + const char *wrapping_key_password, + const char *alias, + const ckmc_key_s *wrapped_key, + const ckmc_policy_s policy); + + +/** + * @brief Wraps one key with another and returns it to the client. + * + * @since_tizen 7.5 + * + * @remarks The wrapping key must be either symmetric (#CKMC_KEY_AES) or public RSA + * (#CKMC_KEY_RSA_PUBLIC). + * + * @param[in] params Algorithm parameter list handle. See #ckmc_param_list_h and #ckmc_algo_type_e + * for details. Supported algorithms: + * - #CKMC_ALGO_AES_CTR, + * - #CKMC_ALGO_AES_CBC, + * - #CKMC_ALGO_AES_GCM, + * - #CKMC_ALGO_AES_CFB, + * - #CKMC_ALGO_RSA_OAEP + * @param[in] wrapping_key_alias The name of the wrapping key + * @param[in] wrapping_key_password An optional password of the wrapping key + * @param[in] alias The name of the key to be wrapped and exported + * @param[in] password An optional password used to decrypt the key pointed by @a alias + * @param[out] ppwrapped_key The wrapped key + * + * @return @c 0 on success, otherwise a negative error value + * @retval #CKMC_ERROR_NONE Successful + * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid mandatory + * algorithm parameter, GCM tag authentication failed, + * @a wrapping_key_alias = NULL, @a alias = NULL, + * @a wrapped_key = NULL, @a ppwrapped_key = NULL) + * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) + * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN @a wrapping_key_alias or @a alias does not exist + * @retval #CKMC_ERROR_DB_ERROR Failed due to a database error + * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Wrapping key decryption failed because + * @a wrapping_key_password is incorrect + * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager + * @retval #CKMC_ERROR_SERVER_ERROR Unknown error + * + * @pre User is already logged in and the user key is already loaded into memory in plain text form. + * + * @see ckmc_import_wrapped_key() + * @see #ckmc_key_s + * @see #ckmc_param_list_h + */ +int ckmc_export_wrapped_key(const ckmc_param_list_h params, + const char *wrapping_key_alias, + const char *wrapping_key_password, + const char *alias, + const char *password, + ckmc_key_s **ppwrapped_key); + + +/** + * @brief Derives a key from another key/secret and stores it inside key manager. + * + * @since_tizen 7.5 + * + * @remarks The derived key will be a symmetric one. It will be stored as a #CKMC_KEY_AES. + * + * @param[in] params Algorithm parameter list handle. See #ckmc_param_list_h and #ckmc_algo_type_e + * for details. Supported algorithms: + * - #CKMC_ALGO_KBKDF, + * - #CKMC_ALGO_ECDH, + * @param[in] secret_alias Alias of the secret/key to use as an input + * @param[in] secret_password Optional password of the secret/key used as an input + * @param[in] new_key_alias The name under which the derived key will be stored + * @param[in] new_key_policy Policy used to store the derived key + * + * @return @c 0 on success, otherwise a negative error value + * @retval #CKMC_ERROR_NONE Successful + * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid mandatory + * algorithm parameter, @a secret_alias = NULL, + * @a new_key_alias = NULL) + * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) + * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN @a secret_alias does not exist + * @retval #CKMC_ERROR_DB_ALIAS_EXISTS @a new_key_alias already exists + * @retval #CKMC_ERROR_DB_ERROR Failed due to a database error + * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager + * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Secret decryption failed because @a secret_password is + * incorrect + * @retval #CKMC_ERROR_SERVER_ERROR Unknown error + * + * @pre User is already logged in and the user key is already loaded into memory in plain text form. + * + * @see ckmc_key_derive_ecdh() + * @see #ckmc_param_list_h + * @see #ckmc_policy_s + */ +int ckmc_key_derive(const ckmc_param_list_h params, + const char *secret_alias, + const char *secret_password, + const char *new_key_alias, + ckmc_policy_s new_key_policy); + #ifdef __cplusplus } #endif diff --git a/src/include/ckmc/ckmc-type.h b/src/include/ckmc/ckmc-type.h index d047eaf..4038791 100644 --- a/src/include/ckmc/ckmc-type.h +++ b/src/include/ckmc/ckmc-type.h @@ -298,9 +298,39 @@ typedef enum __ckmc_param_name { CKMC_PARAM_ED_CTR_LEN, /**< integer - ctr length in bits*/ CKMC_PARAM_ED_AAD, /**< buffer */ CKMC_PARAM_ED_TAG_LEN, /**< integer - tag length in bits */ - CKMC_PARAM_ED_LABEL /**< buffer */ + CKMC_PARAM_ED_LABEL, /**< buffer */ + + CKMC_PARAM_KDF_PRF = 401, /**< integer - pseudo-random function number (see #ckmc_kdf_prf_e) */ + CKMC_PARAM_KDF_LEN, /**< integer - length of the derived key */ + + CKMC_PARAM_KBKDF_MODE, /**< integer - KDF mode number (see #ckmc_kbkdf_mode_e) */ + CKMC_PARAM_KBKDF_LABEL, /**< buffer - the purpose for the derived key */ + CKMC_PARAM_KBKDF_CONTEXT, /**< buffer - information related to the derived key */ + + CKMC_PARAM_ECDH_PUBKEY, /**< buffer - EC public key in DER form (see #ckmc_key_s) */ } ckmc_param_name_e; +/** + * @brief Enumeration for key derivation function pseudo-random function parameter + * @since_tizen 7.5 + * + * @see ckmc_key_derive() + * @see #ckmc_param_name_e + */ +typedef enum __ckmc_kdf_prf { + CKMC_KDF_PRF_HMAC_SHA256 = 1, /**< HMAC SHA256 */ +} ckmc_kdf_prf_e; + +/** + * @brief Enumeration for key based key derivation function mode + * @since_tizen 7.5 + * + * @see ckmc_key_derive() + * @see #ckmc_param_name_e + */ +typedef enum __ckmc_kbkdf_mode { + CKMC_KBKDF_MODE_COUNTER = 1, /**< KBKDF counter mode */ +} ckmc_kbkdf_mode_e; /** * @brief Algorithm parameter list handle. @@ -353,11 +383,25 @@ typedef enum __ckmc_algo_type { - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_AES_CFB(mandatory), - CKMC_PARAM_ED_IV = 16-byte initialization vector(mandatory) */ - CKMC_ALGO_RSA_OAEP /**< RSA-OAEP algorithm - Supported parameters: - - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_RSA_OAEP(required), - - CKMC_PARAM_ED_LABEL = label to be associated with the message - (optional, not supported at the moment) */ + CKMC_ALGO_RSA_OAEP, /**< RSA-OAEP algorithm + Supported parameters: + - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_RSA_OAEP(required), + - CKMC_PARAM_ED_LABEL = label to be associated with the message + (optional, not supported at the moment) */ + + CKMC_ALGO_KBKDF, /**< Key based key derivation algorithm + Supported parameters (all are required): + - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_KBKDF, + - CKMC_PARAM_KDF_PRF = pseudo-random function (see #ckmc_kdf_prf_e), + - CKMC_PARAM_KBKDF_MODE = KDF mode (see #ckmc_kbkdf_mode_e), + - CKMC_PARAM_KBKDF_LABEL = the purpose for the derived key, + - CKMC_PARAM_KBKDF_CONTEXT = information related to the derived key, + - CKMC_PARAM_KDF_LEN = length of the derived key */ + + CKMC_ALGO_ECDH, /**< ECDH shared secret key agreement protocol + Supported parameters (all are required): + - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_ECDH, + - CKMC_PARAM_ECDH_PUBKEY = peer's public key (see #ckmc_key_s) */ } ckmc_algo_type_e; /** -- 2.7.4