static int _wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo, gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, const gnutls_pk_params_st * pk_params) { int ret; mpz_t p; mpz_init(p); switch (algo) { case GNUTLS_PK_RSA: { struct rsa_public_key pub; _rsa_params_to_pubkey(pk_params, &pub); ret = rsa_encrypt(&pub, NULL, rnd_func, plaintext->size, plaintext->data, p); if (ret == 0) { ret = gnutls_assert_val (GNUTLS_E_ENCRYPTION_FAILED); goto cleanup; } ret = _gnutls_mpi_dprint_size(p, ciphertext, pub.size); if (ret < 0) { gnutls_assert(); goto cleanup; } break; } default: gnutls_assert(); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = 0; cleanup: mpz_clear(p); FAIL_IF_LIB_ERROR; return ret; }
static int _wrap_nettle_pk_encrypt (gnutls_pk_algorithm_t algo, gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, const gnutls_pk_params_st * pk_params) { int ret; switch (algo) { case GNUTLS_PK_RSA: { bigint_t p; if (_gnutls_mpi_scan_nz (&p, plaintext->data, plaintext->size) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } mpz_powm (p, p, TOMPZ (pk_params->params[1]) /*e */ , TOMPZ (pk_params->params[0] /*m */ )); ret = _gnutls_mpi_dprint_size (p, ciphertext, plaintext->size); _gnutls_mpi_release (&p); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = 0; cleanup: return ret; }
static int _wrap_gcry_pk_encrypt (gnutls_pk_algorithm_t algo, gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, const gnutls_pk_params_st * pk_params) { gcry_sexp_t s_ciph = NULL, s_data = NULL, s_pkey = NULL; int rc = -1; int ret; bigint_t data, res; gcry_sexp_t list; if (_gnutls_mpi_scan_nz (&data, plaintext->data, plaintext->size) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } /* make a sexp from pkey */ switch (algo) { case GNUTLS_PK_RSA: if (pk_params->params_nr >= 2) rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", pk_params->params[0], pk_params->params[1]); break; default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } if (rc != 0) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } /* put the data into a simple list */ if (gcry_sexp_build (&s_data, NULL, "%m", data)) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } /* pass it to libgcrypt */ rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); if (rc != 0) { gnutls_assert (); ret = GNUTLS_E_PK_ENCRYPTION_FAILED; goto cleanup; } list = gcry_sexp_find_token (s_ciph, "a", 0); if (list == NULL) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } res = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG); gcry_sexp_release (list); if (res == NULL) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = _gnutls_mpi_dprint_size (res, ciphertext, plaintext->size); _gnutls_mpi_release (&res); if (ret < 0) { gnutls_assert (); goto cleanup; } ret = 0; cleanup: _gnutls_mpi_release (&data); if (s_ciph) gcry_sexp_release (s_ciph); if (s_data) gcry_sexp_release (s_data); if (s_pkey) gcry_sexp_release (s_pkey); return ret; }
static int _wrap_gcry_pk_decrypt (gnutls_pk_algorithm_t algo, gnutls_datum_t * plaintext, const gnutls_datum_t * ciphertext, const gnutls_pk_params_st * pk_params) { gcry_sexp_t s_plain = NULL, s_data = NULL, s_pkey = NULL; int rc = -1; int ret; bigint_t data, res; if (_gnutls_mpi_scan_nz (&data, ciphertext->data, ciphertext->size) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } /* make a sexp from pkey */ switch (algo) { case GNUTLS_PK_RSA: if (pk_params->params_nr >= 6) rc = gcry_sexp_build (&s_pkey, NULL, "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", pk_params->params[0], pk_params->params[1], pk_params->params[2], pk_params->params[3], pk_params->params[4], pk_params->params[5]); break; default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } if (rc != 0) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } /* put the data into a simple list */ if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data)) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } /* pass it to libgcrypt */ rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey); if (rc != 0) { gnutls_assert (); ret = GNUTLS_E_PK_DECRYPTION_FAILED; goto cleanup; } res = gcry_sexp_nth_mpi (s_plain, 0, GCRYMPI_FMT_USG); if (res == NULL) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = _gnutls_mpi_dprint_size (res, plaintext, ciphertext->size); _gnutls_mpi_release (&res); if (ret < 0) { gnutls_assert (); goto cleanup; } ret = 0; cleanup: _gnutls_mpi_release (&data); if (s_plain) gcry_sexp_release (s_plain); if (s_data) gcry_sexp_release (s_data); if (s_pkey) gcry_sexp_release (s_pkey); return ret; }
static int _wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo, gnutls_datum_t * plaintext, const gnutls_datum_t * ciphertext, const gnutls_pk_params_st * pk_params) { int ret; /* make a sexp from pkey */ switch (algo) { case GNUTLS_PK_RSA: { struct rsa_private_key priv; bigint_t c, ri, nc; if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } nc = rsa_blind (c, pk_params->params[1] /*e */ , pk_params->params[0] /*m */ , &ri); _gnutls_mpi_release (&c); if (nc == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } memset(&priv, 0, sizeof(priv)); _rsa_params_to_privkey (pk_params, &priv); rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc)); rsa_unblind (nc, ri, pk_params->params[0] /*m */ ); ret = _gnutls_mpi_dprint_size (nc, plaintext, ciphertext->size); _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; }
/* 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_len; const mac_entry_st *me; switch (algo) { case GNUTLS_PK_EC: /* we do ECDSA */ { struct ecc_scalar priv; struct dsa_signature sig; int curve_id = pk_params->flags; const struct ecc_curve *curve; curve = get_supported_curve(curve_id); if (curve == NULL) return gnutls_assert_val (GNUTLS_E_ECC_UNSUPPORTED_CURVE); ret = _ecc_params_to_privkey(pk_params, &priv, curve); if (ret < 0) return gnutls_assert_val(ret); dsa_signature_init(&sig); me = _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(me), hash_len); hash_len = vdata->size; } ecdsa_sign(&priv, NULL, rnd_func, hash_len, vdata->data, &sig); ret = _gnutls_encode_ber_rs(signature, &sig.r, &sig.s); dsa_signature_clear(&sig); ecc_scalar_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); me = _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(me), 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_size(s, signature, pub.size); 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; }