From ddb527ea6ac199b7735ab8943a06562b9d9d3135 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 7 May 2021 19:48:10 -0400 Subject: nettle: extend pk_verify_priv_params to handle X25519 and X448 This is basically a copy of the EdDSA case in the switch statement. Another way to implement it would be to augment the EdDSA case (and the functions it uses) to have that case also handle ECDH use of the CFRG curves. Signed-off-by: Daniel Kahn Gillmor --- lib/nettle/pk.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'lib/nettle') diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 16d9b4a04c..a1642d0f35 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, @@ -3098,6 +3111,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: -- cgit v1.2.1 From f0a9af880a618772fd81584355fa0657639fcbf8 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 7 May 2021 19:53:28 -0400 Subject: Enable X25519 and X448 everywhere that EdDSA is supported. These are just trivial extension points where the codepath is the same for the ECDH scheme as it is for the EdDSA scheme. Signed-off-by: Daniel Kahn Gillmor --- lib/nettle/pk.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/nettle') diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index a1642d0f35..ec2f1e5df6 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -1802,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: -- cgit v1.2.1 From c605e559e890ce77ec033a6c1cad819f266401a8 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 7 May 2021 21:30:53 -0400 Subject: nettle: handle X25519 and X448 in pk_fixup Signed-off-by: Daniel Kahn Gillmor --- lib/nettle/pk.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib/nettle') diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index ec2f1e5df6..6af19c459f 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -3506,6 +3506,30 @@ wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo, return ret; } + 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) -- cgit v1.2.1