diff options
Diffstat (limited to 'lib/nettle/pk.c')
-rw-r--r-- | lib/nettle/pk.c | 2093 |
1 files changed, 1080 insertions, 1013 deletions
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index de578054c3..673495dcf0 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -49,1025 +49,1094 @@ static inline const struct ecc_curve *get_supported_curve(int curve); -static void -rnd_func (void *_ctx, unsigned length, uint8_t * data) +static void rnd_func(void *_ctx, unsigned length, uint8_t * data) { - _gnutls_rnd (GNUTLS_RND_RANDOM, data, length); + _gnutls_rnd(GNUTLS_RND_RANDOM, data, length); } static void -_dsa_params_to_pubkey (const gnutls_pk_params_st * pk_params, - struct dsa_public_key *pub) +_dsa_params_to_pubkey(const gnutls_pk_params_st * pk_params, + struct dsa_public_key *pub) { - memcpy (&pub->p, pk_params->params[0], sizeof (mpz_t)); - memcpy (&pub->q, pk_params->params[1], sizeof (mpz_t)); - memcpy (&pub->g, pk_params->params[2], sizeof (mpz_t)); - memcpy (&pub->y, pk_params->params[3], sizeof (mpz_t)); + memcpy(&pub->p, pk_params->params[0], sizeof(mpz_t)); + memcpy(&pub->q, pk_params->params[1], sizeof(mpz_t)); + memcpy(&pub->g, pk_params->params[2], sizeof(mpz_t)); + memcpy(&pub->y, pk_params->params[3], sizeof(mpz_t)); } static void -_dsa_params_to_privkey (const gnutls_pk_params_st * pk_params, - struct dsa_private_key *pub) +_dsa_params_to_privkey(const gnutls_pk_params_st * pk_params, + struct dsa_private_key *pub) { - memcpy (&pub->x, pk_params->params[4], sizeof (mpz_t)); + memcpy(&pub->x, pk_params->params[4], sizeof(mpz_t)); } static void -_rsa_params_to_privkey (const gnutls_pk_params_st * pk_params, - struct rsa_private_key *priv) +_rsa_params_to_privkey(const gnutls_pk_params_st * pk_params, + struct rsa_private_key *priv) { - memcpy (&priv->d, pk_params->params[2], sizeof (mpz_t)); - memcpy (&priv->p, pk_params->params[3], sizeof (mpz_t)); - memcpy (&priv->q, pk_params->params[4], sizeof (mpz_t)); - memcpy (&priv->c, pk_params->params[5], sizeof (mpz_t)); - memcpy (&priv->a, pk_params->params[6], sizeof (mpz_t)); - memcpy (&priv->b, pk_params->params[7], sizeof (mpz_t)); - priv->size = nettle_mpz_sizeinbase_256_u(TOMPZ(pk_params->params[RSA_MODULUS])); + memcpy(&priv->d, pk_params->params[2], sizeof(mpz_t)); + memcpy(&priv->p, pk_params->params[3], sizeof(mpz_t)); + memcpy(&priv->q, pk_params->params[4], sizeof(mpz_t)); + memcpy(&priv->c, pk_params->params[5], sizeof(mpz_t)); + memcpy(&priv->a, pk_params->params[6], sizeof(mpz_t)); + memcpy(&priv->b, pk_params->params[7], sizeof(mpz_t)); + priv->size = + nettle_mpz_sizeinbase_256_u(TOMPZ + (pk_params->params[RSA_MODULUS])); } static void -_rsa_params_to_pubkey (const gnutls_pk_params_st * pk_params, - struct rsa_public_key *pub) +_rsa_params_to_pubkey(const gnutls_pk_params_st * pk_params, + struct rsa_public_key *pub) { - memcpy (&pub->n, pk_params->params[RSA_MODULUS], sizeof (mpz_t)); - memcpy (&pub->e, pk_params->params[RSA_PUB], sizeof (mpz_t)); - pub->size = nettle_mpz_sizeinbase_256_u(pub->n); + memcpy(&pub->n, pk_params->params[RSA_MODULUS], sizeof(mpz_t)); + memcpy(&pub->e, pk_params->params[RSA_PUB], sizeof(mpz_t)); + pub->size = nettle_mpz_sizeinbase_256_u(pub->n); } static int _ecc_params_to_privkey(const gnutls_pk_params_st * pk_params, - struct ecc_scalar * priv, const struct ecc_curve *curve) + struct ecc_scalar *priv, + const struct ecc_curve *curve) { - ecc_scalar_init(priv, curve); - if (ecc_scalar_set(priv, pk_params->params[ECC_K]) == 0) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ecc_scalar_init(priv, curve); + if (ecc_scalar_set(priv, pk_params->params[ECC_K]) == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - return 0; + return 0; } static int _ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params, - struct ecc_point * pub, const struct ecc_curve *curve) + struct ecc_point *pub, const struct ecc_curve *curve) { - ecc_point_init(pub, curve); - if (ecc_point_set(pub, pk_params->params[ECC_X], pk_params->params[ECC_Y]) == 0) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ecc_point_init(pub, curve); + if (ecc_point_set + (pub, pk_params->params[ECC_X], pk_params->params[ECC_Y]) == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - return 0; + return 0; } static void -ecc_shared_secret (struct ecc_scalar * private_key, - struct ecc_point * public_key, - void *out, unsigned size) +ecc_shared_secret(struct ecc_scalar *private_key, + struct ecc_point *public_key, void *out, unsigned size) { -struct ecc_point r; -mpz_t x; + struct ecc_point r; + mpz_t x; + + mpz_init(x); + ecc_point_init(&r, public_key->ecc); + + ecc_point_mul(&r, private_key, public_key); - mpz_init(x); - ecc_point_init(&r, public_key->ecc); + ecc_point_get(&r, x, NULL); + nettle_mpz_get_str_256(size, out, x); - ecc_point_mul(&r, private_key, public_key); - - ecc_point_get(&r, x, NULL); - nettle_mpz_get_str_256(size, out, x); + mpz_clear(x); + ecc_point_clear(&r); - mpz_clear(x); - ecc_point_clear(&r); - - return; + return; } -static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, gnutls_datum_t * out, - const gnutls_pk_params_st * priv, - const gnutls_pk_params_st * pub) +static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, + gnutls_datum_t * out, + const gnutls_pk_params_st * priv, + const gnutls_pk_params_st * pub) { - int ret; - - switch (algo) - { - case GNUTLS_PK_EC: - { - struct ecc_scalar ecc_priv; - struct ecc_point ecc_pub; - const struct ecc_curve * curve; - - out->data = NULL; - - curve = get_supported_curve(priv->flags); - if (curve == NULL) - return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - - ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _ecc_params_to_privkey(priv, &ecc_priv, curve); - if (ret < 0) - { - ecc_point_clear(&ecc_pub); - return gnutls_assert_val(ret); - } - - out->size = gnutls_ecc_curve_get_size(priv->flags); - /*ecc_size(curve)*sizeof(mp_limb_t);*/ - out->data = gnutls_malloc(out->size); - if (out->data == NULL) - { - ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - goto ecc_cleanup; - } - - ecc_shared_secret(&ecc_priv, &ecc_pub, out->data, out->size); - -ecc_cleanup: - ecc_point_clear(&ecc_pub); - ecc_scalar_clear(&ecc_priv); - if (ret < 0) goto cleanup; - break; - } - default: - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - - ret = 0; - -cleanup: - - return ret; + int ret; + + switch (algo) { + case GNUTLS_PK_EC: + { + struct ecc_scalar ecc_priv; + struct ecc_point ecc_pub; + const struct ecc_curve *curve; + + out->data = NULL; + + curve = get_supported_curve(priv->flags); + if (curve == NULL) + return + gnutls_assert_val + (GNUTLS_E_ECC_UNSUPPORTED_CURVE); + + ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = + _ecc_params_to_privkey(priv, &ecc_priv, curve); + if (ret < 0) { + ecc_point_clear(&ecc_pub); + return gnutls_assert_val(ret); + } + + out->size = gnutls_ecc_curve_get_size(priv->flags); + /*ecc_size(curve)*sizeof(mp_limb_t); */ + out->data = gnutls_malloc(out->size); + if (out->data == NULL) { + ret = + gnutls_assert_val + (GNUTLS_E_MEMORY_ERROR); + goto ecc_cleanup; + } + + ecc_shared_secret(&ecc_priv, &ecc_pub, out->data, + out->size); + + ecc_cleanup: + ecc_point_clear(&ecc_pub); + ecc_scalar_clear(&ecc_priv); + if (ret < 0) + goto cleanup; + break; + } + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + ret = 0; + + cleanup: + + 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) +_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); - return ret; + 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); + 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) +_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; - - plaintext->data = NULL; - - /* make a sexp from pkey */ - switch (algo) - { - case GNUTLS_PK_RSA: - { - struct rsa_private_key priv; - struct rsa_public_key pub; - unsigned length; - bigint_t c; - - _rsa_params_to_privkey (pk_params, &priv); - _rsa_params_to_pubkey (pk_params, &pub); - - if (ciphertext->size != pub.size) - return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); - - if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); - goto cleanup; - } - - length = pub.size; - plaintext->data = gnutls_malloc(length); - if (plaintext->data == NULL) - { - ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - goto cleanup; - } - - ret = rsa_decrypt_tr(&pub, &priv, NULL, rnd_func, &length, plaintext->data, - TOMPZ(c)); - _gnutls_mpi_release (&c); - plaintext->size = length; - - if (ret == 0) - { - ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); - goto cleanup; - } - - break; - } - default: - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - - ret = 0; - -cleanup: - if (ret < 0) - gnutls_free(plaintext->data); - - return ret; + int ret; + + plaintext->data = NULL; + + /* make a sexp from pkey */ + switch (algo) { + case GNUTLS_PK_RSA: + { + struct rsa_private_key priv; + struct rsa_public_key pub; + unsigned length; + bigint_t c; + + _rsa_params_to_privkey(pk_params, &priv); + _rsa_params_to_pubkey(pk_params, &pub); + + if (ciphertext->size != pub.size) + return + gnutls_assert_val + (GNUTLS_E_DECRYPTION_FAILED); + + if (_gnutls_mpi_scan_nz + (&c, ciphertext->data, + ciphertext->size) != 0) { + ret = + gnutls_assert_val + (GNUTLS_E_MPI_SCAN_FAILED); + goto cleanup; + } + + length = pub.size; + plaintext->data = gnutls_malloc(length); + if (plaintext->data == NULL) { + ret = + gnutls_assert_val + (GNUTLS_E_MEMORY_ERROR); + goto cleanup; + } + + ret = + rsa_decrypt_tr(&pub, &priv, NULL, rnd_func, + &length, plaintext->data, + TOMPZ(c)); + _gnutls_mpi_release(&c); + plaintext->size = length; + + if (ret == 0) { + ret = + gnutls_assert_val + (GNUTLS_E_DECRYPTION_FAILED); + goto cleanup; + } + + break; + } + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + ret = 0; + + cleanup: + if (ret < 0) + gnutls_free(plaintext->data); + + 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) +_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; + 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; } static int -_wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, - const gnutls_datum_t * vdata, - const gnutls_datum_t * signature, - const gnutls_pk_params_st * pk_params) +_wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + const gnutls_datum_t * vdata, + const gnutls_datum_t * signature, + const gnutls_pk_params_st * pk_params) { - int ret; - unsigned int hash_len; - bigint_t tmp[2] = { NULL, NULL }; - - switch (algo) - { - case GNUTLS_PK_EC: /* ECDSA */ - { - struct ecc_point pub; - 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 = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _ecc_params_to_pubkey(pk_params, &pub, curve); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - memcpy (&sig.r, tmp[0], sizeof (sig.r)); - memcpy (&sig.s, tmp[1], sizeof (sig.s)); - - _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); - - if (hash_len > vdata->size) - hash_len = vdata->size; - - ret = ecdsa_verify(&pub, hash_len, vdata->data, &sig); - if (ret == 0) - { - gnutls_assert(); - ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; - } - else - ret = 0; - - ecc_point_clear( &pub); - break; - } - case GNUTLS_PK_DSA: - { - struct dsa_public_key pub; - struct dsa_signature sig; - - ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]); - if (ret < 0) - { - gnutls_assert (); - goto cleanup; - } - memset(&pub, 0, sizeof(pub)); - _dsa_params_to_pubkey (pk_params, &pub); - memcpy (&sig.r, tmp[0], sizeof (sig.r)); - memcpy (&sig.s, tmp[1], sizeof (sig.s)); - - _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); - - if (hash_len > vdata->size) - hash_len = vdata->size; - - ret = _dsa_verify (&pub, hash_len, vdata->data, &sig); - if (ret == 0) - { - gnutls_assert(); - ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; - } - else - ret = 0; - - break; - } - case GNUTLS_PK_RSA: - { - struct rsa_public_key pub; - - _rsa_params_to_pubkey (pk_params, &pub); - - if (signature->size != pub.size) - return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED); - - ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size); - if (ret < 0) - { - gnutls_assert (); - goto cleanup; - } - - ret = rsa_pkcs1_verify (&pub, vdata->size, vdata->data, TOMPZ(tmp[0])); - if (ret == 0) - ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED); - else ret = 0; - - break; - } - default: - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - -cleanup: - - _gnutls_mpi_release (&tmp[0]); - _gnutls_mpi_release (&tmp[1]); - return ret; + int ret; + unsigned int hash_len; + bigint_t tmp[2] = { NULL, NULL }; + + switch (algo) { + case GNUTLS_PK_EC: /* ECDSA */ + { + struct ecc_point pub; + 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 = + _gnutls_decode_ber_rs(signature, &tmp[0], + &tmp[1]); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = + _ecc_params_to_pubkey(pk_params, &pub, curve); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + memcpy(&sig.r, tmp[0], sizeof(sig.r)); + memcpy(&sig.s, tmp[1], sizeof(sig.s)); + + _gnutls_dsa_q_to_hash(algo, pk_params, &hash_len); + + if (hash_len > vdata->size) + hash_len = vdata->size; + + ret = + ecdsa_verify(&pub, hash_len, vdata->data, + &sig); + if (ret == 0) { + gnutls_assert(); + ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; + } else + ret = 0; + + ecc_point_clear(&pub); + break; + } + case GNUTLS_PK_DSA: + { + struct dsa_public_key pub; + struct dsa_signature sig; + + ret = + _gnutls_decode_ber_rs(signature, &tmp[0], + &tmp[1]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + memset(&pub, 0, sizeof(pub)); + _dsa_params_to_pubkey(pk_params, &pub); + memcpy(&sig.r, tmp[0], sizeof(sig.r)); + memcpy(&sig.s, tmp[1], sizeof(sig.s)); + + _gnutls_dsa_q_to_hash(algo, pk_params, &hash_len); + + if (hash_len > vdata->size) + hash_len = vdata->size; + + ret = + _dsa_verify(&pub, hash_len, vdata->data, &sig); + if (ret == 0) { + gnutls_assert(); + ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; + } else + ret = 0; + + break; + } + case GNUTLS_PK_RSA: + { + struct rsa_public_key pub; + + _rsa_params_to_pubkey(pk_params, &pub); + + if (signature->size != pub.size) + return + gnutls_assert_val + (GNUTLS_E_PK_SIG_VERIFY_FAILED); + + ret = + _gnutls_mpi_scan_nz(&tmp[0], signature->data, + signature->size); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + rsa_pkcs1_verify(&pub, vdata->size, + vdata->data, TOMPZ(tmp[0])); + if (ret == 0) + ret = + gnutls_assert_val + (GNUTLS_E_PK_SIG_VERIFY_FAILED); + else + ret = 0; + + break; + } + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + cleanup: + + _gnutls_mpi_release(&tmp[0]); + _gnutls_mpi_release(&tmp[1]); + return ret; } static inline const struct ecc_curve *get_supported_curve(int curve) { - switch(curve) - { - case GNUTLS_ECC_CURVE_SECP192R1: - return &nettle_secp_192r1; - case GNUTLS_ECC_CURVE_SECP224R1: - return &nettle_secp_224r1; - case GNUTLS_ECC_CURVE_SECP256R1: - return &nettle_secp_256r1; - case GNUTLS_ECC_CURVE_SECP384R1: - return &nettle_secp_384r1; - case GNUTLS_ECC_CURVE_SECP521R1: - return &nettle_secp_521r1; - default: - return NULL; - } + switch (curve) { + case GNUTLS_ECC_CURVE_SECP192R1: + return &nettle_secp_192r1; + case GNUTLS_ECC_CURVE_SECP224R1: + return &nettle_secp_224r1; + case GNUTLS_ECC_CURVE_SECP256R1: + return &nettle_secp_256r1; + case GNUTLS_ECC_CURVE_SECP384R1: + return &nettle_secp_384r1; + case GNUTLS_ECC_CURVE_SECP521R1: + return &nettle_secp_521r1; + default: + return NULL; + } } static int -wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo, - unsigned int level /*bits */ , - gnutls_pk_params_st * params) +wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo, + unsigned int level /*bits */ , + gnutls_pk_params_st * params) { - int ret; - unsigned int i, q_bits; - - memset(params, 0, sizeof(*params)); - - switch (algo) - { - - case GNUTLS_PK_DSA: - { - struct dsa_public_key pub; - struct dsa_private_key priv; - - dsa_public_key_init (&pub); - dsa_private_key_init (&priv); - - /* the best would be to use _gnutls_pk_bits_to_subgroup_bits() - * but we do NIST DSA here */ - if (level <= 1024) - q_bits = 160; - else - q_bits = 256; - - ret = - dsa_generate_keypair (&pub, &priv, NULL, - rnd_func, NULL, NULL, level, q_bits); - if (ret != 1) - { - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - goto dsa_fail; - } - - params->params_nr = 0; - for (i = 0; i < DSA_PRIVATE_PARAMS; i++) - { - params->params[i] = _gnutls_mpi_alloc_like (&pub.p); - if (params->params[i] == NULL) - { - ret = GNUTLS_E_MEMORY_ERROR; - goto dsa_fail; - } - params->params_nr++; - } - - ret = 0; - _gnutls_mpi_set (params->params[0], pub.p); - _gnutls_mpi_set (params->params[1], pub.q); - _gnutls_mpi_set (params->params[2], pub.g); - _gnutls_mpi_set (params->params[3], pub.y); - _gnutls_mpi_set (params->params[4], priv.x); - -dsa_fail: - dsa_private_key_clear (&priv); - dsa_public_key_clear (&pub); - - if (ret < 0) - goto fail; - - break; - } - case GNUTLS_PK_RSA: - { - struct rsa_public_key pub; - struct rsa_private_key priv; - - rsa_public_key_init (&pub); - rsa_private_key_init (&priv); - - _gnutls_mpi_set_ui (&pub.e, 65537); - - ret = - rsa_generate_keypair (&pub, &priv, NULL, - rnd_func, NULL, NULL, level, 0); - if (ret != 1) - { - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - goto rsa_fail; - } - - params->params_nr = 0; - for (i = 0; i < RSA_PRIVATE_PARAMS; i++) - { - params->params[i] = _gnutls_mpi_alloc_like (&pub.n); - if (params->params[i] == NULL) - { - ret = GNUTLS_E_MEMORY_ERROR; - goto rsa_fail; - } - params->params_nr++; - - } - - ret = 0; - - _gnutls_mpi_set (params->params[0], pub.n); - _gnutls_mpi_set (params->params[1], pub.e); - _gnutls_mpi_set (params->params[2], priv.d); - _gnutls_mpi_set (params->params[3], priv.p); - _gnutls_mpi_set (params->params[4], priv.q); - _gnutls_mpi_set (params->params[5], priv.c); - _gnutls_mpi_set (params->params[6], priv.a); - _gnutls_mpi_set (params->params[7], priv.b); - -rsa_fail: - rsa_private_key_clear (&priv); - rsa_public_key_clear (&pub); - - if (ret < 0) - goto fail; - - break; - } - case GNUTLS_PK_EC: - { - struct ecc_scalar key; - struct ecc_point pub; - const struct ecc_curve* curve; - - curve = get_supported_curve(level); - if (curve == NULL) - return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - - ecc_scalar_init(&key, curve); - ecc_point_init(&pub, curve); - - ecdsa_generate_keypair(&pub, &key, NULL, rnd_func); - - params->params[ECC_X] = _gnutls_mpi_new (0); - params->params[ECC_Y] = _gnutls_mpi_new (0); - params->params[ECC_K] = _gnutls_mpi_new (0); - - if (params->params[ECC_X] == NULL || params->params[ECC_Y] == NULL || - params->params[ECC_K] == NULL) - { - _gnutls_mpi_release(¶ms->params[ECC_X]); - _gnutls_mpi_release(¶ms->params[ECC_Y]); - _gnutls_mpi_release(¶ms->params[ECC_K]); - goto ecc_cleanup; - } - - params->flags = level; - params->params_nr = ECC_PRIVATE_PARAMS; - - ecc_point_get(&pub, TOMPZ(params->params[ECC_X]), TOMPZ(params->params[ECC_Y])); - ecc_scalar_get(&key, TOMPZ(params->params[ECC_K])); - -ecc_cleanup: - ecc_point_clear(&pub); - ecc_scalar_clear(&key); - - break; - } - default: - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - - return 0; - -fail: - - for (i = 0; i < params->params_nr; i++) - { - _gnutls_mpi_release (¶ms->params[i]); - } - params->params_nr = 0; - - return ret; + int ret; + unsigned int i, q_bits; + + memset(params, 0, sizeof(*params)); + + switch (algo) { + + case GNUTLS_PK_DSA: + { + struct dsa_public_key pub; + struct dsa_private_key priv; + + dsa_public_key_init(&pub); + dsa_private_key_init(&priv); + + /* the best would be to use _gnutls_pk_bits_to_subgroup_bits() + * but we do NIST DSA here */ + if (level <= 1024) + q_bits = 160; + else + q_bits = 256; + + ret = + dsa_generate_keypair(&pub, &priv, NULL, + rnd_func, NULL, NULL, + level, q_bits); + if (ret != 1) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto dsa_fail; + } + + params->params_nr = 0; + for (i = 0; i < DSA_PRIVATE_PARAMS; i++) { + params->params[i] = + _gnutls_mpi_alloc_like(&pub.p); + if (params->params[i] == NULL) { + ret = GNUTLS_E_MEMORY_ERROR; + goto dsa_fail; + } + params->params_nr++; + } + + ret = 0; + _gnutls_mpi_set(params->params[0], pub.p); + _gnutls_mpi_set(params->params[1], pub.q); + _gnutls_mpi_set(params->params[2], pub.g); + _gnutls_mpi_set(params->params[3], pub.y); + _gnutls_mpi_set(params->params[4], priv.x); + + dsa_fail: + dsa_private_key_clear(&priv); + dsa_public_key_clear(&pub); + + if (ret < 0) + goto fail; + + break; + } + case GNUTLS_PK_RSA: + { + struct rsa_public_key pub; + struct rsa_private_key priv; + + rsa_public_key_init(&pub); + rsa_private_key_init(&priv); + + _gnutls_mpi_set_ui(&pub.e, 65537); + + ret = + rsa_generate_keypair(&pub, &priv, NULL, + rnd_func, NULL, NULL, + level, 0); + if (ret != 1) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto rsa_fail; + } + + params->params_nr = 0; + for (i = 0; i < RSA_PRIVATE_PARAMS; i++) { + params->params[i] = + _gnutls_mpi_alloc_like(&pub.n); + if (params->params[i] == NULL) { + ret = GNUTLS_E_MEMORY_ERROR; + goto rsa_fail; + } + params->params_nr++; + + } + + ret = 0; + + _gnutls_mpi_set(params->params[0], pub.n); + _gnutls_mpi_set(params->params[1], pub.e); + _gnutls_mpi_set(params->params[2], priv.d); + _gnutls_mpi_set(params->params[3], priv.p); + _gnutls_mpi_set(params->params[4], priv.q); + _gnutls_mpi_set(params->params[5], priv.c); + _gnutls_mpi_set(params->params[6], priv.a); + _gnutls_mpi_set(params->params[7], priv.b); + + rsa_fail: + rsa_private_key_clear(&priv); + rsa_public_key_clear(&pub); + + if (ret < 0) + goto fail; + + break; + } + case GNUTLS_PK_EC: + { + struct ecc_scalar key; + struct ecc_point pub; + const struct ecc_curve *curve; + + curve = get_supported_curve(level); + if (curve == NULL) + return + gnutls_assert_val + (GNUTLS_E_ECC_UNSUPPORTED_CURVE); + + ecc_scalar_init(&key, curve); + ecc_point_init(&pub, curve); + + ecdsa_generate_keypair(&pub, &key, NULL, rnd_func); + + params->params[ECC_X] = _gnutls_mpi_new(0); + params->params[ECC_Y] = _gnutls_mpi_new(0); + params->params[ECC_K] = _gnutls_mpi_new(0); + + if (params->params[ECC_X] == NULL + || params->params[ECC_Y] == NULL + || params->params[ECC_K] == NULL) { + _gnutls_mpi_release(¶ms-> + params[ECC_X]); + _gnutls_mpi_release(¶ms-> + params[ECC_Y]); + _gnutls_mpi_release(¶ms-> + params[ECC_K]); + goto ecc_cleanup; + } + + params->flags = level; + params->params_nr = ECC_PRIVATE_PARAMS; + + ecc_point_get(&pub, TOMPZ(params->params[ECC_X]), + TOMPZ(params->params[ECC_Y])); + ecc_scalar_get(&key, TOMPZ(params->params[ECC_K])); + + ecc_cleanup: + ecc_point_clear(&pub); + ecc_scalar_clear(&key); + + break; + } + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + return 0; + + fail: + + for (i = 0; i < params->params_nr; i++) { + _gnutls_mpi_release(¶ms->params[i]); + } + params->params_nr = 0; + + return ret; } static int -wrap_nettle_pk_verify_params (gnutls_pk_algorithm_t algo, - const gnutls_pk_params_st * params) +wrap_nettle_pk_verify_params(gnutls_pk_algorithm_t algo, + const gnutls_pk_params_st * params) { - int ret; - - switch (algo) - { - case GNUTLS_PK_RSA: - { - bigint_t t1 = NULL, t2 = NULL; - - if (params->params_nr != RSA_PRIVATE_PARAMS) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - t1 = _gnutls_mpi_new (256); - if (t1 == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - _gnutls_mpi_mulm (t1, params->params[RSA_PRIME1], params->params[RSA_PRIME2], params->params[RSA_MODULUS]); - if (_gnutls_mpi_cmp_ui(t1, 0) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto rsa_cleanup; - } - - mpz_invert (TOMPZ(t1), TOMPZ (params->params[RSA_PRIME2]), TOMPZ (params->params[RSA_PRIME1])); - if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF]) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto rsa_cleanup; - } - - /* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */ - _gnutls_mpi_sub_ui (t1, params->params[RSA_PRIME1], 1); - t2 = _gnutls_mpi_mod (params->params[RSA_PRIV], t1); - if (t2 == NULL) - { - ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - goto rsa_cleanup; - } - - if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto rsa_cleanup; - } - - _gnutls_mpi_sub_ui (t1, params->params[RSA_PRIME2], 1); - _gnutls_mpi_release(&t2); - - t2 = _gnutls_mpi_mod (params->params[RSA_PRIV], t1); - if (t2 == NULL) - { - ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - goto rsa_cleanup; - } - - if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto rsa_cleanup; - } - - ret = 0; - -rsa_cleanup: - _gnutls_mpi_release(&t1); - _gnutls_mpi_release(&t2); - } - - break; - case GNUTLS_PK_DSA: - { - bigint_t t1 = NULL; - - if (params->params_nr != DSA_PRIVATE_PARAMS) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - t1 = _gnutls_mpi_new (256); - if (t1 == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - _gnutls_mpi_powm (t1, params->params[DSA_G], params->params[DSA_X], params->params[DSA_P]); - - if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto dsa_cleanup; - } - - ret = 0; - -dsa_cleanup: - _gnutls_mpi_release(&t1); - } - - break; - case GNUTLS_PK_EC: - { - struct ecc_point r, pub; - struct ecc_scalar priv; - mpz_t x1, y1, x2, y2; - const struct ecc_curve * curve; - - if (params->params_nr != ECC_PRIVATE_PARAMS) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - curve = get_supported_curve(params->flags); - if (curve == NULL) - return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - - ret = _ecc_params_to_pubkey(params, &pub, curve); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _ecc_params_to_privkey(params, &priv, curve); - if (ret < 0) - { - ecc_point_clear(&pub); - return gnutls_assert_val(ret); - } - - ecc_point_init(&r, curve); - /* verify that x,y lie on the curve */ - ret = ecc_point_set(&r, TOMPZ(params->params[ECC_X]), TOMPZ(params->params[ECC_Y])); - if (ret == 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto ecc_cleanup; - } - ecc_point_clear(&r); - - ecc_point_init(&r, curve); - ecc_point_mul_g(&r, &priv); - - mpz_init(x1); - mpz_init(y1); - ecc_point_get(&r, x1, y1); - ecc_point_clear(&r); - - mpz_init(x2); - mpz_init(y2); - ecc_point_get(&pub, x2, y2); - - /* verify that k*(Gx,Gy)=(x,y) */ - if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) - { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto ecc_cleanup; - } - - ret = 0; - -ecc_cleanup: - ecc_scalar_clear(&priv); - ecc_point_clear(&pub); - } - break; - default: - ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - } - - return ret; + int ret; + + switch (algo) { + case GNUTLS_PK_RSA: + { + bigint_t t1 = NULL, t2 = NULL; + + if (params->params_nr != RSA_PRIVATE_PARAMS) + return + gnutls_assert_val + (GNUTLS_E_INVALID_REQUEST); + + t1 = _gnutls_mpi_new(256); + if (t1 == NULL) + return + gnutls_assert_val + (GNUTLS_E_MEMORY_ERROR); + + _gnutls_mpi_mulm(t1, params->params[RSA_PRIME1], + params->params[RSA_PRIME2], + params->params[RSA_MODULUS]); + if (_gnutls_mpi_cmp_ui(t1, 0) != 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto rsa_cleanup; + } + + mpz_invert(TOMPZ(t1), + TOMPZ(params->params[RSA_PRIME2]), + TOMPZ(params->params[RSA_PRIME1])); + if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF]) + != 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto rsa_cleanup; + } + + /* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */ + _gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME1], + 1); + t2 = _gnutls_mpi_mod(params->params[RSA_PRIV], t1); + if (t2 == NULL) { + ret = + gnutls_assert_val + (GNUTLS_E_MEMORY_ERROR); + goto rsa_cleanup; + } + + if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) != + 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto rsa_cleanup; + } + + _gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME2], + 1); + _gnutls_mpi_release(&t2); + + t2 = _gnutls_mpi_mod(params->params[RSA_PRIV], t1); + if (t2 == NULL) { + ret = + gnutls_assert_val + (GNUTLS_E_MEMORY_ERROR); + goto rsa_cleanup; + } + + if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) != + 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto rsa_cleanup; + } + + ret = 0; + + rsa_cleanup: + _gnutls_mpi_release(&t1); + _gnutls_mpi_release(&t2); + } + + break; + case GNUTLS_PK_DSA: + { + bigint_t t1 = NULL; + + if (params->params_nr != DSA_PRIVATE_PARAMS) + return + gnutls_assert_val + (GNUTLS_E_INVALID_REQUEST); + + t1 = _gnutls_mpi_new(256); + if (t1 == NULL) + return + gnutls_assert_val + (GNUTLS_E_MEMORY_ERROR); + + _gnutls_mpi_powm(t1, params->params[DSA_G], + params->params[DSA_X], + params->params[DSA_P]); + + if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) != + 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto dsa_cleanup; + } + + ret = 0; + + dsa_cleanup: + _gnutls_mpi_release(&t1); + } + + break; + case GNUTLS_PK_EC: + { + struct ecc_point r, pub; + struct ecc_scalar priv; + mpz_t x1, y1, x2, y2; + const struct ecc_curve *curve; + + if (params->params_nr != ECC_PRIVATE_PARAMS) + return + gnutls_assert_val + (GNUTLS_E_INVALID_REQUEST); + + curve = get_supported_curve(params->flags); + if (curve == NULL) + return + gnutls_assert_val + (GNUTLS_E_ECC_UNSUPPORTED_CURVE); + + ret = _ecc_params_to_pubkey(params, &pub, curve); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _ecc_params_to_privkey(params, &priv, curve); + if (ret < 0) { + ecc_point_clear(&pub); + return gnutls_assert_val(ret); + } + + ecc_point_init(&r, curve); + /* verify that x,y lie on the curve */ + ret = + ecc_point_set(&r, TOMPZ(params->params[ECC_X]), + TOMPZ(params->params[ECC_Y])); + if (ret == 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto ecc_cleanup; + } + ecc_point_clear(&r); + + ecc_point_init(&r, curve); + ecc_point_mul_g(&r, &priv); + + mpz_init(x1); + mpz_init(y1); + ecc_point_get(&r, x1, y1); + ecc_point_clear(&r); + + mpz_init(x2); + mpz_init(y2); + ecc_point_get(&pub, x2, y2); + + /* verify that k*(Gx,Gy)=(x,y) */ + if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) { + ret = + gnutls_assert_val + (GNUTLS_E_ILLEGAL_PARAMETER); + goto ecc_cleanup; + } + + ret = 0; + + ecc_cleanup: + ecc_scalar_clear(&priv); + ecc_point_clear(&pub); + } + break; + default: + ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + } + + return ret; } -static int calc_rsa_exp (gnutls_pk_params_st* params) +static int calc_rsa_exp(gnutls_pk_params_st * params) { - bigint_t tmp = _gnutls_mpi_alloc_like (params->params[0]); + bigint_t tmp = _gnutls_mpi_alloc_like(params->params[0]); - if (params->params_nr < RSA_PRIVATE_PARAMS - 2) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } + if (params->params_nr < RSA_PRIVATE_PARAMS - 2) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } - if (tmp == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } + if (tmp == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } - /* [6] = d % p-1, [7] = d % q-1 */ - _gnutls_mpi_sub_ui (tmp, params->params[3], 1); - params->params[6] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp); + /* [6] = d % p-1, [7] = d % q-1 */ + _gnutls_mpi_sub_ui(tmp, params->params[3], 1); + params->params[6] = + _gnutls_mpi_mod(params->params[2] /*d */ , tmp); - _gnutls_mpi_sub_ui (tmp, params->params[4], 1); - params->params[7] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp); + _gnutls_mpi_sub_ui(tmp, params->params[4], 1); + params->params[7] = + _gnutls_mpi_mod(params->params[2] /*d */ , tmp); - _gnutls_mpi_release (&tmp); + _gnutls_mpi_release(&tmp); - if (params->params[7] == NULL || params->params[6] == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } + if (params->params[7] == NULL || params->params[6] == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } - return 0; + return 0; } static int -wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo, - gnutls_direction_t direction, - gnutls_pk_params_st * params) +wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo, + gnutls_direction_t direction, + gnutls_pk_params_st * params) { - int result; - - if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA) - { - /* do not trust the generated values. Some old private keys - * generated by us have mess on the values. Those were very - * old but it seemed some of the shipped example private - * keys were as old. - */ - mpz_invert (TOMPZ (params->params[RSA_COEF]), - TOMPZ (params->params[RSA_PRIME2]), TOMPZ (params->params[RSA_PRIME1])); - - /* calculate exp1 [6] and exp2 [7] */ - _gnutls_mpi_release (¶ms->params[RSA_E1]); - _gnutls_mpi_release (¶ms->params[RSA_E2]); - - result = calc_rsa_exp (params); - if (result < 0) - { - gnutls_assert (); - return result; - } - params->params_nr = RSA_PRIVATE_PARAMS; - } - - return 0; + int result; + + if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA) { + /* do not trust the generated values. Some old private keys + * generated by us have mess on the values. Those were very + * old but it seemed some of the shipped example private + * keys were as old. + */ + mpz_invert(TOMPZ(params->params[RSA_COEF]), + TOMPZ(params->params[RSA_PRIME2]), + TOMPZ(params->params[RSA_PRIME1])); + + /* calculate exp1 [6] and exp2 [7] */ + _gnutls_mpi_release(¶ms->params[RSA_E1]); + _gnutls_mpi_release(¶ms->params[RSA_E2]); + + result = calc_rsa_exp(params); + if (result < 0) { + gnutls_assert(); + return result; + } + params->params_nr = RSA_PRIVATE_PARAMS; + } + + return 0; } static int extract_digest_info(const struct rsa_public_key *key, - gnutls_datum_t *di, uint8_t** rdi, - const mpz_t signature) + gnutls_datum_t * di, uint8_t ** rdi, + const mpz_t signature) { - unsigned i; - int ret; - mpz_t m; - uint8_t *em; - - if (key->size == 0) - return 0; - - em = gnutls_malloc(key->size); - if (em == NULL) - return 0; - - mpz_init (m); - - mpz_powm(m, signature, key->e, key->n); - - nettle_mpz_get_str_256(key->size, em, m); - mpz_clear(m); - - if (em[0] != 0 || em[1] != 1) - { - ret = 0; - goto cleanup; - } - - for (i = 2; i < key->size; i++) - { - if (em[i] == 0 && i > 2) - break; - - if (em[i] != 0xff) - { - ret = 0; - goto cleanup; - } - } - - i++; - - *rdi = em; - - di->data = &em[i]; - di->size = key->size - i; - - return 1; - -cleanup: - gnutls_free(em); - - return ret; + unsigned i; + int ret; + mpz_t m; + uint8_t *em; + + if (key->size == 0) + return 0; + + em = gnutls_malloc(key->size); + if (em == NULL) + return 0; + + mpz_init(m); + + mpz_powm(m, signature, key->e, key->n); + + nettle_mpz_get_str_256(key->size, em, m); + mpz_clear(m); + + if (em[0] != 0 || em[1] != 1) { + ret = 0; + goto cleanup; + } + + for (i = 2; i < key->size; i++) { + if (em[i] == 0 && i > 2) + break; + + if (em[i] != 0xff) { + ret = 0; + goto cleanup; + } + } + + i++; + + *rdi = em; + + di->data = &em[i]; + di->size = key->size - i; + + return 1; + + cleanup: + gnutls_free(em); + + return ret; } /* Given a signature and parameters, it should return @@ -1075,82 +1144,80 @@ cleanup: * but until we deprecate gnutls_pubkey_get_verify_algorithm() * we depend on it. */ -static int wrap_nettle_hash_algorithm (gnutls_pk_algorithm_t pk, - const gnutls_datum_t * sig, gnutls_pk_params_st * issuer_params, - gnutls_digest_algorithm_t* hash_algo) +static int wrap_nettle_hash_algorithm(gnutls_pk_algorithm_t pk, + const gnutls_datum_t * sig, + gnutls_pk_params_st * issuer_params, + gnutls_digest_algorithm_t * + hash_algo) { - uint8_t digest[MAX_HASH_SIZE]; - uint8_t* rdi = NULL; - gnutls_datum_t di; - unsigned digest_size; - mpz_t s; - struct rsa_public_key pub; - const mac_entry_st* me; - int ret; - - mpz_init(s); - - switch (pk) - { - case GNUTLS_PK_DSA: - case GNUTLS_PK_EC: - - me = _gnutls_dsa_q_to_hash (pk, issuer_params, NULL); - if (hash_algo) - *hash_algo = me->id; - - ret = 0; - break; - case GNUTLS_PK_RSA: - if (sig == NULL) - { /* return a sensible algorithm */ - if (hash_algo) - *hash_algo = GNUTLS_DIG_SHA256; - return 0; - } - - _rsa_params_to_pubkey (issuer_params, &pub); - - digest_size = sizeof(digest); - - nettle_mpz_set_str_256_u(s, sig->size, sig->data); - - ret = extract_digest_info( &pub, &di, &rdi, s); - if (ret == 0) - { - ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; - gnutls_assert (); - goto cleanup; - } - - digest_size = sizeof(digest); - if ((ret = - decode_ber_digest_info (&di, hash_algo, digest, - &digest_size)) < 0) - { - gnutls_assert (); - goto cleanup; - } - - if (digest_size != _gnutls_hash_get_algo_len (mac_to_entry(*hash_algo))) - { - gnutls_assert (); - ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; - goto cleanup; - } - - ret = 0; - break; - - default: - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - } - -cleanup: - mpz_clear(s); - gnutls_free(rdi); - return ret; + uint8_t digest[MAX_HASH_SIZE]; + uint8_t *rdi = NULL; + gnutls_datum_t di; + unsigned digest_size; + mpz_t s; + struct rsa_public_key pub; + const mac_entry_st *me; + int ret; + + mpz_init(s); + + switch (pk) { + case GNUTLS_PK_DSA: + case GNUTLS_PK_EC: + + me = _gnutls_dsa_q_to_hash(pk, issuer_params, NULL); + if (hash_algo) + *hash_algo = me->id; + + ret = 0; + break; + case GNUTLS_PK_RSA: + if (sig == NULL) { /* return a sensible algorithm */ + if (hash_algo) + *hash_algo = GNUTLS_DIG_SHA256; + return 0; + } + + _rsa_params_to_pubkey(issuer_params, &pub); + + digest_size = sizeof(digest); + + nettle_mpz_set_str_256_u(s, sig->size, sig->data); + + ret = extract_digest_info(&pub, &di, &rdi, s); + if (ret == 0) { + ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; + gnutls_assert(); + goto cleanup; + } + + digest_size = sizeof(digest); + if ((ret = + decode_ber_digest_info(&di, hash_algo, digest, + &digest_size)) < 0) { + gnutls_assert(); + goto cleanup; + } + + if (digest_size != + _gnutls_hash_get_algo_len(mac_to_entry(*hash_algo))) { + gnutls_assert(); + ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; + goto cleanup; + } + + ret = 0; + break; + + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + } + + cleanup: + mpz_clear(s); + gnutls_free(rdi); + return ret; } @@ -1158,13 +1225,13 @@ cleanup: int crypto_pk_prio = INT_MAX; gnutls_crypto_pk_st _gnutls_pk_ops = { - .hash_algorithm = wrap_nettle_hash_algorithm, - .encrypt = _wrap_nettle_pk_encrypt, - .decrypt = _wrap_nettle_pk_decrypt, - .sign = _wrap_nettle_pk_sign, - .verify = _wrap_nettle_pk_verify, - .verify_params = wrap_nettle_pk_verify_params, - .generate = wrap_nettle_pk_generate_params, - .pk_fixup_private_params = wrap_nettle_pk_fixup, - .derive = _wrap_nettle_pk_derive, + .hash_algorithm = wrap_nettle_hash_algorithm, + .encrypt = _wrap_nettle_pk_encrypt, + .decrypt = _wrap_nettle_pk_decrypt, + .sign = _wrap_nettle_pk_sign, + .verify = _wrap_nettle_pk_verify, + .verify_params = wrap_nettle_pk_verify_params, + .generate = wrap_nettle_pk_generate_params, + .pk_fixup_private_params = wrap_nettle_pk_fixup, + .derive = _wrap_nettle_pk_derive, }; |