From d85326a119c34789055c388fcd18bb0161fbfd21 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sat, 14 Feb 2026 14:33:50 +0100 Subject: irmd: Add strength-based crypto negotiation Each side's configured cipher, KDF, and KEX algorithm now represents a minimum security floor ("at least this strong"). Cipher and KDF use strongest-wins: the server compares ranks and selects the stronger of client vs server config. The negotiated values are sent in the response header. The client verifies the server's response meets its own minimum, which prevents downgrade attacks on the wire. KEX uses a minimum-floor check: the server extracts the client's algorithm from its public key and rejects if it ranks below the server's configured algorithm. A server configured with ML-KEM will reject all classical algorithms. Special case: for client-encap KEM, the client has already derived its key using its KDF, so the server must use the same KDF and can only reject if it is too weak. The supported_nids arrays are ordered weakest to strongest and serve as the single source of truth for ranking. Cipher ranking (weakest to strongest): aes-128-ctr, aes-192-ctr, aes-256-ctr, aes-128-gcm, aes-192-gcm, aes-256-gcm, chacha20-poly1305 KDF ranking (weakest to strongest): blake2s256, sha256, sha3-256, sha384, sha3-384, blake2b512, sha512, sha3-512 KEX ranking (weakest to strongest): ffdhe2048, prime256v1, X25519, ffdhe3072, secp384r1, ffdhe4096, X448, secp521r1, ML-KEM-512, ML-KEM-768, ML-KEM-1024, X25519MLKEM768, X448MLKEM1024 Negotiation outcomes: strong srv cipher + weak cli cipher -> use strongest weak srv cipher + strong cli cipher -> use strongest srv encryption + cli none -> server rejects srv none + cli encryption -> use client's strong srv KEX + weak cli KEX -> server rejects weak srv KEX + strong cli KEX -> succeeds wire tamper to weaker cipher -> client rejects Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/irmd/oap/internal.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src/irmd/oap/internal.h') diff --git a/src/irmd/oap/internal.h b/src/irmd/oap/internal.h index 8363e3a2..f118cc33 100644 --- a/src/irmd/oap/internal.h +++ b/src/irmd/oap/internal.h @@ -34,24 +34,15 @@ #include #include -/* - * Authentication functions (auth.c) - */ int oap_check_hdr(const struct oap_hdr * hdr); int oap_auth_peer(char * name, const struct oap_hdr * local_hdr, const struct oap_hdr * peer_hdr); -/* - * Key exchange functions (kex.c) - */ int oap_negotiate_cipher(const struct oap_hdr * peer_hdr, struct sec_config * kcfg); -/* - * Credential loading (oap.c) - shared between client and server - */ #ifndef OAP_TEST_MODE int load_credentials(const char * name, const struct name_sec_paths * paths, @@ -63,9 +54,6 @@ int load_kex_config(const char * name, struct sec_config * cfg); #endif -/* - * Server functions (srv.c) - */ #ifndef OAP_TEST_MODE int load_srv_credentials(const struct name_info * info, void ** pkp, @@ -94,9 +82,6 @@ int do_server_kex(const struct name_info * info, buffer_t * kex, struct crypt_sk * sk); -/* - * Client functions (cli.c) - */ #ifndef OAP_TEST_MODE int load_cli_credentials(const struct name_info * info, void ** pkp, -- cgit v1.2.3