Esta tradução foi gerada usando aprendizado de máquina e pode não ser 100% precisa. Ver versão em inglês

NTCP 2

Proposal 111
Fechado
Author EinMByte, orignal, psi, str4d, zzz
Created 2014-02-13
Last Updated 2019-08-13
Target Version 0.9.36
Implemented In 0.9.36
Supercedes: 106

Nota

A fase da proposta está encerrada. Veja a SPEC para a especificação oficial. Esta proposta ainda pode ser referenciada para informações de fundo.

Visão Geral

Esta proposta descreve um protocolo autenticado de acordo de chaves para melhorar a resistência do NTCP a várias formas de identificação automatizada e ataques.

A proposta está organizada da seguinte maneira: os objetivos de segurança são apresentados, seguidos por 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 de roteador e a identificação de versão. Um apêndice discutindo um ataque genérico a esquemas comuns de preenchimento também é incluído, bem como um apêndice contendo uma série de candidatos para a cifra autenticada.

Como em outros transportes do I2P, o NTCP2 é definido exclusivamente para transporte ponto-a-ponto (roteador-a-roteador) de mensagens I2NP. Não é um canal de dados de propósito geral.

Motivação

Os dados do 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 por “análise de conteúdo”. Ainda é vulnerável à identificação do protocolo por “análise de fluxo”. Isso porque as primeiras 4 mensagens (ou seja, o handshake) têm tamanho 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 é abordado na Prop104 e tem problemas próprios. Sempre que apropriado, parágrafos de “trabalho futuro” foram adicionados para indicar recursos ausentes ou tópicos de discussão.

Objetivos de Projeto

  • Suportar NTCP 1 e 2 em uma única porta, detecção automática e publicado como um único “transporte” (ou seja, RouterAddress) no NetDB .

  • Publicar suporte para versão 1 apenas, 2 apenas, ou 1+2 no NetDB em um campo separado, e por padrão usar versão 1 apenas (não vincular suporte de versão a uma versão específica do roteador)

  • 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 dados (ou seja, obfuscaçã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. Os detalhes da distribuição de preenchimento são dependentes da implementação e podem ou não ser especificados no próprio protocolo.

  • Obfuscar o conteúdo das mensagens que não são criptografadas (1 e 2), suficientemente para que caixas DPI e assinaturas de AV não possam classificá-las facilmente. Também garantir que as mensagens enviadas a um único par ou conjunto de pares não tenham um padrão semelhante de bits.

  • Corrigir a 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 do DH diretamente?

  • Adicionar “resistência a sondagem” (como o Tor chama); isso inclui resistência a replay.

  • Manter a troca autenticada de chave bidirecional (2W-AKE). 1W-AKE não é suficiente para nossa aplicação.

  • Continuar a usar assinaturas de tipo variável e comprimento variável (da chave de assinatura publicada na RouterIdentity) como parte da autenticação. Confiar em uma chave pública estática publicada na RouterInfo como outra parte da autenticação.

  • Adicionar opções/versão no handshake para extensibilidade futura.

  • Adicionar resistência a segmentação TCP maliciosa MitM, se possível.

  • Não aumentar significativamente a CPU necessária para a configuração da conexão; se possível, reduzi-la significativamente.

  • Adicionar autenticação de mensagem (MAC), possivelmente HMAC-SHA256 e Poly1305, e remover o 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, duas viagens, para um handshake de 3 mensagens, uma viagem, como no SSU . Isso exigiria mover a assinatura de Bob na mensagem 4 para a mensagem 2. Pesquisar o motivo das 4 mensagens nos arquivos de e-mail/status/reuniões de dez anos atrás.

  • Minimizar a sobrecarga do protocolo antes do preenchimento. Embora o preenchimento será adicionado, e possivelmente muito, a sobrecarga antes do preenchimento ainda é sobrecarga. Nós de baixa largura de banda devem poder usar o NTCP2.

  • Manter timestamps para detecção de replay e desvio.

  • Evitar quaisquer problemas no ano 2038 nos timestamps, deve funcionar até pelo menos 2106.

  • Aumentar o tamanho máximo da mensagem de 16K para 32K ou 64K.

  • Quaisquer primitivas criptográficas novas devem estar prontamente disponíveis em bibliotecas para uso em implementações de roteadores Java (1.7), C++ e Go.

  • Incluir representantes dos desenvolvedores de roteadores Java, C++ e Go no projeto.

  • Minimizar mudanças (mas ainda haverá muitas).

  • Suportar ambas as versões em um conjunto comum de código (isso pode não ser possível e é dependente da implementação em qualquer caso).

Não-Objetivos

  • Resistência a DPI à prova de balas… isso seria transportes plugáveis, Prop109 .

  • Um transporte baseado em TLS (ou semelhante ao HTTPS)… isso seria Prop104 .

  • Está OK mudar a criptografia simétrica de fluxo.

  • Resistência a DPI baseada em tempo (tempo entre mensagens/delays podem ser dependentes da implementação; delays intra-mensagem podem ser introduzidos em qualquer ponto, incluindo antes de enviar o preenchimento aleatório, por exemplo). Delays artificiais (o que o obfs4 chama de IAT ou tempo de chegada) são independentes do próprio protocolo.

  • Negabilidade de participação em uma sessão (há assinaturas lá dentro).

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)

  • Negabilidade

Objetivos Relacionados

  • Implementar uma configuração de teste NTCP 1/2

Objetivos de Segurança

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 duas partes podem participar de ataques ativos.

Alice e Bob possuem um par de chaves estático, que está contido em sua RouterIdentity.

