aboutsummaryrefslogtreecommitdiffstats
path: root/serve/crypto.h
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-27 19:17:02 +0100
committereunhhu <[email protected]>2026-09-27 19:17:02 +0100
commit6d276be51ba89b04a60bb16b5179c015ad202c7c (patch)
tree1d30ae7bbb2d1db9e9a1b627d0fb76dc26eaf074 /serve/crypto.h
parent313c4fa1720a0019c87083d3523b6643606c5aa6 (diff)
downloadpure-6d276be51ba89b04a60bb16b5179c015ad202c7c.tar.gz
pure-6d276be51ba89b04a60bb16b5179c015ad202c7c.zip
Seal in one session a wire, authenticated by the sender's key (088)
A sealed request cost three X25519 operations (about 0.5 ms), so sealed sends drained at half the plain rate. A wire now keeps one HPKE context, encapsulated at its first seal, and seals each request as the context's next number (a failed seal or a restart starts a new session); the header carries the session's encapsulated key and the number, so a receiver opens a session once per connection thread (16 remembered, the least used replaced) and each seal by its number, also after it restarts, unasked. A sender with a key of its own seals in HPKE auth mode and names that key in the header; a receiver started with --sender NAME=KEY takes deliveries only from the senders it names, each sealed with its key (403 sender otherwise). The body is now the ciphertext and its tag. Sealed sends, sender authenticated, drain at 461-464k a second against 462-470k plain and 207-234k sealed a request at a time (Raspberry Pi 5). The check adds: a wire's requests share one session numbered from 0; a changed number or sender key does not open; a receiver restarted naming its sender opens the same session again; another node claiming that sender's name with its own key is refused and applies nothing.
Diffstat (limited to 'serve/crypto.h')
-rw-r--r--serve/crypto.h16
1 files changed, 11 insertions, 5 deletions
diff --git a/serve/crypto.h b/serve/crypto.h
index 5083b23..4919c49 100644
--- a/serve/crypto.h
+++ b/serve/crypto.h
@@ -8,7 +8,7 @@
* first time a server seals, opens a seal or connects to an https receiver
* (serve/crypto.c): one that does none of these maps no OpenSSL, 2.3 MiB
* less resident and 0.6 MiB less of its own. */
-enum { PURE_CRYPTO_VERSION = 1 };
+enum { PURE_CRYPTO_VERSION = 2 };
typedef struct {
unsigned version;
@@ -20,12 +20,18 @@ typedef struct {
int (*tls_read)(PureTls *, void *bytes, int size);
int (*tls_write)(PureTls *, const void *bytes, int size);
void (*tls_close)(PureTls *);
- /* Sealing, as serve/seal.h says, in the suite named. */
+ /* Sealing, as serve/seal.h says; a sender's sessions in the suite named. */
PureSealKey *(*seal_key)(const char *path, char public_hex[2 * PURE_SEAL_KEY + 1], char *error, size_t size);
void (*seal_key_free)(PureSealKey *);
- bool (*seal)(const char *suite, const unsigned char peer[PURE_SEAL_KEY], const char *aad,
- const unsigned char *plain, size_t size, unsigned char *out);
- bool (*unseal)(const PureSealKey *, const char *suite, const char *aad, const unsigned char *sealed, size_t size,
+ PureSealer *(*sealer)(const char *suite, const unsigned char peer[PURE_SEAL_KEY], const PureSealKey *own,
+ unsigned char enc[PURE_SEAL_KEY]);
+ bool (*seal)(PureSealer *, const char *aad, const unsigned char *plain, size_t size, unsigned char *out,
+ uint64_t *n);
+ void (*sealer_free)(PureSealer *);
+ PureOpener *(*opener)(const PureSealKey *, const char *suite, const unsigned char enc[PURE_SEAL_KEY],
+ const unsigned char *from);
+ bool (*unseal)(PureOpener *, uint64_t n, const char *aad, const unsigned char *sealed, size_t size,
unsigned char *plain);
+ void (*opener_free)(PureOpener *);
} PureCrypto;
#endif