C4Err ECC_Sign(ECC_ContextRef privCtx, void *inData, size_t inDataLen, void *outData, size_t bufSize, size_t *outDataLen) { C4Err err = kC4Err_NoErr; int status = CRYPT_OK; unsigned long length = bufSize; validateECCContext(privCtx); ValidateParam(privCtx->isInited); if(privCtx->isBLCurve) { status = ecc_bl_sign_hash(inData, inDataLen, outData, &length, 0, find_prng("sprng"), &privCtx->key); } else { status = ecc_sign_hash(inData, inDataLen, outData, &length, 0, find_prng("sprng"), &privCtx->key); } if(status != CRYPT_OK) { err = sCrypt2C4Err(status); CKERR; } *outDataLen = length; done: return err; }
static int rpmltcSignECDSA(pgpDig dig) /*@*/ { rpmltc ltc = dig->impl; int rc = 0; /* assume failure. */ unsigned char sig[2048]; unsigned long siglen = sizeof(sig); if (ltc->digest == NULL || ltc->digestlen == 0) goto exit; rc = rpmltcErr(ltc, "ecc_sign_hash", ecc_sign_hash(ltc->digest, ltc->digestlen, sig, &siglen, &yarrow_prng, find_prng ("yarrow"), <c->ecdsa)); if (rc == CRYPT_OK) { int xx; _initBN(ltc->r); _initBN(ltc->s); xx = der_decode_sequence_multi(sig, siglen, LTC_ASN1_INTEGER, 1UL, ltc->r, LTC_ASN1_INTEGER, 1UL, ltc->s, LTC_ASN1_EOL, 0UL, NULL); } rc = (rc == CRYPT_OK); #ifdef DYING rpmltcDumpECDSA(__FUNCTION__, ltc); #endif exit: SPEW(!rc, rc, dig); return rc; }
void bench_eccKeyAgree(void) { ecc_key genKey, genKey2; double start, total, each, milliEach; int i; const int agreeTimes = 5; byte shared[1024]; byte sig[1024]; byte digest[32]; word32 x; ecc_make_key(&rng, 32, &genKey); ecc_make_key(&rng, 32, &genKey2); /* 256 bit */ start = current_time(); for(i = 0; i < agreeTimes; i++) { x = sizeof(shared); ecc_shared_secret(&genKey, &genKey2, shared, &x); } total = current_time() - start; each = total / agreeTimes; /* per second */ milliEach = each * 1000; /* millisconds */ printf("EC-DHE key agreement %6.2f milliseconds, avg over %d" " iterations\n", milliEach, agreeTimes); /* make dummy digest */ for (i = 0; i < (int)sizeof(digest); i++) digest[i] = i; start = current_time(); for(i = 0; i < agreeTimes; i++) { x = sizeof(sig); ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &genKey); } total = current_time() - start; each = total / agreeTimes; /* per second */ milliEach = each * 1000; /* millisconds */ printf("EC-DSA sign time %6.2f milliseconds, avg over %d" " iterations\n", milliEach, agreeTimes); ecc_free(&genKey2); ecc_free(&genKey); }
/* ECC DSA Hash Sign */ int CRYPT_ECC_DSA_HashSign(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng, unsigned char* sig, unsigned int sigSz, unsigned int* usedSz, const unsigned char* in, unsigned int inSz) { int ret; unsigned int inOut = sigSz; if (ecc == NULL || rng == NULL || sig == NULL || usedSz == NULL || in == NULL) return BAD_FUNC_ARG; ret = ecc_sign_hash(in, inSz, sig, &inOut, (RNG*)rng, (ecc_key*)ecc->holder); *usedSz = inOut; return ret; }
void bench_eccKeyAgree(void) { ecc_key genKey, genKey2; double start, total, each, milliEach; int i, ret; byte shared[1024]; byte sig[1024]; byte digest[32]; word32 x = 0; ecc_init(&genKey); ecc_init(&genKey2); ret = InitRng(&rng); if (ret < 0) { printf("InitRNG failed\n"); return; } ret = ecc_make_key(&rng, 32, &genKey); if (ret != 0) { printf("ecc_make_key failed\n"); return; } ret = ecc_make_key(&rng, 32, &genKey2); if (ret != 0) { printf("ecc_make_key failed\n"); return; } /* 256 bit */ start = current_time(1); for(i = 0; i < agreeTimes; i++) { x = sizeof(shared); ret = ecc_shared_secret(&genKey, &genKey2, shared, &x); if (ret != 0) { printf("ecc_shared_secret failed\n"); return; } } total = current_time(0) - start; each = total / agreeTimes; /* per second */ milliEach = each * 1000; /* millisconds */ printf("EC-DHE key agreement %6.3f milliseconds, avg over %d" " iterations\n", milliEach, agreeTimes); /* make dummy digest */ for (i = 0; i < (int)sizeof(digest); i++) digest[i] = (byte)i; start = current_time(1); for(i = 0; i < agreeTimes; i++) { x = sizeof(sig); ret = ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &genKey); if (ret != 0) { printf("ecc_sign_hash failed\n"); return; } } total = current_time(0) - start; each = total / agreeTimes; /* per second */ milliEach = each * 1000; /* millisconds */ printf("EC-DSA sign time %6.3f milliseconds, avg over %d" " iterations\n", milliEach, agreeTimes); start = current_time(1); for(i = 0; i < agreeTimes; i++) { int verify = 0; ret = ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &genKey); if (ret != 0) { printf("ecc_verify_hash failed\n"); return; } } total = current_time(0) - start; each = total / agreeTimes; /* per second */ milliEach = each * 1000; /* millisconds */ printf("EC-DSA verify time %6.3f milliseconds, avg over %d" " iterations\n", milliEach, agreeTimes); ecc_free(&genKey2); ecc_free(&genKey); }
int ecc_tests (void) { unsigned char buf[4][4096]; unsigned long x, y, z, s; int stat, stat2; ecc_key usera, userb, pubKey, privKey; DO(ecc_test ()); DO(ecc_test ()); DO(ecc_test ()); DO(ecc_test ()); DO(ecc_test ()); for (s = 0; s < (sizeof(sizes)/sizeof(sizes[0])); s++) { /* make up two keys */ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb)); /* make the shared secret */ x = sizeof(buf[0]); DO(ecc_shared_secret (&usera, &userb, buf[0], &x)); y = sizeof(buf[1]); DO(ecc_shared_secret (&userb, &usera, buf[1], &y)); if (y != x) { fprintf(stderr, "ecc Shared keys are not same size."); return 1; } if (memcmp (buf[0], buf[1], x)) { fprintf(stderr, "ecc Shared keys not same contents."); return 1; } /* now export userb */ y = sizeof(buf[0]); DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb)); ecc_free (&userb); /* import and make the shared secret again */ DO(ecc_import (buf[1], y, &userb)); z = sizeof(buf[0]); DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); if (z != x) { fprintf(stderr, "failed. Size don't match?"); return 1; } if (memcmp (buf[0], buf[2], x)) { fprintf(stderr, "Failed. Contents didn't match."); return 1; } /* export with ANSI X9.63 */ y = sizeof(buf[1]); DO(ecc_ansi_x963_export(&userb, buf[1], &y)); ecc_free (&userb); /* now import the ANSI key */ DO(ecc_ansi_x963_import(buf[1], y, &userb)); /* shared secret */ z = sizeof(buf[0]); DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); if (z != x) { fprintf(stderr, "failed. Size don't match?"); return 1; } if (memcmp (buf[0], buf[2], x)) { fprintf(stderr, "Failed. Contents didn't match."); return 1; } ecc_free (&usera); ecc_free (&userb); /* test encrypt_key */ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); /* export key */ x = sizeof(buf[0]); DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera)); DO(ecc_import(buf[0], x, &pubKey)); x = sizeof(buf[0]); DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera)); DO(ecc_import(buf[0], x, &privKey)); for (x = 0; x < 32; x++) { buf[0][x] = x; } y = sizeof (buf[1]); DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); zeromem (buf[0], sizeof (buf[0])); x = sizeof (buf[0]); DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey)); if (x != 32) { fprintf(stderr, "Failed (length)"); return 1; } for (x = 0; x < 32; x++) { if (buf[0][x] != x) { fprintf(stderr, "Failed (contents)"); return 1; } } /* test sign_hash */ for (x = 0; x < 16; x++) { buf[0][x] = x; } x = sizeof (buf[1]); DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); buf[0][0] ^= 1; DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2); return 1; } ecc_free (&usera); ecc_free (&pubKey); ecc_free (&privKey); } #ifdef LTC_ECC_SHAMIR return ecc_test_shamir(); #else return 0; #endif }
/* in case of DSA puts into data, r,s */ static int _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo, gnutls_datum_t * signature, const gnutls_datum_t * vdata, const gnutls_pk_params_st * pk_params) { int ret; unsigned int hash; unsigned int hash_len; switch (algo) { case GNUTLS_PK_EC: /* we do ECDSA */ { ecc_key priv; struct dsa_signature sig; int curve_id = pk_params->flags; if (is_supported_curve(curve_id) == 0) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); _ecc_params_to_privkey(pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = ecc_sign_hash(vdata->data, hash_len, &sig, NULL, rnd_func, &priv, curve_id); if (ret != 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto ecdsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); ecdsa_fail: dsa_signature_clear (&sig); _ecc_params_clear( &priv); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_DSA: { struct dsa_public_key pub; struct dsa_private_key priv; struct dsa_signature sig; memset(&priv, 0, sizeof(priv)); memset(&pub, 0, sizeof(pub)); _dsa_params_to_pubkey (pk_params, &pub); _dsa_params_to_privkey (pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = _dsa_sign (&pub, &priv, NULL, rnd_func, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto dsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); dsa_fail: dsa_signature_clear (&sig); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_RSA: { struct rsa_private_key priv; struct rsa_public_key pub; mpz_t s; _rsa_params_to_privkey (pk_params, &priv); _rsa_params_to_pubkey (pk_params, &pub); mpz_init(s); ret = rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func, vdata->size, vdata->data, s); if (ret == 0) { gnutls_assert(); ret = GNUTLS_E_PK_SIGN_FAILED; goto rsa_fail; } ret = _gnutls_mpi_dprint (s, signature); rsa_fail: mpz_clear(s); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = 0; cleanup: return ret; }
/* in case of DSA puts into data, r,s */ static int _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo, gnutls_datum_t * signature, const gnutls_datum_t * vdata, const gnutls_pk_params_st * pk_params) { int ret; unsigned int hash; unsigned int hash_len; switch (algo) { case GNUTLS_PK_EC: /* we do ECDSA */ { ecc_key priv; struct dsa_signature sig; _ecc_params_to_privkey(pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = ecc_sign_hash(vdata->data, hash_len, &sig, NULL, rnd_func, &priv); if (ret != 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto ecdsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); ecdsa_fail: dsa_signature_clear (&sig); _ecc_params_clear( &priv); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_DSA: { struct dsa_public_key pub; struct dsa_private_key priv; struct dsa_signature sig; memset(&priv, 0, sizeof(priv)); memset(&pub, 0, sizeof(pub)); _dsa_params_to_pubkey (pk_params, &pub); _dsa_params_to_privkey (pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = _dsa_sign (&pub, &priv, NULL, rnd_func, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto dsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); dsa_fail: dsa_signature_clear (&sig); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_RSA: { struct rsa_private_key priv; bigint_t hash, nc, ri; if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } memset(&priv, 0, sizeof(priv)); _rsa_params_to_privkey (pk_params, &priv); nc = rsa_blind (hash, pk_params->params[1] /*e */ , pk_params->params[0] /*m */ , &ri); _gnutls_mpi_release (&hash); if (nc == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto rsa_fail; } rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc)); rsa_unblind (nc, ri, pk_params->params[0] /*m */ ); ret = _gnutls_mpi_dprint (nc, signature); rsa_fail: _gnutls_mpi_release (&nc); _gnutls_mpi_release (&ri); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = 0; cleanup: return ret; }