O protocolo proposto tenta permitir que Alice e Bob concordem em uma chave secreta compartilhada (K) sob os seguintes requisitos:

  1. Segurança da chave privada: nem Bob nem Mallory aprendem nada sobre a chave privada estática de Alice. Simetricamente, Alice não aprende nada sobre a chave privada estática de Bob.

  2. A chave de sessão K é conhecida apenas por Alice e Bob.

  3. Segredo perfeito futuro: a chave de sessão acordada permanece secreta no futuro, mesmo quando as chaves privadas estáticas de Alice e/ou Bob forem reveladas após a chave ter sido acordada.

  4. Autenticação bidirecional: Alice tem certeza de que estabeleceu uma sessão com Bob, e vice-versa.

  5. 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.

  6. Negabilidade limitada: nem Alice nem Bob podem negar a participação no protocolo, mas se um deles 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 com base no protocolo Station-To-Station (STS). Note que este protocolo também é a base para o protocolo SSU .

Discussão Adicional sobre DPI

Assumimos dois componentes DPI:

1) DPI Online

DPI online inspecionando todos os fluxos em tempo real. Conexões podem ser bloqueadas ou de outra forma alteradas. Dados ou metadados da conexão podem ser identificados e armazenados para análise offline. O DPI online não tem acesso ao banco de dados de rede do 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 essas seriam muito caras para aplicar na maioria ou em todos os fluxos. Qualquer aplicação dessas operações criptográficas se aplicaria 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 custo como DH ou elligator2. O DPI online não é projetado especificamente para detectar I2P, embora possa ter regras de classificação limitadas para esse fim.

É um objetivo impedir 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:

  1. A capacidade de inspecionar todos os dados enviados ou recebidos pelo alvo.

  2. A capacidade de realizar operações nos dados observados, como aplicar cifras de bloco ou funções hash.

  3. A capacidade de armazenar e comparar com mensagens enviadas anteriormente.

  4. A capacidade de modificar, atrasar ou fragmentar pacotes.

No entanto, assume-se que o DPI online tem as seguintes restrições:

  1. A incapacidade de mapear endereços IP para hashes de roteador. Embora isso seja trivial com acesso em tempo real ao banco de dados de rede, exigiria um sistema DPI projetado especificamente para atacar o I2P.

  2. A incapacidade de usar informações de tempo para detectar o protocolo.

  3. De modo geral, a caixa de ferramentas do DPI online não contém ferramentas embutidas projetadas especificamente para detecção de I2P. Isso inclui criar “isca” (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 combater a análise de conteúdo, garante-se que todas as mensagens sejam indistinguíveis de dados aleatórios. Isso também exige que seus comprimentos sejam aleatórios, o que é mais complicado do que apenas adicionar preenchimento aleatório. Na verdade, no Apêndice A, os autores argumentam que um esquema de preenchimento 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 preenchimento 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 poderiam também resolver os problemas de comprimento de preenchimento. Em resumo, a proposta fornece boa proteção contra análise de conteúdo (quando as considerações no Apêndice A são levadas em conta), mas apenas proteção limitada contra análise de fluxo.

2) DPI Offline

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 tem acesso em tempo real ao banco de dados de rede do I2P. O DPI offline tem acesso a esta e outras especificações do 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 enviar em tempo quase real (dentro de minutos da configuração) para o 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 impedir a identificação do protocolo por um DPI offline. Toda decodificação de dados ofuscados nas duas primeiras mensagens, que é implementada pelos roteadores I2P, também pode ser implementada pelo DPI offline.

É um objetivo rejeitar tentativas de conexão usando replay de mensagens anteriores.

Trabalho Futuro

  • Considerar o comportamento do protocolo quando pacotes são descartados ou reordenados por um atacante. Trabalhos recentes interessantes nesta área podem ser encontrados em IACR-1150 .

  • Fornecer uma classificação mais precisa de 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.

Framework do Protocolo Noise

Esta proposta fornece os requisitos com base no Framework do Protocolo Noise NOISE (Revisão 33, 2017-10-04). O Noise tem propriedades semelhantes ao protocolo Station-To-Station, que é a base para o protocolo SSU . Na terminologia do Noise, Alice é o iniciador, e Bob é o respondente.

NTCP2 é baseado no protocolo Noise Noise_XK_25519_ChaChaPoly_SHA256. (O identificador real para a função inicial de derivação de chave é “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:

  • Padrão de Handshake: XK Alice transmite sua chave para Bob (X) Alice já conhece a chave estática de Bob (K)

  • Função DH: X25519 DH X25519 com comprimento de chave de 32 bytes conforme especificado em RFC-7748 .

  • Função 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.

  • Função Hash: SHA256 Hash padrão de 32 bytes, já usado extensivamente no I2P.

Adições ao Framework

Esta proposta define os seguintes aprimoramentos para Noise_XK_25519_ChaChaPoly_SHA256. Geralmente seguem as diretrizes da seção 13 do NOISE .

  1. Chaves efêmeras em texto claro são ofuscadas com criptografia AES usando uma chave e IV conhecidos. Isso é mais rápido que o elligator2.

  2. Preenchimento em texto claro aleatório é adicionado às mensagens 1 e 2. O preenchimento em texto claro é incluído no cálculo do hash do handshake (MixHash). Veja as seções KDF abaixo para mensagem 2 e parte 1 da mensagem 3. Preenchimento AEAD aleatório é adicionado à mensagem 3 e mensagens da fase de dados.

  3. Um campo de comprimento de quadro de dois bytes é adicionado, conforme exigido para Noise sobre TCP, e como no obfs4. Isso é usado apenas nas mensagens da fase de dados. Os quadros AEAD das mensagens 1 e 2 têm comprimento fixo. O quadro AEAD da parte 1 da mensagem 3 tem comprimento fixo. O comprimento do quadro AEAD da parte 2 da mensagem 3 é especificado na mensagem 1.

  4. O campo de comprimento de quadro de dois bytes é ofuscado com SipHash-2-4, como no obfs4.

  5. O formato da carga útil é definido para as mensagens 1, 2, 3 e a fase de dados. É claro que isso não é definido no Noise.

Novas Primitivas Criptográficas para o I2P

Implementações existentes de roteadores I2P exigirão implementações para as seguintes primitivas criptográficas padrão, que não são exigidas para protocolos I2P atuais:

  1. Geração de chave e DH X25519

  2. AEAD_ChaCha20_Poly1305 (abreviado como ChaChaPoly abaixo)

  3. SipHash-2-4

Estimativa de sobrecarga de processamento

Tamanhos de mensagens para as 3 mensagens:

  1. 64 bytes + preenchimento (NTCP era 288 bytes)
  2. 64 bytes + preenchimento (NTCP era 304 bytes)
  3. aproximadamente 64 bytes + informações do roteador Alice + preenchimento. Informações médias do roteador são cerca de 750 bytes. Total médio 814 bytes antes do preenchimento (NTCP era 448 bytes)
  4. não exigido no NTCP2 (NTCP era 48 bytes)

Total antes do preenchimento: NTCP2: 942 bytes NTCP: 1088 bytes Note que se Alice se conectou a Bob com o objetivo de enviar uma mensagem DatabaseStore de suas informações de roteador, essa mensagem não é necessária, economizando aproximadamente 800 bytes.

As seguintes operações criptográficas são exigidas por cada parte para concluir 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
  • DH X25519: 3
  • Verificação de assinatura: 1 (Bob) (Alice assinou anteriormente ao gerar sua RI) Presumivelmente Ed25519 (dependente do tipo de assinatura da RI)

As seguintes operações criptográficas são exigidas por cada parte para cada mensagem da fase de dados:

  • SipHash: 1
  • ChaChaPoly: 1

Mensagens

Todas as mensagens NTCP2 têm comprimento menor ou igual a 65537 bytes. 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 o 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 do Noise, a sequência de estabelecimento e dados é a seguinte: (Propriedades de Segurança da Carga Útil)

XK(s, rs):           Autenticação   Confidencialidade
    <- 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) são especificados nesta seção.

