mirror of
https://github.com/waku-org/nwaku.git
synced 2025-02-26 14:00:57 +00:00
feat(noise): add padding to transport messages (#1056)
* feat(noise): add padding to transport messages (handshakes+write+read) * fix(noise): address reviewers' comments * fix(noise): update padding block size const name
This commit is contained in:
parent
8a14b5b243
commit
2aeaba48e4
@ -23,6 +23,22 @@ procSuite "Waku Noise":
|
||||
# We initialize the RNG in std/random
|
||||
randomize()
|
||||
|
||||
test "PKCS#7 Padding/Unpadding":
|
||||
|
||||
# We test padding for different message lengths
|
||||
let maxMessageLength = 3 * NoisePaddingBlockSize
|
||||
for messageLen in 0..maxMessageLength:
|
||||
|
||||
let
|
||||
message = randomSeqByte(rng[], messageLen)
|
||||
padded = pkcs7_pad(message, NoisePaddingBlockSize)
|
||||
unpadded = pkcs7_unpad(padded, NoisePaddingBlockSize)
|
||||
|
||||
check:
|
||||
padded.len != 0
|
||||
padded.len mod NoisePaddingBlockSize == 0
|
||||
message == unpadded
|
||||
|
||||
test "ChaChaPoly Encryption/Decryption: random byte sequences":
|
||||
|
||||
let cipherState = randomChaChaPolyCipherState(rng[])
|
||||
|
@ -221,8 +221,10 @@ proc processMessagePatternPayload(hs: var HandshakeState, transportMessage: seq[
|
||||
# We decrypt the transportMessage, if any
|
||||
if reading:
|
||||
payload = hs.ss.decryptAndHash(transportMessage)
|
||||
payload = pkcs7_unpad(payload, NoisePaddingBlockSize)
|
||||
elif writing:
|
||||
payload = hs.ss.encryptAndHash(transportMessage)
|
||||
payload = pkcs7_pad(transportMessage, NoisePaddingBlockSize)
|
||||
payload = hs.ss.encryptAndHash(payload)
|
||||
|
||||
return payload
|
||||
|
||||
@ -558,8 +560,10 @@ proc writeMessage*(hsr: var HandshakeResult, transportMessage: seq[byte]): Paylo
|
||||
# According to 35/WAKU2-NOISE RFC, no Handshake protocol information is sent when exchanging messages
|
||||
# This correspond to setting protocol-id to 0
|
||||
payload2.protocolId = 0.uint8
|
||||
# We pad the transport message
|
||||
let paddedTransportMessage = pkcs7_pad(transportMessage, NoisePaddingBlockSize)
|
||||
# Encryption is done with zero-length associated data as per specification
|
||||
payload2.transportMessage = encryptWithAd(hsr.csOutbound, @[], transportMessage)
|
||||
payload2.transportMessage = encryptWithAd(hsr.csOutbound, @[], paddedTransportMessage)
|
||||
|
||||
return payload2
|
||||
|
||||
@ -578,7 +582,9 @@ proc readMessage*(hsr: var HandshakeResult, readPayload2: PayloadV2): Result[seq
|
||||
# (this because an attacker may flood the content topic on which messages are exchanged)
|
||||
try:
|
||||
# Decryption is done with zero-length associated data as per specification
|
||||
message = decryptWithAd(hsr.csInbound, @[], readPayload2.transportMessage)
|
||||
let paddedMessage = decryptWithAd(hsr.csInbound, @[], readPayload2.transportMessage)
|
||||
# We unpdad the decrypted message
|
||||
message = pkcs7_unpad(paddedMessage, NoisePaddingBlockSize)
|
||||
except NoiseDecryptTagError:
|
||||
debug "A read message failed decryption. Returning empty message as plaintext."
|
||||
message = @[]
|
||||
|
@ -247,3 +247,7 @@ const
|
||||
"ChaChaPoly": 30.uint8
|
||||
|
||||
}.toTable()
|
||||
|
||||
# Other constants
|
||||
const
|
||||
NoisePaddingBlockSize* = 248
|
@ -5,7 +5,7 @@
|
||||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import std/[oids, options, strutils, tables]
|
||||
import std/[oids, options, strutils, tables, sequtils]
|
||||
import chronos
|
||||
import chronicles
|
||||
import bearssl
|
||||
@ -33,6 +33,29 @@ proc randomSeqByte*(rng: var BrHmacDrbgContext, size: int): seq[byte] =
|
||||
brHmacDrbgGenerate(rng, output)
|
||||
return output
|
||||
|
||||
# Pads a payload according to PKCS#7 as per RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3
|
||||
proc pkcs7_pad*(payload: seq[byte], paddingSize: int): seq[byte] =
|
||||
|
||||
assert(paddingSize<256)
|
||||
|
||||
let k = paddingSize - (payload.len mod paddingSize)
|
||||
|
||||
var padding: seq[byte]
|
||||
|
||||
if k != 0:
|
||||
padding = newSeqWith(k, k.byte)
|
||||
else:
|
||||
padding = newSeqWith(paddingSize, paddingSize.byte)
|
||||
|
||||
let padded = concat(payload, padding)
|
||||
|
||||
return padded
|
||||
|
||||
# Unpads a payload according to PKCS#7 as per RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3
|
||||
proc pkcs7_unpad*(payload: seq[byte], paddingSize: int): seq[byte] =
|
||||
let k = payload[payload.high]
|
||||
let unpadded = payload[0..payload.high-k.int]
|
||||
return unpadded
|
||||
|
||||
#################################################################
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user