summaryrefslogtreecommitdiff
path: root/lib/nettle/pk.c
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2021-09-23 07:50:38 +0000
committerDaiki Ueno <ueno@gnu.org>2021-09-23 07:50:38 +0000
commit7a220bf3899f3a32d6ff667d3861d15312ccd35b (patch)
tree131eb151d1185653a4c34ad345872a980420e4c0 /lib/nettle/pk.c
parent970000abfe3f88a8659da084852db258310246fd (diff)
parenta00a79ddf41eb14d56bdea076b5c252029896431 (diff)
downloadgnutls-7a220bf3899f3a32d6ff667d3861d15312ccd35b.tar.gz
Merge branch 'x25519-and-x448' into 'master'
certtool: generate, parse, and manipulate X25519 and X448 pubkeys, privkeys, and certificates See merge request gnutls/gnutls!1428
Diffstat (limited to 'lib/nettle/pk.c')
-rw-r--r--lib/nettle/pk.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index 16d9b4a04c..6af19c459f 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -831,6 +831,19 @@ get_eddsa_curve(gnutls_pk_algorithm_t algo)
}
}
+static inline gnutls_ecc_curve_t
+get_ecdh_curve(gnutls_pk_algorithm_t algo)
+{
+ switch (algo) {
+ case GNUTLS_PK_ECDH_X25519:
+ return GNUTLS_ECC_CURVE_X25519;
+ case GNUTLS_PK_ECDH_X448:
+ return GNUTLS_ECC_CURVE_X448;
+ default:
+ return gnutls_assert_val(GNUTLS_ECC_CURVE_INVALID);
+ }
+}
+
static inline int
eddsa_sign(gnutls_pk_algorithm_t algo,
const uint8_t *pub,
@@ -1789,6 +1802,8 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
case GNUTLS_PK_ECDSA:
case GNUTLS_PK_EDDSA_ED25519:
case GNUTLS_PK_EDDSA_ED448:
+ case GNUTLS_PK_ECDH_X25519:
+ case GNUTLS_PK_ECDH_X448:
#if ENABLE_GOST
case GNUTLS_PK_GOST_01:
case GNUTLS_PK_GOST_12_256:
@@ -3098,6 +3113,34 @@ wrap_nettle_pk_verify_priv_params(gnutls_pk_algorithm_t algo,
ret = 0;
break;
}
+ case GNUTLS_PK_ECDH_X25519:
+ case GNUTLS_PK_ECDH_X448: {
+ gnutls_ecc_curve_t curve;
+ const gnutls_ecc_curve_entry_st *e;
+ uint8_t pub[57]; /* can accommodate both curves */
+
+ curve = get_ecdh_curve(algo);
+ e = _gnutls_ecc_curve_get_params(curve);
+ if (e == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (params->raw_pub.data == NULL) {
+ return 0; /* nothing to verify */
+ }
+
+ if (params->raw_pub.size != e->size)
+ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
+
+ ret = edwards_curve_mul_g(algo, pub, params->raw_priv.data);
+ if (ret < 0)
+ return ret;
+
+ if (memcmp(params->raw_pub.data, pub, e->size) != 0)
+ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
+
+ ret = 0;
+ break;
+ }
#if ENABLE_GOST
case GNUTLS_PK_GOST_01:
case GNUTLS_PK_GOST_12_256:
@@ -3464,6 +3507,30 @@ wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo,
}
params->raw_pub.size = params->raw_priv.size;
+ } else if (algo == GNUTLS_PK_ECDH_X25519 ||
+ algo == GNUTLS_PK_ECDH_X448) {
+ if (unlikely(get_ecdh_curve(algo) != params->curve))
+ return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
+
+ if (params->raw_priv.data == NULL)
+ return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
+
+ if (params->raw_pub.data == NULL) {
+ params->raw_pub.data = gnutls_malloc(params->raw_priv.size);
+ }
+
+ if (params->raw_pub.data == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ ret = edwards_curve_mul_g(algo,
+ params->raw_pub.data,
+ params->raw_priv.data);
+ if (ret < 0) {
+ gnutls_free(params->raw_pub.data);
+ return ret;
+ }
+
+ params->raw_pub.size = params->raw_priv.size;
} else if (algo == GNUTLS_PK_RSA_PSS) {
if (params->params_nr < RSA_PRIVATE_PARAMS - 3)
return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);