Nota
La fase de propuesta está cerrada. Consulta la SPEC para la especificación oficial. Esta propuesta aún puede ser referenciada para información de contexto.
Descripción general
Esta propuesta describe un protocolo de acuerdo de claves autenticado para mejorar la resistencia de NTCP a diversas formas de identificación automatizada y ataques.
La propuesta está organizada de la siguiente manera: se presentan los objetivos de seguridad, seguido de una discusión del protocolo básico. A continuación, se proporciona una especificación completa de todos los mensajes del protocolo. Finalmente, se discuten las direcciones del router y la identificación de versiones. También se incluye un apéndice que discute un ataque genérico a esquemas de relleno comunes, así como un apéndice que contiene una serie de candidatos para el cifrado autenticado.
Al igual que con otros transportes de I2P, NTCP2 está definido únicamente para el transporte punto a punto (router a router) de mensajes I2NP. No es una tubería de datos de propósito general.
Motivación
Los datos de NTCP se cifran después del primer mensaje (y el primer mensaje parece ser datos aleatorios), evitando así la identificación del protocolo mediante “análisis de carga útil”. Sin embargo, sigue siendo vulnerable a la identificación del protocolo mediante “análisis de flujo”. Esto se debe a que los primeros 4 mensajes (es decir, el handshake) tienen longitud fija (288, 304, 448 y 48 bytes).
Al agregar cantidades aleatorias de datos aleatorios a cada uno de los mensajes, podemos hacerlo mucho más difícil.
Los autores reconocen que las prácticas de seguridad estándar sugerirían usar un protocolo existente como TLS, pero esto es Prop104 y tiene sus propios problemas. Donde sea apropiado, se han añadido párrafos de “trabajo futuro” para indicar características faltantes o temas de discusión.
Objetivos de Diseño
Soporta NTCP 1 y 2 en un solo puerto, detección automática, y publicado como un solo “transporte” (es decir, RouterAddress) en la NetDB.
Publicar soporte para versión 1 solamente, 2 solamente, o 1+2 en la NetDB en un campo separado, y usar versión 1 solamente como predeterminado (no vincular el soporte de versión a una versión particular del router)
Asegurar que todas las implementaciones (Java/i2pd/Kovri/go) puedan agregar soporte de versión 2 (o no) en sus propios cronogramas
Añadir relleno aleatorio a todos los mensajes NTCP incluyendo mensajes de handshake y datos (es decir, ofuscación de longitud para que todos los mensajes no sean múltiplos de 16 bytes) Proporcionar mecanismo de opciones para que ambos lados soliciten relleno mínimo y máximo y/o distribución de relleno. Los detalles específicos de la distribución de relleno dependen de la implementación y pueden o no estar especificados en el protocolo mismo.
Ofuscar el contenido de los mensajes que no están cifrados (1 y 2), lo suficiente para que las cajas DPI y las firmas AV no puedan clasificarlos fácilmente. También asegurar que los mensajes que van a un único peer o conjunto de peers no tengan un patrón similar de bits.
Corregir pérdida de bits en DH debido al formato de Java Ticket1112, posiblemente (¿probablemente?) cambiando a X25519.
¿Cambiar a una función de derivación de claves (KDF) real en lugar de usar el resultado DH tal como está?
Añadir “resistencia a sondeo” (como lo llama Tor); esto incluye resistencia a replay.
Mantener intercambio de claves autenticado bidireccional (2W-AKE). 1W-AKE no es suficiente para nuestra aplicación.
Continuar usando las firmas de tipo variable y longitud variable (de la clave de firma RouterIdentity publicada) como parte de la autenticación. Confiar en una clave pública estática publicada en el RouterInfo como otra parte de la autenticación.
Añadir opciones/versión en handshake para extensibilidad futura.
Agregar resistencia a la segmentación TCP MitM maliciosa si es posible.
No agregar significativamente a la CPU requerida para la configuración de conexión; si es posible, reducirla significativamente.
Agregar autenticación de mensajes (MAC), posiblemente HMAC-SHA256 y Poly1305, y eliminar la suma de verificación Adler.
Acortar y simplificar el encabezado I2NP: Acortar la expiración a 4 bytes, como en SSU. Eliminar el checksum SHA256 truncado de un byte.
Si es posible, reducir el handshake de 4 mensajes y dos round-trip a un handshake de 3 mensajes y un round-trip, como en SSU. Esto requeriría mover la firma de Bob del mensaje 4 al mensaje 2. Investigar la razón de los 4 mensajes en los archivos de correos/estado/reuniones de hace diez años.
Minimizar la sobrecarga del protocolo antes del relleno. Aunque se añadirá relleno, y posiblemente mucho, la sobrecarga antes del relleno sigue siendo sobrecarga. Los nodos de ancho de banda bajo deben poder usar NTCP2.
Mantener marcas de tiempo para la detección de repetición y desviación.
Evitar cualquier problema del año 2038 en las marcas de tiempo, debe funcionar hasta al menos 2106.
Incrementar el tamaño máximo de mensaje de 16K a 32K o 64K.
Cualquier nueva primitiva criptográfica debe estar fácilmente disponible en bibliotecas para su uso en implementaciones de router en Java (1.7), C++, y Go.
Incluir representantes de los desarrolladores de router de Java, C++, y Go en el diseño.
Minimizar los cambios (pero aún habrá muchos).
Soportar ambas versiones en un conjunto común de código (esto puede no ser posible y depende de la implementación en cualquier caso).
Non-Goals
Resistencia a DPI a prueba de balas… eso serían los transportes conectables, Prop109.
Un transporte basado en TLS (o similar a HTTPS)… que sería Prop104.
Es aceptable cambiar la criptografía simétrica de flujo.
Resistencia a DPI basada en temporización (la temporización/retrasos entre mensajes pueden ser dependientes de la implementación; los retrasos intra-mensaje pueden introducirse en cualquier punto, incluyendo antes de enviar el padding aleatorio, por ejemplo). Los retrasos artificiales (lo que obfs4 llama IAT o tiempo entre llegadas) son independientes del protocolo en sí.
Negabilidad de participar en una sesión (hay firmas ahí).
No-objetivos que pueden ser parcialmente reconsiderados o discutidos:
El grado de protección contra Deep Packet Inspection (DPI)
Seguridad Post-Cuántica (PQ)
Negación plausible
Related Goals
- Implementar una configuración de prueba NTCP 1/2
Security Goals
Consideramos tres partes:
- Alice, quien desea establecer una nueva sesión.
- Bob, con quien Alice desea establecer una sesión.
- Mallory, el “hombre en el medio” entre Alice y Bob.
Como máximo dos participantes pueden participar en ataques activos.
Alice y Bob poseen ambos un par de claves estáticas, que está contenido en su RouterIdentity.
El protocolo propuesto intenta permitir que Alice y Bob acuerden una clave secreta compartida (K) bajo los siguientes requisitos:
Seguridad de clave privada: ni Bob ni Mallory aprenden nada sobre la clave privada estática de Alice. Simétricamente, Alice no aprende nada sobre la clave privada estática de Bob.
La clave de sesión K solo es conocida por Alice y Bob.
Secreto perfecto hacia adelante: la clave de sesión acordada permanece secreta en el futuro, incluso cuando las claves privadas estáticas de Alice y/o Bob son reveladas después de que la clave haya sido acordada.
Autenticación bidireccional: Alice está segura de que ha establecido una sesión con Bob, y viceversa.
Protección contra DPI en línea: Asegurar que no sea trivial detectar que Alice y Bob están participando en el protocolo usando únicamente técnicas sencillas de inspección profunda de paquetes (DPI). Ver más abajo.
Denegabilidad limitada: ni Alice ni Bob pueden negar su participación en el protocolo, pero si cualquiera de los dos filtra la clave compartida, la otra parte puede negar la autenticidad del contenido de los datos transmitidos.
La presente propuesta intenta proporcionar los cinco requisitos basándose en el protocolo Station-To-Station (STS). Tenga en cuenta que este protocolo también es la base para el protocolo SSU.
Additional DPI Discussion
Asumimos dos componentes DPI:
1) Online DPI
DPI en línea inspeccionando todos los flujos en tiempo real. Las conexiones pueden ser bloqueadas o manipuladas de otra manera. Los datos de conexión o metadatos pueden ser identificados y almacenados para análisis fuera de línea. El DPI en línea no tiene acceso a la base de datos de red de I2P. El DPI en línea tiene solo capacidad computacional limitada en tiempo real, incluyendo cálculo de longitud, inspección de campos y cálculos simples como XOR. El DPI en línea sí tiene la capacidad de funciones criptográficas rápidas en tiempo real como AES, AEAD y hashing, pero estas serían demasiado costosas para aplicar a la mayoría o todos los flujos. Cualquier aplicación de estas operaciones criptográficas se aplicaría solo a flujos en combinaciones IP/Puerto previamente identificadas por análisis fuera de línea. El DPI en línea no tiene la capacidad de funciones criptográficas de alta sobrecarga como DH o elligator2. El DPI en línea no está diseñado específicamente para detectar I2P, aunque puede tener reglas de clasificación limitadas para ese propósito.
Es un objetivo prevenir la identificación del protocolo por parte de un DPI en línea.
La noción de DPI en línea o “directa” se considera aquí que incluye las siguientes capacidades del adversario:
La capacidad de inspeccionar todos los datos enviados o recibidos por el objetivo.
La capacidad de realizar operaciones sobre los datos observados, como aplicar cifrados de bloque o funciones hash.
La capacidad de almacenar y comparar con mensajes enviados previamente.
La capacidad de modificar, retrasar o fragmentar paquetes.
Sin embargo, se asume que el DPI en línea tiene las siguientes restricciones:
La incapacidad de mapear direcciones IP a hashes de router. Aunque esto es trivial con acceso en tiempo real a la base de datos de red, requeriría un sistema DPI específicamente diseñado para atacar I2P.
La incapacidad de usar información de temporización para detectar el protocolo.
En términos generales, la caja de herramientas de DPI en línea no contiene ninguna herramienta integrada que esté específicamente diseñada para la detección de I2P. Esto incluye la creación de “honeypots”, que por ejemplo incluirían relleno no aleatorio en sus mensajes. Tenga en cuenta que esto no excluye los sistemas de aprendizaje automático o las herramientas de DPI altamente configurables siempre que cumplan con los otros requisitos.
Para contrarrestar el análisis de carga útil, se garantiza que todos los mensajes sean indistinguibles de datos aleatorios. Esto también requiere que su longitud sea aleatoria, lo cual es más complicado que simplemente agregar padding aleatorio. De hecho, en el Apéndice A, los autores argumentan que un esquema de padding ingenuo (es decir, uniforme) no resuelve el problema. Por lo tanto, el Apéndice A propone incluir retrasos aleatorios o desarrollar un esquema de padding alternativo que pueda proporcionar protección razonable contra el ataque propuesto.
Para proteger contra la sexta entrada mencionada anteriormente, las implementaciones deberían incluir retrasos aleatorios en el protocolo. Tales técnicas no están cubiertas por esta propuesta, pero también podrían resolver los problemas de longitud de relleno. En resumen, la propuesta proporciona buena protección contra el análisis de carga útil (cuando se toman en cuenta las consideraciones del Apéndice A), pero solo protección limitada contra el análisis de flujo.
2) Offline DPI
DPI offline inspeccionando datos almacenados por el DPI online para análisis posterior. El DPI offline puede estar diseñado específicamente para detectar I2P. El DPI offline no tiene acceso en tiempo real a la base de datos de red de I2P. El DPI offline sí tiene acceso a esta y otras especificaciones de I2P. El DPI offline tiene capacidad computacional ilimitada, incluyendo todas las funciones criptográficas definidas en esta especificación.
El DPI fuera de línea no tiene la capacidad de bloquear conexiones existentes. El DPI fuera de línea sí tiene la capacidad de enviar en tiempo casi real (en cuestión de minutos desde la configuración) a host/puerto de las partes, por ejemplo TCP RST. El DPI fuera de línea sí tiene la capacidad de hacer repetición en tiempo casi real (en cuestión de minutos desde la configuración) de mensajes anteriores (modificados o no) para “sondeo” u otras razones.
No es un objetivo prevenir la identificación del protocolo por parte de un DPI offline. Toda la decodificación de datos ofuscados en los primeros dos mensajes, que es implementada por los routers I2P, también puede ser implementada por el DPI offline.
Es un objetivo rechazar los intentos de conexión que usen la repetición de mensajes anteriores.
Future work
Considera el comportamiento del protocolo cuando los paquetes son descartados o reordenados por un atacante. Trabajo interesante reciente en esta área se puede encontrar en IACR-1150.
Proporcionar una clasificación más precisa de los sistemas DPI, teniendo en cuenta la literatura existente relacionada con el tema.
Discutir la seguridad formal del protocolo propuesto, idealmente teniendo en cuenta el modelo de atacante DPI.
Noise Protocol Framework
Esta propuesta proporciona los requisitos basados en el Noise Protocol Framework NOISE (Revisión 33, 2017-10-04). Noise tiene propiedades similares al protocolo Station-To-Station, que es la base del protocolo SSU. En la terminología de Noise, Alice es el iniciador, y Bob es el respondedor.
NTCP2 se basa en el protocolo Noise Noise_XK_25519_ChaChaPoly_SHA256. (El identificador real para la función de derivación de claves inicial es “Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256” para indicar las extensiones de I2P - ver la sección KDF 1 más abajo) Este protocolo Noise utiliza las siguientes primitivas:
Patrón de Handshake: XK Alice transmite su clave a Bob (X) Alice ya conoce la clave estática de Bob (K)
Función DH: X25519 X25519 DH con una longitud de clave de 32 bytes según se especifica en RFC-7748.
Función de Cifrado: ChaChaPoly AEAD_CHACHA20_POLY1305 como se especifica en RFC-7539 sección 2.8. Nonce de 12 bytes, con los primeros 4 bytes establecidos en cero.
Función Hash: SHA256 Hash estándar de 32 bytes, ya utilizado extensivamente en I2P.
Objetivos de Seguridad
Esta propuesta define las siguientes mejoras a Noise_XK_25519_ChaChaPoly_SHA256. Estas generalmente siguen las pautas en NOISE sección 13.
Las claves efímeras en texto claro son ofuscadas con cifrado AES usando una clave e IV conocidos. Esto es más rápido que elligator2.
Se añade relleno de texto claro aleatorio a los mensajes 1 y 2. El relleno de texto claro se incluye en el cálculo del hash de handshake (MixHash). Consulte las secciones KDF a continuación para el mensaje 2 y la parte 1 del mensaje 3. Se añade relleno AEAD aleatorio al mensaje 3 y a los mensajes de la fase de datos.
Se añade un campo de longitud de frame de dos bytes, como es requerido para Noise sobre TCP, y como en obfs4. Esto se usa únicamente en los mensajes de la fase de datos. Los frames AEAD del Mensaje 1 y 2 son de longitud fija. El frame AEAD de la parte 1 del Mensaje 3 es de longitud fija. La longitud del frame AEAD de la parte 2 del Mensaje 3 se especifica en el mensaje 1.
El campo de longitud de frame de dos bytes está ofuscado con SipHash-2-4, como en obfs4.
El formato de payload está definido para los mensajes 1, 2, 3, y la fase de datos. Por supuesto, esto no está definido en Noise.
New Cryptographic Primitives for I2P
Las implementaciones existentes de router I2P requerirán implementaciones para las siguientes primitivas criptográficas estándar, las cuales no son requeridas para los protocolos actuales de I2P:
Generación de clave X25519 y DH
AEAD_ChaCha20_Poly1305 (abreviado como ChaChaPoly a continuación)
SipHash-2-4
Processing overhead estimate
Tamaños de mensaje para los 3 mensajes:
- 64 bytes + relleno (NTCP era 288 bytes) 2) 64 bytes + relleno (NTCP era 304 bytes) 3) aprox. 64 bytes + información del router de Alice + relleno La información promedio del router es de aproximadamente 750 bytes Total promedio 814 bytes antes del relleno (NTCP era 448 bytes) 4) no requerido en NTCP2 (NTCP era 48 bytes)
Total antes del relleno: NTCP2: 942 bytes NTCP: 1088 bytes Nota que si Alice se conectó a Bob con el propósito de enviar un Mensaje DatabaseStore de su RouterInfo, ese mensaje no es requerido, ahorrando aproximadamente 800 bytes.
Las siguientes operaciones criptográficas son requeridas por cada parte para completar el handshake e iniciar la fase de datos:
- AES: 2
- SHA256: 7 (Alice), 6 (Bob) (sin incluir 1 Alice, 2 Bob precalculados para todas las conexiones) (sin incluir HMAC-SHA256)
- HMAC-SHA256: 19
- ChaChaPoly: 4
- Generación de claves X25519: 1
- X25519 DH: 3
- Verificación de firma: 1 (Bob) (Alice firmó previamente al generar su RI) Presumiblemente Ed25519 (dependiente del tipo de firma RI)
Las siguientes operaciones criptográficas son requeridas por cada parte para cada mensaje de fase de datos:
- SipHash: 1
- ChaChaPoly: 1
Messages
Todos los mensajes NTCP2 tienen una longitud menor o igual a 65537 bytes. El formato del mensaje está basado en mensajes Noise, con modificaciones para el enmarcado y la indistinguibilidad. Las implementaciones que utilicen bibliotecas Noise estándar pueden necesitar preprocesar los mensajes recibidos hacia/desde el formato de mensaje Noise. Todos los campos cifrados son textos cifrados AEAD.
La secuencia de establecimiento es la siguiente:
Alice Bob
SessionRequest ------------------->
<------------------- SessionCreated
SessionConfirmed ----------------->
Usando la terminología Noise, la secuencia de establecimiento y datos es la siguiente: (Propiedades de Seguridad del Payload)
XK(s, rs): Authentication Confidentiality
<- s
...
-> e, es 0 2
<- e, ee 2 1
-> s, se 2 5
<- 2 5
Una vez que se ha establecido una sesión, Alice y Bob pueden intercambiar mensajes de datos.
Todos los tipos de mensajes (SessionRequest, SessionCreated, SessionConfirmed, Data y TimeSync) se especifican en esta sección.
Algunas notaciones:
- RH_A = Hash del Router para Alice (32 bytes)
- RH_B = Hash del Router para Bob (32 bytes)
Authenticated Encryption
Hay tres instancias separadas de cifrado autenticado (CipherStates). Una durante la fase de handshake, y dos (transmisión y recepción) para la fase de datos. Cada una tiene su propia clave de un KDF.
Los datos cifrados/autenticados se representarán como
+----+----+----+----+----+----+----+----+
| |
+ +
| Encrypted and authenticated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Objetivos Excluidos
Formato de datos cifrado y autenticado.
Entradas a las funciones de cifrado/descifrado:
k :: 32 byte cipher key, as generated from KDF
nonce :: Counter-based nonce, 12 bytes.
Starts at 0 and incremented for each message.
First four bytes are always zero.
Last eight bytes are the counter, little-endian encoded.
Maximum value is 2**64 - 2.
Connection must be dropped and restarted after
it reaches that value.
The value 2**64 - 1 must never be sent.
ad :: In handshake phase:
Associated data, 32 bytes.
The SHA256 hash of all preceding data.
In data phase:
Zero bytes
data :: Plaintext data, 0 or more bytes
Salida de la función de cifrado, entrada de la función de descifrado:
+----+----+----+----+----+----+----+----+
|Obfs Len | |
+----+----+ +
| ChaCha20 encrypted data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) +
| 16 bytes |
+----+----+----+----+----+----+----+----+
Obfs Len :: Length of (encrypted data + MAC) to follow, 16 - 65535
Obfuscation using SipHash (see below)
Not used in message 1 or 2, or message 3 part 1, where the length is fixed
Not used in message 3 part 1, as the length is specified in message 1
encrypted data :: Same size as plaintext data, 0 - 65519 bytes
MAC :: Poly1305 message authentication code, 16 bytes
Para ChaCha20, lo que se describe aquí corresponde a RFC-7539, que también se utiliza de manera similar en TLS RFC-7905.
Notes
Dado que ChaCha20 es un cifrado de flujo, los textos en claro no necesitan ser rellenados. Los bytes adicionales del flujo de claves se descartan.
La clave para el cifrado (256 bits) se acuerda mediante el SHA256 KDF. Los detalles del KDF para cada mensaje están en secciones separadas a continuación.
Los frames ChaChaPoly para los mensajes 1, 2 y la primera parte del mensaje 3, son de tamaño conocido. Comenzando con la segunda parte del mensaje 3, los frames son de tamaño variable. El tamaño de la parte 1 del mensaje 3 se especifica en el mensaje 1. Comenzando con la fase de datos, los frames van precedidos de una longitud de dos bytes ofuscada con SipHash como en obfs4.
El relleno está fuera del marco de datos autenticado para los mensajes 1 y 2. El relleno se usa en la KDF para el siguiente mensaje, por lo que se detectará cualquier manipulación. A partir del mensaje 3, el relleno está dentro del marco de datos autenticado.
Objetivos Relacionados
En los mensajes 1, 2, y las partes 1 y 2 del mensaje 3, el tamaño del mensaje AEAD se conoce de antemano. En caso de fallo de autenticación AEAD, el destinatario debe detener el procesamiento adicional de mensajes y cerrar la conexión sin responder. Esto debería ser un cierre anormal (TCP RST).
Para resistencia al sondeo, en el mensaje 1, después de un fallo AEAD, Bob debe establecer un timeout aleatorio (rango por determinar) y luego leer un número aleatorio de bytes (rango por determinar) antes de cerrar el socket. Bob debe mantener una lista negra de IPs con fallos repetidos.
En la fase de datos, el tamaño del mensaje AEAD está “cifrado” (ofuscado) con SipHash. Se debe tener cuidado de evitar crear un oráculo de descifrado. En caso de falla de autenticación AEAD en la fase de datos, el destinatario debería establecer un tiempo de espera aleatorio (rango por determinar) y luego leer un número aleatorio de bytes (rango por determinar). Después de la lectura, o al agotar el tiempo de espera de lectura, el destinatario debería enviar una carga útil con un bloque de terminación que contenga un código de razón de “falla AEAD”, y cerrar la conexión.
Tomar la misma acción de error para un valor de campo de longitud inválido en la fase de datos.
Key Derivation Function (KDF) (for handshake message 1)
El KDF genera una clave de cifrado de fase de handshake k a partir del resultado DH, utilizando HMAC-SHA256(key, data) como se define en RFC-2104. Estas son las funciones InitializeSymmetric(), MixHash(), y MixKey(), exactamente como se definen en la especificación Noise.
This is the "e" message pattern:
// Define protocol_name.
Set protocol_name = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
(48 bytes, US-ASCII encoded, no NULL termination).
// Define Hash h = 32 bytes
h = SHA256(protocol_name);
Define ck = 32 byte chaining key. Copy the h data to ck.
Set ck = h
Define rs = Bob's 32-byte static key as published in the RouterInfo
// MixHash(null prologue)
h = SHA256(h);
// up until here, can all be precalculated by Alice for all outgoing connections
// Alice must validate that Bob's static key is a valid point on the curve here.
// Bob static key
// MixHash(rs)
// || below means append
h = SHA256(h || rs);
// up until here, can all be precalculated by Bob for all incoming connections
This is the "e" message pattern:
Alice generates her ephemeral DH key pair e.
// Alice ephemeral key X
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 1
// Retain the Hash h for the message 2 KDF
End of "e" message pattern.
This is the "es" message pattern:
// DH(e, rs) == DH(s, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's static key
Set input_key_material = X25519 DH result
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, defined above
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 2 KDF
End of "es" message pattern.
Discusión Adicional sobre DPI
Alice envía a Bob.
Contenido Noise: clave efímera X de Alice Carga útil Noise: bloque de opciones de 16 bytes Carga útil no-noise: Relleno aleatorio
(Propiedades de Seguridad de la Carga Útil)
XK(s, rs): Authentication Confidentiality
-> e, es 0 2
Authentication: None (0).
This payload may have been sent by any party, including an active attacker.
Confidentiality: 2.
Encryption to a known recipient, forward secrecy for sender compromise
only, vulnerable to replay. This payload is encrypted based only on DHs
involving the recipient's static key pair. If the recipient's static
private key is compromised, even at a later date, this payload can be
decrypted. This message can also be replayed, since there's no ephemeral
contribution from the recipient.
"e": Alice generates a new ephemeral key pair and stores it in the e
variable, writes the ephemeral public key as cleartext into the
message buffer, and hashes the public key along with the old h to
derive a new h.
"es": A DH is performed between the Alice's ephemeral key pair and the
Bob's static key pair. The result is hashed along with the old ck to
derive a new ck and k, and n is set to zero.
El valor X se cifra para garantizar la indistinguibilidad y unicidad de la carga útil, que son contramedidas DPI necesarias. Utilizamos cifrado AES para lograr esto, en lugar de alternativas más complejas y lentas como elligator2. El cifrado asimétrico con la clave pública del router de Bob sería demasiado lento. El cifrado AES utiliza el hash del router de Bob como clave y el IV de Bob tal como se publica en la base de datos de red.
El cifrado AES es solo para resistencia a DPI. Cualquier parte que conozca el hash del router de Bob y el IV, que se publican en la base de datos de la red, puede descifrar el valor X en este mensaje.
El relleno no está cifrado por Alice. Puede ser necesario que Bob descifre el relleno, para inhibir los ataques de temporización.
Contenido sin procesar:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaChaPoly frame |
+ (32 bytes) +
| k defined in KDF for message 1 |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
~ padding (optional) ~
| length defined in options block |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: As published in Bobs network database entry
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as NTCP
(see Version Detection section below).
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
Datos no cifrados (etiqueta de autenticación Poly1305 no mostrada):
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as "NTCP"
(see Version Detection section below)
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
Bloque de opciones: Nota: Todos los campos están en big-endian.
+----+----+----+----+----+----+----+----+
| id | ver| padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
| tsA | Reserved (0) |
+----+----+----+----+----+----+----+----+
id :: 1 byte, the network ID (currently 2, except for test networks)
As of 0.9.42. See proposal 147.
ver :: 1 byte, protocol version (currently 2)
padLen :: 2 bytes, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
m3p2Len :: 2 bytes, length of the the second AEAD frame in SessionConfirmed
(message 3 part 2) See notes below
Rsvd :: 2 bytes, set to 0 for compatibility with future options
tsA :: 4 bytes, Unix timestamp, unsigned seconds.
Wraps around in 2106
Reserved :: 4 bytes, set to 0 for compatibility with future options
Notes
Cuando la dirección publicada es “NTCP”, Bob soporta tanto NTCP como NTCP2 en el mismo puerto. Por compatibilidad, cuando inicia una conexión a una dirección publicada como “NTCP”, Alice debe limitar el tamaño máximo de este mensaje, incluyendo el relleno, a 287 bytes o menos. Esto facilita la identificación automática del protocolo por parte de Bob. Cuando se publica como “NTCP2”, no hay restricción de tamaño. Ver las secciones de Direcciones Publicadas y Detección de Versión a continuación.
El valor X único en el bloque AES inicial asegura que el texto cifrado sea diferente para cada sesión.
Bob debe rechazar conexiones donde el valor de timestamp esté demasiado alejado del tiempo actual. Llamemos “D” al delta de tiempo máximo. Bob debe mantener una caché local de valores de handshake utilizados previamente y rechazar duplicados, para prevenir ataques de replay. Los valores en la caché deben tener una vida útil de al menos 2*D. Los valores de caché dependen de la implementación, sin embargo el valor X de 32 bytes (o su equivalente cifrado) puede ser utilizado.
Las claves efímeras de Diffie-Hellman nunca deben reutilizarse, para prevenir ataques criptográficos, y la reutilización será rechazada como un ataque de repetición.
Las opciones “KE” y “auth” deben ser compatibles, es decir, el secreto compartido K debe tener el tamaño apropiado. Si se agregan más opciones “auth”, esto podría cambiar implícitamente el significado de la bandera “KE” para usar un KDF diferente o un tamaño de truncamiento diferente.
Bob debe validar que la clave efímera de Alice es un punto válido en la curva aquí.
El padding debería limitarse a una cantidad razonable. Bob puede rechazar conexiones con padding excesivo. Bob especificará sus opciones de padding en el mensaje 2. Pautas min/max por determinar. ¿Tamaño aleatorio de 0 a 31 bytes como mínimo? (Distribución por determinar, ver Apéndice A.)
En caso de cualquier error, incluyendo AEAD, DH, timestamp, aparente repetición, o falla de validación de clave, Bob debe detener el procesamiento de mensajes adicionales y cerrar la conexión sin responder. Esto debería ser un cierre anormal (TCP RST). Para resistencia al sondeo, después de una falla AEAD, Bob debería establecer un timeout aleatorio (rango por determinar) y luego leer un número aleatorio de bytes (rango por determinar), antes de cerrar el socket.
Mitigación DoS: DH es una operación relativamente costosa. Al igual que con el protocolo NTCP anterior, los routers deben tomar todas las medidas necesarias para prevenir el agotamiento de CPU o conexiones. Establecer límites en conexiones activas máximas y configuraciones de conexión máximas en progreso. Aplicar timeouts de lectura (tanto por lectura como total para “slowloris”). Limitar conexiones repetidas o simultáneas desde la misma fuente. Mantener listas negras para fuentes que fallen repetidamente. No responder a fallas AEAD.
Para facilitar la detección rápida de versión y el handshaking, las implementaciones deben asegurar que Alice almacene en buffer y luego envíe todo el contenido del primer mensaje de una vez, incluyendo el padding. Esto incrementa la probabilidad de que los datos estén contenidos en un solo paquete TCP (a menos que sean segmentados por el SO o middleboxes), y sean recibidos todos a la vez por Bob. Adicionalmente, las implementaciones deben asegurar que Bob almacene en buffer y luego envíe todo el contenido del segundo mensaje de una vez, incluyendo el padding, y que Bob almacene en buffer y luego envíe todo el contenido del tercer mensaje de una vez. Esto también es por eficiencia y para asegurar la efectividad del padding aleatorio.
Campo “ver”: El protocolo Noise general, extensiones, y protocolo NTCP incluyendo especificaciones de carga útil, indicando NTCP2. Este campo puede usarse para indicar soporte para cambios futuros.
Longitud de la parte 2 del mensaje 3: Este es el tamaño del segundo frame AEAD (incluyendo MAC de 16 bytes) que contiene el Router Info de Alice y relleno opcional que será enviado en el mensaje SessionConfirmed. Como los routers regeneran periódicamente y republicán su Router Info, el tamaño del Router Info actual puede cambiar antes de que se envíe el mensaje 3. Las implementaciones deben elegir una de dos estrategias: a) guardar el Router Info actual para ser enviado en el mensaje 3, de modo que se conozca el tamaño, y opcionalmente agregar espacio para relleno; b) aumentar el tamaño especificado lo suficiente para permitir un posible incremento en el tamaño del Router Info, y siempre agregar relleno cuando el mensaje 3 sea realmente enviado. En cualquier caso, la longitud “m3p2len” incluida en el mensaje 1 debe ser exactamente el tamaño de ese frame cuando se envíe en el mensaje 3.
Bob debe fallar la conexión si queda algún dato entrante después de validar el mensaje 1 y leer el relleno. No debería haber datos adicionales de Alice, ya que Bob aún no ha respondido con el mensaje 2.
El campo network ID se utiliza para identificar rápidamente conexiones entre redes. Si este campo es distinto de cero y no coincide con el network ID de Bob, Bob debería desconectarse y bloquear futuras conexiones. A partir de 0.9.42. Ver propuesta 147 para más información.
Key Derivation Function (KDF) (for handshake message 2 and message 3 part 1)
// take h saved from message 1 KDF
// MixHash(ciphertext)
h = SHA256(h || 32 byte encrypted payload from message 1)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 1)
This is the "e" message pattern:
Bob generates his ephemeral DH key pair e.
// h is from KDF for handshake message 1
// Bob ephemeral key Y
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 2
// Retain the Hash h for the message 3 KDF
End of "e" message pattern.
This is the "ee" message pattern:
// DH(e, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Alice's ephemeral key in memory, no longer needed
// Alice:
e(public and private) = (all zeros)
// Bob:
re = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 3 KDF
End of "ee" message pattern.
2) SessionCreated
Bob envía a Alice.
Contenido Noise: Clave efímera Y de Bob Carga útil Noise: Bloque de opción de 16 bytes Carga útil no-noise: Relleno aleatorio
(Propiedades de Seguridad del Payload)
XK(s, rs): Authentication Confidentiality
<- e, ee 2 1
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 1.
Encryption to an ephemeral recipient.
This payload has forward secrecy, since encryption involves an ephemeral-ephemeral DH ("ee").
However, the sender has not authenticated the recipient,
so this payload might be sent to any party, including an active attacker.
"e": Bob generates a new ephemeral key pair and stores it in the e variable,
writes the ephemeral public key as cleartext into the message buffer,
and hashes the public key along with the old h to derive a new h.
"ee": A DH is performed between the Bob's ephemeral key pair and the Alice's ephemeral key pair.
The result is hashed along with the old ck to derive a new ck and k, and n is set to zero.
El valor Y se cifra para garantizar la indistinguibilidad e unicidad de la carga útil, que son contramedidas DPI necesarias. Utilizamos cifrado AES para lograr esto, en lugar de alternativas más complejas y lentas como elligator2. El cifrado asimétrico con la clave pública del router de Alice sería demasiado lento. El cifrado AES utiliza el hash del router de Bob como clave y el estado AES del mensaje 1 (que se inicializó con el IV de Bob tal como se publicó en la base de datos de red).
El cifrado AES es solo para resistencia DPI. Cualquier parte que conozca el hash del router de Bob y el IV, que se publican en la base de datos de la red, y haya capturado los primeros 32 bytes del mensaje 1, puede descifrar el valor Y en este mensaje.
Contenido sin procesar:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaChaPoly frame |
+ Encrypted and authenticated data +
| 32 bytes |
+ k defined in KDF for message 2 +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: Using AES state from message 1
Datos no encriptados (etiqueta de autenticación Poly1305 no mostrada):
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Alice and Bob will use the padding data in the KDF for message 3 part 1.
It is authenticated so that any tampering will cause the
next message to fail.
Notes
Alice debe validar que la clave efímera de Bob es un punto válido en la curva aquí.
El relleno debería limitarse a una cantidad razonable. Alice puede rechazar conexiones con relleno excesivo. Alice especificará sus opciones de relleno en el mensaje 3. Directrices mín/máx por determinar. ¿Tamaño aleatorio de 0 a 31 bytes como mínimo? (Distribución por determinar, ver Apéndice A.)
En caso de cualquier error, incluyendo AEAD, DH, timestamp, aparente replay, o fallo de validación de clave, Alice debe detener el procesamiento adicional de mensajes y cerrar la conexión sin responder. Esto debe ser un cierre anormal (TCP RST).
Para facilitar el handshaking rápido, las implementaciones deben asegurar que Bob almacene en búfer y luego vacíe todo el contenido del primer mensaje de una vez, incluyendo el padding. Esto aumenta la probabilidad de que los datos estén contenidos en un solo paquete TCP (a menos que sean segmentados por el SO o middleboxes), y recibidos de una vez por Alice. Esto también es por eficiencia y para asegurar la efectividad del padding aleatorio.
Alice debe fallar la conexión si queda algún dato entrante después de validar el mensaje 2 y leer el relleno. No debería haber datos adicionales de Bob, ya que Alice aún no ha respondido con el mensaje 3.
Bloque de opciones: Nota: Todos los campos están en big-endian.
+----+----+----+----+----+----+----+----+
| Rsvd(0) | padLen | Reserved (0) |
+----+----+----+----+----+----+----+----+
| tsB | Reserved (0) |
+----+----+----+----+----+----+----+----+
Reserved :: 10 bytes total, set to 0 for compatibility with future options
padLen :: 2 bytes, big endian, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
tsB :: 4 bytes, big endian, Unix timestamp, unsigned seconds.
Wraps around in 2106
Notes
- Alice debe rechazar conexiones donde el valor de timestamp esté demasiado alejado del tiempo actual. Llama al delta de tiempo máximo “D”. Alice debe mantener una caché local de valores de handshake utilizados previamente y rechazar duplicados, para prevenir ataques de replay. Los valores en la caché deben tener una vida útil de al menos 2*D. Los valores de caché dependen de la implementación, sin embargo el valor Y de 32 bytes (o su equivalente cifrado) puede ser utilizado.
Issues
- ¿Incluir opciones de padding mínimo/máximo aquí?
Encryption for for handshake message 3 part 1, using message 2 KDF)
// take h saved from message 2 KDF
// MixHash(ciphertext)
h = SHA256(h || 24 byte encrypted payload from message 2)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 2)
// h is used as the associated data for the AEAD in message 3 part 1, below
This is the "s" message pattern:
Define s = Alice's static public key, 32 bytes
// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// k is from handshake message 1
// n is 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// h is used as the associated data for the AEAD in message 3 part 2
End of "s" message pattern.
Key Derivation Function (KDF) (for handshake message 3 part 2)
This is the "se" message pattern:
// DH(s, re) == DH(e, rs)
Define input_key_material = 32 byte DH result of Alice's static key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Bob's ephemeral key in memory, no longer needed
// Alice:
re = (all zeros)
// Bob:
e(public and private) = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// h from message 3 part 1 is used as the associated data for the AEAD in message 3 part 2
// EncryptAndHash(payload)
// EncryptWithAd(h, payload)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// n is 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, payload)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// retain the chaining key ck for the data phase KDF
// retain the hash h for the data phase Additional Symmetric Key (SipHash) KDF
End of "se" message pattern.
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
3) SessionConfirmed
Alice envía a Bob.
Contenido de Noise: clave estática de Alice Carga útil de Noise: RouterInfo de Alice y relleno aleatorio Carga útil no-noise: ninguna
(Propiedades de Seguridad de la Carga Útil)
XK(s, rs): Authentication Confidentiality
-> s, se 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI). The
sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key
pair. Assuming the corresponding private keys are secure, this
authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy. This payload is
encrypted based on an ephemeral-ephemeral DH as well as an ephemeral-static
DH with the recipient's static key pair. Assuming the ephemeral private
keys are secure, and the recipient is not being actively impersonated by an
attacker that has stolen its static private key, this payload cannot be
decrypted.
"s": Alice writes her static public key from the s variable into the
message buffer, encrypting it, and hashes the output along with the old h
to derive a new h.
"se": A DH is performed between the Alice's static key pair and the Bob's
ephemeral key pair. The result is hashed along with the old ck to derive a
new ck and k, and n is set to zero.
Esto contiene dos frames ChaChaPoly. El primero es la clave pública estática cifrada de Alice. El segundo es la carga útil de Noise: el RouterInfo cifrado de Alice, opciones opcionales y relleno opcional. Utilizan claves diferentes, porque la función MixKey() se llama entre ellos.
Contenidos sin procesar:
+----+----+----+----+----+----+----+----+
| |
+ ChaChaPoly frame (48 bytes) +
| Encrypted and authenticated |
+ Alice static key S +
| (32 bytes) |
+ +
| k defined in KDF for message 2 |
+ n = 1 +
| see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ Length specified in message 1 +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ +
| Alice RouterInfo |
+ using block format 2 +
| Alice Options (optional) |
+ using block format 1 +
| Arbitrary padding |
+ using block format 254 +
| |
+ +
| k defined in KDF for message 3 part 2 |
+ n = 0 +
| see KDF for associated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, ChaChaPoly encrypted Alice's X25519 static key, little endian
inside 48 byte ChaChaPoly frame
Datos no cifrados (etiquetas de autenticación Poly1305 no mostradas):
+----+----+----+----+----+----+----+----+
| |
+ +
| S |
+ Alice static key +
| (32 bytes) |
+ +
| |
+ +
+----+----+----+----+----+----+----+----+
| |
+ +
| |
+ +
| Alice RouterInfo block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Options block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Padding block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, Alice's X25519 static key, little endian
1) DPI en línea
Bob debe realizar la validación habitual del Router Info. Asegurar que el tipo de firma sea compatible, verificar la firma, verificar que la marca de tiempo esté dentro de los límites, y cualquier otra verificación necesaria.
Bob debe verificar que la clave estática de Alice recibida en el primer frame coincida con la clave estática en el Router Info. Bob debe primero buscar en el Router Info una NTCP o NTCP2 Router Address con una opción de versión (v) coincidente. Ver las secciones Published Router Info y Unpublished Router Info más abajo.
Si Bob tiene una versión más antigua del RouterInfo de Alice en su netdb, verificar que la clave estática en el router info es la misma en ambos, si está presente, y si la versión más antigua tiene menos de XXX de antigüedad (ver tiempo de rotación de clave abajo)
Bob debe validar que la clave estática de Alice es un punto válido en la curva aquí.
Las opciones deben incluirse, para especificar parámetros de padding.
En caso de cualquier error, incluyendo falla de validación de AEAD, RI, DH, timestamp, o clave, Bob debe detener el procesamiento adicional de mensajes y cerrar la conexión sin responder. Esto debe ser un cierre anormal (TCP RST).
Para facilitar el establecimiento rápido de conexión, las implementaciones deben asegurar que Alice almacene en búfer y luego envíe todo el contenido del tercer mensaje de una vez, incluyendo ambos marcos AEAD. Esto aumenta la probabilidad de que los datos estén contenidos en un solo paquete TCP (a menos que sean segmentados por el SO o middleboxes), y sean recibidos de una vez por Bob. Esto también es por eficiencia y para asegurar la efectividad del relleno aleatorio.
Longitud del frame de la parte 2 del mensaje 3: La longitud de este frame (incluyendo MAC) es enviada por Alice en el mensaje 1. Consulta ese mensaje para notas importantes sobre permitir suficiente espacio para el padding.
Contenido del frame de la parte 2 del mensaje 3: El formato de este frame es el mismo que el formato de los frames de la fase de datos, excepto que la longitud del frame es enviada por Alice en el mensaje 1. Ver más abajo para el formato del frame de la fase de datos. El frame debe contener de 1 a 3 bloques en el siguiente orden:
- Bloque de Router Info de Alice (requerido)
- Bloque de opciones (opcional)
- Bloque de relleno (opcional) Este frame nunca debe contener ningún otro tipo de bloque.
El relleno de la parte 2 del mensaje 3 no es necesario si Alice añade una trama de fase de datos (opcionalmente conteniendo relleno) al final del mensaje 3 y envía ambos a la vez, ya que aparecerá como un gran flujo de bytes para un observador. Como Alice generalmente, pero no siempre, tendrá un mensaje I2NP para enviar a Bob (por eso se conectó a él), esta es la implementación recomendada, por eficiencia y para asegurar la efectividad del relleno aleatorio.
La longitud total de ambos marcos AEAD del Mensaje 3 (partes 1 y 2) es de 65535 bytes; la parte 1 es de 48 bytes, por lo que la longitud máxima del marco de la parte 2 es de 65487; la longitud máxima del texto plano de la parte 2, excluyendo el MAC, es de 65471.
Key Derivation Function (KDF) (for data phase)
La fase de datos utiliza una entrada de datos asociados de longitud cero.
El KDF genera dos claves de cifrado k_ab y k_ba a partir de la clave de encadenamiento ck, utilizando HMAC-SHA256(key, data) como se define en RFC-2104. Esta es la función Split(), exactamente como se define en la especificación Noise.
ck = from handshake phase
// k_ab, k_ba = HKDF(ck, zerolen)
// ask_master = HKDF(ck, zerolen, info="ask")
// zerolen is a zero-length byte array
temp_key = HMAC-SHA256(ck, zerolen)
// overwrite the chaining key in memory, no longer needed
ck = (all zeros)
// Output 1
// cipher key, for Alice transmits to Bob (Noise doesn't make clear which is which, but Java code does)
k_ab = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// cipher key, for Bob transmits to Alice (Noise doesn't make clear which is which, but Java code does)
k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)).
KDF for SipHash for length field:
Generate an Additional Symmetric Key (ask) for SipHash
SipHash uses two 8-byte keys (big endian) and 8 byte IV for first data.
// "ask" is 3 bytes, US-ASCII, no null termination
ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01))
// sip_master = HKDF(ask_master, h || "siphash")
// "siphash" is 7 bytes, US-ASCII, no null termination
// overwrite previous temp_key in memory
// h is from KDF for message 3 part 2
temp_key = HMAC-SHA256(ask_master, h || "siphash")
// overwrite ask_master in memory, no longer needed
ask_master = (all zeros)
sip_master = HMAC-SHA256(temp_key, byte(0x01))
Alice to Bob SipHash k1, k2, IV:
// sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen)
// overwrite previous temp_key in memory
temp_key = HMAC-SHA256(sip_master, zerolen)
// overwrite sip_master in memory, no longer needed
sip_master = (all zeros)
sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)).
sipk1_ab = sipkeys_ab[0:7], little endian
sipk2_ab = sipkeys_ab[8:15], little endian
sipiv_ab = sipkeys_ab[16:23]
Bob to Alice SipHash k1, k2, IV:
sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02)).
sipk1_ba = sipkeys_ba[0:7], little endian
sipk2_ba = sipkeys_ba[8:15], little endian
sipiv_ba = sipkeys_ba[16:23]
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
4) Data Phase
Payload de Noise: Como se define a continuación, incluyendo relleno aleatorio Payload que no es de Noise: ninguno
Comenzando con la segunda parte del mensaje 3, todos los mensajes están dentro de un “frame” ChaChaPoly autenticado y encriptado con una longitud ofuscada de dos bytes antepuesta. Todo el relleno está dentro del frame. Dentro del frame hay un formato estándar con cero o más “bloques”. Cada bloque tiene un tipo de un byte y una longitud de dos bytes. Los tipos incluyen fecha/hora, mensaje I2NP, opciones, terminación y relleno.
Nota: Bob puede, pero no está obligado, enviar su RouterInfo a Alice como su primer mensaje a Alice en la fase de datos.
(Propiedades de Seguridad del Payload)
XK(s, rs): Authentication Confidentiality
<- 2 5
-> 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy.
This payload is encrypted based on an ephemeral-ephemeral DH as well as
an ephemeral-static DH with the recipient's static key pair.
Assuming the ephemeral private keys are secure, and the recipient is not being actively impersonated
by an attacker that has stolen its static private key, this payload cannot be decrypted.
2) DPI Offline
Para eficiencia y minimizar la identificación del campo de longitud, las implementaciones deben asegurar que el remitente almacene en búfer y luego vacíe todo el contenido de los mensajes de datos de una vez, incluyendo el campo de longitud y el marco AEAD. Esto aumenta la probabilidad de que los datos estén contenidos en un solo paquete TCP (a menos que sean segmentados por el SO o middleboxes), y sean recibidos de una vez por la otra parte. Esto también es por eficiencia y para asegurar la efectividad del relleno aleatorio.
El router puede elegir terminar la sesión en caso de error AEAD, o puede continuar intentando comunicaciones. Si continúa, el router debería terminar después de errores repetidos.
SipHash obfuscated length
Referencia: SipHash
Una vez que ambos lados han completado el handshake, transfieren cargas útiles que luego son cifradas y autenticadas en “frames” de ChaChaPoly.
Cada frame está precedido por una longitud de dos bytes, big endian. Esta longitud especifica el número de bytes de frame cifrados que siguen, incluyendo el MAC. Para evitar transmitir campos de longitud identificables en el stream, la longitud del frame se ofusca mediante XOR con una máscara derivada de SipHash, como se inicializa desde el KDF de la fase de datos. Tenga en cuenta que las dos direcciones tienen claves SipHash e IVs únicos del KDF.
sipk1, sipk2 = The SipHash keys from the KDF. (two 8-byte long integers)
IV[0] = sipiv = The SipHash IV from the KDF. (8 bytes)
length is big endian.
For each frame:
IV[n] = SipHash-2-4(sipk1, sipk2, IV[n-1])
Mask[n] = First 2 bytes of IV[n]
obfuscatedLength = length ^ Mask[n]
The first length output will be XORed with with IV[1].
El receptor tiene las claves SipHash e IV idénticas. La decodificación de la longitud se realiza derivando la máscara utilizada para ofuscar la longitud y aplicando XOR al digest truncado para obtener la longitud del frame. La longitud del frame es la longitud total del frame cifrado incluyendo el MAC.
Trabajo futuro
- Si usas una función de biblioteca SipHash que devuelve un entero largo sin signo, usa los dos bytes menos significativos como la Mask. Convierte el entero largo al siguiente IV como little endian.
Cifrado Autenticado
+----+----+----+----+----+----+----+----+
|obf size | |
+----+----+ +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ key is k_ab for Alice to Bob +
| key is k_ba for Bob to Alice |
+ as defined in KDF for data phase +
| n starts at 0 and increments |
+ for each frame in that direction +
| no associated data |
+ 16 bytes minimum +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
obf size :: 2 bytes length obfuscated with SipHash
when de-obfuscated: 16 - 65535
Minimum size including length field is 18 bytes.
Maximum size including length field is 65537 bytes.
Obfuscated length is 2 bytes.
Maximum ChaChaPoly frame is 65535 bytes.
ChaCha20/Poly1305
Hay cero o más bloques en el frame cifrado. Cada bloque contiene un identificador de un byte, una longitud de dos bytes y cero o más bytes de datos.
Para extensibilidad, los receptores deben ignorar bloques con identificadores desconocidos y tratarlos como relleno.
Los datos encriptados tienen un máximo de 65535 bytes, incluyendo un encabezado de autenticación de 16 bytes, por lo que el máximo de datos sin encriptar es de 65519 bytes.
(Etiqueta de autenticación Poly1305 no mostrada):
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
~ . . . ~
blk :: 1 byte
0 for datetime
1 for options
2 for RouterInfo
3 for I2NP message
4 for termination
224-253 reserved for experimental features
254 for padding
255 reserved for future extension
size :: 2 bytes, big endian, size of data to follow, 0 - 65516
data :: the data
Maximum ChaChaPoly frame is 65535 bytes.
Poly1305 tag is 16 bytes
Maximum total block size is 65519 bytes
Maximum single block size is 65519 bytes
Block type is 1 byte
Block length is 2 bytes
Maximum single block data size is 65516 bytes.
Block Ordering Rules
En el mensaje de handshake 3 parte 2, el orden debe ser: RouterInfo, seguido de Options si están presentes, seguido de Padding si está presente. No se permiten otros bloques.
En la fase de datos, el orden no está especificado, excepto por los siguientes requisitos: El relleno (Padding), si está presente, debe ser el último bloque. La terminación (Termination), si está presente, debe ser el último bloque excepto por el relleno (Padding).
Puede haber múltiples bloques I2NP en una sola trama. No se permiten múltiples bloques de relleno en una sola trama. Otros tipos de bloques probablemente no tendrán múltiples bloques en una sola trama, pero no está prohibido.
Manejo de Errores AEAD
Caso especial para sincronización de tiempo:
+----+----+----+----+----+----+----+
| 0 | 4 | timestamp |
+----+----+----+----+----+----+----+
blk :: 0
size :: 2 bytes, big endian, value = 4
timestamp :: Unix timestamp, unsigned seconds.
Wraps around in 2106
Función de Derivación de Claves (KDF) (para el mensaje de handshake 1)
Pasar opciones actualizadas. Las opciones incluyen: Relleno mínimo y máximo.
El bloque de opciones tendrá longitud variable.
+----+----+----+----+----+----+----+----+
| 1 | size |tmin|tmax|rmin|rmax|tdmy|
+----+----+----+----+----+----+----+----+
|tdmy| rdmy | tdelay | rdelay | |
~----+----+----+----+----+----+----+ ~
| more_options |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 1
size :: 2 bytes, big endian, size of options to follow, 12 bytes minimum
tmin, tmax, rmin, rmax :: requested padding limits
tmin and rmin are for desired resistance to traffic analysis.
tmax and rmax are for bandwidth limits.
tmin and tmax are the transmit limits for the router sending this options block.
rmin and rmax are the receive limits for the router sending this options block.
Each is a 4.4 fixed-point float representing 0 to 15.9375
(or think of it as an unsigned 8-bit integer divided by 16.0).
This is the ratio of padding to data. Examples:
Value of 0x00 means no padding
Value of 0x01 means add 6 percent padding
Value of 0x10 means add 100 percent padding
Value of 0x80 means add 800 percent (8x) padding
Alice and Bob will negotiate the minimum and maximum in each direction.
These are guidelines, there is no enforcement.
Sender should honor receiver's maximum.
Sender may or may not honor receiver's minimum, within bandwidth constraints.
tdmy: Max dummy traffic willing to send, 2 bytes big endian, bytes/sec average
rdmy: Requested dummy traffic, 2 bytes big endian, bytes/sec average
tdelay: Max intra-message delay willing to insert, 2 bytes big endian, msec average
rdelay: Requested intra-message delay, 2 bytes big endian, msec average
Padding distribution specified as additional parameters?
Random delay specified as additional parameters?
more_options :: Format TBD
1) SessionRequest
- El formato de opciones está por definir.
- La negociación de opciones está por definir.
RouterInfo
Pasa el RouterInfo de Alice a Bob. Usado en el mensaje de handshake 3 parte 2. Pasa el RouterInfo de Alice a Bob, o el de Bob a Alice. Usado opcionalmente en la fase de datos.
+----+----+----+----+----+----+----+----+
| 2 | size |flg | RouterInfo |
+----+----+----+----+ +
| (Alice RI in handshake msg 3 part 2) |
~ (Alice, Bob, or third-party ~
| RI in data phase) |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 2
size :: 2 bytes, big endian, size of flag + router info to follow
flg :: 1 byte flags
bit order: 76543210
bit 0: 0 for local store, 1 for flood request
bits 7-1: Unused, set to 0 for future compatibility
routerinfo :: Alice's or Bob's RouterInfo
Notes
Cuando se usa en la fase de datos, el receptor (Alice o Bob) debe validar que es el mismo Router Hash que se envió originalmente (para Alice) o al que se envió (para Bob). Luego, tratarlo como un mensaje I2NP DatabaseStore local. Validar la firma, validar que tenga una marca de tiempo más reciente, y almacenarlo en el netdb local. Si el bit de bandera 0 es 1, y la parte receptora es floodfill, tratarlo como un mensaje DatabaseStore con un token de respuesta diferente de cero, y propagarlo a los floodfills más cercanos.
La Router Info NO está comprimida con gzip (a diferencia de en un DatabaseStore Message, donde sí lo está)
El flooding no debe solicitarse a menos que haya RouterAddresses publicadas en el RouterInfo. El router receptor no debe hacer flood del RouterInfo a menos que contenga RouterAddresses publicadas.
Los implementadores deben asegurar que al leer un bloque, datos malformados o maliciosos no causarán que las lecturas se desborden hacia el siguiente bloque.
Este protocolo no proporciona una confirmación de que la RouterInfo fue recibida, almacenada o propagada (ya sea en la fase de handshake o de datos). Si se desea confirmación, y el receptor es floodfill, el emisor debería enviar en su lugar un DatabaseStoreMessage I2NP estándar con un token de respuesta.
Issues
También podría usarse en la fase de datos, en lugar de un I2NP DatabaseStoreMessage. Por ejemplo, Bob podría usarlo para iniciar la fase de datos.
¿Está permitido que esto contenga el RI para routers distintos al originador, como un reemplazo general para DatabaseStoreMessages, por ejemplo, para flooding por floodfills?
Función de Derivación de Claves (KDF) (para mensaje de handshake 2 y mensaje 3 parte 1)
Un solo mensaje I2NP con un encabezado modificado. Los mensajes I2NP no pueden ser fragmentados a través de bloques o a través de marcos ChaChaPoly.
Esto utiliza los primeros 9 bytes del encabezado I2NP NTCP estándar, y elimina los últimos 7 bytes del encabezado, de la siguiente manera: truncar la expiración de 8 a 4 bytes, eliminar la longitud de 2 bytes (usar el tamaño de bloque - 9), y eliminar el checksum SHA256 de un byte.
+----+----+----+----+----+----+----+----+
| 3 | size |type| msg id |
+----+----+----+----+----+----+----+----+
| short exp | message |
+----+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 3
size :: 2 bytes, big endian, size of type + msg id + exp + message to follow
I2NP message body size is (size - 9).
type :: 1 byte, I2NP msg type, see I2NP spec
msg id :: 4 bytes, big endian, I2NP message ID
short exp :: 4 bytes, big endian, I2NP message expiration, Unix timestamp, unsigned seconds.
Wraps around in 2106
message :: I2NP message body
Notes
- Los implementadores deben asegurar que al leer un bloque, los datos malformados o maliciosos no causarán que las lecturas se desborden hacia el siguiente bloque.
2) SessionCreated
Noise recomienda un mensaje de terminación explícito. El NTCP original no tiene uno. Descartar la conexión. Este debe ser el último bloque sin relleno en la trama.
+----+----+----+----+----+----+----+----+
| 4 | size | valid data frames |
+----+----+----+----+----+----+----+----+
received | rsn| addl data |
+----+----+----+----+ +
~ . . . ~
+----+----+----+----+----+----+----+----+
blk :: 4
size :: 2 bytes, big endian, value = 9 or more
valid data frames received :: The number of valid AEAD data phase frames received
(current receive nonce value)
0 if error occurs in handshake phase
8 bytes, big endian
rsn :: reason, 1 byte:
0: normal close or unspecified
1: termination received
2: idle timeout
3: router shutdown
4: data phase AEAD failure
5: incompatible options
6: incompatible signature type
7: clock skew
8: padding violation
9: AEAD framing error
10: payload format error
11: message 1 error
12: message 2 error
13: message 3 error
14: intra-frame read timeout
15: RI signature verification fail
16: s parameter missing, invalid, or mismatched in RouterInfo
17: banned
addl data :: optional, 0 or more bytes, for future expansion, debugging,
or reason text.
Format unspecified and may vary based on reason code.
Notes
No todas las razones pueden ser realmente utilizadas, depende de la implementación. Los fallos de handshake generalmente resultarán en un cierre con TCP RST en su lugar. Ver las notas en las secciones de mensajes de handshake arriba. Las razones adicionales listadas son por consistencia, registro, depuración, o si las políticas cambian.
Padding
Esto es para el relleno dentro de tramas AEAD. El relleno para los mensajes 1 y 2 está fuera de las tramas AEAD. Todo el relleno para el mensaje 3 y la fase de datos está dentro de las tramas AEAD.
El padding dentro de AEAD debería adherirse aproximadamente a los parámetros negociados. Bob envió sus parámetros mínimos/máximos tx/rx solicitados en el mensaje 2. Alice envió sus parámetros mínimos/máximos tx/rx solicitados en el mensaje 3. Se pueden enviar opciones actualizadas durante la fase de datos. Ver la información del bloque de opciones arriba.
Si está presente, este debe ser el último bloque en el frame.
+----+----+----+----+----+----+----+----+
|254 | size | padding |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 254
size :: 2 bytes, big endian, size of padding to follow
padding :: random data
Notes
- Estrategias de relleno por determinar.
- Relleno mínimo por determinar.
- Se permiten tramas que contengan solo relleno.
- Valores predeterminados de relleno por determinar.
- Ver bloque de opciones para negociación de parámetros de relleno
- Ver bloque de opciones para parámetros de relleno mín/máx
- Noise limita los mensajes a 64KB. Si es necesario más relleno, envía múltiples tramas.
- La respuesta del router ante la violación del relleno negociado depende de la implementación.
Other block types
Las implementaciones deben ignorar los tipos de bloques desconocidos para compatibilidad hacia adelante, excepto en el mensaje 3 parte 2, donde no se permiten bloques desconocidos.
Future work
- La longitud del padding debe decidirse por mensaje individual y estimaciones de la distribución de longitud, o se deben agregar retrasos aleatorios. Estas contramedidas deben incluirse para resistir DPI, ya que los tamaños de mensaje revelarían de otra manera que el tráfico I2P está siendo transportado por el protocolo de transporte. El esquema exacto de padding es un área de trabajo futuro, el Apéndice A proporciona más información sobre el tema.
5) Termination
Las conexiones pueden terminarse mediante el cierre normal o anormal del socket TCP, o, como recomienda Noise, un mensaje de terminación explícito. El mensaje de terminación explícito se define en la fase de datos anterior.
Ante cualquier terminación normal o anormal, los routers deben poner a cero cualquier dato efímero en memoria, incluyendo claves efímeras de handshake, claves de cifrado simétricas e información relacionada.
Published Router Info
Cifrado para la parte 1 del mensaje 3 de handshake, utilizando KDF del mensaje 2)
La RouterAddress publicada (parte del RouterInfo) tendrá un identificador de protocolo de “NTCP” o “NTCP2”.
El RouterAddress debe contener las opciones “host” y “port”, como en el protocolo NTCP actual.
El RouterAddress debe contener tres opciones para indicar compatibilidad con NTCP2:
s=(Clave Base64) La clave pública estática (s) de Noise actual para esta RouterAddress. Codificada en Base 64 usando el alfabeto estándar I2P Base 64. 32 bytes en binario, 44 bytes codificada en Base 64, clave pública X25519 en little-endian.
i=(Base64 IV) El IV actual para cifrar el valor X en el mensaje 1 para esta RouterAddress. Codificado en Base 64 usando el alfabeto estándar Base 64 de I2P. 16 bytes en binario, 24 bytes como Base 64 codificado, big-endian.
v=2 La versión actual (2). Cuando se publica como “NTCP”, se implica soporte adicional para la versión 1. El soporte para versiones futuras será con valores separados por comas, p. ej. v=2,3 La implementación debe verificar la compatibilidad, incluyendo múltiples versiones si hay una coma presente. Las versiones separadas por comas deben estar en orden numérico.
Alice debe verificar que las tres opciones estén presentes y sean válidas antes de conectarse usando el protocolo NTCP2.
Cuando se publica como “NTCP” con las opciones “s”, “i” y “v”, el router debe aceptar conexiones entrantes en ese host y puerto para ambos protocolos NTCP y NTCP2, y detectar automáticamente la versión del protocolo.
Cuando se publica como “NTCP2” con las opciones “s”, “i” y “v”, el router acepta conexiones entrantes en ese host y puerto únicamente para el protocolo NTCP2.
Si un router admite tanto conexiones NTCP1 como NTCP2 pero no implementa detección automática de versión para conexiones entrantes, debe anunciar tanto direcciones “NTCP” como “NTCP2”, e incluir las opciones NTCP2 únicamente en la dirección “NTCP2”. El router debe establecer un valor de costo menor (mayor prioridad) en la dirección “NTCP2” que en la dirección “NTCP”, para que NTCP2 sea preferido.
Si múltiples RouterAddresses NTCP2 (ya sea como “NTCP” o “NTCP2”) son publicadas en el mismo RouterInfo (para direcciones IP o puertos adicionales), todas las direcciones que especifiquen el mismo puerto deben contener las opciones y valores NTCP2 idénticos. En particular, todas deben contener la misma clave estática e iv.
Función de Derivación de Claves (KDF) (para el mensaje de handshake 3 parte 2)
Si Alice no publica su dirección NTCP2 (como “NTCP” o “NTCP2”) para conexiones entrantes, debe publicar una dirección de router “NTCP2” que contenga únicamente su clave estática y la versión NTCP2, para que Bob pueda validar la clave después de recibir el RouterInfo de Alice en la parte 2 del mensaje 3.
s=(Clave Base64) Como se define arriba para direcciones publicadas.
v=2 Como se define arriba para direcciones publicadas.
Esta dirección del router no contendrá las opciones “i”, “host” o “port”, ya que no son necesarias para las conexiones NTCP2 salientes. El coste publicado para esta dirección no importa estrictamente, ya que es solo de entrada; sin embargo, puede ser útil para otros routers si el coste se establece más alto (menor prioridad) que otras direcciones. El valor sugerido es 14.
Alice también puede simplemente añadir las opciones “s” y “v” a una dirección “NTCP” publicada existente.
3) SessionConfirmed
Debido al almacenamiento en caché de RouterInfos, los routers no deben rotar la clave pública estática o el IV mientras el router esté funcionando, ya sea en una dirección publicada o no. Los routers deben almacenar de forma persistente esta clave e IV para reutilización después de un reinicio inmediato, para que las conexiones entrantes continúen funcionando y los tiempos de reinicio no sean expuestos. Los routers deben almacenar de forma persistente, o determinar de otro modo, el tiempo del último apagado, para que el tiempo de inactividad previo pueda ser calculado al iniciar.
Sujeto a preocupaciones sobre exponer tiempos de reinicio, los routers pueden rotar esta clave o IV al inicio si el router estuvo previamente inactivo durante algún tiempo (un par de horas como mínimo).
Si el router tiene alguna NTCP2 RouterAddresses publicada (como NTCP o NTCP2), el tiempo mínimo de inactividad antes de la rotación debería ser mucho más largo, por ejemplo un mes, a menos que la dirección IP local haya cambiado o el router realice un “rekeys”.
Si el router tiene SSU RouterAddresses publicadas, pero no NTCP2 (como NTCP o NTCP2), el tiempo mínimo de inactividad antes de la rotación debería ser más largo, por ejemplo un día, a menos que la dirección IP local haya cambiado o el router realice un “rekeys”. Esto aplica incluso si la dirección SSU publicada tiene introducers.
Si el router no tiene ninguna RouterAddress publicada (NTCP, NTCP2, o SSU), el tiempo mínimo de inactividad antes de la rotación puede ser tan corto como dos horas, incluso si la dirección IP cambia, a menos que el router haga un “rekeys”.
Si el router “rekeys” a un Router Hash diferente, también debería generar una nueva clave de noise y IV.
Las implementaciones deben tener en cuenta que cambiar la clave pública estática o el IV impedirá las conexiones NTCP2 entrantes de routers que hayan almacenado en caché un RouterInfo más antiguo. La publicación de RouterInfo, la selección de pares de túnel (incluyendo tanto OBGW como el salto más cercano IB), la selección de túneles de cero saltos, la selección de transporte y otras estrategias de implementación deben tomar esto en consideración.
La rotación de IV está sujeta a reglas idénticas a la rotación de claves, excepto que los IVs no están presentes excepto en RouterAddresses publicadas, por lo que no hay IV para routers ocultos o protegidos por firewall. Si algo cambia (versión, clave, opciones?) se recomienda que el IV también cambie.
Nota: El tiempo mínimo de inactividad antes del recambio de claves puede modificarse para garantizar la salud de la red y prevenir el reseeding por parte de un router inactivo durante un período moderado de tiempo.
Identity Hiding
La denegabilidad no es un objetivo. Ver la descripción general anterior.
A cada patrón se le asignan propiedades que describen la confidencialidad proporcionada a la clave pública estática del iniciador, y a la clave pública estática del respondedor. Las suposiciones subyacentes son que las claves privadas efímeras son seguras, y que las partes abortan el handshake si reciben una clave pública estática de la otra parte en la que no confían.
Esta sección solo considera la filtración de identidad a través de campos de clave pública estáticos en los handshakes. Por supuesto, las identidades de los participantes de Noise podrían estar expuestas a través de otros medios, incluyendo campos de payload, análisis de tráfico, o metadatos como direcciones IP.
Alice: (8) Cifrado con forward secrecy hacia una parte autenticada.
Bob: (3) No se transmite, pero un atacante pasivo puede verificar candidatos para la clave privada del respondedor y determinar si el candidato es correcto.
Bob publica su clave pública estática en la netDb. ¿Alice puede o no puede?
Issues
- Si Bob cambia su clave estática, ¿podría recurrir a un patrón “XX”?
Marco de Protocolo Noise
Cuando se publica como “NTCP”, el router debe detectar automáticamente la versión del protocolo para las conexiones entrantes.
Esta detección depende de la implementación, pero aquí se proporciona una guía general.
Para detectar la versión de una conexión NTCP entrante, Bob procede de la siguiente manera:
Espera al menos 64 bytes (tamaño mínimo del mensaje 1 de NTCP2)
Si los datos iniciales recibidos son de 288 o más bytes, la conexión entrante es versión 1.
Si son menos de 288 bytes, entonces
Esperar un corto tiempo por más datos (buena estrategia antes de la adopción generalizada de NTCP2) si se han recibido al menos 288 en total, es NTCP 1.
Intenta las primeras etapas de decodificación como versión 2, si falla, espera un tiempo corto para obtener más datos (buena estrategia después de la adopción generalizada de NTCP2)
- Decrypt the first 32 bytes (the X key) of the SessionRequest packet using AES-256 with key RH_B. - Verify a valid point on the curve. If it fails, wait a short time for more data for NTCP 1 - Verify the AEAD frame. If it fails, wait a short time for more data for NTCP 1
Ten en cuenta que se pueden recomendar cambios o estrategias adicionales si detectamos ataques activos de segmentación TCP en NTCP 1.
Para facilitar la detección rápida de versión y el handshaking, las implementaciones deben asegurar que Alice almacene en buffer y luego envíe todo el contenido del primer mensaje de una vez, incluyendo el padding. Esto aumenta la probabilidad de que los datos estén contenidos en un solo paquete TCP (a menos que sean segmentados por el SO o middleboxes), y sean recibidos de una vez por Bob. Esto también es por eficiencia y para asegurar la efectividad del padding aleatorio. Esto aplica tanto a los handshakes NTCP como NTCP2.
Adiciones al Framework
Si Alice y Bob ambos soportan NTCP2, Alice debería conectarse con NTCP2.
Si Alice no logra conectarse a Bob usando NTCP2 por cualquier razón, la conexión falla. Alice no puede reintentar usando NTCP 1.
¿Recurrir al patrón XX si Bob cambia sus claves? ¿Esto requeriría un byte de tipo antepuesto?
¿“Avanzar” al patrón KK si Alice se reconecta, asumiendo que Bob aún tiene su clave estática? Esto no ahorra ningún viaje de ida y vuelta y usa 4 rondas DH comparado con 3 para XK. Probablemente no.
KK(s, rs):
-> s
<- s
...
-> e, es, ss
<- e, ee, se
Nuevas Primitivas Criptográficas para I2P
Esta sección discute un ataque contra esquemas de padding típicos que permite a los atacantes descubrir la distribución de probabilidad de la longitud de los mensajes sin padding, observando únicamente la longitud de los mensajes con padding. Sea N una variable aleatoria que describe el número de bytes sin padding, y P de manera similar para el número de bytes de padding. El tamaño total del mensaje es entonces N + P.
Supongamos que para un tamaño sin relleno de n, se añaden al menos P_min(n) >= 0 y como máximo P_max(n) >= P_min(n) bytes de relleno en un esquema de padding. El esquema obvio utiliza relleno de longitud P elegida uniformemente al azar:
Pr[P = p | N = n] = 1 / (P_max(n) - P_min(n)) if P_min(n) <= p <= P_max(n),
0 otherwise.
Un esquema de relleno ingenuo simplemente aseguraría que el tamaño del mensaje con relleno no exceda N_max:
P_max(n) = N_max - n, n <= N_max
P_min(n) = 0.
Sin embargo, esto filtra información sobre la longitud sin relleno.
Un atacante puede fácilmente estimar Pr[x <= N + P <= y], por ejemplo mediante un histograma.
- A partir de esto, también puede tratar de estimar
Pr[n_1 <= N <= n_2], de hecho:
Pr[N + P = m] = Σ_n Pr[N = n] Pr[P = m - n | N = n].
En el esquema naive,
Pr[N + P = m] = Σ_{n <= m} Pr[N = n] / (N_max - n).
Es bastante obvio, como lo era antes de hacer el cálculo anterior, que esto filtra información sobre Pr[N = n]: si la longitud de los paquetes es casi siempre mayor que m, entonces N + P <= m casi nunca será observado. Sin embargo, este no es el problema más grande, aunque poder observar la longitud mínima del mensaje puede considerarse un problema en sí mismo.
Un problema mayor es que es posible determinar Pr[N = n] exactamente:
Pr[N + P = m] - Pr[N + P = m-1] = Pr[N = m] / (N_max - m),
es decir
Pr[N = n] = (N_max - n)(Pr[N + P = n] - Pr[N + P = n - 1])
Para distinguir NTCP2, entonces, el atacante puede usar cualquiera de los siguientes:
Estimar
Pr[kB <= N <= (k + 1)B - 1]para enteros positivos k. Siempre será cero para NTCP2.Estimar
Pr[N = kB]y comparar con un perfil estándar de I2P.
Este ataque simple por tanto destruye parcialmente el propósito del padding, que intenta ofuscar la distribución de tamaños de los mensajes sin padding. La cantidad de mensajes que el atacante tiene que observar para distinguir el protocolo depende de la precisión deseada y de los tamaños mínimo y máximo de mensajes sin padding que ocurren en la práctica. Nótese que es fácil para el atacante recopilar muchos mensajes, ya que puede usar todo el tráfico enviado desde y hacia el puerto particular que el objetivo está usando.
En algunas formas (p. ej., estimación de Pr[kB <= N <= (k + 1)B - 1]) el ataque requiere solo unos pocos bytes de memoria (un entero es suficiente) y se podría argumentar que tal ataque podría incluirse en muchos marcos DPI ligeramente más avanzados pero sin embargo estándar.
Esta propuesta sugiere usar una de las siguientes contramedidas:
Desarrollar un esquema de padding alternativo que tenga en cuenta la distribución (estimada) de N utilizando una distribución de longitud de padding no uniforme. Un buen esquema de padding probablemente requeriría mantener un histograma del número de bloques por mensaje.
Añadir retrasos aleatorios entre fragmentos (de tamaño aleatorio) de mensajes.
La segunda opción es generalmente más preferida, porque puede ser utilizada simultáneamente como una contramedida contra el análisis de flujo. Sin embargo, tales retrasos pueden estar fuera del alcance del protocolo NTCP2, de tal manera que la primera opción, que también es más fácil de implementar, puede ser preferida en su lugar.
Estimación de sobrecarga de procesamiento
Resistencia a DPI basada en temporización (la temporización/retrasos entre mensajes pueden depender de la implementación; los retrasos intra-mensaje pueden introducirse en cualquier punto, incluso antes de enviar el padding aleatorio, por ejemplo). Los retrasos artificiales (lo que obfs4 llama IAT o tiempo entre llegadas) son independientes del protocolo en sí.