Algumas notações:

  • RH_A = Hash do Roteador para Alice (32 bytes)
  • RH_B = Hash do Roteador para Bob (32 bytes)

Criptografia Autenticada

Há 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 um KDF.

Dados criptografados/autenticados serão representados como

+----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   Dados criptografados e autenticados |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

ChaCha20/Poly1305

Formato de dados criptografados e autenticados.

Entradas para as funções de criptografia/descriptografia:

k :: chave de cifra de 32 bytes, gerada a partir do KDF

  nonce :: nonce baseado em contador, 12 bytes.
           Começa em 0 e é incrementado para cada mensagem.
           Os primeiros quatro bytes são sempre zero.
           Os últimos oito bytes são o contador, codificados em little-endian.
           Valor máximo é 2**64 - 2.
           A conexão deve ser encerrada e reiniciada após
           atingir esse valor.
           O valor 2**64 - 1 nunca deve ser enviado.

  ad :: Na fase de handshake:
        Dados associados, 32 bytes.
        O hash SHA256 de todos os dados anteriores.
        Na fase de dados:
        Bytes zero

  data :: Dados em texto claro, 0 ou mais bytes

Saída da função de criptografia, entrada para a função de descriptografia:

+----+----+----+----+----+----+----+----+
  |Obfs Len |                             |
  +----+----+                             +
  |       Dados criptografados ChaCha20   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Código de Autenticação de Mensagem   |
  +              (MAC)                    +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+

  Obfs Len :: Comprimento de (dados criptografados + MAC) a seguir, 16 - 65535
              Ofuscação usando SipHash (veja abaixo)
              Não usado nas mensagens 1 ou 2, ou na parte 1 da mensagem 3, onde o comprimento é fixo
              Não usado na parte 1 da mensagem 3, pois o comprimento é especificado na mensagem 1

  dados criptografados :: Mesmo tamanho que os dados em texto claro, 0 - 65519 bytes

  MAC :: Código de autenticação de mensagem Poly1305, 16 bytes

Para ChaCha20, o que é descrito aqui corresponde à RFC-7539 , que também é usado de forma semelhante no TLS RFC-7905 .

Notas

  • Como ChaCha20 é uma cifra de fluxo, textos claros não precisam ser preenchidos. Bytes adicionais do fluxo de chave são descartados.

  • A chave para a cifra (256 bits) é acordada por meio do KDF SHA256. Os detalhes do KDF para cada mensagem estão em seções separadas abaixo.

  • Quadros ChaChaPoly para as mensagens 1, 2 e a primeira parte da mensagem 3, são de tamanho conhecido. A partir da segunda parte da mensagem 3, os quadros são de tamanho variável. O tamanho da parte 1 da mensagem 3 é especificado na mensagem 1. A partir da fase de dados, os quadros são precedidos por um campo de comprimento de dois bytes ofuscado com SipHash como no obfs4.

  • O preenchimento está fora do quadro de dados autenticados para as mensagens 1 e 2. O preenchimento é usado no KDF para a próxima mensagem, então qualquer adulteração será detectada. A partir da mensagem 3, o preenchimento está dentro do quadro de dados autenticados.

Tratamento de Erros AEAD

  • 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 da mensagem e fechar a conexão sem responder. Isso deve ser um fechamento anormal (TCP RST).

  • Para resistência a sondagem, na mensagem 1, após uma falha AEAD, Bob deve definir um tempo limite aleatório (intervalo a ser definido) e então ler um número aleatório de bytes (intervalo a ser definido) 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. Cuidado deve ser tomado para evitar a criação de um oráculo de descriptografia. Em caso de falha de autenticação AEAD na fase de dados, o destinatário deve definir um tempo limite aleatório (intervalo a ser definido) e então ler um número aleatório de bytes (intervalo a ser definido). Após a leitura, ou em caso de tempo limite de leitura, o destinatário deve enviar uma carga útil com um bloco de término contendo um código de motivo “falha AEAD”, e fechar a conexão.

  • Adote a mesma ação de erro para um valor de campo de comprimento inválido na fase de dados.

Função de Derivação de Chave (KDF) (para a mensagem de handshake 1)

