From c6a39e37ba4a42721594e0a907fe016f8e2198a8 Mon Sep 17 00:00:00 2001 From: Armin Preiml Date: Thu, 16 Nov 2023 15:42:49 +0100 Subject: [PATCH] harden against "compromise via lattices" --- format/ssh/sign.ha | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/format/ssh/sign.ha b/format/ssh/sign.ha index ff757bb..8ebfb4e 100644 --- a/format/ssh/sign.ha +++ b/format/ssh/sign.ha @@ -1,5 +1,8 @@ use crypto::ed25519; use io; +use memio; +use os; +use bytes; // Signs a message using the provided key, writing the message signature in the // SSH format to the provided sink. @@ -7,8 +10,24 @@ export fn sign( sink: io::handle, key: *key, msg: []u8, -) (void | io::error) = { - key.vtable.sign(key, sink, msg)?; +) (void | error) = { + static let sigbuf: [os::BUFSZ]u8 = [0...]; + let memsink = memio::fixed(sigbuf); + + key.vtable.sign(key, &memsink, msg)?; + + // Natural occuring computational errors during the signature generation + // can lead to a complete compromise. Therefore to work around this + // issue the signature will be verified before writing it to 'sink'. + // + // See "Passive SSH Key Compromise via Lattices" + // https://eprint.iacr.org/2023/1711 + let sig = memio::buffer(&memsink); + defer bytes::zero(sig); + io::seek(&memsink, io::whence::SET, 0)!; + verify(&memsink, key, msg)?; + + io::writeall(sink, sig)?; }; // Reads an SSH wire signature from the provided I/O handle and verifies that it -- 2.45.2