TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; mbedtls_ecdsa_context ecdsa; size_t key_size_bytes = 0; size_t key_size_bits = 0; memset(&ecdsa, 0, sizeof(ecdsa)); res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits); if (res != TEE_SUCCESS) return res; mbedtls_ecdsa_init(&ecdsa); /* Generate the ECC key */ lmd_res = mbedtls_ecdsa_genkey(&ecdsa, key->curve, mbd_rand, NULL); if (lmd_res != 0) { res = TEE_ERROR_BAD_PARAMETERS; FMSG("mbedtls_ecdsa_genkey failed."); goto exit; } ecc_clear_precomputed(&ecdsa.grp); /* check the size of the keys */ if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) || (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) || (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) { res = TEE_ERROR_BAD_PARAMETERS; FMSG("Check the size of the keys failed."); goto exit; } /* check LMD is returning z==1 */ if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) { res = TEE_ERROR_BAD_PARAMETERS; FMSG("Check LMD failed."); goto exit; } /* Copy the key */ crypto_bignum_copy(key->d, (void *)&ecdsa.d); crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X); crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y); res = TEE_SUCCESS; exit: mbedtls_ecdsa_free(&ecdsa); /* Free the temporary key */ return res; }
tt_result_t tt_ecdsa_generate(IN tt_ecdsa_t *dsa, IN tt_ecgrp_t g) { mbedtls_ecdsa_context *ctx; int e; TT_ASSERT(dsa != NULL); TT_ASSERT(TT_ECGRP_VALID(g)); ctx = &dsa->ctx; e = mbedtls_ecdsa_genkey(ctx, tt_g_ecgrp_map[g], tt_ctr_drbg, tt_current_ctr_drbg()); if (e != 0) { tt_crypto_error("fail to generate ecdsa"); return TT_FAIL; } return TT_SUCCESS; }
/******************************************************************************* * Asymmetric ciphers * *******************************************************************************/ int __attribute__((weak)) wrapped_asym_keygen(Cipher c, CryptoKey key_type, uint8_t* pub, size_t* pub_len, uint8_t* priv, size_t* priv_len) { if (keygen_deferred_handling(key_type)) { // If overriden by user implementation. return _keygen_overrides[key_type](c, key_type, pub, pub_len, priv, priv_len); } int ret = -1; mbedtls_pk_context key; mbedtls_pk_init(&key); uint32_t pers = randomInt(); mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_init(&ctr_drbg); ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const uint8_t*) &pers, 4 ); if (0 == ret) { switch (c) { #if defined(WRAPPED_ASYM_RSA) case Cipher::ASYM_RSA: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); if (0 == ret) { mbedtls_rsa_context* rsa = mbedtls_pk_rsa(key); ret = mbedtls_rsa_gen_key(rsa, mbedtls_ctr_drbg_random, &ctr_drbg, (int) key_type, 65537 ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif #if defined(MBEDTLS_ECDSA_C) case Cipher::ASYM_ECDSA: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { mbedtls_ecp_keypair* ec_kp = mbedtls_pk_ec(key); ret = mbedtls_ecdsa_genkey(ec_kp, (mbedtls_ecp_group_id) key_type, mbedtls_ctr_drbg_random, &ctr_drbg ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif #if defined(MBEDTLS_ECP_C) case Cipher::ASYM_ECKEY: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { mbedtls_ecp_keypair* ec_kp = mbedtls_pk_ec(key); ret = mbedtls_ecp_gen_key( (mbedtls_ecp_group_id) key_type, ec_kp, mbedtls_ctr_drbg_random, &ctr_drbg ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif default: break; } } mbedtls_pk_free(&key); mbedtls_ctr_drbg_free(&ctr_drbg); return ret; }