O KDF gera uma chave de cifra k da fase de handshake a partir do resultado DH, usando HMAC-SHA256(chave, dados) conforme definido na RFC-2104 . Essas são as funções InitializeSymmetric(), MixHash() e MixKey(), exatamente como definidas na especificação Noise.

Este é o padrão de mensagem "e":

  // Define protocol_name.
  Define protocol_name = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
   (48 bytes, codificado em US-ASCII, sem terminação nula).

  // Define Hash h = 32 bytes
  h = SHA256(protocol_name);

  Define ck = 32 byte chaining key. Copia os dados de h para ck.
  Define ck = h

  Define rs = chave estática de 32 bytes de Bob conforme publicado na RouterInfo

  // MixHash(null prologue)
  h = SHA256(h);

  // até aqui, pode ser pré-calculado por Alice para todas as conexões de saída

  // Alice deve validar que a chave estática de Bob é um ponto válido na curva aqui.

  // Chave estática de Bob
  // MixHash(rs)
  // || abaixo significa anexar
  h = SHA256(h || rs);

  // até aqui, pode ser pré-calculado por Bob para todas as conexões de entrada

  Este é o padrão de mensagem "e":

  Alice gera seu par de chaves efêmeras DH e.

  // Chave efêmera de Alice X
  // MixHash(e.pubkey)
  // || abaixo significa anexar
  h = SHA256(h || e.pubkey);

  // h é usado como dados associados para o AEAD na mensagem 1
  // Mantenha o Hash h para o KDF da mensagem 2


  Fim do padrão de mensagem "e".

  Este é o padrão de mensagem "es":

  // DH(e, rs) == DH(s, re)
  Define input_key_material = resultado DH de 32 bytes da chave efêmera de Alice e chave estática de Bob
  Define input_key_material = resultado DH X25519

  // MixKey(DH())

  Define temp_key = 32 bytes
  Define HMAC-SHA256(chave, dados) conforme na [RFC-2104](https://tools.ietf.org/html/rfc2104)
  // Gera uma chave temporária a partir da chave de encadeamento e resultado DH
  // ck é a chave de encadeamento, definida acima
  temp_key = HMAC-SHA256(ck, input_key_material)
  // sobrescreve o resultado DH na memória, não mais necessário
  input_key_material = (todos zeros)

  // Saída 1
  // Define uma nova chave de encadeamento a partir da chave temporária
  // byte() abaixo significa um único byte
  ck =       HMAC-SHA256(temp_key, byte(0x01)).

  // Saída 2
  // Gera a chave de cifra k
  Define k = 32 bytes
  // || abaixo significa anexar
  // byte() abaixo significa um único byte
  k =        HMAC-SHA256(temp_key, ck || byte(0x02)).
  // sobrescreve a temp_key na memória, não mais necessária
  temp_key = (todos zeros)

  // mantém a chave de encadeamento ck para o KDF da mensagem 2


  Fim do padrão de mensagem "es".

1) SessionRequest

Alice envia para Bob.

Conteúdo Noise: Chave efêmera de Alice X Carga útil Noise: Bloco de opções de 16 bytes Carga útil não-Noise: Preenchimento aleatório

(Propriedades de Segurança da Carga Útil)

XK(s, rs):           Autenticação   Confidencialidade
    -> e, es                  0                2

    Autenticação: Nenhuma (0).
    Esta carga útil pode ter sido enviada por qualquer parte, incluindo um atacante ativo.

    Confidencialidade: 2.
    Criptografia para um destinatário conhecido, segredo futuro apenas para comprometimento do remetente,
    vulnerável a replay. Esta carga útil é criptografada com base apenas em DHs
    envolvendo o par de chaves estáticas do destinatário. Se a chave privada estática do destinatário for comprometida,
    mesmo em uma data posterior, esta carga útil pode ser descriptografada. Esta mensagem também pode ser repetida,
    pois não há contribuição efêmera do destinatário.

    "e": Alice gera um novo par de chaves efêmeras e armazena-o na variável e,
         escreve a chave pública efêmera como texto claro no buffer da mensagem,
         e faz hash da chave pública junto com o h antigo para derivar um novo h.

    "es": Um DH é realizado entre o par de chaves efêmeras de Alice e o
          par de chaves estáticas de Bob. O resultado é feito hash junto com o ck antigo para
          derivar um novo ck e k, e n é definido como zero.

O valor X é criptografado para garantir indistinguibilidade da carga útil e unicidade, que são contramedidas necessárias contra DPI. Usamos criptografia AES para alcançar isso, em vez de alternativas mais complexas e lentas como o elligator2. Criptografia assimétrica para a chave pública do roteador de Bob seria muito lenta. A criptografia AES usa o hash do roteador de Bob como chave e o IV de Bob conforme publicado no banco de dados de rede.

A criptografia AES é apenas para resistência a DPI. Qualquer parte que conheça o hash do roteador de Bob e o IV, que são publicados no banco de dados de rede, pode descriptografar o valor X nesta mensagem.

O preenchimento não é criptografado por Alice. Pode ser necessário que Bob descriptografe o preenchimento, para inibir ataques de tempo.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
|                                       |
+        ofuscado com RH_B              +
|       X criptografado com AES-CBC-256 |
+             (32 bytes)                +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|   quadro ChaChaPoly                   |
+             (32 bytes)                +
|   k definido no KDF para mensagem 1   |
+   n = 0                               +
|   veja KDF para dados associados      |
+----+----+----+----+----+----+----+----+
|     preenchimento autenticado         |
~         não criptografado (opcional)  ~
|     comprimento definido no bloco de opções |
+----+----+----+----+----+----+----+----+

X :: 32 bytes, chave efêmera X25519 criptografada com AES-256-CBC, little endian
        chave: RH_B
        iv: Conforme publicado na entrada do banco de dados de rede de Bob

