Norbert Pócs writes:
> I took an another look at the PR, if there is anything possible to delete
> without loosing the functionality, but unfortunately didn't find anything.
To get a better understanding of the HPKE spec and its complexities,
I've tried to implement KEM x25519-sha256 (and nothing else from the
spec). Patch below.
Some notes:
1. Nettle's hkdf interface isn't that a good fit, if one wants to avoid
memcpy calls to assemble the inputs. Below, I haven't used Nettle's
hkdf_extract / hkdf_expand, instead doing corresponding operations
directly on hmac_sha256. Unless I'm missing something, it seems a
LabeledExpand function limited to at most 32 octets of output (the
sha256 digest size) is sufficient for everything in hpke, except for
the Export feature.
2. I don't quite like that some functions (in particular DeriveKeyPair)
are defined so that it can fail (not for x25519, though). Having a
success/failure indication there forces applications to have an error
handling path, that it's rather difficult to test. I see no obvious
way for Nettle to shield applications from that, though.
3. For those of you who have looked closer at proposed post-quantum KEM
mechanisms, is the interface suitable for those too?
4. It seems that HPKE defines a very clean interface between the KEM and
the rest of the message handling, with the shared_secret the only
piece of data shered between KEM and the rest of the processing.
Regards,
/Niels
diff --git a/Makefile.in b/Makefile.in
index f027e762..eb520f7a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -225,7 +225,8 @@ hogweed_SOURCES = sexp.c sexp-format.c \
ed25519-sha512.c ed25519-sha512-pubkey.c \
ed25519-sha512-sign.c ed25519-sha512-verify.c \
ed448-shake256.c ed448-shake256-pubkey.c \
- ed448-shake256-sign.c ed448-shake256-verify.c
+ ed448-shake256-sign.c ed448-shake256-verify.c \
+ kem-x25519-sha256.c
OPT_SOURCES = fat-arm.c fat-arm64.c fat-ppc.c fat-s390x.c fat-x86_64.c
mini-gmp.c
diff --git a/hpke-kem.h b/hpke-kem.h
new file mode 100644
index ..00b4610b
--- /dev/null
+++ b/hpke-kem.h
@@ -0,0 +1,71 @@
+/* hpke-kem.h
+
+ Key encapsulation mechanism, suitable for HPKE (RFC 9180).
+
+ Copyright (C) 2024 Niels Möller
+
+ This file is part of GNU Nettle.
+
+ GNU Nettle is free software: you can redistribute it and/or
+ modify it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ or both in parallel, as here.
+
+ GNU Nettle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef NETTLE_HPKE_KEM_H_INCLUDED
+#define NETTLE_HPKE_KEM_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define get_kem_x25519_sha256 nettle_get_kem_x25519_sha256
+
+typedef int kem_derive_keypair_func (uint8_t *public_key, uint8_t *private_key,
+size_t seed_size, const uint8_t *seed);
+/* Take randomness source instead? Passing seed suites deterministic tests. */
+typedef void kem_encapsulate_func (uint8_t *shared_secret, uint8_t
*encapsulation,
+ const uint8_t *receiver_public_key,
+ void *random_ctx, nettle_random_func
*random);
+typedef void kem_decapsulate_func (uint8_t *shared_secret, const uint8_t
*encapsulation,
+ const uint8_t *private_key);
+
+struct hpke_kem {
+ unsigned public_key_size;
+ unsigned private_key_size;
+ unsigned encapsulation_size;
+ unsigned shared_secret_size;
+ kem_derive_keypair_func *derive_keypair;
+ kem_encapsulate_func *encapsulate;
+ kem_decapsulate_func *decapsulate;
+};
+
+const struct hpke_kem *get_kem_x25519_sha256 (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_HPKE_KEM_H_INCLUDED */
diff --git a/kem-x25519-sha256.c b/kem-x25519-sha256.c
new file mode 100644
index ..186ced6c
--- /dev/null
+++ b/kem-x25519-sha256.c
@@ -0,0 +1,170 @@
+/* kem-x25519-sha256.c
+
+ KEM using curve25519, suitable for HPKE (RFC 9180).
+
+ Copyright (C) 2024 Niels Möller
+
+ This file is part of GNU Nettle.
+
+ GNU Nettle is free software: you can redistribute it