/* * Compute and write signature */ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; mbedtls_mpi r, s; mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s ); #if defined(MBEDTLS_ECDSA_DETERMINISTIC) (void) f_rng; (void) p_rng; MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx->grp, &r, &s, &ctx->d, hash, hlen, md_alg ) ); #else (void) md_alg; MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d, hash, hlen, f_rng, p_rng ) ); #endif MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) ); cleanup: mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s ); return( ret ); }
/* * Deterministic signature wrapper */ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, mbedtls_md_type_t md_alg ) { int ret; mbedtls_hmac_drbg_context rng_ctx; unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; size_t grp_len = ( grp->nbits + 7 ) / 8; const mbedtls_md_info_t *md_info; mbedtls_mpi h; if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); mbedtls_mpi_init( &h ); mbedtls_hmac_drbg_init( &rng_ctx ); /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len ); ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, &rng_ctx ); cleanup: mbedtls_hmac_drbg_free( &rng_ctx ); mbedtls_mpi_free( &h ); return( ret ); }
TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, const uint8_t *msg, size_t msg_len, uint8_t *sig, size_t *sig_len) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; const mbedtls_pk_info_t *pk_info = NULL; mbedtls_ecdsa_context ecdsa; size_t key_size_bytes = 0; size_t key_size_bits = 0; mbedtls_mpi r; mbedtls_mpi s; memset(&ecdsa, 0, sizeof(ecdsa)); memset(&r, 0, sizeof(r)); memset(&s, 0, sizeof(s)); if (algo == 0) return TEE_ERROR_BAD_PARAMETERS; mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); mbedtls_ecdsa_init(&ecdsa); lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve); if (lmd_res != 0) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } ecdsa.d = *(mbedtls_mpi *)key->d; res = ecc_get_keysize(key->curve, algo, &key_size_bytes, &key_size_bits); if (res != TEE_SUCCESS) goto out; pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA); if (pk_info == NULL) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg, msg_len, mbd_rand, NULL); if (lmd_res == 0) { *sig_len = 2 * key_size_bytes; memset(sig, 0, *sig_len); mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 - mbedtls_mpi_size(&r), mbedtls_mpi_size(&r)); mbedtls_mpi_write_binary(&s, sig + *sig_len - mbedtls_mpi_size(&s), mbedtls_mpi_size(&s)); res = TEE_SUCCESS; } else { FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res); res = TEE_ERROR_GENERIC; } out: mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); /* Reset mpi to skip freeing here, those mpis will be freed with key */ mbedtls_mpi_init(&ecdsa.d); mbedtls_ecdsa_free(&ecdsa); return res; }
/* * Deterministic signature wrapper */ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, mbedtls_md_type_t md_alg, mbedtls_ecdsa_restart_ctx *rs_ctx ) { int ret; mbedtls_hmac_drbg_context rng_ctx; mbedtls_hmac_drbg_context *p_rng = &rng_ctx; unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; size_t grp_len = ( grp->nbits + 7 ) / 8; const mbedtls_md_info_t *md_info; mbedtls_mpi h; if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); mbedtls_mpi_init( &h ); mbedtls_hmac_drbg_init( &rng_ctx ); ECDSA_RS_ENTER( det ); #if defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && rs_ctx->det != NULL ) { /* redirect to our context */ p_rng = &rs_ctx->det->rng_ctx; /* jump to current step */ if( rs_ctx->det->state == ecdsa_det_sign ) goto sign; } #endif /* MBEDTLS_ECP_RESTARTABLE */ /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len ); #if defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && rs_ctx->det != NULL ) rs_ctx->det->state = ecdsa_det_sign; sign: #endif #if defined(MBEDTLS_ECDSA_SIGN_ALT) ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng ); #else ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng, rs_ctx ); #endif /* MBEDTLS_ECDSA_SIGN_ALT */ cleanup: mbedtls_hmac_drbg_free( &rng_ctx ); mbedtls_mpi_free( &h ); ECDSA_RS_LEAVE( det ); return( ret ); }