net/tls: support HW ecdsa sign
authorJunyeon Lee <junyeon2.lee@samsung.com>
Thu, 23 Mar 2017 11:49:51 +0000 (20:49 +0900)
committerHeesub Shin <heesub.shin@samsung.com>
Mon, 17 Apr 2017 10:58:11 +0000 (19:58 +0900)
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 <junyeon2.lee@samsung.com>
os/include/tls/ecdsa.h
os/include/tls/ecp.h
os/include/tls/pk.h
os/include/tls/see_api.h
os/net/tls/ecdsa.c
os/net/tls/pk_wrap.c
os/net/tls/see_api.c

index e8f6b60..a515d76 100644 (file)
@@ -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)
index 1453746..4d71669 100644 (file)
@@ -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;
 
 /**
index 5231297..2ff2afe 100644 (file)
@@ -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
index ad5a733..487309b 100644 (file)
@@ -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 */
index 29e8d3f..7191b29 100644 (file)
@@ -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];
index 2521f54..7f71bdb 100644 (file)
@@ -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)
 {
index 9bdd759..8248ba0 100644 (file)
@@ -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;
+}