#include "../../../os/arch/arm/src/s5j/sss/isp_driver_error.h"
#include "../../../os/arch/arm/src/s5j/sss/isp_oid.h"
+#include "../../../os/arch/arm/src/s5j/sss/isp_driver_aes_securekey.h"
+#include "../../../os/arch/arm/src/s5j/sss/isp_driver_ecdsa_encryptedkey.h"
+#include "../../../os/arch/arm/src/s5j/sss/isp_driver_dh_encryptedkey.h"
+#include "see_cert.h"
+
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
*/
//#define SEE_API_DEBUG
//#define SEE_CHECK_SSS_BUSY
-//#define SEE_SUPPORT_USERCERT
-//#define SEE_SUPPORT_USERKEY
/*
* Return values
#define ISP_CHECKBUSY()
#endif
+#ifdef CONFIG_SUPPORT_FULL_SECURITY
+
+/* Key type */
+#define AES_KEY 0x010000
+#define HMAC_KEY 0x020000
+#define RSA_KEY 0x030000
+#define ECC_KEY 0x040000
+
+#define AES_KEY_128 ((AES_KEY) | (0x1))
+#define AES_KEY_256 ((AES_KEY) | (0x2))
+#define HMAC_KEY_128 ((HMAC_KEY) | (0x1))
+#define HMAC_KEY_256 ((HMAC_KEY) | (0x2))
+#define RSA_KEY_1024 ((RSA_KEY) | (0xB1))
+#define RSA_KEY_2048 ((RSA_KEY) | (0xB2))
+
+#define ECC_KEY_BP256 ((ECC_KEY) | (0x53))
+
+#define ECC_KEY_NIST192 ((ECC_KEY) | (0x21))
+#define ECC_KEY_NIST224 ((ECC_KEY) | (0x22))
+#define ECC_KEY_NIST256 ((ECC_KEY) | (0x23))
+#define ECC_KEY_NIST384 ((ECC_KEY) | (0x24))
+#define ECC_KEY_NIST512 ((ECC_KEY) | (0x25))
+
+/* cert type */
+#define CERT_DER 0x01
+#define CERT_PEM 0x02
+
+/* index */
+#define MAX_DATA_INDEX 32
+#define MIN_DATA_INDEX 0
+#define MAX_KEY_INDEX 8
+#define MIN_KEY_INDEX 0
+#define MAX_CERT_INDEX 6
+#define MIN_CERT_INDEX 0
+
+#define MAX_DATA_SIZE (208)
+#define SEE_BUF_MAX_SIZE (4096)
+
+#define SEE_IOTIVITY_MAXSIZE (SEE_IOTIVITY_MAX_SLOT_SIZE * SEE_IOTIVITY_SLOT_NUM)
+#define SEE_IOTIVITY_MAX_SLOT_SIZE (SEE_BUF_MAX_SIZE - 8)
+#define SEE_IOTIVITY_SLOT_NUM (2)
+#define SEE_IOTIVITY_SLOT_START (6)
+#define SEE_IOTIVITY_SLOT_END (7)
+#define SEE_IOTIVITY_DATAMASK (0xFFFFFFFF)
+
+struct iotivity_data {
+ unsigned int size; /* Size field, this field indicate size of data */
+ unsigned int mask; /* Masking field, it should be set 0xFFFFFFFF */
+ unsigned char data[SEE_IOTIVITY_MAXSIZE]; /* Data field */
+};
+
+/**
+ * @brief structure to contain options for making cert.
+ */
+struct cert_opt {
+ unsigned int cert_index; ///< certificate index
+ unsigned int issuer_key_index; ///< index number of the issuer key
+ unsigned int subject_key_index; ///< index number of the subject key
+ unsigned int subject_pub_keylen; ///< publickey length
+ unsigned char *subject_pub_key; ///< publickey data
+ const char *subject_name; ///< subject name for certificate
+ const char *issuer_name; ///< issuer name for certificate
+ const char *not_before; ///< validity period not before
+ const char *not_after; ///< validity period not after
+ const unsigned char *subject_pwd; ///< password for the subject key file
+ const char *serial; ///< serial number string
+ unsigned char key_usage; ///< key usage flags
+ unsigned char ns_cert_type; ///< NS cert type
+ int is_ca; ///< is a CA certificate
+ int max_pathlen; ///< maximum CA path length
+ int selfsign;
+};
+#endif
/****************************************************************************
* Public types
****************************************************************************/
*/
int see_free(void);
-/****************************************************************************
- * Name: Authentication
+/**
+ * @brief Generate random number
*
- * Description:
+ * @param[out] data Random number.
+ * @param[in] len Random size (1 ~ 256).
*
- ****************************************************************************/
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
int see_generate_random(unsigned int *data, unsigned int len);
+
+/**
+ * @brief Get certificate in Secure Storage
+ *
+ * @param[out] cert Cert data.
+ * @param[out] cert_len Cert length (1 ~ 4096).
+ * @param[in] cert_index Index number of Secure Storage cert slot (0 ~ 5).
+ * @param[in] cert_type Signature algorithm type (not used, CERT_PEM, CERT_DER)
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
int see_get_certificate(unsigned char *cert, unsigned int *cert_len, unsigned int cert_index, unsigned int cert_type);
-int see_set_certificate(unsigned char *cert, unsigned int cert_len, unsigned int cert_index, unsigned int cert_type);
+
+/**
+ * @brief Get ECDSA signature from hash.
+ * Should set the target key using see_setup_key in Key Manager before this API.
+ *
+ * @param[in/out] ecc_sign ECDSA signature.
+ * @param[in] hash Hashed data for making signature.
+ * @param[in] hash_len Length of hashed data.
+ * @param[in] key_index Index number of Secure Storage for user key of ECDSA.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
int see_get_ecdsa_signature(struct sECC_SIGN *ecc_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index);
-int see_verify_ecdsa_signature(struct sECC_SIGN *ecc_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index);
-int see_get_hash(struct sHASH_MSG *h_param, unsigned char *hash, unsigned int mode);
+
+/**
+ * @brief Compute ecdh shared secret. P = d * Q
+ *
+ * @param[in] ecc_pub Structure for public key value.
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[out] output Shared secret value.
+ * @param[out] olen Length of shared secret value.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
int see_compute_ecdh_param(struct sECC_KEY *ecc_pub, unsigned int key_index, unsigned char *output, unsigned int *olen);
+#ifdef CONFIG_SUPPORT_FULL_SECURITY
+/**
+ * @brief Set certificate in Secure Storage
+ *
+ * @param[out] cert Cert data.
+ * @param[in] cert_len Cert length (1 ~ 4096).
+ * @param[in] cert_index Index number of Secure Storage cert slot (0 ~ 5)
+ * @param[in] cert_type Signature algorithm type (not used, CERT_PEM, CERT_DER).
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_set_certificate(unsigned char *cert, unsigned int cert_len, unsigned int cert_index, unsigned int cert_type);
+
+/****************************************************************************
+ * Name: Secure Storage
+ *
+ * Description:
+ * - Data, Credential (exclude certificates) and Keys can be stored
+ * in Secure Storage.
+ * - Limitation
+ * a. Each File size : 208 Byte
+ * b. The number of all files : 32 ea
+ *
+ ****************************************************************************/
+
+/**
+ * @brief Write data in secure storage.
+ *
+ * @param[in] data Data.
+ * @param[in] data_len Length of data (1 ~ 208).
+ * @param[in] key_index Index number of SecureStorage data slot (0 ~ 31).
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_write_secure_storage(unsigned char *data, unsigned int data_len, unsigned int index);
+
+/**
+ * @brief Read data from secure storage.
+ *
+ * @param[out] data Data buf.
+ * @param[in/out] data_len Sizeof buf or Length of data.
+ * @param[in] key_index Index number of SecureStorage data slot.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_read_secure_storage(unsigned char *data, unsigned int *data_len, unsigned int index);
+
+/**
+ * @brief Get DA public key in Secure Storage.
+ *
+ * @param[out] key_der Key data.
+ * @param[out] key_len Key length.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_get_publickey(unsigned char *key_der, unsigned int *key_len);
+
+/**
+ * @brief Get ECC public key in Secure Storage.
+ *
+ * @param[out] ecc_pub Publickey buffer.
+ * @param[in] key_index Index number of SecureStorage key slot (0 ~ 7 or factory keyid).
+ * @param[in] object_id Ecc curve id. (reference : isp_oid.h)
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_get_ecc_publickey(struct sECC_KEY *ecc_pub, unsigned int key_index, unsigned int object_id);
+
+/****************************************************************************
+ * Name: Key Manager
+ *
+ * Description:
+ * - Manage symmetric and asymmetric keys.
+ * - Managed keys is not exposed to USER SPACE
+ *
+ ****************************************************************************/
+
+/**
+ * @brief Generate symmetric/asymmetric key and store it in Secure Storage.
+ *
+ * @param[in] key_type Key algorithm type (KEY_TYPE | OBJECT_ID).
+ * @param[in] key_index Index number of SecureStorage key slot (0 ~ 7).
+ * @param[in] key_len Length of key.
+ * @param[in] pukey_e Generate exponent value When it is 0.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_generate_key(unsigned int key_type, unsigned int key_index, unsigned int key_len, unsigned int pukey_e);
+
+/**
+ * @brief Set a key that was generated from external
+ *
+ * @param[in] key_der Key data.
+ * @param[in] key_len Key length.
+ * @param[in] key_type Key algorithm type.
+ * @param[in] key_index Index number of SecureStorage key slot.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_setup_key(unsigned char *key_der, unsigned int key_len, unsigned int key_type, unsigned int key_index);
+
+/**
+ * @brief Remove a key in Secure Storage
+ *
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[in] key_type Key algorithm type.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_remove_key(unsigned int key_index, unsigned int key_type);
+
+/****************************************************************************
+ * Name: Encrypt and Decrypt
+ *
+ * Description:
+ * - Data can be encrypted and decrypted using a key in secure storage
+ *
+ ****************************************************************************/
+
+/**
+ * @brief Encrypt using AES key that was stored in Secure Storage.
+ *
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[in/out] aes_param All parameter about aes except key.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_aes_encrypt(unsigned int key_index, struct sAES_PARAM *aes_param);
+
+/**
+ * @brief Decrypt using AES key that was stored in Secure Storage.
+ *
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[in/out] aes_param All parameter about aes except key.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_aes_decrypt(unsigned int key_index, struct sAES_PARAM *aes_param);
+
+/**
+ * @brief Hash with message authentication code.
+ *
+ * @param[in/out] hmac_msg Structure contains msg address and length.
+ * @param[out] output Generic HMAC checksum result.
+ * @param[in] object_id Hash id.
+ * @param[in] key_index Index number of SecureStorage key slot.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_get_hmac(struct sHMAC_MSG *hmac_msg, unsigned char *output, unsigned int object_id, unsigned int key_index);
+
+/**
+ * @brief Hash function.
+ *
+ * @param[in/out] h_param Structure contains msg address and length.
+ * @param[out] hash Hashed data output.
+ * @param[in] mode Selected hash algorithm id.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_get_hash(struct sHASH_MSG *h_param, unsigned char *hash, unsigned int mode);
+
+/**
+ * @brief Generate DH parameter and store secret in secure storage.
+ *
+ * @param[out] d_param DH param struct, It is configured as p, q, g number.
+ * @param[in] key_index Index number of SecureStorage key slot.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_generate_dhm_params(struct sDH_PARAM *d_param, unsigned int key_index);
+
+/**
+ * @brief Compute shared secret value = GXY ((G^Y)^X mod P).
+ *
+ * @param[out] d_param DH param struct, It is configured as p, q, g number.
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[out] output Shared secret value (GXY).
+ * @param[out] olen Length of shared secret value.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_compute_dhm_param(struct sDH_PARAM *d_param, unsigned int key_index, unsigned char *output, unsigned int *olen);
+
+/**
+ * @brief Encrypt using RSA key that was stored in Secure Storage.
+ *
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[in] pad_type Padding type.
+ * @param[out] output Plain text output.
+ * @param[out] outlen Length of output.
+ * @param[in] input Cipher text input.
+ * @param[in] inlen Length of cipher text input.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_rsa_decryption(unsigned int key_index, unsigned int pad_type, unsigned char *output, unsigned int *outlen, unsigned char *input, unsigned int inlen);
+
+/**
+ * @brief Decrypt using RSA key that was stored in Secure Storage.
+ *
+ * @param[in] key_index Index number of SecureStorage key slot.
+ * @param[in] pad_type Padding type.
+ * @param[out] output Cipher text output.
+ * @param[out] outlen Length of output.
+ * @param[in] input Plain text input.
+ * @param[in] inlen Length of cipher text input.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_rsa_encryption(unsigned int key_index, unsigned int pad_type, unsigned char *output, unsigned int *outlen, unsigned char *input, unsigned int inlen);
+
+/**
+ * @brief Get RSA signature from hash.
+ * Should set the target key using see_setup_key in Key Manager before this API.
+ *
+ * @param[in/out] rsa_sign RSA signature.
+ * @param[in] hash Hashed data for making signature.
+ * @param[in] hash_len Length of hashed data.
+ * @param[in] key_index Index number of Secure Storage for user key of RSA.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_get_rsa_signature(struct sRSA_SIGN *rsa_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index);
+
+/**
+ * @brief Verify RSA signature.
+ * Should set the target key using see_setup_key in Key Manager before this API.
+ *
+ * @param[in/out] rsa_sign RSA signature.
+ * @param[in] hash Hashed data.
+ * @param[in] hash_len Length of hashed data.
+ * @param[in] key_index Index number of Secure Storage for user key of RSA.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_verify_rsa_signature(struct sRSA_SIGN *rsa_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index);
+
+/**
+ * @brief Verify ECDSA signature.
+ * Should set the target key using see_setup_key in Key Manager before this API.
+ *
+ * @param[in/out] ecc_sign ECDSA signature.
+ * @param[in] hash Hashed data.
+ * @param[in] hash_len Length of hashed data.
+ * @param[in] key_index Index number of Secure Storage for user key of ECDSA.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_verify_ecdsa_signature(struct sECC_SIGN *ecc_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index);
+
+/****************************************************************************
+ * Name: Iotivity Storage
+ *
+ * Description:
+ * - Data of large size for Iotivity can be stored in Secure Storage.
+ * - Limitation
+ * a. File size : 8 Kbyte
+ *
+ ****************************************************************************/
+/**
+ * @brief Write data in secure storage.
+ *
+ * @param[in] buf Data.
+ * @param[in] buflen Length of data (1 ~ 8176 byte).
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_write_iotivity_storage(unsigned char *buf, unsigned int buflen);
+
+/**
+ * @brief Read data from secure storage.
+ *
+ * @param[out] buf Data buf.
+ * @param[in] buflen Sizeof buf or Length of data.
+ * @param[out] olen Data size.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_read_iotivity_storage(unsigned char *buf, unsigned int buflen, unsigned int *olen);
+
+/**
+ * @brief Generate certificate and store the generated certificate in Secure Storage.
+ * Only support RSA signed certificate.
+ *
+ * @param[in] opt Options for generate certificate.
+ * Please check cert_opt structure before using it.
+ * @param[out] out_buf Cert data (PEM).
+ * @param[out] out_buflen Cert length.
+ *
+ * @return On success, SEE_OK will be returned.
+ * On failure, SEE_ERROR or SEE_INVALID_INPUT_PARAMS will be returned.
+ */
+int see_generate_certificate(struct cert_opt opt, unsigned char *out_buf, unsigned int *out_buflen);
+#endif
+
/****************************************************************************
* Name: Internal functions
*
#include "mbedtls/see_api.h"
+#ifdef CONFIG_SUPPORT_FULL_SECURITY
+#include "mbedtls/pk.h"
+#include "mbedtls/pem.h"
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/pk_internal.h"
+#endif
+
see_mutex_t m_handler = { PTHREAD_MUTEX_INITIALIZER, 0 };
int see_init(void)
}
ISP_CHECKBUSY();
-#if defined(SEE_SUPPORT_USERCERT)
+#if defined(CONFIG_SUPPORT_FULL_SECURITY)
if (cert_index < SEE_MAX_CERT_INDEX) {
if ((r = isp_read_cert(buf, &buf_len, cert_index)) != 0) {
isp_clear(0);
}
} else
#endif
- if ((r = isp_get_factorykey_data(buf, &buf_len, cert_index)) != 0) {
- isp_clear(0);
- r = SEE_READ_CERT_ERROR;
- if (see_mutex_unlock(&m_handler) != SEE_OK) {
- r = SEE_MUTEX_UNLOCK_ERROR;
+ {
+ r = isp_get_factorykey_data(buf, &buf_len, cert_index);
+ if (r != 0) {
+ isp_clear(0);
+ r = SEE_READ_CERT_ERROR;
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ r = SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_read_cert fail %x\n", r);
+ goto get_cert_exit;
}
- SEE_DEBUG("isp_read_cert fail %x\n", r);
- goto get_cert_exit;
}
if (see_mutex_unlock(&m_handler) != SEE_OK) {
return SEE_INVALID_KEY_INDEX;
}
- SEE_DEBUG("%s : key_index : %d \n", __func__, key_index);
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
if (see_mutex_lock(&m_handler) != SEE_OK) {
return SEE_MUTEX_LOCK_ERROR;
int see_check_certindex(unsigned int index)
{
-#ifdef SEE_SUPPORT_USERCERT
+#ifdef CONFIG_SUPPORT_FULL_SECURITY
if (index >= MIN_CERT_INDEX && index < SEE_MAX_CERT_INDEX) {
return SEE_OK;
}
int see_check_keyindex(unsigned int index)
{
-#ifdef SEE_SUPPORT_USERKEY
+#ifdef CONFIG_SUPPORT_FULL_SECURITY
if (index < SEE_MAX_KEY_INDEX) {
return SEE_OK;
}
}
return SEE_INVALID_KEY_INDEX;
}
+
+#ifdef CONFIG_SUPPORT_FULL_SECURITY
+int see_set_certificate(unsigned char *cert, unsigned int cert_len, unsigned int cert_index, unsigned int cert_type)
+{
+
+ int r;
+ (void)cert_type;
+
+ if (cert == NULL || cert_len == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ if (cert_index >= MIN_CERT_INDEX && cert_index < MAX_CERT_INDEX) {
+ r = isp_write_cert(cert, cert_len, cert_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_write_cert fail %x\n", r);
+ return SEE_ERROR;
+ }
+ } else {
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("wrong index %d\n", cert_index);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_write_secure_storage(unsigned char *data, unsigned int data_len, unsigned int index)
+{
+ int r;
+
+ if (data == NULL || !data_len) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (index >= MAX_DATA_INDEX || data_len > MAX_DATA_SIZE) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_write_storage(data, data_len, index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_write_storage fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_read_secure_storage(unsigned char *data, unsigned int *data_len, unsigned int index)
+{
+ int r;
+ unsigned int t_size;
+ unsigned char *t_buf;
+
+ if (data == NULL || !data_len) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (index >= MAX_DATA_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ t_buf = malloc(MAX_DATA_SIZE);
+
+ if (t_buf == NULL) {
+ return SEE_ALLOC_ERROR;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_read_storage(t_buf, &t_size, index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_read_storage fail %x\n", r);
+ free(t_buf);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ if (t_size > *data_len) {
+ free(t_buf);
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ memcpy(data, t_buf, t_size);
+ *data_len = t_size;
+
+ free(t_buf);
+
+ return SEE_OK;
+}
+
+int see_get_publickey(unsigned char *key_der, unsigned int *key_len)
+{
+ int r = 0;
+
+ if (key_der == NULL || key_len == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_get_factorykey_data(key_der, key_len, FACTORYKEY_ARTIK_DEVICE);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_read_publickey fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_get_ecc_publickey(struct sECC_KEY *ecc_pub, unsigned int key_index, unsigned int object_id)
+{
+ unsigned int r;
+
+ if (ecc_pub == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+ ISP_CHECKBUSY();
+ r = isp_ecdsa_get_publickey_securekey(ecc_pub, key_index, object_id);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_get_ecdsa_pubkey fail %x\n", r);
+ return SEE_ERROR;
+ }
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_generate_key(unsigned int key_type, unsigned int key_index, unsigned int key_len, unsigned int pukey_e)
+{
+ int r = 0;
+ unsigned int key = key_type & 0xFF0000;
+ unsigned int object_id = key_type & 0xFF;
+
+ if (key_index >= MAX_KEY_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ switch (key) {
+ case AES_KEY:
+ ISP_CHECKBUSY();
+ r = isp_aes_generate_key_securekey(key_len, key_index);
+ break;
+ case HMAC_KEY:
+ ISP_CHECKBUSY();
+ r = isp_hmac_generate_key_securekey(key_len, key_index);
+ break;
+ case RSA_KEY:
+ ISP_CHECKBUSY();
+ r = isp_rsa_generate_key_securekey(key_index, object_id, pukey_e);
+ break;
+ case ECC_KEY:
+ ISP_CHECKBUSY();
+ r = isp_ecdsa_generate_key_securekey(key_index, object_id);
+ break;
+ default:
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ if (r) {
+ SEE_DEBUG("isp_generate_key fail %x %x %x\n", r, key, object_id);
+ isp_clear(0);
+ return SEE_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_setup_key(unsigned char *key_der, unsigned int key_len, unsigned int key_type, unsigned int key_index)
+{
+ int r;
+
+ if (key_der == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (key_index >= MAX_KEY_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d key_type %d\n", __func__, key_index, key_type);
+
+ if (key_type < SECURE_STORAGE_TYPE_KEY_AES || key_type > SECURE_STORAGE_TYPE_KEY_ECC) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_set_securekey(key_der, key_len, key_type, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ SEE_DEBUG("isp_set_userkey fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_remove_key(unsigned int key_index, unsigned int key_type)
+{
+ int r;
+
+ if (key_index >= MAX_KEY_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (key_type < SECURE_STORAGE_TYPE_KEY_AES || key_type > SECURE_STORAGE_TYPE_KEY_ECC) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_remove_key(key_type, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ SEE_DEBUG("isp_remove_key fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_aes_encrypt(unsigned int key_index, struct sAES_PARAM *aes_param)
+{
+ int r;
+
+ if (aes_param == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_aes_encrypt_securekey(aes_param, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ SEE_DEBUG("isp_aes_encrypt fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_aes_decrypt(unsigned int key_index, struct sAES_PARAM *aes_param)
+{
+ int r;
+
+ if (aes_param == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_aes_decrypt_securekey(aes_param, key_index);
+ if (r != 0) {
+ isp_clear(0);
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_aes_decrypt fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_get_hmac(struct sHMAC_MSG *hmac_msg, unsigned char *output, unsigned int object_id, unsigned int key_index)
+{
+ int r;
+
+ if (!hmac_msg || !output) {
+ return SEE_ERROR;
+ }
+
+ if (key_index >= MAX_KEY_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_hmac_securekey(output, hmac_msg, object_id, key_index);
+ if (r != 0) {
+ isp_clear(0);
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_hmac fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_get_hash(struct sHASH_MSG *h_param, unsigned char *hash, unsigned int mode)
+{
+ int r;
+
+ if (hash == NULL || h_param == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s\n", __func__);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_hash(hash, h_param, mode);
+ if (r != 0) {
+ isp_clear(0);
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_hash fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+/* Generate G, P, GX (G^X mod P) */
+int see_generate_dhm_params(struct sDH_PARAM *d_param, unsigned int key_index)
+{
+ int r;
+
+ if (d_param == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (key_index >= MAX_KEY_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_dh_generate_keypair_userparam_securestorage(d_param, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_generate_dh_param fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+/* Compute shared secret key = GXY ((G^Y)^X mod P) */
+int see_compute_dhm_param(struct sDH_PARAM *d_param, unsigned int key_index, unsigned char *output, unsigned int *olen)
+{
+ int r;
+
+ if (d_param == NULL || output == NULL || olen == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (key_index >= MAX_KEY_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_dh_compute_shared_secret_securekey(output, olen, *d_param, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_compute_dh_param fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_rsa_decryption(unsigned int key_index, unsigned int pad_type, unsigned char *output, unsigned int *outlen, unsigned char *input, unsigned int inlen)
+{
+ int r;
+
+ if (input == NULL || output == NULL || inlen == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (pad_type != MBEDTLS_RSA_PKCS_V15) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_rsa_decrypt_securekey(output, outlen, input, inlen, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_rsa_decrypt fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_rsa_encryption(unsigned int key_index, unsigned int pad_type, unsigned char *output, unsigned int *outlen, unsigned char *input, unsigned int inlen)
+{
+ int r;
+
+ if (input == NULL || output == NULL || inlen == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (pad_type != MBEDTLS_RSA_PKCS_V15) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_rsa_encrypt_securekey(output, outlen, input, inlen, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_rsa_encrypt fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_get_rsa_signature(struct sRSA_SIGN *rsa_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index)
+{
+ int r;
+
+ if (rsa_sign == NULL || hash == NULL || hash_len == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_rsa_sign_md_securekey(rsa_sign, hash, hash_len, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_rsa_sign fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_verify_rsa_signature(struct sRSA_SIGN *rsa_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index)
+{
+ int r;
+
+ if (rsa_sign == NULL || hash == NULL || hash_len == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_rsa_verify_md_securekey(rsa_sign, hash, hash_len, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_rsa_verify fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_verify_ecdsa_signature(struct sECC_SIGN *ecc_sign, unsigned char *hash, unsigned int hash_len, unsigned int key_index)
+{
+ int r;
+
+ if (ecc_sign == NULL || hash == NULL || hash_len == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_check_keyindex(key_index)) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ SEE_DEBUG("%s : key_index : %d\n", __func__, key_index);
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_ecdsa_verify_md_securekey(ecc_sign, hash, hash_len, key_index);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_ecdsa_verify fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+int see_write_iotivity_storage(unsigned char *buf, unsigned int buflen)
+{
+ int r = SEE_OK;
+ unsigned int size = 0;
+ unsigned int index = SEE_IOTIVITY_SLOT_START;
+ unsigned char *pbuf = buf;
+ struct iotivity_data *input;
+
+ /* 0. check input params */
+ if (buf == NULL || buflen == 0) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (buflen > SEE_IOTIVITY_MAXSIZE) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ input = malloc(sizeof(struct iotivity_data));
+ if (input == NULL) {
+ return SEE_ALLOC_ERROR;
+ }
+
+ /* 1. lock mutex */
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+
+ /* 2. write */
+ while (buflen && r == SEE_OK) {
+ size = (buflen > SEE_IOTIVITY_MAX_SLOT_SIZE) ? (SEE_IOTIVITY_MAX_SLOT_SIZE) : (buflen);
+
+ input->size = buflen;
+ input->mask = SEE_IOTIVITY_DATAMASK;
+ memcpy(&input->data, pbuf, size);
+
+ r = isp_write_cert((unsigned char *)input, size + 8, index++);
+ if (r) {
+ SEE_DEBUG("isp_write_cert fail %d\n", r);
+ }
+
+ buflen -= size;
+ pbuf += size;
+ }
+
+ /* reset sss status */
+ if (r) {
+ isp_clear(0);
+ }
+
+ /* unlock mutex */
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ memset(input, 0, sizeof(struct iotivity_data));
+ free(input);
+
+ return r;
+}
+
+int see_read_iotivity_storage(unsigned char *buf, unsigned int buflen, unsigned int *olen)
+{
+ int r;
+ int index = SEE_IOTIVITY_SLOT_START;
+ int remains = SEE_IOTIVITY_SLOT_NUM;
+ unsigned int readlen = SEE_BUF_MAX_SIZE;
+ unsigned char *pbuf = buf;
+ struct iotivity_data *output;
+
+ /* 0. check input params */
+ if (buf == NULL || !buflen) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ output = malloc(sizeof(struct iotivity_data));
+ if (output == NULL) {
+ return SEE_ALLOC_ERROR;
+ }
+
+ *olen = 0;
+
+ /* 1. lock mutex */
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+
+ /* 2. read */
+ while (remains-- > 0) {
+ memset(output, 0, sizeof(struct iotivity_data));
+
+ r = isp_read_cert((unsigned char *)output, &readlen, index++);
+ if (r) {
+ SEE_DEBUG("isp_read_cert fail %d\n", r);
+ }
+
+ /* Error1. No data */
+ if (readlen == 0) {
+ remains = 0;
+ continue;
+ }
+
+ /* Error2. Invalid mask or size */
+ if (output->mask != SEE_IOTIVITY_DATAMASK || output->size > SEE_IOTIVITY_MAXSIZE) {
+ remains = 0;
+ continue;
+ }
+
+ /* Error3. Input buffer is too small */
+ if (buflen < *olen + readlen - 8) {
+ free(output);
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ return SEE_INVALID_BUFFER_SIZE;
+ }
+
+ memcpy(pbuf + *olen, output->data, readlen - 8);
+ *olen += readlen - 8;
+
+ /* No more data */
+ if (output->size <= SEE_IOTIVITY_MAX_SLOT_SIZE) {
+ remains = 0;
+ }
+ }
+
+ /* reset sss status */
+ if (r) {
+ isp_clear(0);
+ }
+
+ /* 3. unlock mutex */
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ free(output);
+ return r;
+}
+
+int see_generate_certificate(struct cert_opt opt, unsigned char *out_buf, unsigned int *out_buflen)
+{
+ int r = 0;
+ int cert_len, cert_buflen = 2500;
+ unsigned int subject_key_len = 1024;
+ unsigned char *subject_key_buf = NULL;
+ unsigned char *cert_buf = NULL;
+
+ mbedtls_pk_context subject_key;
+ mbedtls_pk_context issuer_key;
+ mbedtls_x509write_cert crt;
+ mbedtls_mpi serial;
+
+ if (opt.cert_index < MIN_CERT_INDEX || opt.cert_index >= MAX_CERT_INDEX) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (out_buf == NULL || out_buflen == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ mbedtls_pk_init(&subject_key);
+ mbedtls_pk_init(&issuer_key);
+
+ mbedtls_x509write_crt_init(&crt);
+ mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256);
+ mbedtls_mpi_init(&serial);
+
+ mbedtls_pk_setup(&issuer_key, &mbedtls_rsa_info);
+
+ /* Check mandatory params */
+ if (!opt.subject_key_index && !opt.issuer_key_index) {
+ opt.subject_key_index = SEE_SUBJECT_KEY_INDEX;
+ opt.issuer_key_index = SEE_ISSUER_KEY_INDEX;
+ }
+
+ /* Check optional params */
+ if (!opt.issuer_name || !opt.subject_name || !opt.not_before || !opt.not_after) {
+ opt.issuer_name = SEE_ISSUER_NAME;
+ opt.subject_name = SEE_SUBJECT_NAME;
+ opt.not_before = SEE_NOT_BEFORE;
+ opt.not_after = SEE_NOT_AFTER;
+ opt.serial = SEE_SERIAL;
+ opt.is_ca = SEE_IS_CA;
+ opt.max_pathlen = SEE_MAX_PATHLEN;
+ opt.key_usage = SEE_KEY_USAGE;
+ opt.ns_cert_type = SEE_NS_CERT_TYPE;
+ }
+
+ subject_key_buf = malloc(subject_key_len);
+ cert_buf = malloc(cert_buflen);
+
+ if (subject_key_buf == NULL) {
+ goto see_exit;
+ }
+ if (cert_buf == NULL) {
+ goto see_exit;
+ }
+
+ /*
+ * 0. Parse serial to MPI
+ */
+ r = mbedtls_mpi_read_string(&serial, 10, opt.serial);
+ if (r != 0) {
+ SEE_DEBUG("mpi_read_string returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+
+ /*
+ * 1.0 Load subject key
+ */
+ if (opt.subject_pub_key) {
+ r = mbedtls_pk_parse_public_key(&subject_key, opt.subject_pub_key, opt.subject_pub_keylen);
+ if (r != 0) {
+ SEE_DEBUG("pk_parse_key returned -0x%x\n\n", -r);
+ goto see_exit;
+ }
+ } else {
+ r = isp_get_factorykey_data(subject_key_buf, &subject_key_len, FACTORYKEY_ARTIK_DEVICE);
+ if (r != 0) {
+ SEE_DEBUG("see_get_publickey returned %x\n\n", r);
+ goto see_exit;
+ }
+
+ r = mbedtls_pk_parse_public_key(&subject_key, subject_key_buf, subject_key_len);
+ if (r != 0) {
+ SEE_DEBUG("pk_parse_key returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+ }
+
+ /*
+ * 1.1 Set key
+ */
+ if (subject_key.pk_info->type == MBEDTLS_PK_RSA) {
+ ((mbedtls_rsa_context *)(subject_key.pk_ctx))->key_index = opt.subject_key_index;
+ }
+ if (issuer_key.pk_info->type == MBEDTLS_PK_RSA) {
+ ((mbedtls_rsa_context *)(issuer_key.pk_ctx))->key_index = opt.issuer_key_index;
+ }
+ mbedtls_x509write_crt_set_subject_key(&crt, &subject_key);
+ crt.issuer_key = &issuer_key;
+
+ /*
+ * 2.0 Setting the certificate value.
+ */
+ r = mbedtls_x509write_crt_set_subject_name(&crt, opt.subject_name);
+ if (r != 0) {
+ SEE_DEBUG("x509write_crt_set_subject_name returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+
+ r = mbedtls_x509write_crt_set_issuer_name(&crt, opt.issuer_name);
+ if (r != 0) {
+ SEE_DEBUG("x509write_crt_set_issuer_name returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+
+ r = mbedtls_x509write_crt_set_serial(&crt, &serial);
+ if (r != 0) {
+ SEE_DEBUG("x509write_crt_set_serial returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+
+ r = mbedtls_x509write_crt_set_validity(&crt, opt.not_before, opt.not_after);
+ if (r != 0) {
+ SEE_DEBUG("x509write_crt_set_validity returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+
+ /*
+ * 2.1 Adding the basic constraints extension.
+ */
+ r = mbedtls_x509write_crt_set_basic_constraints(&crt, opt.is_ca, opt.max_pathlen);
+ if (r != 0) {
+ SEE_DEBUG("x509write_crt_set_basic_constraints returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+#if defined(MBEDTLS_SHA1_C)
+ /*
+ * 2.2 Adding the Subject/Authority key identifier.
+ */
+ r = mbedtls_x509write_crt_set_subject_key_identifier(&crt);
+ if (r != 0) {
+ SEE_DEBUG("crt_set_subject_key_identifier returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+
+ r = mbedtls_x509write_crt_set_authority_key_identifier(&crt);
+ if (r != 0) {
+ SEE_DEBUG("crt_set_authority_key_identifier returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+#endif
+ /*
+ * 2.3 Adding the key usage extension.
+ */
+ if (opt.key_usage) {
+ r = mbedtls_x509write_crt_set_key_usage(&crt, opt.key_usage);
+ if (r != 0) {
+ SEE_DEBUG("crt_set_key_usage returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+ }
+ if (opt.ns_cert_type) {
+ r = mbedtls_x509write_crt_set_ns_cert_type(&crt, opt.ns_cert_type);
+ if (r != 0) {
+ SEE_DEBUG("crt_set_ns_cert_type returned -0x%02x\n\n", -r);
+ goto see_exit;
+ }
+ }
+
+ /*
+ * 3.0 Writing the certificate.
+ */
+ cert_len = mbedtls_x509write_crt_der(&crt, cert_buf, cert_buflen, NULL, NULL);
+ if (cert_len <= 0) {
+ SEE_DEBUG("x509write_crt_der returned -0x%02x\n\n", -cert_len);
+ r = cert_len;
+ goto see_exit;
+ }
+
+ r = mbedtls_pem_write_buffer(SEE_BEGIN_CERT, SEE_END_CERT, cert_buf + cert_buflen - cert_len, cert_len, out_buf, *out_buflen, out_buflen);
+ if (r != 0) {
+ SEE_DEBUG("mbedt pem write buffer fail %x\n", r);
+ goto see_exit;
+ }
+
+ r = see_set_certificate(out_buf, *out_buflen, opt.cert_index, CERT_PEM);
+ if (r != 0) {
+ SEE_DEBUG("mbedt pem write buffer fail %x\n", r);
+ goto see_exit;
+ }
+
+see_exit:
+ mbedtls_pk_free(&subject_key);
+ mbedtls_pk_free(&issuer_key);
+ mbedtls_x509write_crt_free(&crt);
+ mbedtls_mpi_free(&serial);
+
+ if (cert_buf) {
+ free(cert_buf);
+ }
+ if (subject_key_buf) {
+ free(subject_key_buf);
+ }
+
+ if (r) {
+ return SEE_ERROR;
+ }
+
+ return SEE_OK;
+}
+
+#endif
#include "mbedtls/see_internal.h"
#if defined(CONFIG_HW_ECDH_PARAM)
-int see_generate_key_internal(unsigned int key_type, unsigned char *key_buf,
- unsigned int key_len, unsigned int pukey_e)
+int see_generate_key_internal(unsigned int key_type, unsigned char *key_buf, unsigned int key_len, unsigned int pukey_e)
{
int r = 0;
unsigned int key = key_type & 0xFF0000;
return SEE_OK;
}
-int see_get_ecc_publickey_internal(struct sECC_KEY *ecc_pub, unsigned char *key_buf,
- unsigned int object_id)
+int see_get_ecc_publickey_internal(struct sECC_KEY *ecc_pub, unsigned char *key_buf, unsigned int object_id)
{
unsigned int r;
}
ISP_CHECKBUSY();
- if ((r = isp_ecdsa_get_publickey_encryptedkey(ecc_pub, object_id, key_buf)) != 0) {
+ r = isp_ecdsa_get_publickey_encryptedkey(ecc_pub, object_id, key_buf);
+ if (r != 0) {
isp_clear(0);
SEE_DEBUG("isp_get_ecdsa_pubkey fail %x\n", r);
if (see_mutex_unlock(&m_handler) != SEE_OK) {
return SEE_OK;
}
-int see_compute_ecdh_param_internal(struct sECC_KEY *ecc_pub, unsigned char *key_buf,
- unsigned char *output, unsigned int *olen)
+int see_compute_ecdh_param_internal(struct sECC_KEY *ecc_pub, unsigned char *key_buf, unsigned char *output, unsigned int *olen)
{
int r;
}
ISP_CHECKBUSY();
- if ((r = isp_compute_ecdh_encryptedkey(output, olen, *ecc_pub, key_buf)) != 0) {
+ r = isp_compute_ecdh_encryptedkey(output, olen, *ecc_pub, key_buf);
+ if (r != 0) {
isp_clear(0);
SEE_DEBUG("isp_compute_ecdh_param fail %x\n", r);
if (see_mutex_unlock(&m_handler) != SEE_OK) {
}
ISP_CHECKBUSY();
- if ((r = isp_dh_generate_keypair_userparam_encryptedkey(d_param, key_buf)) != 0) {
+ r = isp_dh_generate_keypair_userparam_encryptedkey(d_param, key_buf);
+ if (r != 0) {
isp_clear(0);
SEE_DEBUG("isp_generate_dh_param fail %x\n", r);
if (see_mutex_unlock(&m_handler) != SEE_OK) {
}
/* Compute shared secret key = GXY ((G^Y)^X mod P) */
-int see_compute_dhm_param_internal(struct sDH_PARAM *d_param, unsigned char *key_buf,
- unsigned char *output, unsigned int *olen)
+int see_compute_dhm_param_internal(struct sDH_PARAM *d_param, unsigned char *key_buf, unsigned char *output, unsigned int *olen)
{
int r;
}
ISP_CHECKBUSY();
- if ((r = isp_dh_compute_shared_secret_encryptedkey(output, olen, *d_param, key_buf)) != 0) {
+ r = isp_dh_compute_shared_secret_encryptedkey(output, olen, *d_param, key_buf);
+ if (r != 0) {
isp_clear(0);
SEE_DEBUG("isp_compute_dh_param fail %x\n", r);
if (see_mutex_unlock(&m_handler) != SEE_OK) {
#endif /* CONFIG_HW_DH_PARAM */
#if defined(CONFIG_HW_ECDSA_VERIFICATION)
-int see_setup_key_internal(unsigned char *key_der, unsigned int key_len,
- unsigned int key_type, unsigned char *key_buf)
+int see_setup_key_internal(unsigned char *key_der, unsigned int key_len, unsigned int key_type, unsigned char *key_buf)
{
int r;
return SEE_INVALID_INPUT_PARAMS;
}
- if (key_type < SECURE_STORAGE_TYPE_KEY_AES ||
- key_type > SECURE_STORAGE_TYPE_KEY_ECC) {
+ if (key_type < SECURE_STORAGE_TYPE_KEY_AES || key_type > SECURE_STORAGE_TYPE_KEY_ECC) {
return SEE_INVALID_INPUT_PARAMS;
}
}
ISP_CHECKBUSY();
- if ((r = isp_set_encryptedkey(key_der, key_len, key_type, key_buf)) != 0) {
+ r = isp_set_encryptedkey(key_der, key_len, key_type, key_buf);
+ if (r != 0) {
isp_clear(0);
SEE_DEBUG("isp_set_userkey fail %x\n", r);
if (see_mutex_unlock(&m_handler) != SEE_OK) {
return SEE_OK;
}
-int see_verify_ecdsa_signature_internal(struct sECC_SIGN *ecc_sign,
- unsigned char *hash, unsigned int hash_len,
- unsigned char *key_buf)
+int see_verify_ecdsa_signature_internal(struct sECC_SIGN *ecc_sign, unsigned char *hash, unsigned int hash_len, unsigned char *key_buf)
{
int r;
}
ISP_CHECKBUSY();
- if ((r = isp_ecdsa_verify_md_encryptedkey(ecc_sign,
- hash, hash_len, key_buf)) != 0) {
+ r = isp_ecdsa_verify_md_encryptedkey(ecc_sign, hash, hash_len, key_buf);
+ if (r != 0) {
isp_clear(0);
SEE_DEBUG("isp_ecdsa_verify fail %x\n", r);
if (see_mutex_unlock(&m_handler) != SEE_OK) {
return SEE_OK;
}
#endif /* CONFIG_HW_ECDSA_VERIFICATION */
+
+#if defined(CONFIG_HW_RSA_VERIFICATION)
+int see_verify_rsa_signature_internal(struct sRSA_SIGN *rsa_sign, unsigned char *hash, unsigned int hash_len, unsigned char *key_buf)
+{
+ int r;
+
+ SEE_DEBUG("%s IN\n", __func__);
+
+ if (rsa_sign == NULL || hash == NULL || hash_len == 0 || key_buf == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_rsa_verify_md_encryptedkey(rsa_sign, hash, hash_len, key_buf);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_rsa_verify fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ SEE_DEBUG("%s OUT\n", __func__);
+ return SEE_OK;
+}
+#endif /* CONFIG_HW_RSA_VERIFICATION */
+
+#if defined(CONFIG_HW_RSA_ENC)
+int see_rsa_encryption_internal(unsigned char *key_buf, unsigned int pad_type, unsigned char *output, unsigned int *outlen, unsigned char *input, unsigned int inlen)
+{
+ int r;
+
+ SEE_DEBUG("%s IN\n", __func__);
+
+ if (input == NULL || output == NULL || inlen == 0 || key_buf == NULL) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (pad_type != MBEDTLS_RSA_PKCS_V15) {
+ return SEE_INVALID_INPUT_PARAMS;
+ }
+
+ if (see_mutex_lock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_LOCK_ERROR;
+ }
+
+ ISP_CHECKBUSY();
+ r = isp_rsa_encrypt_encryptedkey(output, outlen, input, inlen, key_buf);
+ if (r != 0) {
+ isp_clear(0);
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+ SEE_DEBUG("isp_rsa_encrypt fail %x\n", r);
+ return SEE_ERROR;
+ }
+
+ if (see_mutex_unlock(&m_handler) != SEE_OK) {
+ return SEE_MUTEX_UNLOCK_ERROR;
+ }
+
+ SEE_DEBUG("%s OUT\n", __func__);
+ return SEE_OK;
+}
+#endif /* CONFIG_HW_RSA_ENC */