preenchimento :: Dados aleatórios, 0 ou mais bytes.
           O comprimento total da mensagem deve ser 65535 bytes ou menos.
           O comprimento total da mensagem deve ser 287 bytes ou menos se
           Bob estiver publicando seu endereço como NTCP
           (veja a seção Detecção de Versão abaixo).
           Alice e Bob usarão os dados de preenchimento no KDF para a mensagem 2.
           É autenticado para que qualquer adulteração cause falha na
           próxima mensagem.

Dados não criptografados (tag de autenticação Poly1305 não mostrada):

+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|                   X                   |
+              (32 bytes)               +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|               opções                  |
+              (16 bytes)               +
|                                       |
+----+----+----+----+----+----+----+----+
|     preenchimento autenticado         |
+         não criptografado (opcional)  +
|     comprimento definido no bloco de opções |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

X :: 32 bytes, chave efêmera X25519, little endian

opções :: bloco de opções, 16 bytes, veja abaixo

preenchimento :: Dados aleatórios, 0 ou mais bytes.
           O comprimento total da mensagem deve ser 65535 bytes ou menos.
           O comprimento total da mensagem deve ser 287 bytes ou menos se
           Bob estiver publicando seu endereço como "NTCP"
           (veja a seção Detecção de Versão abaixo)
           Alice e Bob usarão os dados de preenchimento no KDF para a mensagem 2.
           É autenticado para que qualquer adulteração cause falha na
           próxima mensagem.

Bloco de opções: Nota: Todos os campos são big-endian.

+----+----+----+----+----+----+----+----+
| id | ver|  padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
|        tsA        |   Reserved (0)    |
+----+----+----+----+----+----+----+----+

id :: 1 byte, o ID da rede (atualmente 2, exceto para redes de teste)
      A partir de 0.9.42. Veja a proposta 147.

ver :: 1 byte, versão do protocolo (atualmente 2)

padLen :: 2 bytes, comprimento do preenchimento, 0 ou mais
          Diretrizes mín/máx a serem definidas. Tamanho aleatório de 0 a 31 bytes mínimo?
          (Distribuição a ser determinada, veja Apêndice A.)

m3p2Len :: 2 bytes, comprimento do segundo quadro AEAD em SessionConfirmed
           (parte 2 da mensagem 3) Veja notas abaixo

Rsvd :: 2 bytes, definido como 0 para compatibilidade com opções futuras

tsA :: 4 bytes, timestamp Unix, segundos sem sinal.
       Volta em 2106

Reserved :: 4 bytes, definido como 0 para compatibilidade com opções futuras

Notas

  • Quando o endereço publicado é “NTCP”, Bob suporta NTCP e NTCP2 na mesma porta. Para compatibilidade, ao iniciar uma conexão com um endereço publicado como “NTCP”, Alice deve limitar o tamanho máximo desta mensagem, incluindo preenchimento, a 287 bytes ou menos. Isso facilita a identificação automática do protocolo por Bob. Quando publicado como “NTCP2”, não há restrição de tamanho. Veja as seções Endereços Publicados e Detecção de Versão 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 estiver muito distante do tempo atual. Chame o delta máximo de tempo de “D”. Bob deve manter um cache local de valores de handshake usados anteriormente e rejeitar duplicatas, para prevenir ataques de replay. Os valores no cache devem ter uma vida útil de pelo menos 2*D. Os valores de cache são dependentes da implementação, no entanto o valor X de 32 bytes (ou seu equivalente criptografado) pode ser usado.

  • Chaves efêmeras Diffie-Hellman nunca devem 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 ser do tamanho apropriado. Se mais opções “auth” forem adicionadas, isso poderia mudar implicitamente o significado da flag “KE” para usar um 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 preenchimento deve ser limitado a uma quantidade razoável. Bob pode rejeitar conexões com preenchimento excessivo. Bob especificará suas opções de preenchimento na mensagem 2. Diretrizes mín/máx a serem definidas. Tamanho aleatório de 0 a 31 bytes 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 da chave, Bob deve interromper o processamento da mensagem e fechar a conexão sem responder. Isso deve ser um fechamento anormal (TCP RST). Para resistência a sondagem, após uma falha AEAD, Bob deve definir um tempo limite aleatório (intervalo a ser definido) e então ler um número aleatório de bytes (intervalo a ser definido), antes de fechar o socket.

  • Mitigação de DoS: DH é uma operação relativamente cara. Como no protocolo NTCP anterior, roteadores devem tomar todas as medidas necessárias para prevenir esgotamento de CPU ou conexão. Defina limites para conexões ativas máximas e configurações de conexão máximas em andamento. Imponha tempos limite de leitura (tanto por leitura quanto total para “slowloris”). Limite conexões repetidas ou simultâneas da mesma fonte. Mantenha listas negras para fontes que falham repetidamente. Não responda a falhas AEAD.

  • Para facilitar a detecção rápida de versão e handshake, as implementações devem garantir que Alice armazene em buffer e depois envie todo o conteúdo da primeira mensagem de uma vez, incluindo o preenchimento. Isso aumenta a probabilidade de que os dados estarão contidos em um único pacote TCP (a menos que segmentado pelo SO ou middleboxes), e recebidos de uma vez por Bob. Além disso, as implementações devem garantir que Bob armazene em buffer e depois envie todo o conteúdo da segunda mensagem de uma vez, incluindo o preenchimento, e que Bob armazene em buffer e depois envie todo o conteúdo da terceira mensagem de uma vez. Isso também é para eficiência e para garantir a eficácia do preenchimento aleatório.

  • Campo “ver”: O protocolo Noise geral, extensões e protocolo NTCP incluindo especificações de carga útil, 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 quadro AEAD (incluindo MAC de 16 bytes) contendo as informações do roteador de Alice e preenchimento opcional que será enviada na mensagem SessionConfirmed. Como roteadores periodicamente regeneram e republicam suas informações de roteador, o tamanho das informações atuais pode mudar antes da mensagem 3 ser enviada. As implementações devem escolher uma das duas estratégias: a) salvar as informações atuais do roteador para serem enviadas na mensagem 3, para que o tamanho seja conhecido, e opcionalmente adicionar espaço para preenchimento; b) aumentar o tamanho especificado o suficiente para permitir possível aumento no tamanho das informações do roteador, e sempre adicionar preenchimento quando a mensagem 3 for realmente enviada. Em qualquer caso, o comprimento “m3p2len” incluído na mensagem 1 deve ser exatamente o tamanho desse quadro quando enviado na mensagem 3.

  • Bob deve falhar a conexão se houver dados recebidos restantes após validar a mensagem 1 e ler o preenchimento. Não deve haver dados extras de Alice, pois Bob ainda não respondeu com a mensagem 2.

  • O campo ID da rede é usado para identificar rapidamente conexões entre redes. Se este campo for diferente de zero e não corresponder ao ID da rede de Bob, Bob deve se desconectar e bloquear conexões futuras. A partir de 0.9.42. Veja a proposta 147 para mais informações.

