╭ changed ─────────────────╮ │src/serve_ssh_protocol.zig│ ╰──────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │1131 ChaCha20.stream(&poly_key, 0, self.main_key, nonce); │ │1132 │ │1133 // mac over encrypted_length || encrypted_body │ │1134 - const mac_input = try allocator.alloc(u8, 4 + body_len);│ │1135 - defer allocator.free(mac_input); │ │1136 - @memcpy(mac_input[0..4], &enc_length); │ │1137 - @memcpy(mac_input[4..], body); │ │1134 + var poly = Poly1305.init(&poly_key); │ │1135 + poly.update(&enc_length); │ │1136 + poly.update(body); │ │1137 var tag: [Poly1305.mac_length]u8 = undefined; │ │1139 - Poly1305.create(&tag, mac_input, &poly_key); │ │1138 + poly.final(&tag); │ │1139 │ │1140 try writer.writeAll(&enc_length); │ │1141 try writer.writeAll(body); │ ╰──────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │1170 var poly_key: [Poly1305.key_length]u8 = undefined; │ │1171 ChaCha20.stream(&poly_key, 0, self.main_key, nonce); │ │1172 │ │1174 - const mac_input = try allocator.alloc(u8, 4 + body_len); │ │1175 - defer allocator.free(mac_input); │ │1176 - @memcpy(mac_input[0..4], &enc_length); │ │1177 - @memcpy(mac_input[4..], enc_body); │ │1173 + var poly = Poly1305.init(&poly_key); │ │1174 + poly.update(&enc_length); │ │1175 + poly.update(enc_body); │ │1176 var tag_computed: [Poly1305.mac_length]u8 = undefined; │ │1179 - Poly1305.create(&tag_computed, mac_input, &poly_key); │ │1177 + poly.final(&tag_computed); │ │1178 if (!std.crypto.timing_safe.eql([Poly1305.mac_length]u8, tag_recv, tag_computed)) {│ │1179 return error.MacVerificationFailed; │ │1180 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1181 │ │1184 - // decrypt body in place into a separate buffer (caller owns) │ │1185 - const body = try allocator.alloc(u8, body_len); │ │1186 - errdefer allocator.free(body); │ │1187 - ChaCha20.xor(body, enc_body, 1, self.main_key, nonce); │ │1182 + // decrypt the body in place, then copy out the payload (caller owns) │ │1183 + ChaCha20.xor(enc_body, enc_body, 1, self.main_key, nonce); │ │1184 │ │1189 - const padding_len = body[0]; │ │1185 + const padding_len = enc_body[0]; │ │1186 if (padding_len < 4 or 1 + @as(u32, padding_len) > body_len) return error.InvalidPadding;│ │1187 const payload_len = body_len - 1 - @as(u32, padding_len); │ │1188 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │1193 - const payload = try allocator.dupe(u8, body[1 .. 1 + payload_len]); │ │1194 - allocator.free(body); │ │1189 + const payload = try allocator.dupe(u8, enc_body[1 .. 1 + payload_len]);│ │1190 │ │1191 self.seq += 1; │ │1192 return payload; │ ╰─────────────────────────────────────────────────────────────────────────────────────╯