From: Fabio Scotoni <34964387+fscoto@users.noreply.github.com> Date: Thu, 7 Mar 2019 09:48:35 +0000 (+0100) Subject: Address points brought up by @LoupVaillant in review X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=0c35d8f7fc91ce21c52c6b3805f9f44451981d9c;p=Monocypher.git Address points brought up by @LoupVaillant in review --- diff --git a/doc/man/man3/crypto_kex_x_init_client.3monocypher b/doc/man/man3/crypto_kex_x_init_client.3monocypher index 499485a..0e0b3af 100644 --- a/doc/man/man3/crypto_kex_x_init_client.3monocypher +++ b/doc/man/man3/crypto_kex_x_init_client.3monocypher @@ -48,13 +48,14 @@ that is suitable for use with .Xr crypto_lock 3monocypher . The .Em server -generates an X25519 secret key and its corresponding public -key ahead of time using -.Xr crypto_key_exchange_public_key 3monocypher -when the key exchange starts. +and the +.Em client +each generate a long-term X25519 secret key and its corresponding public +key ahead of time before the key exchange using +.Xr crypto_key_exchange_public_key 3monocypher . The .Em client -does not need to know the +must know the .Em server's public key before performing the key exchange. The @@ -64,16 +65,14 @@ initiates the key exchange. These functions differ from the .Xr crypto_kex_xk1_init_client 3monocypher functions in that the functions described in this page -.Em do not -authenticate the server's identity. -If you can share a server's public key with client applications ahead of -time, -always prefer +can be used even if a server is offline (i.e. asynchronous +communication); they have lower security guarantees, see +.Sx SECURITY CONSIDERATIONS . +If you can, always prefer .Xr crypto_kex_xk1_init_client 3monocypher . .Ss Key exchange as the client When starting a new connection to the server, the client first reads -the server's public key from the network; -then it calls +the server's public key from the network; then it calls .Fn crypto_client_x_init_client to initialize a .Vt crypto_kex_ctx . @@ -90,9 +89,10 @@ See .Xr intro 3monocypher for advice about generating random bytes (use the operating system's random number generator). +This argument is not constant because it is wiped after use. .It Fa local_sk A 32-byte secret random number. -This should be different for every connection you make. +This is a long-term secret used to identify the respective party. .It Fa local_pk The public key corresponding to the .Fa local_sk , @@ -105,7 +105,7 @@ the public key will be generated for you. The public key of the server. .El .Pp -After creating initializing +After creating initialising .Fa ctx , the client calls .Fn crypto_kex_x_1 @@ -117,12 +117,7 @@ It proceeds to send .Fa msg1 to the server to complete the key exchange. .Ss Key exchange as the server -When accepting a new connection from a client, the server first -generates a new secret key and sends the corresponding public key, -derived from the secret key using -.Xr crypto_key_exchange_public_key 3monocypher , -to the client. -It then calls +When accepting a new connection from a client, the server calls .Fn crypto_client_xk1_init_server to initialize a .Vt crypto_kex_ctx . @@ -130,12 +125,13 @@ The arguments to .Fn crypto_client_xk1_init_server are identical to the arguments to .Fn crypto_client_xk1_init_client , -except that the server does not need a -.Fa random_seed -and does not need to know a client's public key, -so no +except that the server does not need a +.Fa random_seed ; +no .Fa remote_pk -can be specified. +can be specified because the server authenticates clients +only once the handshake completes, +which is application logic and not part of the key exchange protocol. .Pp After initializing .Fa ctx , @@ -151,11 +147,13 @@ which yields and .Fa remote_pk , the client's public key. +The server can use this to authenticate clients by their public key; +.Em if possible, always authenticate clients . .Fn crypto_kex_x_2 returns zero on success and -1 if the client's message mismatches the key exchange until now. .Em Always check the return value . -On success, this function also wipes the data in +This function also wipes the data in .Fa ctx . .Sh RETURN VALUES .Fn crypto_kex_x_init_client , @@ -170,7 +168,7 @@ server's identity. Corruption can be caused by transmission errors, programmer error, or an attacker's interference. .Sh EXAMPLES -These examples use UNIX\(rg networking functions to keep the examples +These examples use *NIX networking functions to keep the examples concise, but any kind of networking code will work. It is assumed that the client and server have already established a @@ -179,16 +177,15 @@ connection with each other. Client: .Bd -literal -offset indent crypto_kex_ctx client_ctx; /* key exchange context */ -uint8_t sk[32]; /* 32 random bytes ephemeral secret key */ -uint8_t their_pk[32]; /* the server's ephemeral public key */ +uint8_t sk[32]; /* 32 random bytes long-term secret key */ +uint8_t their_pk[32]; /* the server's public key + * (known ahead of time) */ uint8_t seed[32]; /* 32 random bytes */ uint8_t buf[80]; /* buffer for the key exchange messages */ uint8_t session_key[32]; /* the resulting session key */ int fd; /* the socket of the connection */ -if (read(fd, their_pk, 32) != 32) - return -1; -/* (generate random bytes in seed and sk here) */ +/* (generate random bytes in seed) */ crypto_kex_x_init_client(&client_ctx, seed, sk, NULL, their_pk); crypto_kex_x_1(&client_ctx, session_key, buf); if (write(fd, buf, 80) != 80) @@ -200,18 +197,14 @@ if (write(fd, buf, 80) != 80) Server: .Bd -literal -offset indent crypto_kex_ctx server_ctx; /* key exchange context */ -uint8_t sk[32]; /* 32 random bytes ephemeral secret key */ +uint8_t sk[32]; /* 32 random bytes long-term secret key */ uint8_t my_pk[32]; /* public key to sk */ -uint8_t their_pk[32]; /* the server's public key */ +uint8_t their_pk[32]; /* the client's public key */ uint8_t seed[32]; /* 32 random bytes */ uint8_t buf[80]; /* buffer for the key exchange messages */ uint8_t session_key[32]; /* the resulting session key */ int fd; /* the socket of the connection */ -/* (generate random bytes in sk here) */ -crypto_key_exchange_public_key(my_pk, sk); -if (write(fd, my_pk, 32) != 32) - return -1; crypto_kex_x_init_server(&server_ctx, sk, my_pk); if (read(fd, buf, 80) != 80) return -2; @@ -227,3 +220,26 @@ crypto_kex_1_2(&server_ctx, session_key, their_pk, buf); .Sh STANDARDS These functions are equivalent to an implementation of the X pattern of the Noise protocol framework. +.Sh SECURITY CONSIDERATIONS +Unlike the +.Xr crypto_kex_xk1_init_client 3monocypher +family of functions, the functions described on this page suffer from a +number of security issues: +.Bl -tag -width Ds +.It Limited forward secrecy +If an attacker manages to steal the server's long-term secret key, +past messages may be recovered. +.It Replay attacks +The server does not send a random challenge in this. +.It Key compromise impersonation +If an attacker manages to steal the server's long-term secret key, +the attacker can impersonate +.Em any +client to that server; if client identity is tied to authorization, +this also means that authorization requirements can be bypassed. +.El +.Pp +The reason they are provided is because they work even if the other +party cannot respond to a key exchange immediately (e.g. if the server +may not always be available; consider something like crash dumps where +a program may be used temporarily in an offline environment). diff --git a/doc/man/man3/crypto_kex_xk1_init_client.3monocypher b/doc/man/man3/crypto_kex_xk1_init_client.3monocypher index e43e02f..5a5e7a9 100644 --- a/doc/man/man3/crypto_kex_xk1_init_client.3monocypher +++ b/doc/man/man3/crypto_kex_xk1_init_client.3monocypher @@ -63,10 +63,13 @@ that is suitable for use with .Xr crypto_lock 3monocypher . The .Em server -must have generated an X25519 secret key and its corresponding public -key ahead of time using +and the +.Em client +each generate a long-term X25519 secret key and its corresponding public +key ahead of time before the key exchange using .Xr crypto_key_exchange_public_key 3monocypher . -This key is also used by the client to verify the server's identity. +These keys are also used by the by each party to verify the other +party's identity. The .Em client must know the @@ -78,8 +81,9 @@ initiates the key exchange. .Pp These functions differ from the .Xr crypto_kex_x_init_client 3monocypher -functions in that the functions described in this page authenticate a -server's identity. +functions in that the functions described in this page provide stronger +security guarantees, but also require the server to be able to respond +to a connection from a client immediately. .Ss Key exchange as the client When starting a new connection to the server, the client first calls .Fn crypto_client_xk1_init_client @@ -98,9 +102,10 @@ See .Xr intro 3monocypher for advice about generating random bytes (use the operating system's random number generator). +This argument is not constant because it is wiped after use. .It Fa local_sk A 32-byte secret random number. -This should be different for every connection the client makes. +This is a long-term secret used to identify the respective party. .It Fa local_pk The public key corresponding to the .Fa local_sk , @@ -115,7 +120,7 @@ making a connection. This is used to authenticate the server's identity. .El .Pp -After creating initializing +After initialising .Fa ctx , the client calls .Fn crypto_kex_xk1_1 @@ -137,7 +142,7 @@ and returns zero on success and -1 if the server's message mismatches the key exchange until now. .Em Always check the return value . -On success, this function also wipes the data in +This function also wipes the data in .Fa ctx . The client sends .Fa msg3 @@ -151,11 +156,11 @@ The arguments to .Fn crypto_client_xk1_init_server are identical to the arguments to .Fn crypto_client_xk1_init_client , -except that the server does not know a client's public key yet, +except that the server does not know the client's public key yet, so no .Fa remote_pk -can be specified; -the server's +can be specified because the server authenticates clients +once the handshake completes; the server's .Fa local_sk and .Fa local_pk @@ -185,11 +190,13 @@ which yields and .Fa remote_pk , the client's public key. +The server can use this to authenticate clients by their public key; +.Em if possible, always authenticate clients . .Fn crypto_kex_xk1_4 returns zero on success and -1 if the client's message mismatches the key exchange until now. .Em Always check the return value . -On success, this function also wipes the data in +This function also wipes the data in .Fa ctx . .Sh RETURN VALUES .Fn crypto_kex_xk1_init_client , @@ -207,7 +214,7 @@ server's identity. Corruption can be caused by transmission errors, programmer error, or an attacker's interference. .Sh EXAMPLES -These examples use UNIX\(rg networking functions to keep the examples +These examples use *NIX networking functions to keep the examples readable, but any kind of networking code will work. It is assumed that the client and server have already established a @@ -216,7 +223,7 @@ connection with each other. Client: .Bd -literal -offset indent crypto_kex_ctx client_ctx; /* key exchange context */ -uint8_t sk[32]; /* 32 random bytes ephemeral secret key */ +uint8_t sk[32]; /* 32 random bytes long-term secret key */ uint8_t their_pk[32]; /* the server's public key * (known ahead of time) */ uint8_t seed[32]; /* 32 random bytes */ @@ -224,7 +231,7 @@ uint8_t buf[48]; /* buffer for the key exchange messages */ uint8_t session_key[32]; /* the resulting session key */ int fd; /* the socket of the connection */ -/* (generate random bytes in seed and sk here) */ +/* (generate random bytes in seed here) */ crypto_kex_xk1_init_client(&client_ctx, seed, sk, NULL, their_pk); crypto_kex_xk1_1(&client_ctx, buf); if (write(fd, buf, 32) != 32) diff --git a/doc/man/man3/crypto_x25519.3monocypher b/doc/man/man3/crypto_x25519.3monocypher index ad6c35e..07053e3 100644 --- a/doc/man/man3/crypto_x25519.3monocypher +++ b/doc/man/man3/crypto_x25519.3monocypher @@ -1,4 +1,4 @@ -.Dd July 18, 2018 +.Dd March 6, 2019 .Dt CRYPTO_X25519 3MONOCYPHER .Os .Sh NAME @@ -106,6 +106,12 @@ If either of the long term secret keys leaks, it may compromise .Em all past messages . This can be avoided by using protocols that provide forward secrecy, such as the X3DH key agreement protocol. +Monocypher provides the +.Xr crypto_kex_xk1_init_client 3monocypher +and +.Xr crypto_kex_x_init_client 3monocypher +families of functions, +which provide forward secrecy. .Sh IMPLEMENTATION DETAILS The most significant bit of the public key is systematically ignored. It is not needed because every public key should be smaller than diff --git a/doc/man/man3/intro.3monocypher b/doc/man/man3/intro.3monocypher index 9dbde6b..c4cd2ba 100644 --- a/doc/man/man3/intro.3monocypher +++ b/doc/man/man3/intro.3monocypher @@ -1,4 +1,4 @@ -.Dd December 28, 2017 +.Dd March 6, 2019 .Dt INTRO 3MONOCYPHER .Os .Sh NAME @@ -34,8 +34,17 @@ implements the Argon2i resource intensive hash algorithm. Argon2 won the password hashing competition in 2015. Unlike Scrypt, Argon2i is immune to timing attacks. .Ss Key exchange -.Xr crypto_key_exchange 3monocypher -implements X25519, an elliptic curve Diffie Hellman key exchange +The +.Xr crypto_kex_xk1_init_client 3monocypher +and +.Xr crypto_kex_x_init_client 3monocypher +families of functions, +provide key exhange protocols with forward secrecy. +.Pp +If more control over the key exchange is required, +there is +.Xr crypto_key_exchange 3monocypher , +which implements X25519, an elliptic curve Diffie Hellman key exchange algorithm based on Curve25519. X25519 derives a shared secret from two private/public key pairs. It is fast, simple, and relatively easy to implement securely. @@ -78,6 +87,8 @@ the chances of leaks. .Xr crypto_check_final 3monocypher , .Xr crypto_check_init 3monocypher , .Xr crypto_check_update 3monocypher , +.Xr crypto_kex_xk1_init_client 3monocypher , +.Xr crypto_kex_x_init_client 3monocypher , .Xr crypto_key_exchange 3monocypher , .Xr crypto_lock 3monocypher , .Xr crypto_lock_aead 3monocypher , @@ -195,7 +206,13 @@ vulnerability and be compromised. To mitigate this problem, some protocols guarantee that past messages are not compromised even if the long term keys are. This is done by generating temporary keys, then encrypting messages -with them. +using them. +Monocypher provides the +.Xr crypto_kex_xk1_init_client 3monocypher +and +.Xr crypto_kex_x_init_client 3monocypher +families of functions, +which provide forward secrecy. .Pp In general, secrets that went through a computer should not be compromised when this computer is stolen or infected at a later point.