Função de Derivação de Chave (KDF) (para a mensagem de handshake 2 e parte 1 da mensagem 3)


// pega h salvo do KDF da mensagem 1
// MixHash(ciphertext)
h = SHA256(h || payload criptografado de 32 bytes da mensagem 1)

// MixHash(padding)
// Apenas se o comprimento do preenchimento for diferente de zero
h = SHA256(h || preenchimento aleatório da mensagem 1)

Este é o padrão de mensagem "e":

Bob gera seu par de chaves efêmeras DH e.

// h é do KDF para a mensagem de handshake 1
// Chave efêmera de Bob Y
// MixHash(e.pubkey)
// || abaixo significa anexar
h = SHA256(h || e.pubkey);

// h é usado como dados associados para o AEAD na mensagem 2
// Mantenha o Hash h para o KDF da mensagem 3

Fim do padrão de mensagem "e".

Este é o padrão de mensagem "ee":

// DH(e, re)
Define input_key_material = resultado DH de 32 bytes da chave efêmera de Alice e chave efêmera de Bob
Define input_key_material = resultado DH X25519
// sobrescreve a chave efêmera de Alice na memória, não mais necessária
// Alice:
e(pública e privada) = (todos zeros)
// Bob:
re = (todos zeros)

// MixKey(DH())

Define temp_key = 32 bytes
Define HMAC-SHA256(chave, dados) conforme na [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Gera uma chave temporária a partir da chave de encadeamento e resultado DH
// ck é a chave de encadeamento, do KDF para a mensagem de handshake 1
temp_key = HMAC-SHA256(ck, input_key_material)
// sobrescreve o resultado DH na memória, não mais necessário
input_key_material = (todos zeros)

// Saída 1
// Define uma nova chave de encadeamento a partir da chave temporária
// byte() abaixo significa um único byte
ck =       HMAC-SHA256(temp_key, byte(0x01)).

// Saída 2
// Gera a chave de cifra k
Define k = 32 bytes
// || abaixo significa anexar
// byte() abaixo significa um único byte
k =        HMAC-SHA256(temp_key, ck || byte(0x02)).
// sobrescreve a temp_key na memória, não mais necessária
temp_key = (todos zeros)

// mantém a chave de encadeamento ck para o KDF da mensagem 3

Fim do padrão de mensagem "ee".

2) SessionCreated

Bob envia para Alice.

Conteúdo Noise: Chave efêmera de Bob Y Carga útil Noise: Bloco de opções de 16 bytes Carga útil não-Noise: Preenchimento aleatório

(Propriedades de Segurança da Carga Útil)

XK(s, rs):           Autenticação   Confidencialidade
  <- e, ee                  2                1

  Autenticação: 2.
  Autenticação do remetente resistente à personificação por comprometimento de chave (KCI).
  A autenticação do remetente é baseada em um DH efêmero-estático ("es" ou "se")
  entre o par de chaves estáticas do remetente e o par de chaves efêmeras do destinatário.
  Assumindo que as chaves privadas correspondentes estão seguras, esta autenticação não pode ser falsificada.

  Confidencialidade: 1.
  Criptografia para um destinatário efêmero.
  Esta carga útil tem segredo futuro, pois a criptografia envolve um DH efêmero-efêmero ("ee").
  No entanto, o remetente não autenticou o destinatário,
  então esta carga útil pode ser enviada para qualquer parte, incluindo um atacante ativo.


  "e": Bob gera um novo par de chaves efêmeras e armazena-o na variável e,
  escreve a chave pública efêmera como texto claro no buffer da mensagem,
  e faz hash da chave pública junto com o h antigo para derivar um novo h.

  "ee": Um DH é realizado entre o par de chaves efêmeras de Bob e o par de chaves efêmeras de Alice.
  O resultado é feito hash junto com o ck antigo para derivar um novo ck e k, e n é definido como zero.

O valor Y é criptografado para garantir indistinguibilidade da carga útil e unicidade, que são contramedidas necessárias contra DPI. Usamos criptografia AES para alcançar isso, em vez de alternativas mais complexas e lentas como o elligator2. Criptografia assimétrica para a chave pública do roteador de Alice seria muito lenta. A criptografia AES usa o hash do roteador de Bob como chave e o estado AES da mensagem 1 (que foi inicializado com o IV de Bob conforme publicado no banco de dados de rede).

A criptografia AES é apenas para resistência a DPI. Qualquer parte que conheça o hash do roteador de Bob e o IV, que são publicados no banco de dados de rede, e capturou os primeiros 32 bytes da mensagem 1, pode descriptografar o valor Y nesta mensagem.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
|                                       |
+        ofuscado com RH_B              +
|       Y criptografado com AES-CBC-256 |
+              (32 bytes)               +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|   quadro ChaChaPoly                   |
+   Dados criptografados e autenticados |
+   32 bytes                            |
|   k definido no KDF para mensagem 2   |
+   n = 0; veja KDF para dados associados |
|                                       |
+                                       +
+----+----+----+----+----+----+----+----+
|     preenchimento autenticado         |
+         não criptografado (opcional)  +
|     comprimento definido no bloco de opções |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

