Nota
A fase de proposta está encerrada. Consulte SPEC para a especificação oficial. Esta proposta ainda pode ser referenciada para informações de contexto.
Visão Geral
Esta proposta descreve um protocolo de acordo de chaves autenticado para melhorar a resistência do NTCP a várias formas de identificação automatizada e ataques.
A proposta está organizada da seguinte forma: os objetivos de segurança são apresentados, seguidos de uma discussão sobre o protocolo básico. Em seguida, é fornecida uma especificação completa de todas as mensagens do protocolo. Finalmente, são discutidos os endereços do router e a identificação de versão. Um apêndice discutindo um ataque genérico em esquemas de padding comuns também está incluído, bem como um apêndice contendo vários candidatos para a cifra autenticada.
Assim como outros transportes I2P, o NTCP2 é definido exclusivamente para transporte ponto-a-ponto (router-para-router) de mensagens I2NP. Não é um pipe de dados de uso geral.
Motivação
Os dados NTCP são criptografados após a primeira mensagem (e a primeira mensagem parece ser dados aleatórios), impedindo assim a identificação do protocolo através de “análise de payload”. Ainda assim, permanece vulnerável à identificação do protocolo através de “análise de fluxo”. Isso ocorre porque as primeiras 4 mensagens (ou seja, o handshake) têm comprimento fixo (288, 304, 448 e 48 bytes).
Ao adicionar quantidades aleatórias de dados aleatórios a cada uma das mensagens, podemos tornar isso muito mais difícil.
Os autores reconhecem que as práticas padrão de segurança sugeririam o uso de um protocolo existente como o TLS, mas isso é Prop104 e tem seus próprios problemas. Sempre que apropriado, parágrafos de “trabalho futuro” foram adicionados para indicar recursos ausentes ou assuntos de discussão.
Objetivos de Design
Suporte NTCP 1 e 2 em uma única porta, detecção automática, e publicado como um único “transport” (ou seja, RouterAddress) no NetDB.
Publicar suporte apenas para versão 1, apenas 2, ou 1+2 no NetDB em um campo separado, e usar versão 1 apenas como padrão (não vincular o suporte de versão a uma versão específica do router)
Garantir que todas as implementações (Java/i2pd/Kovri/go) possam adicionar suporte à versão 2 (ou não) em seus próprios cronogramas
Adicionar preenchimento aleatório a todas as mensagens NTCP incluindo mensagens de handshake e de dados (ou seja, ofuscação de comprimento para que todas as mensagens não sejam múltiplas de 16 bytes) Fornecer mecanismo de opções para ambos os lados solicitarem preenchimento mínimo e máximo e/ou distribuição de preenchimento. As especificidades da distribuição de preenchimento são dependentes da implementação e podem ou não ser especificadas no próprio protocolo.
Ofuscar o conteúdo das mensagens que não estão criptografadas (1 e 2), de forma suficiente para que caixas DPI e assinaturas AV não possam classificá-las facilmente. Também garantir que as mensagens enviadas para um único peer ou conjunto de peers não tenham um padrão similar de bits.
Corrigir perda de bits no DH devido ao formato Java Ticket1112, possivelmente (provavelmente?) mudando para X25519.
Mudar para uma função real de derivação de chave (KDF) em vez de usar o resultado DH como está?
Adicionar “resistência a sondagem” (como o Tor chama); isso inclui resistência a replay.
Manter troca de chaves autenticada bidirecional (2W-AKE). 1W-AKE não é suficiente para nossa aplicação.
Continue a usar as assinaturas de tipo variável e comprimento variável (da chave de assinatura RouterIdentity publicada) como parte da autenticação. Confie numa chave pública estática publicada no RouterInfo como outra parte da autenticação.
Adicionar opções/versão no handshake para extensibilidade futura.
Adicionar resistência à segmentação TCP maliciosa de MitM (Man-in-the-Middle) se possível.
Não adicione significativamente à CPU necessária para configuração de conexão; se possível, reduza-a significativamente.
Adicionar autenticação de mensagem (MAC), possivelmente HMAC-SHA256 e Poly1305, e remover checksum Adler.
Encurtar e simplificar o cabeçalho I2NP: Encurtar a expiração para 4 bytes, como no SSU. Remover o checksum SHA256 truncado de um byte.
Se possível, reduzir o handshake de 4 mensagens e duas viagens de ida e volta para um handshake de 3 mensagens e uma viagem de ida e volta, como no SSU. Isso exigiria mover a assinatura de Bob da mensagem 4 para a mensagem 2. Pesquisar o motivo das 4 mensagens nos arquivos de email/status/reuniões de dez anos atrás.
Minimizar a sobrecarga do protocolo antes do preenchimento. Embora o preenchimento seja adicionado, e possivelmente muito dele, a sobrecarga antes do preenchimento ainda é sobrecarga. Nós de baixa largura de banda devem ser capazes de usar NTCP2.
Manter timestamps para detecção de replay e desvio.
Evitar qualquer problema do ano 2038 em timestamps, deve funcionar até pelo menos 2106.
Aumentar o tamanho máximo da mensagem de 16K para 32K ou 64K.
Qualquer nova primitiva criptográfica deve estar prontamente disponível em bibliotecas para uso nas implementações de router em Java (1.7), C++, e Go.
Incluir representantes dos desenvolvedores de router Java, C++, e Go no design.
Minimize alterações (mas ainda haverá muitas).
Suporte ambas as versões em um conjunto comum de código (isso pode não ser possível e é dependente da implementação de qualquer forma).
Non-Goals
Resistência à DPI à prova de balas… isso seriam transportes plugáveis, Prop109.
Um transporte baseado em TLS (ou similar ao HTTPS)… que seria Prop104.
É aceitável alterar a criptografia simétrica de fluxo.
Resistência a DPI baseada em tempo (temporização/atrasos entre mensagens podem ser dependentes da implementação; atrasos intra-mensagem podem ser introduzidos em qualquer ponto, incluindo antes de enviar o padding aleatório, por exemplo). Atrasos artificiais (o que o obfs4 chama de IAT ou tempo entre chegadas) são independentes do protocolo em si.
Negação plausível de participação em uma sessão (há assinaturas presentes).
Não-objetivos que podem ser parcialmente reconsiderados ou discutidos:
O grau de proteção contra Deep Packet Inspection (DPI)
Segurança Pós-Quântica (PQ)
Negação plausível
Related Goals
- Implementar uma configuração de teste NTCP 1/2
Security Goals
Consideramos três partes:
- Alice, que deseja estabelecer uma nova sessão.
- Bob, com quem Alice deseja estabelecer uma sessão.
- Mallory, o “homem no meio” entre Alice e Bob.
No máximo dois participantes podem se envolver em ataques ativos.
Alice e Bob estão ambos de posse de um par de chaves estático, que está contido em seu RouterIdentity.
O protocolo proposto tenta permitir que Alice e Bob concordem com uma chave secreta compartilhada (K) sob os seguintes requisitos:
Segurança da chave privada: nem Bob nem Mallory aprendem algo sobre a chave privada estática de Alice. Simetricamente, Alice não aprende nada sobre a chave privada estática de Bob.
A chave de sessão K é conhecida apenas por Alice e Bob.
Perfect forward secrecy: a chave de sessão acordada permanece secreta no futuro, mesmo quando as chaves privadas estáticas de Alice e/ou Bob são reveladas após a chave ter sido acordada.
Autenticação bidirecional: Alice tem certeza de que estabeleceu uma sessão com Bob, e vice-versa.
Proteção contra DPI online: Garantir que não seja trivial detectar que Alice e Bob estão envolvidos no protocolo usando apenas técnicas diretas de inspeção profunda de pacotes (DPI). Veja abaixo.
Negação limitada: nem Alice nem Bob podem negar a participação no protocolo, mas se qualquer um vazar a chave compartilhada, a outra parte pode negar a autenticidade do conteúdo dos dados transmitidos.
A presente proposta tenta fornecer todos os cinco requisitos baseados no protocolo Station-To-Station (STS). Note que este protocolo também é a base para o protocolo SSU.
Additional DPI Discussion
Assumimos dois componentes DPI:
1) Online DPI
DPI online inspecionando todos os fluxos em tempo real. As conexões podem ser bloqueadas ou manipuladas de outra forma. Os dados de conexão ou metadados podem ser identificados e armazenados para análise offline. O DPI online não tem acesso à base de dados da rede I2P. O DPI online tem apenas capacidade computacional limitada em tempo real, incluindo cálculo de comprimento, inspeção de campos e cálculos simples como XOR. O DPI online tem a capacidade de funções criptográficas rápidas em tempo real, como AES, AEAD e hashing, mas estas seriam muito caras para aplicar à maioria ou a todos os fluxos. Qualquer aplicação destas operações criptográficas aplicar-se-ia apenas a fluxos em combinações IP/Porta previamente identificadas por análise offline. O DPI online não tem a capacidade de funções criptográficas de alto overhead como DH ou elligator2. O DPI online não foi projetado especificamente para detectar I2P, embora possa ter regras de classificação limitadas para esse propósito.
É um objetivo prevenir a identificação do protocolo por um DPI online.
A noção de DPI online ou “direta” é aqui considerada como incluindo as seguintes capacidades do adversário:
A capacidade de inspecionar todos os dados enviados ou recebidos pelo alvo.
A capacidade de realizar operações nos dados observados, como aplicar cifras de bloco ou funções hash.
A capacidade de armazenar e comparar com mensagens enviadas anteriormente.
A capacidade de modificar, atrasar ou fragmentar pacotes.
No entanto, assume-se que o DPI online tem as seguintes restrições:
A incapacidade de mapear endereços IP para hashes de router. Embora isso seja trivial com acesso em tempo real à base de dados da rede, exigiria um sistema DPI especificamente projetado para visar o I2P.
A incapacidade de usar informações de temporização para detectar o protocolo.
De modo geral, a caixa de ferramentas DPI online não contém quaisquer ferramentas incorporadas que sejam especificamente projetadas para detecção de I2P. Isso inclui a criação de “honeypots”, que por exemplo incluiriam preenchimento não aleatório em suas mensagens. Note que isso não exclui sistemas de aprendizado de máquina ou ferramentas DPI altamente configuráveis, desde que atendam aos outros requisitos.
Para neutralizar a análise de payload, é garantido que todas as mensagens sejam indistinguíveis de dados aleatórios. Isso também requer que seu comprimento seja aleatório, o que é mais complicado do que apenas adicionar padding aleatório. Na verdade, no Apêndice A, os autores argumentam que um esquema de padding ingênuo (ou seja, uniforme) não resolve o problema. O Apêndice A, portanto, propõe incluir atrasos aleatórios ou desenvolver um esquema de padding alternativo que possa fornecer proteção razoável contra o ataque proposto.
Para proteger contra a sexta entrada acima, as implementações devem incluir atrasos aleatórios no protocolo. Tais técnicas não são cobertas por esta proposta, mas elas também poderiam resolver os problemas de comprimento de preenchimento. Em resumo, a proposta fornece boa proteção contra análise de payload (quando as considerações no Apêndice A são levadas em conta), mas apenas proteção limitada contra análise de fluxo.
2) Offline DPI
DPI offline inspecionando dados armazenados pelo DPI online para análise posterior. O DPI offline pode ser projetado especificamente para detectar I2P. O DPI offline não tem acesso em tempo real à base de dados da rede I2P. O DPI offline tem acesso a esta e outras especificações I2P. O DPI offline tem capacidade computacional ilimitada, incluindo todas as funções criptográficas definidas nesta especificação.
O DPI offline não tem a capacidade de bloquear conexões existentes. O DPI offline tem a capacidade de fazer envio em tempo quase real (dentro de minutos da configuração) para host/porta das partes, por exemplo TCP RST. O DPI offline tem a capacidade de fazer replay em tempo quase real (dentro de minutos da configuração) de mensagens anteriores (modificadas ou não) para “sondagem” ou outras razões.
Não é um objetivo prevenir a identificação do protocolo por um DPI offline. Toda decodificação de dados ofuscados nas duas primeiras mensagens, que é implementada pelos routers I2P, também pode ser implementada pelo DPI offline.
É um objetivo rejeitar tentativas de conexão usando replay de mensagens anteriores.
Future work
Considere o comportamento do protocolo quando pacotes são descartados ou reordenados por um atacante. Trabalhos interessantes recentes nesta área podem ser encontrados em IACR-1150.
Fornecer uma classificação mais precisa dos sistemas DPI, levando em conta a literatura existente relacionada ao assunto.
Discutir a segurança formal do protocolo proposto, idealmente levando em conta o modelo de atacante DPI.
Noise Protocol Framework
Esta proposta fornece os requisitos baseados no Noise Protocol Framework NOISE (Revisão 33, 2017-10-04). O Noise tem propriedades similares ao protocolo Station-To-Station, que é a base para o protocolo SSU. Na terminologia do Noise, Alice é o iniciador, e Bob é o respondedor.
NTCP2 é baseado no protocolo Noise Noise_XK_25519_ChaChaPoly_SHA256. (O identificador real para a função de derivação de chave inicial é “Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256” para indicar extensões I2P - veja a seção KDF 1 abaixo) Este protocolo Noise usa as seguintes primitivas:
Handshake Pattern: XK Alice transmite sua chave para Bob (X) Alice já conhece a chave estática de Bob (K)
Função DH: X25519 X25519 DH com um comprimento de chave de 32 bytes conforme especificado em RFC-7748.
Função de Cifra: ChaChaPoly AEAD_CHACHA20_POLY1305 conforme especificado na RFC-7539 seção 2.8. Nonce de 12 bytes, com os primeiros 4 bytes definidos como zero.
Hash Function: SHA256 Hash padrão de 32 bytes, já amplamente utilizado no I2P.
Objetivos de Segurança
Esta proposta define as seguintes melhorias para Noise_XK_25519_ChaChaPoly_SHA256. Estas geralmente seguem as diretrizes na seção 13 do NOISE.
Chaves efêmeras em texto claro são ofuscadas com criptografia AES usando uma chave conhecida e IV. Isso é mais rápido que elligator2.
Preenchimento aleatório de texto limpo é adicionado às mensagens 1 e 2. O preenchimento de texto limpo é incluído no cálculo do hash do handshake (MixHash). Veja as seções KDF abaixo para a mensagem 2 e mensagem 3 parte 1. Preenchimento AEAD aleatório é adicionado à mensagem 3 e mensagens da fase de dados.
Um campo de comprimento de frame de dois bytes é adicionado, conforme exigido para Noise sobre TCP, e como no obfs4. Isso é usado apenas nas mensagens da fase de dados. Os frames AEAD das mensagens 1 e 2 têm comprimento fixo. O frame AEAD da parte 1 da mensagem 3 tem comprimento fixo. O comprimento do frame AEAD da parte 2 da mensagem 3 é especificado na mensagem 1.
O campo de comprimento de quadro de dois bytes é ofuscado com SipHash-2-4, como no obfs4.
O formato de payload é definido para as mensagens 1,2,3 e a fase de dados. Claro, isso não é definido no Noise.
New Cryptographic Primitives for I2P
As implementações existentes de router I2P exigirão implementações para as seguintes primitivas criptográficas padrão, que não são necessárias para os protocolos I2P atuais:
Geração de chave X25519 e DH
AEAD_ChaCha20_Poly1305 (abreviado como ChaChaPoly abaixo)
SipHash-2-4
Processing overhead estimate
Tamanhos das mensagens para as 3 mensagens:
- 64 bytes + preenchimento (NTCP era 288 bytes) 2) 64 bytes + preenchimento (NTCP era 304 bytes) 3) aprox. 64 bytes + informações do roteador Alice + preenchimento Informações médias do roteador são cerca de 750 bytes Total médio de 814 bytes antes do preenchimento (NTCP era 448 bytes) 4) não necessário no NTCP2 (NTCP era 48 bytes)
Total antes do padding: NTCP2: 942 bytes NTCP: 1088 bytes Observe que se Alice conectou ao Bob com o propósito de enviar uma DatabaseStore Message de seu RouterInfo, essa mensagem não é necessária, economizando aproximadamente 800 bytes.
As seguintes operações criptográficas são necessárias por cada parte para completar o handshake e iniciar a fase de dados:
- AES: 2
- SHA256: 7 (Alice), 6 (Bob) (não incluindo 1 Alice, 2 Bob pré-calculados para todas as conexões) (não incluindo HMAC-SHA256)
- HMAC-SHA256: 19
- ChaChaPoly: 4
- Geração de chave X25519: 1
- X25519 DH: 3
- Verificação de assinatura: 1 (Bob) (Alice assinou previamente ao gerar seu RI) Presumivelmente Ed25519 (dependente do tipo de assinatura RI)
As seguintes operações criptográficas são necessárias por cada parte para cada mensagem da fase de dados:
- SipHash: 1
- ChaChaPoly: 1
Messages
Todas as mensagens NTCP2 têm 65537 bytes ou menos de comprimento. O formato da mensagem é baseado em mensagens Noise, com modificações para enquadramento e indistinguibilidade. Implementações que usam bibliotecas Noise padrão podem precisar pré-processar mensagens recebidas para/do formato de mensagem Noise. Todos os campos criptografados são textos cifrados AEAD.
A sequência de estabelecimento é a seguinte:
Alice Bob
SessionRequest ------------------->
<------------------- SessionCreated
SessionConfirmed ----------------->
Usando a terminologia Noise, a sequência de estabelecimento e dados é a seguinte: (Propriedades de Segurança do Payload)
XK(s, rs): Authentication Confidentiality
<- s
...
-> e, es 0 2
<- e, ee 2 1
-> s, se 2 5
<- 2 5
Uma vez que uma sessão foi estabelecida, Alice e Bob podem trocar mensagens de dados.
Todos os tipos de mensagem (SessionRequest, SessionCreated, SessionConfirmed, Data e TimeSync) estão especificados nesta seção.
Algumas notações:
- RH_A = Router Hash para Alice (32 bytes)
- RH_B = Router Hash para Bob (32 bytes)
Authenticated Encryption
Existem três instâncias separadas de criptografia autenticada (CipherStates). Uma durante a fase de handshake, e duas (transmissão e recepção) para a fase de dados. Cada uma tem sua própria chave de uma KDF.
Os dados criptografados/autenticados serão representados como
+----+----+----+----+----+----+----+----+
| |
+ +
| Encrypted and authenticated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Não-Objetivos
Formato de dados criptografado e autenticado.
Entradas para as funções de encriptação/desencriptação:
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
Saída da função de criptografia, entrada da função de descriptografia:
+----+----+----+----+----+----+----+----+
|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, o que é descrito aqui corresponde ao RFC-7539, que também é usado de forma similar no TLS RFC-7905.
Notes
Como o ChaCha20 é uma cifra de fluxo, os textos simples não precisam ser preenchidos. Bytes adicionais de keystream são descartados.
A chave para a cifra (256 bits) é acordada por meio do SHA256 KDF. Os detalhes do KDF para cada mensagem estão em seções separadas abaixo.
Frames ChaChaPoly para mensagens 1, 2 e a primeira parte da mensagem 3 são de tamanho conhecido. Começando com a segunda parte da mensagem 3, frames são de tamanho variável. O tamanho da parte 1 da mensagem 3 é especificado na mensagem 1. Começando com a fase de dados, frames são precedidos por um comprimento de dois bytes ofuscado com SipHash como no obfs4.
O padding está fora do quadro de dados autenticados para as mensagens 1 e 2. O padding é usado no KDF para a próxima mensagem, então adulterações serão detectadas. A partir da mensagem 3, o padding está dentro do quadro de dados autenticados.
Objetivos Relacionados
Nas mensagens 1, 2 e partes 1 e 2 da mensagem 3, o tamanho da mensagem AEAD é conhecido antecipadamente. Em caso de falha de autenticação AEAD, o destinatário deve interromper o processamento adicional de mensagens e fechar a conexão sem responder. Este deve ser um fechamento anormal (TCP RST).
Para resistência a sondagem, na mensagem 1, após uma falha AEAD, Bob deve definir um timeout aleatório (intervalo a ser determinado) e então ler um número aleatório de bytes (intervalo a ser determinado) antes de fechar o socket. Bob deve manter uma lista negra de IPs com falhas repetidas.
Na fase de dados, o tamanho da mensagem AEAD é “criptografado” (ofuscado) com SipHash. Deve-se ter cuidado para evitar criar um oráculo de descriptografia. Em uma falha de autenticação AEAD na fase de dados, o destinatário deve definir um timeout aleatório (faixa a ser determinada) e então ler um número aleatório de bytes (faixa a ser determinada). Após a leitura, ou no timeout da leitura, o destinatário deve enviar uma carga útil com um bloco de terminação contendo um código de motivo “falha AEAD”, e fechar a conexão.
Execute a mesma ação de erro para um valor de campo de comprimento inválido na fase de dados.
Key Derivation Function (KDF) (for handshake message 1)
O KDF gera uma chave de cifra da fase de handshake k a partir do resultado DH, usando HMAC-SHA256(key, data) conforme definido na RFC-2104. Estas são as funções InitializeSymmetric(), MixHash(), e MixKey(), exatamente como definidas na especificação 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.
Discussão Adicional sobre DPI
Alice envia para Bob.
Conteúdo Noise: Chave efêmera X da Alice Payload Noise: bloco de opção de 16 bytes Payload não-noise: Preenchimento aleatório
(Propriedades de Segurança da 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.
O valor X é criptografado para garantir a indistinguibilidade e unicidade do payload, que são contramedidas DPI necessárias. Usamos criptografia AES para alcançar isso, em vez de alternativas mais complexas e lentas como elligator2. A criptografia assimétrica para a chave pública do router de Bob seria muito lenta. A criptografia AES usa o hash do router de Bob como chave e o IV de Bob conforme publicado no netDb.
A criptografia AES é apenas para resistência a DPI. Qualquer parte que conheça o hash do router do Bob e o IV, que são publicados na base de dados da rede, pode descriptografar o valor X nesta mensagem.
O padding não é criptografado por Alice. Pode ser necessário que Bob descriptografe o padding, para inibir ataques de temporização.
Conteúdo bruto:
+----+----+----+----+----+----+----+----+
| |
+ 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.
Dados não criptografados (tag de autenticação Poly1305 não 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.
Bloco de opções: Nota: Todos os campos estão em 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
Quando o endereço publicado é “NTCP”, Bob suporta tanto NTCP quanto NTCP2 na mesma porta. Para compatibilidade, ao iniciar uma conexão para um endereço publicado como “NTCP”, Alice deve limitar o tamanho máximo desta mensagem, incluindo padding, a 287 bytes ou menos. Isso facilita a identificação automática de protocolo pelo Bob. Quando publicado como “NTCP2”, não há restrição de tamanho. Veja as seções Published Addresses e Version Detection abaixo.
O valor X único no bloco AES inicial garante que o texto cifrado seja diferente para cada sessão.
Bob deve rejeitar conexões onde o valor do timestamp está muito distante do tempo atual. Chame o delta de tempo máximo de “D”. Bob deve manter um cache local de valores de handshake previamente utilizados e rejeitar duplicatas, para prevenir ataques de replay. Valores no cache devem ter um tempo de vida de pelo menos 2*D. Os valores do cache são dependentes da implementação, contudo o valor X de 32 bytes (ou seu equivalente criptografado) pode ser utilizado.
As chaves efêmeras Diffie-Hellman nunca podem ser reutilizadas, para prevenir ataques criptográficos, e a reutilização será rejeitada como um ataque de replay.
As opções “KE” e “auth” devem ser compatíveis, ou seja, o segredo compartilhado K deve ter o tamanho apropriado. Se mais opções “auth” forem adicionadas, isso poderia implicitamente alterar o significado da flag “KE” para usar uma KDF diferente ou um tamanho de truncamento diferente.
Bob deve validar que a chave efêmera de Alice é um ponto válido na curva aqui.
O padding deve ser limitado a uma quantidade razoável. Bob pode rejeitar conexões com padding excessivo. Bob especificará suas opções de padding na mensagem 2. Diretrizes min/max a serem definidas. Tamanho aleatório de 0 a 31 bytes no mínimo? (Distribuição a ser determinada, veja Apêndice A.)
Em qualquer erro, incluindo AEAD, DH, timestamp, replay aparente, ou falha na validação de chave, Bob deve interromper o processamento adicional de mensagens e fechar a conexão sem responder. Este deve ser um fechamento anormal (TCP RST). Para resistência a sondagem, após uma falha AEAD, Bob deve definir um timeout aleatório (faixa TBD) e então ler um número aleatório de bytes (faixa TBD), antes de fechar o socket.
Mitigação de DoS: DH é uma operação relativamente custosa. Assim como no protocolo NTCP anterior, os routers devem tomar todas as medidas necessárias para prevenir exaustão de CPU ou conexão. Estabelecer limites no máximo de conexões ativas e máximo de configurações de conexão em progresso. Aplicar timeouts de leitura (tanto por leitura quanto total para “slowloris”). Limitar conexões repetidas ou simultâneas da mesma origem. Manter listas negras para origens que falham repetidamente. Não responder a falha AEAD.
Para facilitar a detecção rápida de versão e handshaking, as implementações devem garantir que Alice armazene em buffer e então descarregue todo o conteúdo da primeira mensagem de uma vez, incluindo o padding. Isso aumenta a probabilidade de que os dados sejam contidos em um único pacote TCP (a menos que sejam segmentados pelo SO ou middleboxes), e recebidos de uma vez por Bob. Adicionalmente, as implementações devem garantir que Bob armazene em buffer e então descarregue todo o conteúdo da segunda mensagem de uma vez, incluindo o padding. e que Bob armazene em buffer e então descarregue todo o conteúdo da terceira mensagem de uma vez. Isso também é para eficiência e para garantir a efetividade do padding aleatório.
Campo “ver”: O protocolo Noise geral, extensões e protocolo NTCP incluindo especificações de payload, indicando NTCP2. Este campo pode ser usado para indicar suporte para mudanças futuras.
Comprimento da parte 2 da mensagem 3: Este é o tamanho do segundo frame AEAD (incluindo MAC de 16 bytes) contendo o Router Info de Alice e padding opcional que será enviado na mensagem SessionConfirmed. Como os routers periodicamente regeneram e republicam seu Router Info, o tamanho do Router Info atual pode mudar antes da mensagem 3 ser enviada. As implementações devem escolher uma das duas estratégias: a) salvar o Router Info atual para ser enviado na mensagem 3, assim o tamanho é conhecido, e opcionalmente adicionar espaço para padding; b) aumentar o tamanho especificado o suficiente para permitir possível aumento no tamanho do Router Info, e sempre adicionar padding quando a mensagem 3 for efetivamente enviada. Em qualquer caso, o comprimento “m3p2len” incluído na mensagem 1 deve ser exatamente o tamanho daquele frame quando enviado na mensagem 3.
Bob deve falhar a conexão se quaisquer dados de entrada permanecerem após validar a mensagem 1 e ler o padding. Não deve haver dados extras de Alice, já que Bob ainda não respondeu com a mensagem 2.
O campo network ID é usado para identificar rapidamente conexões entre redes diferentes. Se este campo for diferente de zero e não corresponder ao network ID do Bob, Bob deve desconectar e bloquear conexões futuras. A partir da versão 0.9.42. Consulte a proposta 147 para mais informações.
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 envia para Alice.
Conteúdo Noise: Chave efêmera Y do Bob Payload Noise: Bloco de opção de 16 bytes Payload não-noise: Preenchimento aleatório
(Propriedades de Segurança da Carga Útil)
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.
O valor Y é criptografado para garantir indistinguibilidade e unicidade da carga útil, que são contramedidas DPI necessárias. Utilizamos criptografia AES para alcançar isso, em vez de alternativas mais complexas e lentas como elligator2. Criptografia assimétrica para a chave pública do router de Alice seria muito lenta. A criptografia AES usa o hash do router de Bob como chave e o estado AES da mensagem 1 (que foi inicializado com o IV de Bob conforme publicado no netDb).
A criptografia AES é apenas para resistência a DPI. Qualquer parte que conheça o hash do router do Bob e o IV, que são publicados na base de dados da rede, e que tenha capturado os primeiros 32 bytes da mensagem 1, pode descriptografar o valor Y nesta mensagem.
Conteúdo bruto:
+----+----+----+----+----+----+----+----+
| |
+ 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
Dados não criptografados (tag de autenticação Poly1305 não 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 deve validar que a chave efêmera de Bob é um ponto válido na curva aqui.
O padding deve ser limitado a uma quantidade razoável. Alice pode rejeitar conexões com padding excessivo. Alice especificará suas opções de padding na mensagem 3. Diretrizes de mín/máx a serem definidas. Tamanho aleatório de 0 a 31 bytes no mínimo? (Distribuição a ser determinada, ver Apêndice A.)
Em qualquer erro, incluindo AEAD, DH, timestamp, replay aparente, ou falha na validação de chave, Alice deve interromper o processamento adicional de mensagens e fechar a conexão sem responder. Isso deve ser um fechamento anormal (TCP RST).
Para facilitar o handshaking rápido, as implementações devem garantir que Bob armazene em buffer e então envie todo o conteúdo da primeira mensagem de uma só vez, incluindo o padding. Isso aumenta a probabilidade de que os dados sejam contidos em um único pacote TCP (a menos que segmentados pelo SO ou middleboxes), e recebidos de uma só vez por Alice. Isso também é por eficiência e para garantir a eficácia do padding aleatório.
Alice deve falhar a conexão se qualquer dado de entrada permanecer após validar a mensagem 2 e ler o preenchimento. Não deve haver dados extras de Bob, já que Alice ainda não respondeu com a mensagem 3.
Bloco de opções: Nota: Todos os campos são 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 deve rejeitar conexões onde o valor do timestamp está muito distante do tempo atual. Chame o delta máximo de tempo de “D”. Alice deve manter um cache local de valores de handshake utilizados anteriormente e rejeitar duplicatas, para prevenir ataques de replay. Valores no cache devem ter um tempo de vida de pelo menos 2*D. Os valores do cache são dependentes da implementação, no entanto o valor Y de 32 bytes (ou seu equivalente criptografado) pode ser usado.
Issues
- Incluir opções de preenchimento mín/máx aqui?
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 envia para Bob.
Conteúdo Noise: chave estática da Alice Payload Noise: RouterInfo da Alice e preenchimento aleatório Payload não-noise: nenhum
(Propriedades de Segurança do Payload)
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.
Isto contém dois frames ChaChaPoly. O primeiro é a chave pública estática criptografada da Alice. O segundo é o payload Noise: o RouterInfo criptografado da Alice, opções opcionais e padding opcional. Eles usam chaves diferentes, porque a função MixKey() é chamada entre eles.
Conteúdo bruto:
+----+----+----+----+----+----+----+----+
| |
+ 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
Dados não criptografados (tags de autenticação Poly1305 não 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 Online
Bob deve realizar a validação usual do Router Info. Certifique-se de que o tipo de assinatura é suportado, verifique a assinatura, verifique se o timestamp está dentro dos limites, e quaisquer outras verificações necessárias.
Bob deve verificar se a chave estática de Alice recebida no primeiro frame corresponde à chave estática no Router Info. Bob deve primeiro buscar no Router Info por um Router Address NTCP ou NTCP2 com uma opção de versão (v) correspondente. Veja as seções Published Router Info e Unpublished Router Info abaixo.
Se Bob tem uma versão mais antiga do RouterInfo da Alice em seu netDb, verificar se a chave estática no router info é a mesma em ambos, se presente, e se a versão mais antiga tem menos de XXX de idade (veja o tempo de rotação de chave abaixo)
Bob deve validar que a chave estática de Alice é um ponto válido na curva aqui.
As opções devem ser incluídas, para especificar parâmetros de padding.
Em qualquer erro, incluindo falha de validação AEAD, RI, DH, timestamp, ou chave, Bob deve interromper o processamento adicional de mensagens e fechar a conexão sem responder. Este deve ser um fechamento anormal (TCP RST).
Para facilitar o handshaking rápido, as implementações devem garantir que Alice armazene em buffer e então descarregue todo o conteúdo da terceira mensagem de uma só vez, incluindo ambos os quadros AEAD. Isso aumenta a probabilidade de que os dados sejam contidos em um único pacote TCP (a menos que sejam segmentados pelo SO ou middleboxes), e recebidos de uma só vez por Bob. Isso também é para eficiência e para garantir a eficácia do preenchimento aleatório.
Comprimento do frame da parte 2 da mensagem 3: O comprimento deste frame (incluindo MAC) é enviado por Alice na mensagem 1. Consulte essa mensagem para notas importantes sobre permitir espaço suficiente para padding.
Conteúdo do frame da parte 2 da mensagem 3: O formato deste frame é o mesmo que o formato dos frames da fase de dados, exceto que o comprimento do frame é enviado pela Alice na mensagem 1. Veja abaixo o formato do frame da fase de dados. O frame deve conter 1 a 3 blocos na seguinte ordem:
- Bloco de Router Info da Alice (obrigatório)
- Bloco de opções (opcional)
- Bloco de padding (opcional) Este frame nunca deve conter qualquer outro tipo de bloco.
O padding da parte 2 da mensagem 3 não é necessário se Alice anexar um quadro de fase de dados (opcionalmente contendo padding) ao final da mensagem 3 e enviar ambos de uma vez, pois aparecerá como um grande fluxo de bytes para um observador. Como Alice geralmente, mas nem sempre, terá uma mensagem I2NP para enviar para Bob (é por isso que ela se conectou a ele), esta é a implementação recomendada, para eficiência e para garantir a eficácia do padding aleatório.
O comprimento total de ambos os frames AEAD da Mensagem 3 (partes 1 e 2) é de 65535 bytes; a parte 1 tem 48 bytes, então o comprimento máximo do frame da parte 2 é 65487; o comprimento máximo do texto simples da parte 2, excluindo MAC, é 65471.
Key Derivation Function (KDF) (for data phase)
A fase de dados usa uma entrada de dados associados de comprimento zero.
O KDF gera duas chaves de cifra k_ab e k_ba a partir da chave de encadeamento ck, usando HMAC-SHA256(key, data) conforme definido na RFC-2104. Esta é a função Split(), exatamente como definida na especificação 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 Noise: Conforme definido abaixo, incluindo padding aleatório Payload não-noise: nenhum
A partir da 2ª parte da mensagem 3, todas as mensagens estão dentro de um “frame” ChaChaPoly autenticado e criptografado com um comprimento ofuscado de dois bytes anexado. Todo o preenchimento está dentro do frame. Dentro do frame há um formato padrão com zero ou mais “blocos”. Cada bloco tem um tipo de um byte e um comprimento de dois bytes. Os tipos incluem data/hora, mensagem I2NP, opções, terminação e preenchimento.
Nota: Bob pode, mas não é obrigatório, enviar seu RouterInfo para Alice como sua primeira mensagem para Alice na fase de dados.
(Propriedades de Segurança da Carga Útil)
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 eficiência e para minimizar a identificação do campo de comprimento, as implementações devem garantir que o remetente armazene em buffer e então descarregue todo o conteúdo das mensagens de dados de uma só vez, incluindo o campo de comprimento e o frame AEAD. Isso aumenta a probabilidade de que os dados sejam contidos em um único pacote TCP (a menos que segmentados pelo SO ou middleboxes), e recebidos de uma só vez pela outra parte. Isso também é para eficiência e para garantir a efetividade do padding aleatório.
O router pode escolher terminar a sessão em erro AEAD, ou pode continuar a tentar comunicações. Se continuar, o router deve terminar após erros repetidos.
SipHash obfuscated length
Referência: SipHash
Uma vez que ambos os lados tenham completado o handshake, eles transferem payloads que são então criptografados e autenticados em “frames” ChaChaPoly.
Cada frame é precedido por um comprimento de dois bytes, big endian. Este comprimento especifica o número de bytes de frame criptografados a seguir, incluindo o MAC. Para evitar a transmissão de campos de comprimento identificáveis no stream, o comprimento do frame é ofuscado através de XOR com uma máscara derivada do SipHash, conforme inicializada pela KDF da fase de dados. Note que as duas direções possuem chaves SipHash e IVs únicos da 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].
O receptor possui as chaves SipHash e IV idênticos. A decodificação do comprimento é feita derivando a máscara usada para ofuscar o comprimento e aplicando XOR ao digest truncado para obter o comprimento do frame. O comprimento do frame é o comprimento total do frame criptografado incluindo o MAC.
Trabalho futuro
- Se você usar uma função de biblioteca SipHash que retorna um inteiro longo sem sinal, use os dois bytes menos significativos como a Mask. Converta o inteiro longo para o próximo IV como little endian.
Criptografia Autenticada
+----+----+----+----+----+----+----+----+
|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
Há zero ou mais blocos no frame criptografado. Cada bloco contém um identificador de um byte, um comprimento de dois bytes e zero ou mais bytes de dados.
Para extensibilidade, os receptores devem ignorar blocos com identificadores desconhecidos e tratá-los como preenchimento.
Os dados criptografados têm no máximo 65535 bytes, incluindo um cabeçalho de autenticação de 16 bytes, portanto os dados não criptografados têm no máximo 65519 bytes.
(Tag de autenticação Poly1305 não 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
Na mensagem 3 parte 2 do handshake, a ordem deve ser: RouterInfo, seguido por Options se presente, seguido por Padding se presente. Nenhum outro bloco é permitido.
Na fase de dados, a ordem não é especificada, exceto pelos seguintes requisitos: Padding, se presente, deve ser o último bloco. Termination, se presente, deve ser o último bloco exceto pelo Padding.
Pode haver múltiplos blocos I2NP em um único frame. Múltiplos blocos Padding não são permitidos em um único frame. Outros tipos de blocos provavelmente não terão múltiplos blocos em um único frame, mas isso não é proibido.
Tratamento de Erros AEAD
Caso especial para sincronização de tempo:
+----+----+----+----+----+----+----+
| 0 | 4 | timestamp |
+----+----+----+----+----+----+----+
blk :: 0
size :: 2 bytes, big endian, value = 4
timestamp :: Unix timestamp, unsigned seconds.
Wraps around in 2106
Função de Derivação de Chave (KDF) (para mensagem de handshake 1)
Passar opções atualizadas. As opções incluem: Padding mínimo e máximo.
O bloco de opções terá comprimento variável.
+----+----+----+----+----+----+----+----+
| 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
- O formato das opções está por definir.
- A negociação de opções está por definir.
RouterInfo
Passe o RouterInfo da Alice para o Bob. Usado na mensagem de handshake 3 parte 2. Passe o RouterInfo da Alice para o Bob, ou o do Bob para a Alice. Usado opcionalmente na fase de dados.
+----+----+----+----+----+----+----+----+
| 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
Quando usado na fase de dados, o receptor (Alice ou Bob) deve validar que é o mesmo Router Hash que foi originalmente enviado (para Alice) ou enviado para (para Bob). Em seguida, trate-o como uma Mensagem I2NP DatabaseStore local. Valide a assinatura, valide o timestamp mais recente e armazene no netDb local. Se o bit de flag 0 for 1, e a parte receptora for floodfill, trate-o como uma Mensagem DatabaseStore com um token de resposta não-zero, e propague-o para os floodfills mais próximos.
O Router Info NÃO é comprimido com gzip (ao contrário de uma DatabaseStore Message, onde é)
O flooding não deve ser solicitado a menos que existam RouterAddresses publicados no RouterInfo. O router receptor não deve fazer flood do RouterInfo a menos que existam RouterAddresses publicados nele.
Os implementadores devem garantir que, ao ler um bloco, dados malformados ou maliciosos não causem leituras que transbordem para o próximo bloco.
Este protocolo não fornece uma confirmação de que o RouterInfo foi recebido, armazenado ou propagado (seja na fase de handshake ou de dados). Se for desejada uma confirmação, e o receptor for floodfill, o remetente deve enviar uma DatabaseStoreMessage I2NP padrão com um token de resposta.
Issues
Também poderia ser usado na fase de dados, em vez de uma I2NP DatabaseStoreMessage. Por exemplo, Bob poderia usá-lo para iniciar a fase de dados.
É permitido que isso contenha o RI para routers diferentes do originador, como substituição geral para DatabaseStoreMessages, por exemplo, para flooding por floodfills?
Função de Derivação de Chave (KDF) (para mensagem de handshake 2 e mensagem 3 parte 1)
Uma única mensagem I2NP com um cabeçalho modificado. Mensagens I2NP não podem ser fragmentadas entre blocos ou entre frames ChaChaPoly.
Isto usa os primeiros 9 bytes do cabeçalho NTCP I2NP padrão, e remove os últimos 7 bytes do cabeçalho, da seguinte forma: trunca a expiração de 8 para 4 bytes, remove o comprimento de 2 bytes (usa o tamanho do bloco - 9), e remove o checksum SHA256 de um 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
- Os implementadores devem garantir que ao ler um bloco, dados malformados ou maliciosos não causem leituras que transbordem para o próximo bloco.
2) SessionCreated
O Noise recomenda uma mensagem de terminação explícita. O NTCP2 original não possui uma. Encerre a conexão. Este deve ser o último bloco não-padding no quadro.
+----+----+----+----+----+----+----+----+
| 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
Nem todos os motivos podem ser realmente utilizados, dependente da implementação. Falhas de handshake geralmente resultarão em fechamento com TCP RST. Veja as notas nas seções de mensagem de handshake acima. Motivos adicionais listados são para consistência, logging, depuração, ou caso as políticas mudem.
Padding
Isto é para preenchimento dentro de frames AEAD. O preenchimento para mensagens 1 e 2 está fora dos frames AEAD. Todo o preenchimento para a mensagem 3 e a fase de dados está dentro dos frames AEAD.
O padding dentro do AEAD deve aderir aproximadamente aos parâmetros negociados. Bob enviou seus parâmetros mín/máx de tx/rx solicitados na mensagem 2. Alice enviou seus parâmetros mín/máx de tx/rx solicitados na mensagem 3. Opções atualizadas podem ser enviadas durante a fase de dados. Veja as informações do bloco de opções acima.
Se presente, este deve ser o último bloco no frame.
+----+----+----+----+----+----+----+----+
|254 | size | padding |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 254
size :: 2 bytes, big endian, size of padding to follow
padding :: random data
Notes
- Estratégias de padding a serem definidas.
- Padding mínimo a ser definido.
- Frames contendo apenas padding são permitidos.
- Padrões de padding a serem definidos.
- Consulte o bloco de opções para negociação de parâmetros de padding
- Consulte o bloco de opções para parâmetros de padding mín/máx
- O Noise limita mensagens a 64KB. Se mais padding for necessário, envie múltiplos frames.
- A resposta do router em caso de violação do padding negociado depende da implementação.
Other block types
As implementações devem ignorar tipos de blocos desconhecidos para compatibilidade futura, exceto na mensagem 3 parte 2, onde blocos desconhecidos não são permitidos.
Future work
- O comprimento do padding deve ser decidido por mensagem com base em estimativas da distribuição de comprimento, ou atrasos aleatórios devem ser adicionados. Essas contramedidas devem ser incluídas para resistir ao DPI, já que os tamanhos das mensagens revelariam que o tráfego I2P está sendo transportado pelo protocolo de transporte. O esquema exato de padding é uma área de trabalho futuro, o Apêndice A fornece mais informações sobre o tópico.
5) Termination
As conexões podem ser terminadas via fechamento normal ou anormal do socket TCP, ou, como o Noise recomenda, uma mensagem de terminação explícita. A mensagem de terminação explícita é definida na fase de dados acima.
Após qualquer encerramento normal ou anormal, os routers devem zerar todos os dados efêmeros na memória, incluindo chaves efêmeras de handshake, chaves de criptografia simétricas e informações relacionadas.
Published Router Info
Criptografia para a mensagem de handshake 3 parte 1, usando KDF da mensagem 2)
O RouterAddress publicado (parte do RouterInfo) terá um identificador de protocolo de “NTCP” ou “NTCP2”.
O RouterAddress deve conter as opções “host” e “port”, como no protocolo NTCP atual.
O RouterAddress deve conter três opções para indicar suporte NTCP2:
s=(Chave Base64) A chave pública estática atual do Noise (s) para este RouterAddress. Codificada em Base 64 usando o alfabeto padrão Base 64 do I2P. 32 bytes em binário, 44 bytes codificados em Base 64, chave pública X25519 em little-endian.
i=(Base64 IV) O IV atual para criptografar o valor X na mensagem 1 para este RouterAddress. Codificado em Base 64 usando o alfabeto padrão Base 64 do I2P. 16 bytes em binário, 24 bytes codificado em Base 64, big-endian.
v=2 A versão atual (2). Quando publicado como “NTCP”, suporte adicional para versão 1 está implícito. Suporte para versões futuras será com valores separados por vírgulas, por exemplo v=2,3 A implementação deve verificar compatibilidade, incluindo múltiplas versões se uma vírgula estiver presente. Versões separadas por vírgulas devem estar em ordem numérica.
Alice deve verificar que todas as três opções estão presentes e válidas antes de se conectar usando o protocolo NTCP2.
Quando publicado como “NTCP” com as opções “s”, “i” e “v”, o router deve aceitar conexões de entrada nesse host e porta para os protocolos NTCP e NTCP2, e detectar automaticamente a versão do protocolo.
Quando publicado como “NTCP2” com as opções “s”, “i” e “v”, o router aceita conexões de entrada nesse host e porta apenas para o protocolo NTCP2.
Se um router suporta conexões NTCP1 e NTCP2 mas não implementa detecção automática de versão para conexões de entrada, ele deve anunciar tanto endereços “NTCP” quanto “NTCP2”, e incluir as opções NTCP2 apenas no endereço “NTCP2”. O router deve definir um valor de custo menor (prioridade maior) no endereço “NTCP2” do que no endereço “NTCP”, para que NTCP2 seja preferido.
Se múltiplos NTCP2 RouterAddresses (seja como “NTCP” ou “NTCP2”) forem publicados no mesmo RouterInfo (para endereços IP ou portas adicionais), todos os endereços especificando a mesma porta devem conter as opções e valores NTCP2 idênticos. Em particular, todos devem conter a mesma chave estática e iv.
Função de Derivação de Chave (KDF) (para mensagem de handshake 3 parte 2)
Se Alice não publicar seu endereço NTCP2 (como “NTCP” ou “NTCP2”) para conexões de entrada, ela deve publicar um endereço de router “NTCP2” contendo apenas sua chave estática e versão NTCP2, para que Bob possa validar a chave após receber o RouterInfo de Alice na parte 2 da mensagem 3.
s=(Chave Base64) Como definido acima para endereços publicados.
v=2 Como definido acima para endereços publicados.
Este endereço do router não conterá as opções “i”, “host” ou “port”, pois estas não são necessárias para conexões NTCP2 de saída. O custo publicado para este endereço não importa estritamente, já que é apenas de entrada; no entanto, pode ser útil para outros routers se o custo for definido como mais alto (menor prioridade) que outros endereços. O valor sugerido é 14.
Alice também pode simplesmente adicionar as opções “s” e “v” a um endereço “NTCP” já publicado.
3) SessionConfirmed
Devido ao cache de RouterInfos, os routers não devem rotacionar a chave pública estática ou IV enquanto o router estiver ativo, seja em um endereço publicado ou não. Os routers devem armazenar persistentemente esta chave e IV para reutilização após um reinício imediato, para que as conexões de entrada continuem a funcionar, e os tempos de reinício não sejam expostos. Os routers devem armazenar persistentemente, ou de outra forma determinar, o horário do último desligamento, para que o tempo de inatividade anterior possa ser calculado na inicialização.
Sujeito a preocupações sobre exposição de tempos de reinicialização, os routers podem rotacionar esta chave ou IV na inicialização se o router esteve previamente inativo por algum tempo (pelo menos algumas horas).
Se o router tiver quaisquer RouterAddresses NTCP2 publicados (como NTCP ou NTCP2), o tempo mínimo de inatividade antes da rotação deve ser muito mais longo, por exemplo um mês, a menos que o endereço IP local tenha mudado ou o router execute um “rekeys”.
Se o router tiver algum RouterAddresses SSU publicado, mas não NTCP2 (como NTCP ou NTCP2), o tempo mínimo de inatividade antes da rotação deve ser maior, por exemplo um dia, a menos que o endereço IP local tenha mudado ou o router execute um “rekeys”. Isso se aplica mesmo se o endereço SSU publicado tiver introducers.
Se o router não tiver nenhum RouterAddresses publicado (NTCP, NTCP2, ou SSU), o tempo mínimo de inatividade antes da rotação pode ser de apenas duas horas, mesmo se o endereço IP mudar, a menos que o router faça “rekeys”.
Se o router “rekeys” para um Router Hash diferente, deve gerar uma nova chave noise e IV também.
As implementações devem estar cientes de que alterar a chave pública estática ou o IV impedirá conexões NTCP2 de entrada de routers que tenham em cache um RouterInfo mais antigo. A publicação do RouterInfo, seleção de peers de tunnel (incluindo tanto OBGW quanto o hop mais próximo IB), seleção de tunnel zero-hop, seleção de transporte e outras estratégias de implementação devem levar isso em consideração.
A rotação de IV está sujeita às mesmas regras da rotação de chaves, exceto que IVs não estão presentes exceto em RouterAddresses publicados, portanto não há IV para routers ocultos ou protegidos por firewall. Se qualquer coisa mudar (versão, chave, opções?) é recomendado que o IV também mude.
Nota: O tempo mínimo de inatividade antes da renovação de chaves pode ser modificado para garantir a saúde da rede e para evitar o reseeding por um router inativo por um período moderado de tempo.
Identity Hiding
A negação plausível não é um objetivo. Veja a visão geral acima.
Cada padrão recebe propriedades que descrevem a confidencialidade fornecida à chave pública estática do iniciador e à chave pública estática do respondente. As premissas subjacentes são que as chaves privadas efêmeras são seguras, e que as partes abortam o handshake se receberem uma chave pública estática da outra parte na qual não confiam.
Esta seção considera apenas o vazamento de identidade através de campos de chave pública estática em handshakes. Naturalmente, as identidades dos participantes do Noise podem ser expostas por outros meios, incluindo campos de payload, análise de tráfego, ou metadados como endereços IP.
Alice: (8) Criptografado com sigilo futuro para uma parte autenticada.
Bob: (3) Não transmitida, mas um atacante passivo pode verificar candidatos para a chave privada do respondente e determinar se o candidato está correto.
Bob publica sua chave pública estática na netdb. Alice pode ou não pode?
Issues
- Se Bob alterar sua chave estática, poderia recorrer a um padrão “XX”?
Framework de Protocolo Noise
Quando publicado como “NTCP”, o router deve detectar automaticamente a versão do protocolo para conexões de entrada.
Esta detecção depende da implementação, mas aqui estão algumas orientações gerais.
Para detectar a versão de uma conexão NTCP recebida, Bob procede da seguinte forma:
Aguarde pelo menos 64 bytes (tamanho mínimo da mensagem 1 NTCP2)
Se os dados iniciais recebidos forem de 288 ou mais bytes, a conexão de entrada é versão 1.
Se menos de 288 bytes, então
Aguarde um curto período por mais dados (boa estratégia antes da adoção generalizada do NTCP2) se pelo menos 288 total recebidos, é NTCP 1.
Tente os primeiros estágios de decodificação como versão 2, se falhar, aguarde um pouco mais de dados (boa estratégia após adoção generalizada do 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
Note que mudanças ou estratégias adicionais podem ser recomendadas se detectarmos ataques ativos de segmentação TCP no NTCP 1.
Para facilitar a detecção rápida de versão e handshaking, as implementações devem garantir que Alice armazene em buffer e então libere todo o conteúdo da primeira mensagem de uma só vez, incluindo o padding. Isso aumenta a probabilidade de que os dados sejam contidos em um único pacote TCP (a menos que sejam segmentados pelo SO ou middleboxes), e recebidos de uma só vez por Bob. Isso também é para eficiência e para garantir a eficácia do padding aleatório. Isso se aplica aos handshakes NTCP e NTCP2.
Adições ao Framework
Se Alice e Bob suportam NTCP2, Alice deve conectar com NTCP2.
Se Alice falhar ao conectar-se a Bob usando NTCP2 por qualquer motivo, a conexão falhará. Alice não pode tentar novamente usando NTCP 1.
Fallback para padrão XX se Bob alterar suas chaves? Isso exigiria um byte de tipo prefixado?
“Fall forward” para o padrão KK se Alice se reconectar, assumindo que Bob ainda tem sua chave estática? Isso não economiza nenhum round trip e usa 4 rodadas DH comparado a 3 para XK. Provavelmente não.
KK(s, rs):
-> s
<- s
...
-> e, es, ss
<- e, ee, se
Novas Primitivas Criptográficas para I2P
Esta seção discute um ataque em esquemas típicos de preenchimento que permite aos atacantes descobrir a distribuição de probabilidade do comprimento das mensagens não preenchidas, observando apenas o comprimento das mensagens preenchidas. Seja N uma variável aleatória descrevendo o número de bytes não preenchidos, e P da mesma forma para o número de bytes de preenchimento. O tamanho total da mensagem é então N + P.
Suponha que para um tamanho sem padding de n, pelo menos P_min(n) >= 0 e no máximo P_max(n) >= P_min(n) bytes de padding sejam adicionados em um esquema de padding. O esquema óbvio usa padding de comprimento P escolhido uniformemente ao acaso:
Pr[P = p | N = n] = 1 / (P_max(n) - P_min(n)) if P_min(n) <= p <= P_max(n),
0 otherwise.
Um esquema de padding ingênuo simplesmente garantiria que o tamanho da mensagem com padding não exceda N_max:
P_max(n) = N_max - n, n <= N_max
P_min(n) = 0.
No entanto, isso vaza informações sobre o comprimento sem preenchimento.
Um atacante pode facilmente estimar Pr[x <= N + P <= y], por exemplo através de um histograma.
- A partir disso, ele também pode tentar estimar
Pr[n_1 <= N <= n_2], de fato:
Pr[N + P = m] = Σ_n Pr[N = n] Pr[P = m - n | N = n].
No esquema ingênuo,
Pr[N + P = m] = Σ_{n <= m} Pr[N = n] / (N_max - n).
É bastante óbvio, como era antes de fazer o cálculo acima, que isso vaza informações sobre Pr[N = n]: se o comprimento dos pacotes é quase sempre maior que m, então N + P <= m quase nunca será observado. Esta não é a maior questão, no entanto, embora ser capaz de observar o comprimento mínimo da mensagem possa ser considerado um problema por si só.
Um problema maior é que é possível determinar Pr[N = n] exatamente:
Pr[N + P = m] - Pr[N + P = m-1] = Pr[N = m] / (N_max - m),
ou seja
Pr[N = n] = (N_max - n)(Pr[N + P = n] - Pr[N + P = n - 1])
Para distinguir NTCP2, então, o atacante pode usar qualquer um dos seguintes:
Estimar
Pr[kB <= N <= (k + 1)B - 1]para inteiros positivos k. Será sempre zero para NTCP2.Estime
Pr[N = kB]e compare com um perfil I2P padrão.
Este ataque simples, portanto, destrói parcialmente o propósito do padding, que tenta ofuscar a distribuição de tamanho das mensagens sem padding. A quantidade de mensagens que o atacante tem que observar para distinguir o protocolo depende da precisão desejada e dos tamanhos mínimo e máximo das mensagens sem padding que ocorrem na prática. Note que é fácil para o atacante coletar muitas mensagens, já que ele pode usar todo o tráfego enviado de e para a porta específica que o alvo está usando.
Em algumas formas (por exemplo, estimação de Pr[kB <= N <= (k + 1)B - 1]) o ataque requer apenas alguns bytes de memória (um número inteiro é suficiente) e pode-se argumentar que tal ataque poderia ser incluído em muitos frameworks de DPI ligeiramente mais avançados, mas ainda assim padrão.
Esta proposta sugere usar uma das seguintes contramedidas:
Desenvolver um esquema alternativo de padding que leve em consideração a distribuição (estimada) de N usando uma distribuição não uniforme de comprimento de padding. Um bom esquema de padding provavelmente exigiria manter um histograma do número de blocos por mensagem.
Adicionar atrasos aleatórios entre fragmentos (de tamanho aleatório) das mensagens.
A segunda opção é geralmente mais preferida, pois pode ser simultaneamente usada como contramedida contra análise de fluxo. No entanto, tais atrasos podem estar fora do escopo do protocolo NTCP2, de modo que a primeira opção, que também é mais fácil de implementar, pode ser preferida em vez disso.
Estimativa de sobrecarga de processamento
Resistência a DPI baseada em temporização (temporização/atrasos entre mensagens podem ser dependentes da implementação; atrasos intra-mensagem podem ser introduzidos em qualquer ponto, incluindo antes de enviar o padding aleatório, por exemplo). Atrasos artificiais (o que o obfs4 chama de IAT ou tempo entre chegadas) são independentes do protocolo em si.