From 7ef6d71b51f6989a395e9f92002a33e74d77278b Mon Sep 17 00:00:00 2001 From: Junyeon Lee Date: Thu, 23 Mar 2017 20:49:51 +0900 Subject: [PATCH] net/tls: support HW ecdsa sign This patch adds to support ECDSA sign based on hardware. SSS supporting curves: . SECP NIST : 192, 224, 256, 384, 512 . Brainpool : 256 Precondition: Before using HW ECDSA sign, user should set hardware key and register key index to mbedtls_ecp_keypair. Change-Id: I08d6770e79b1bac2c8871f446605eb23614dda50 Signed-off-by: Junyeon Lee --- os/include/tls/ecdsa.h | 15 +++++++ os/include/tls/ecp.h | 5 +++ os/include/tls/pk.h | 3 ++ os/include/tls/see_api.h | 1 + os/net/tls/ecdsa.c | 2 +- os/net/tls/pk_wrap.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++- os/net/tls/see_api.c | 49 +++++++++++++++++++++++ 7 files changed, 174 insertions(+), 2 deletions(-) diff --git a/os/include/tls/ecdsa.h b/os/include/tls/ecdsa.h index e8f6b60..a515d76 100644 --- a/os/include/tls/ecdsa.h +++ b/os/include/tls/ecdsa.h @@ -127,6 +127,21 @@ int mbedtls_ecdsa_sign_det(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi * int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, const unsigned char *buf, size_t blen, const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s); /** + * \brief Convert ecdsa signature to asn.1 type. + * + * \param r First integer of the signature + * \param s Second integer of the signature + * \param sig Buffer that will hold the signature + * \param slen Length of the signature written + * + * \return 0 if successful, + * or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or + * MBEDTLS_ERR_ASN1_XXX error code + */ +int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, + unsigned char *sig, size_t *slen ); + +/** * \brief Compute ECDSA signature and write it to buffer, * serialized as defined in RFC 4492 page 20. * (Not thread-safe to use same context in multiple threads) diff --git a/os/include/tls/ecp.h b/os/include/tls/ecp.h index 1453746..4d71669 100644 --- a/os/include/tls/ecp.h +++ b/os/include/tls/ecp.h @@ -157,6 +157,8 @@ typedef struct { size_t T_size; /*!< number for pre-computed points */ #if defined(CONFIG_HW_ECDH_PARAM) unsigned char *key_buf; +#endif +#if defined(CONFIG_HW_ECDSA_SIGN) unsigned int key_index; #endif } mbedtls_ecp_group; @@ -172,6 +174,9 @@ typedef struct { mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ mbedtls_mpi d; /*!< our secret value */ mbedtls_ecp_point Q; /*!< our public value */ +#if defined(CONFIG_HW_ECDSA_SIGN) + unsigned int key_index; +#endif } mbedtls_ecp_keypair; /** diff --git a/os/include/tls/pk.h b/os/include/tls/pk.h index 5231297..2ff2afe 100644 --- a/os/include/tls/pk.h +++ b/os/include/tls/pk.h @@ -592,6 +592,9 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, const mbedt int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n); #endif +#if defined(CONFIG_HW_ECDSA_SIGN) +int hw_ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); +#endif #if defined(CONFIG_HW_ECDSA_VERIFICATION) int hw_ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len); #endif diff --git a/os/include/tls/see_api.h b/os/include/tls/see_api.h index ad5a733..487309b 100644 --- a/os/include/tls/see_api.h +++ b/os/include/tls/see_api.h @@ -251,4 +251,5 @@ int see_mutex_unlock(see_mutex_t *m); unsigned int see_get_keyindex(unsigned int key_type); unsigned int see_free_keyindex(unsigned int key_type, unsigned int key_index); +int see_check_keyindex(unsigned int key_index); #endif /* __SEE_API_H */ diff --git a/os/net/tls/ecdsa.c b/os/net/tls/ecdsa.c index 29e8d3f..7191b29 100644 --- a/os/net/tls/ecdsa.c +++ b/os/net/tls/ecdsa.c @@ -290,7 +290,7 @@ cleanup: /* * Convert a signature (given by context) to ASN.1 */ -static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen) +int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t *slen) { int ret; unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; diff --git a/os/net/tls/pk_wrap.c b/os/net/tls/pk_wrap.c index 2521f54..7f71bdb 100644 --- a/os/net/tls/pk_wrap.c +++ b/os/net/tls/pk_wrap.c @@ -231,6 +231,9 @@ static int eckey_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, const unsigned c mbedtls_ecdsa_init(&ecdsa); +#if defined(CONFIG_HW_ECDSA_SIGN) + ecdsa.key_index = ((mbedtls_ecp_keypair *)ctx)->key_index; +#endif if ((ret = mbedtls_ecdsa_from_keypair(&ecdsa, ctx)) == 0) { ret = ecdsa_sign_wrap(&ecdsa, md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng); } @@ -366,8 +369,12 @@ const mbedtls_pk_info_t mbedtls_ecdsa_info = { hw_ecdsa_verify_wrap, #else ecdsa_verify_wrap, -#endif +#endif /* CONFIG_HW_ECDSA_VERIFICATION */ +#if defined(CONFIG_HW_ECDSA_SIGN) + hw_ecdsa_sign_wrap, +#else ecdsa_sign_wrap, +#endif /* CONFIG_HW_ECDSA_SIGN */ NULL, NULL, eckey_check_pair, /* Compatible key structures */ @@ -481,6 +488,98 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = { #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ +#if defined(CONFIG_HW_ECDSA_SIGN) +int hw_ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + unsigned int curve = ((mbedtls_ecdsa_context *)ctx)->grp.id; + unsigned int key_index = ((mbedtls_ecdsa_context *)ctx)->key_index; + unsigned char s_buf[SEE_MAX_ECP_KEY_SIZE]; + unsigned char r_buf[SEE_MAX_ECP_KEY_SIZE]; + unsigned char *t_hash = (unsigned char *)hash; + + /* + * 1. Check key existance + */ + if (see_check_keyindex(key_index)) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + /* + * 2. Check hash algorithm and sign curve + */ + mbedtls_mpi r, s; + struct sECC_SIGN ecc_sign; + memset(&ecc_sign, 0, sizeof(struct sECC_SIGN)); + + ecc_sign.s = s_buf; + ecc_sign.r = r_buf; + + switch(md_alg) { + case MBEDTLS_MD_SHA1: + ecc_sign.sign_type |= OID_SHA1_160; + break; + case MBEDTLS_MD_SHA256: + ecc_sign.sign_type |= OID_SHA2_256; + break; + case MBEDTLS_MD_SHA384: + ecc_sign.sign_type |= OID_SHA2_384; + break; + case MBEDTLS_MD_SHA512: + ecc_sign.sign_type |= OID_SHA2_512; + break; + default: + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + switch(curve) { + case MBEDTLS_ECP_DP_SECP192R1: + ecc_sign.sign_type |= OID_ECC_P192; + break; + case MBEDTLS_ECP_DP_SECP224R1: + ecc_sign.sign_type |= OID_ECC_P224; + break; + case MBEDTLS_ECP_DP_SECP256R1: + ecc_sign.sign_type |= OID_ECC_P256; + break; + case MBEDTLS_ECP_DP_SECP384R1: + ecc_sign.sign_type |= OID_ECC_P384; + break; + case MBEDTLS_ECP_DP_SECP521R1: + ecc_sign.sign_type |= OID_ECC_P521; + break; + case MBEDTLS_ECP_DP_BP256R1: + ecc_sign.sign_type |= OID_ECC_BP256; + break; + default: + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + goto cleanup; + } + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* + * 3. Sign + */ + if((ret = see_get_ecdsa_signature(&ecc_sign, t_hash, hash_len, key_index)) != 0) { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + mbedtls_mpi_read_binary(&r, ecc_sign.r, ecc_sign.r_byte_len); + mbedtls_mpi_read_binary(&s, ecc_sign.s, ecc_sign.s_byte_len); + + MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, sig_len )); + +cleanup: + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + + return ret; +} +#endif /* CONFIG_HW_ECDSA_SIGN */ + #if defined(CONFIG_HW_ECDSA_VERIFICATION) int hw_ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len) { diff --git a/os/net/tls/see_api.c b/os/net/tls/see_api.c index 9bdd759..8248ba0 100644 --- a/os/net/tls/see_api.c +++ b/os/net/tls/see_api.c @@ -692,6 +692,33 @@ int see_compute_dhm_param(struct sDH_PARAM *d_param, unsigned int key_index, uns _SEE_MUTEX_UNLOCK return SEE_OK; } +int see_compute_ecdh_param(struct sECC_KEY *ecc_pub, unsigned int key_index, unsigned char *output, unsigned int *olen) +{ + int r; + + if (ecc_pub == NULL || output == NULL || olen == 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); + + _SEE_MUTEX_LOCK + ISP_CHECKBUSY(); + if ((r = isp_compute_ecdh_securekey(output, olen, *ecc_pub, key_index)) != 0) { + isp_clear(0); + _SEE_MUTEX_UNLOCK + SEE_DEBUG("isp_compute_ecdh_param fail %x\n", r); + return SEE_ERROR; + } + _SEE_MUTEX_UNLOCK + + 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; @@ -928,3 +955,25 @@ unsigned int see_get_keyindex(unsigned int key_type) return 0xFF; } + +int see_check_keyindex(unsigned int index) +{ +#ifdef SEE_SUPPORT_USERKEY + if (index < MAX_KEY_INDEX) { + return 0; + } +#endif + + switch (index) { + case FACTORYKEY_ARTIK_PSK: + case FACTORYKEY_ARTIK_DEVICE: + case FACTORYKEY_DA_CA: + case FACTORYKEY_DA_DEVICE: + case FACTORYKEY_DA_PBKEY: + case FACTORYKEY_IOTIVITY_ECC: + return 0; + default: + return -1; + } + return -1; +} -- 2.7.4