Y :: 32 bytes, chave efêmera X25519 criptografada com AES-256-CBC, little endian
        chave: RH_B
        iv: Usando estado AES da mensagem 1

Dados não criptografados (tag de autenticação Poly1305 não mostrada):

+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|                  Y                    |
+              (32 bytes)               +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|               opções                  |
+              (16 bytes)               +
|                                       |
+----+----+----+----+----+----+----+----+
|     preenchimento autenticado         |
+         não criptografado (opcional)  +
|     comprimento definido no bloco de opções |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

Y :: 32 bytes, chave efêmera X25519, little endian

opções :: bloco de opções, 16 bytes, veja abaixo

preenchimento :: Dados aleatórios, 0 ou mais bytes.
           O comprimento total da mensagem deve ser 65535 bytes ou menos.
           Alice e Bob usarão os dados de preenchimento no KDF para a parte 1 da mensagem 3.
           É autenticado para que qualquer adulteração cause falha na
           próxima mensagem.

Notas

  • Alice deve validar que a chave efêmera de Bob é um ponto válido na curva aqui.

  • O preenchimento deve ser limitado a uma quantidade razoável. Alice pode rejeitar conexões com preenchimento excessivo. Alice especificará suas opções de preenchimento na mensagem 3. Diretrizes mín/máx a serem definidas. Tamanho aleatório de 0 a 31 bytes 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 da chave, Alice deve interromper o processamento da mensagem e fechar a conexão sem responder. Isso deve ser um fechamento anormal (TCP RST).

  • Para facilitar o handshake rápido, as implementações devem garantir que Bob armazene em buffer e depois envie todo o conteúdo da primeira mensagem de uma vez, incluindo o preenchimento. Isso aumenta a probabilidade de que os dados estarão contidos em um único pacote TCP (a menos que segmentado pelo SO ou middleboxes), e recebidos de uma vez por Alice. Isso também é para eficiência e para garantir a eficácia do preenchimento aleatório.

  • Alice deve falhar a conexão se houver dados recebidos restantes após validar a mensagem 2 e ler o preenchimento. Não deve haver dados extras de Bob, pois 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 no total, definido como 0 para compatibilidade com opções futuras

padLen :: 2 bytes, big endian, comprimento do preenchimento, 0 ou mais
          Diretrizes mín/máx a serem definidas. Tamanho aleatório de 0 a 31 bytes mínimo?
          (Distribuição a ser determinada, veja Apêndice A.)

tsB :: 4 bytes, big endian, timestamp Unix, segundos sem sinal.
       Volta em 2106

Notas

  • Alice deve rejeitar conexões onde o valor do timestamp estiver muito distante do tempo atual. Chame o delta máximo de tempo de “D”. Alice deve manter um cache local de valores de handshake usados anteriormente e rejeitar duplicatas, para prevenir ataques de replay. Os valores no cache devem ter uma vida útil de pelo menos 2*D. Os valores de cache são dependentes da implementação, no entanto o valor Y de 32 bytes (ou seu equivalente criptografado) pode ser usado.

Problemas

  • Incluir opções mín/máx de preenchimento aqui?

Criptografia para a parte 1 da mensagem 3, usando o KDF da mensagem 2)


// pega h salvo do KDF da mensagem 2
// MixHash(ciphertext)
h = SHA256(h || payload criptografado de 24 bytes da mensagem 2)

// MixHash(padding)
// Apenas se o comprimento do preenchimento for diferente de zero
h = SHA256(h || preenchimento aleatório da mensagem 2)
// h é usado como dados associados para o AEAD na parte 1 da mensagem 3, abaixo

Este é o padrão de mensagem "s":

Define s = chave pública estática de Alice, 32 bytes

// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(chave, nonce, dados associados, dados)
// k é do handshake da mensagem 1
// n é 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || abaixo significa anexar
h = SHA256(h || ciphertext);

// h é usado como dados associados para o AEAD na parte 2 da mensagem 3

Fim do padrão de mensagem "s".

Função de Derivação de Chave (KDF) (para a parte 2 da mensagem de handshake 3)


Este é o padrão de mensagem "se":

// DH(s, re) == DH(e, rs)
Define input_key_material = resultado DH de 32 bytes da chave estática de Alice e chave efêmera de Bob
Define input_key_material = resultado DH X25519
// sobrescreve a chave efêmera de Bob na memória, não mais necessária
// Alice:
re = (todos zeros)
// Bob:
e(pública e privada) = (todos zeros)

// MixKey(DH())

Define temp_key = 32 bytes
Define HMAC-SHA256(chave, dados) conforme na [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Gera uma chave temporária a partir da chave de encadeamento e resultado DH
// ck é a chave de encadeamento, do KDF para a mensagem de handshake 1
temp_key = HMAC-SHA256(ck, input_key_material)
// sobrescreve o resultado DH na memória, não mais necessário
input_key_material = (todos zeros)

// Saída 1
// Define uma nova chave de encadeamento a partir da chave temporária
// byte() abaixo significa um único byte
ck =       HMAC-SHA256(temp_key, byte(0x01)).

// Saída 2
// Gera a chave de cifra k
Define k = 32 bytes
// || abaixo significa anexar
// byte() abaixo significa um único byte
k =        HMAC-SHA256(temp_key, ck || byte(0x02)).

// h da parte 1 da mensagem 3 é usado como dados associados para o AEAD na parte 2 da mensagem 3

// EncryptAndHash(payload)
// EncryptWithAd(h, payload)
// AEAD_ChaCha20_Poly1305(chave, nonce, dados associados, dados)
// n é 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, payload)
// MixHash(ciphertext)
// || abaixo significa anexar
h = SHA256(h || ciphertext);

// mantém a chave de encadeamento ck para o KDF da fase de dados
// mantém o hash h para o KDF adicional de chave simétrica (SipHash) da fase de dados

Fim do padrão de mensagem "se".

// sobrescreve a temp_key na memória, não mais necessária
temp_key = (todos zeros)

3) SessionConfirmed

