+ stop_it(eddsa_doit, testnum);
+ }
+ }
+ }
+
+# ifndef OPENSSL_NO_SM2
+ for (testnum = 0; testnum < SM2_NUM; testnum++) {
+ int st = 1;
+ EVP_PKEY *sm2_pkey = NULL;
+
+ if (!sm2_doit[testnum])
+ continue; /* Ignore Curve */
+ /* Init signing and verification */
+ for (i = 0; i < loopargs_len; i++) {
+ EVP_PKEY_CTX *sm2_pctx = NULL;
+ EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
+ st = 0;
+
+ loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
+ loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
+ if (loopargs[i].sm2_ctx[testnum] == NULL
+ || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
+ break;
+
+ /* SM2 keys are generated as normal EC keys with a special curve */
+ st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL
+ || EVP_PKEY_keygen_init(pctx) <= 0
+ || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
+ sm2_curves[testnum].nid) <= 0
+ || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
+ EVP_PKEY_CTX_free(pctx);
+ if (st == 0)
+ break;
+
+ st = 0; /* set back to zero */
+ /* attach it sooner to rely on main final cleanup */
+ loopargs[i].sm2_pkey[testnum] = sm2_pkey;
+ loopargs[i].sigsize = ECDSA_size(EVP_PKEY_get0_EC_KEY(sm2_pkey));
+ if (!EVP_PKEY_set_alias_type(sm2_pkey, EVP_PKEY_SM2))
+ break;
+
+ sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
+ sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
+ if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
+ EVP_PKEY_CTX_free(sm2_vfy_pctx);
+ break;
+ }
+ /* attach them directly to respective ctx */
+ EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
+ EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
+
+ /*
+ * No need to allow user to set an explicit ID here, just use
+ * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
+ */
+ if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
+ || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
+ break;
+
+ if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
+ EVP_sm3(), NULL, sm2_pkey))
+ break;
+ if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
+ EVP_sm3(), NULL, sm2_pkey))
+ break;
+ st = 1; /* mark loop as succeeded */
+ }
+ if (st == 0) {
+ BIO_printf(bio_err, "SM2 init failure.\n");
+ ERR_print_errors(bio_err);
+ rsa_count = 1;
+ } else {
+ for (i = 0; i < loopargs_len; i++) {
+ size_t sm2_sigsize = loopargs[i].sigsize;
+
+ /* Perform SM2 signature test */
+ st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
+ loopargs[i].buf2, &sm2_sigsize,
+ loopargs[i].buf, 20);
+ if (st == 0)
+ break;
+ }
+ if (st == 0) {
+ BIO_printf(bio_err,
+ "SM2 sign failure. No SM2 sign will be done.\n");
+ ERR_print_errors(bio_err);
+ rsa_count = 1;
+ } else {
+ pkey_print_message("sign", sm2_curves[testnum].name,
+ sm2_c[testnum][0],
+ sm2_curves[testnum].bits, seconds.sm2);
+ Time_F(START);
+ count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
+ d = Time_F(STOP);
+
+ BIO_printf(bio_err,
+ mr ? "+R8:%ld:%u:%s:%.2f\n" :
+ "%ld %u bits %s signs in %.2fs \n",
+ count, sm2_curves[testnum].bits,
+ sm2_curves[testnum].name, d);
+ sm2_results[testnum][0] = (double)count / d;
+ rsa_count = count;
+ }
+
+ /* Perform SM2 verification test */
+ for (i = 0; i < loopargs_len; i++) {
+ st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
+ loopargs[i].buf2, loopargs[i].sigsize,
+ loopargs[i].buf, 20);
+ if (st != 1)
+ break;
+ }
+ if (st != 1) {
+ BIO_printf(bio_err,
+ "SM2 verify failure. No SM2 verify will be done.\n");
+ ERR_print_errors(bio_err);
+ sm2_doit[testnum] = 0;
+ } else {
+ pkey_print_message("verify", sm2_curves[testnum].name,
+ sm2_c[testnum][1],
+ sm2_curves[testnum].bits, seconds.sm2);
+ Time_F(START);
+ count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R9:%ld:%u:%s:%.2f\n"
+ : "%ld %u bits %s verify in %.2fs\n",
+ count, sm2_curves[testnum].bits,
+ sm2_curves[testnum].name, d);
+ sm2_results[testnum][1] = (double)count / d;
+ }
+
+ if (rsa_count <= 1) {
+ /* if longer than 10s, don't do any more */
+ for (testnum++; testnum < SM2_NUM; testnum++)
+ sm2_doit[testnum] = 0;