<div dir="ltr"><div class="gmail_extra">Hi Trevor,
</div><div class="gmail_extra"><br></div><div class="gmail_extra">I've implemented Noise_IS according to this branch. Below is a condensed representation of this, if you're curious to check it for correctness. But before that, I'll also paste a diff here to the previous version, before the recent round of substantive changes.</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><table summary="diff" class="" style="border-collapse:collapse;width:1827px"><tbody><tr><td style="font-family:monospace;white-space:pre"><div class="" style="font-weight:bold;margin-top:1em;color:black;font-size:13.3333px">diff --git a/doc/<a href="http://protocol.md">protocol.md</a> b/doc/<a href="http://protocol.md">protocol.md</a><br>index 9f1d0de..7f817ae 100644<br>--- a/<a href="http://git.zx2c4.com/WireGuard/tree/doc/protocol.md?id=7d647b293345fe60decc16197c2e40be8f1a4a01" style="color:blue;text-decoration:none">doc/protocol.md</a><br>+++ b/<a href="http://git.zx2c4.com/WireGuard/tree/doc/protocol.md?id=dfc3f8c0a143732d75b4a58092a1439dd2b6d5db" style="color:blue;text-decoration:none">doc/protocol.md</a></div><div class="" style="color:rgb(0,0,153);font-size:13.3333px">@@ -61,19 +61,19 @@ The initiator sends this message:</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> </div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> The fields are populated as follows:</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> </div><div class="" style="color:red;font-size:13.3333px">- initiator.key = "Noise WireGuard zx2c4 2015-08-31"</div><div class="" style="color:red;font-size:13.3333px">- initiator.hash = HASH(responder.static_public)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ initiator.key = 32 bytes of zeros</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ initiator.hash = HASH("Noise WireGuard zx2c4 2015-09-30" || responder.static_public)</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> initiator.ephemeral_private = DH_GENERATE()</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.message_type = 1</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.sender_index = little_endian(initiator.sender_index)</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.unencrypted_ephemeral = DH_PUBKEY(initiator.ephemeral_private)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ initiator.hash = HASH(initiator.hash || msg.unencrypted_ephemeral)</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> initiator.key = KDF(GETKEY(initiator.key, 0), DH(initiator.ephemeral_private, responder.static_public))</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.encrypted_static = AEAD(initiator.key, 0, initiator.static_public, initiator.hash)</div><div class="" style="color:red;font-size:13.3333px">- initiator.hash = HASH(initiator.hash || initiator.static_public)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ initiator.hash = HASH(initiator.hash || msg.encrypted_static)</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> initiator.key = KDF(GETKEY(initiator.key, 1), DH(initiator.static_private, responder.static_public))</div><div class="" style="color:red;font-size:13.3333px">- stamp = TAI64N()</div><div class="" style="color:red;font-size:13.3333px">- msg.encrypted_timestamp = AEAD(initiator.key, 0, stamp, initiator.hash)</div><div class="" style="color:red;font-size:13.3333px">- initiator.hash = HASH(initiator.hash || stamp)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ msg.encrypted_timestamp = AEAD(initiator.key, 0, TAI64N(), initiator.hash)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ initiator.hash = HASH(initiator.hash || msg.encrypted_timestamp)</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> </div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> When the responder receives this message, he decrypts and does all the above operations in reverse, so that the state is identical.</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> </div><div class="" style="color:rgb(0,0,153);font-size:13.3333px">@@ -85,7 +85,7 @@ The responder sends this message, after processing the first message above and a</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> u8 message_type</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> u16 sender_index</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> u16 receiver_index</div><div class="" style="color:red;font-size:13.3333px">- u8 unencrypted_ephemeral[32]</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ u8 encrypted_ephemeral[AEAD_LEN(32)]</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> u8 encrypted_nothing[AEAD_LEN(0)]</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> }</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> </div><div class="" style="color:rgb(0,0,153);font-size:13.3333px">@@ -95,8 +95,9 @@ The fields are populated as follows:</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.message_type = 2</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.sender_index = little_endian(responder.sender_index)</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.receiver_index = little_endian(initiator.sender_index)</div><div class="" style="color:red;font-size:13.3333px">- msg.unencrypted_ephemeral = DH_PUBKEY(responder.ephemeral_private)</div><div class="" style="color:red;font-size:13.3333px">- responder.key = KDF(GETKEY(responder.key, 1), DH(responder.ephemeral_private, initiator.ephemeral_public))</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ msg.encrypted_ephemeral = AEAD(responder.key, 1, DH_PUBKEY(responder.ephemeral_private), responder.hash)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ responder.hash = HASH(responder.hash || msg.encrypted_ephemeral)</div><div class="" style="color:green;font-size:13.3333px;line-height:normal">+ responder.key = KDF(GETKEY(responder.key, 2), DH(responder.ephemeral_private, initiator.ephemeral_public))</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> responder.key = KDF(GETKEY(responder.key, 0), DH(responder.ephemeral_private, initiator.static_public))</div><div class="" style="color:rgb(51,51,51);font-size:13.3333px"> msg.encrypted_nothing = AEAD(responder.key, 0, [empty], responder.hash)</div></td></tr></tbody></table></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Jason</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><h3 style="margin:20px 0px 10px;padding:0px;font-size:18px;color:rgb(51,51,51);font-family:sans-serif">First Message: Initiator to Responder</h3><p style="margin:0px 0px 15px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The initiator sends this message:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">msg = handshake_initiation {
u8 message_type
u16 sender_index
u8 unencryped_ephemeral[32]
u8 encrypted_static[AEAD_LEN(32)]
u8 encrypted_timestamp[AEAD_LEN(12)]
}
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The fields are populated as follows:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">initiator.key = 32 bytes of zeros
initiator.hash = HASH("Noise WireGuard zx2c4 2015-09-30" || responder.static_public)
initiator.ephemeral_private = DH_GENERATE()
msg.message_type = 1
msg.sender_index = little_endian(initiator.sender_index)
msg.unencrypted_ephemeral = DH_PUBKEY(initiator.ephemeral_private)
initiator.hash = HASH(initiator.hash || msg.unencrypted_ephemeral)
initiator.key = KDF(GETKEY(initiator.key, 0), DH(initiator.ephemeral_private, responder.static_public))
msg.encrypted_static = AEAD(initiator.key, 0, initiator.static_public, initiator.hash)
initiator.hash = HASH(initiator.hash || msg.encrypted_static)
initiator.key = KDF(GETKEY(initiator.key, 1), DH(initiator.static_private, responder.static_public))
msg.encrypted_timestamp = AEAD(initiator.key, 0, TAI64N(), initiator.hash)
initiator.hash = HASH(initiator.hash || msg.encrypted_timestamp)
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">When the responder receives this message, he decrypts and does all the above operations in reverse, so that the state is identical.</p><h3 style="margin:20px 0px 10px;padding:0px;font-size:18px;color:rgb(51,51,51);font-family:sans-serif">Second Message: Responder to Initiator</h3><p style="margin:0px 0px 15px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The responder sends this message, after processing the first message above and applying the same operations to arrive at an identical state:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">msg = handshake_response {
u8 message_type
u16 sender_index
u16 receiver_index
u8 encrypted_ephemeral[AEAD_LEN(32)]
u8 encrypted_nothing[AEAD_LEN(0)]
}
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The fields are populated as follows:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">responder.ephemeral_private = DH_GENERATE()
msg.message_type = 2
msg.sender_index = little_endian(responder.sender_index)
msg.receiver_index = little_endian(initiator.sender_index)
msg.encrypted_ephemeral = AEAD(responder.key, 1, DH_PUBKEY(responder.ephemeral_private), responder.hash)
responder.hash = HASH(responder.hash || msg.encrypted_ephemeral)
responder.key = KDF(GETKEY(responder.key, 2), DH(responder.ephemeral_private, initiator.ephemeral_public))
responder.key = KDF(GETKEY(responder.key, 0), DH(responder.ephemeral_private, initiator.static_public))
msg.encrypted_nothing = AEAD(responder.key, 0, [empty], responder.hash)
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">When the initiator receives this message, he decrypts and does all the above operations in reverse, so that the state is identical.</p><h3 style="margin:20px 0px 10px;padding:0px;font-size:18px;color:rgb(51,51,51);font-family:sans-serif">Data Keys Derivation</h3><p style="margin:0px 0px 15px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">After the above two messages have been exchanged, keys are calculated by the initiator for sending and receiving data:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">initiator.sending_key = GETKEY(initiator.key, 1)
initiator.sending_key_counter = 0
initiator.receiving_key = GETKEY(initiator.key, 2)
initiator.receiving_key_counter = 0
responder.receiving_key = GETKEY(responder.key, 1)
responder.receiving_key_counter = 0
responder.sending_key = GETKEY(responder.key, 2)
responder.sending_key_counter = 0
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">And then all previous keys, ephemeral keys, and hashes are zeroed out.</p><h3 style="margin:20px 0px 10px;padding:0px;font-size:18px;color:rgb(51,51,51);font-family:sans-serif">Subsequent Messages: Exchange of Data Packets</h3><p style="margin:0px 0px 15px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The initiator and the responder exchange this packet for sharing encapsulated packet data:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">msg = packet_data {
u8 message_type
u16 receiver_index
u64 counter
u8 encrypted_encapsulated_packet[]
}
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The fields are populated as follows:</p><pre style="margin-top:15px;margin-bottom:15px;border:1px solid rgb(204,204,204);font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px;color:rgb(51,51,51);background-color:rgb(248,248,248)"><code style="margin:0px;padding:0px;border:none;border-radius:3px;background:transparent">msg.message_type = 3
msg.receiver_index = little_endian(responder.sender_index)
encapsulated_packet = encapsulated_packet || random padding in order to make the length a multiple of 16
counter = ++initiator.sending_key_counter
msg.counter = little_endian(counter)
msg.encrypted_encapsulated_packet = AEAD(initiator.sending_key, counter, encapsulated_packet, [empty])
</code></pre><p style="margin:15px 0px;color:rgb(51,51,51);font-family:sans-serif;font-size:14px;line-height:22.4px">The responder uses his <code style="margin:0px 2px;padding:0px 5px;border:1px solid rgb(234,234,234);border-radius:3px;white-space:nowrap;background-color:rgb(248,248,248)">responder.receiving_key</code> to read the message.</p></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div></div>