int bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen, uint8_t key_id) { int rc; uint8_t *cp; uint8_t *end; mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); cp = (uint8_t *)bootutil_keys[key_id].key; end = cp + *bootutil_keys[key_id].len; rc = bootutil_parse_eckey(&ctx, &cp, end); if (rc) { return -1; } while (sig[slen - 1] == '\0') { slen--; } rc = bootutil_cmp_sig(&ctx, hash, hlen, sig, slen); mbedtls_ecdsa_free(&ctx); return rc; }
tt_result_t tt_ecdsa_load(IN tt_ecdsa_t *dsa, IN tt_pk_t *pk) { mbedtls_ecdsa_context *ctx; mbedtls_ecp_keypair *ec; int e; TT_ASSERT(dsa != NULL); TT_ASSERT(pk != NULL); if (tt_pk_get_type(pk) != TT_ECKEY) { TT_ERROR("pk is not ec key"); return TT_FAIL; } ctx = &dsa->ctx; ec = mbedtls_pk_ec(pk->ctx); e = mbedtls_ecdsa_from_keypair(ctx, ec); if (e != 0) { tt_crypto_error("fail to copy ec key"); mbedtls_ecdsa_free(ctx); return TT_FAIL; } return TT_SUCCESS; }
static void eckey_rs_free( void *ctx ) { eckey_restart_ctx *rs_ctx; if( ctx == NULL) return; rs_ctx = ctx; mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); mbedtls_free( ctx ); }
/* * Set context from an mbedtls_ecp_keypair */ int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) { int ret; if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) { mbedtls_ecdsa_free( ctx ); } return( ret ); }
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; }
static int eckey_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 ) { int ret; mbedtls_ecdsa_context ecdsa; mbedtls_ecdsa_init( &ecdsa ); if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); mbedtls_ecdsa_free( &ecdsa ); return( ret ); }
static int eckey_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; mbedtls_ecdsa_context ecdsa; mbedtls_ecdsa_init( &ecdsa ); 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 ); mbedtls_ecdsa_free( &ecdsa ); return( ret ); }
TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, const uint8_t *msg, size_t msg_len, const uint8_t *sig, size_t sig_len) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; mbedtls_ecdsa_context ecdsa; size_t key_size_bytes, key_size_bits = 0; uint8_t one[1] = { 1 }; 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.Q.X = *(mbedtls_mpi *)key->x; ecdsa.Q.Y = *(mbedtls_mpi *)key->y; mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one)); res = ecc_get_keysize(key->curve, algo, &key_size_bytes, &key_size_bits); if (res != TEE_SUCCESS) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } /* check keysize vs sig_len */ if ((key_size_bytes * 2) != sig_len) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } mbedtls_mpi_read_binary(&r, sig, sig_len / 2); mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2); lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q, &r, &s); if (lmd_res != 0) { FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res); res = get_tee_result(lmd_res); } 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.Q.X); mbedtls_mpi_init(&ecdsa.Q.Y); mbedtls_ecdsa_free(&ecdsa); return res; }
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; }
static void ecdsa_free_wrap( void *ctx ) { mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); mbedtls_free( ctx ); }
extern void tt_ecdsa_destroy(IN tt_ecdsa_t *dsa) { TT_ASSERT(dsa != NULL); mbedtls_ecdsa_free(&dsa->ctx); }