Alice envia para Bob.

Conteúdo Noise: Chave estática de Alice Carga útil Noise: Informações do roteador de Alice e preenchimento aleatório Carga útil não-Noise: nenhuma

(Propriedades de Segurança da Carga Útil)

XK(s, rs):           Autenticação   Confidencialidade
  -> s, se                  2                5

  Autenticação: 2.
  Autenticação do remetente resistente à personificação por comprometimento de chave (KCI). A
  autenticação do remetente é baseada em um DH efêmero-estático ("es" ou "se")
  entre o par de chaves estáticas do remetente e o par de chaves efêmeras do destinatário.
  Assumindo que as chaves privadas correspondentes estão seguras, esta
  autenticação não pode ser falsificada.

  Confidencialidade: 5.
  Criptografia para um destinatário conhecido, segredo futuro forte. Esta carga útil é
  criptografada com base em um DH efêmero-efêmero, bem como um DH efêmero-estático
  com o par de chaves estáticas do destinatário. Assumindo que as chaves privadas efêmeras estão seguras,
  e o destinatário não está sendo ativamente personificado por um
  atacante que roubou sua chave privada estática, esta carga útil não pode ser
  descriptografada.

  "s": Alice escreve sua chave pública estática da variável s no
  buffer da mensagem, criptografando-a, e faz hash da saída junto com o h antigo
  para derivar um novo h.

  "se": Um DH é realizado entre o par de chaves estáticas de Alice e o par de chaves efêmeras de Bob.
  O resultado é feito hash junto com o ck antigo para derivar um
  novo ck e k, e n é definido como zero.

Isso contém dois quadros ChaChaPoly. O primeiro é a chave pública estática criptografada de Alice. O segundo é a carga útil Noise: as informações do roteador de Alice criptografadas, opções opcionais e preenchimento opcional. Eles usam chaves diferentes, porque a função MixKey() é chamada entre eles.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
|                                       |
+   quadro ChaChaPoly (48 bytes)        +
|   Dados criptografados e autenticados |
+   chave estática S de Alice           +
|      (32 bytes)                       |
+                                       +
|     k definido no KDF para mensagem 2 |
+     n = 1                             |
|     veja KDF para dados associados    |
+                                       |
|                                       |
+----+----+----+----+----+----+----+----+
|                                       |
+     Comprimento especificado na mensagem 1     |
|                                       |
+   quadro ChaChaPoly                   +
|   Dados criptografados e autenticados |
+                                       +
|       Informações do roteador Alice   |
+       usando formato de bloco 2       |
|       Opções de Alice (opcional)      |
+       usando formato de bloco 1       |
|       Preenchimento arbitrário        |
+       usando formato de bloco 254     |
|                                       |
+                                       +
| k definido no KDF para parte 2 da mensagem 3 |
+     n = 0                             |
|     veja KDF para dados associados    |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

S :: 32 bytes, chave estática X25519 de Alice criptografada com ChaChaPoly, little endian
     dentro de quadro ChaChaPoly de 48 bytes

Dados não criptografados (tags de autenticação Poly1305 não mostradas):

+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|              S                        |
+       chave estática de Alice         |
|          (32 bytes)                   |
+                                       +
|                                       |
+                                       +
+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|                                       |
+                                       +
|       bloco de Informações do roteador Alice          |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+
|                                       |
+       bloco de Opções opcional        |
|                                       |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+
|                                       |
+       bloco de Preenchimento opcional |
|                                       |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

S :: 32 bytes, chave estática X25519 de Alice, little endian

Notas

  • Bob deve realizar a validação usual das informações do roteador. Garantir que o tipo de assinatura seja suportado, verificar a assinatura, verificar que o timestamp está dentro dos limites, e quaisquer outras verificações necessárias.

  • Bob deve verificar que a chave estática de Alice recebida no primeiro quadro corresponda à chave estática nas informações do roteador. Bob deve primeiro procurar nas informações do roteador por um endereço de roteador NTCP ou NTCP2 com uma opção de versão (v) correspondente. Veja as seções Informações do Roteador Publicadas e Não Publicadas abaixo.

  • Se Bob tiver uma versão mais antiga das informações do roteador de Alice em seu netdb, verifique que a chave estática nas informações do roteador seja a mesma em ambas, se presente, e se a versão mais antiga for menos que XXX antiga (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 preenchimento.

  • Em qualquer erro, incluindo AEAD, RI, DH, timestamp ou falha na validação da chave, Bob deve interromper o processamento da mensagem e fechar a conexão sem responder. Isso deve ser um fechamento anormal (TCP RST).

  • Para facilitar o handshake rápido, as implementações devem garantir que Alice armazene em buffer e depois envie todo o conteúdo da terceira mensagem de uma vez, incluindo ambos os quadros AEAD. Isso aumenta a probabilidade de que os dados estarão contidos em um único pacote TCP (a menos que segmentado pelo SO ou middleboxes), e recebidos de uma vez por Bob. Isso também é para eficiência e para garantir a eficácia do preenchimento aleatório.

  • Comprimento do quadro da parte 2 da mensagem 3: O comprimento deste quadro (incluindo MAC) é enviado por Alice na mensagem 1. Veja essa mensagem para notas importantes sobre permitir espaço suficiente para preenchimento.

  • Conteúdo do quadro da parte 2 da mensagem 3: Este formato do quadro é o mesmo que o formato dos quadros da fase de dados, exceto que o comprimento do quadro é enviado por Alice na mensagem 1. Veja abaixo para o formato do quadro da fase de dados. O quadro deve conter de 1 a 3 blocos na seguinte ord