[О блоге] [наверх] [пред] [2022-09-05 17:07:48+03:00] [239051325eeacf7f9ef7404624d48dba6a6e73c6]
Темы: [go]

Чуть обновил gohpenc

http://www.git.cypherpunks.ru/?p=gohpenc.git;a=commitdiff;h=d863cee82aad34900144198abf740bb7f75a4642
Как-то давно написал альтернативу https://github.com/vstakhov/hpenc --
gohpenc (a43bb2e06daf52402c01ec522174e0c00a4b66d6), так как hpenc тупо
после 8192 блоков обламывалась на аутентификации блоков между разными ОС.

Сегодня вновь в неё заглянул и удивился почему я решил перед каждым
блоком явно указывать его размер. Пустые потери места, ведь все блоки
одинаковы, кроме последнего. Пока правил это -- по сути всё с нуля
переписал, существенно упростив код. Я думал что это один из самых
простых и маленьких проектов у меня -- но в нём несколько структур с
кучей полей. О чём я думал?

А ещё захотел добавить явную аутентификацию последнего блока --
сигнализация о том, что да, это действительно конец передачи. Иначе ведь
злоумышленник может просто обрезать данные (по границам блоком) и мы об
этом не узнаем. Захотел использовать идею из NNCP: когда последний блок
будет шифроваться другим ключом. При дешифровании, если получили ошибку,
то пробуем на другом ключе. Я хочу странного? Вроде бы нет. Но обломал
меня интерфейс chacha20poly1305 (почти) родной библиотеки Go.

Я хотел было просто сделать Open(), получить ошибку, сделать Open() над
там же самым буфером с другим ключом. Но шифротекст меняется при этом
процессе. Ступил. Предположил что он дешифрует этот шифротекст,
параллельно скармливая его в Poly1305, и в самом конце просто проверяя
совпадает ли он с предоставленным тэгом. То есть мы бы получили
раскорёженный шифротекст. Но так как ChaCha20 это потоковый шифр, то
снова применив шифрование (на том же ключе) -- мы получили бы
оригинальное содержимое, которое уже дешифровать можно вторым ключом.

Но по непонятной мне причине, в chacha20poly1305 если MAC не валиден, то
он явно просто в цикле обнуляет значение шифротекста. Зачем??? В NNCP я
для дешифрования использовал отдельный буфер в памяти, так как всё равно
там работа с 128KiB блоками и поэтому не страшна такая не экономия. Но в
gohpenc я для каждого параллельного процесса выделяю довольно большие
буферы (по умолчанию в 1MiB) и увеличивать потребление в два раза (в
одном месте plaintext, в другом ciphertext) или, тем более, делать
копирование очень не хотелось бы.

В итоге, в классике жанра Go -- просто скопировал код chacha20poly1305 и
убрал из него обнуление шифротекста при плохом MAC. Это всё равно лишь
несколько строчек вызова Poly1305 и ChaCha20. Но уже в который раз
ощущение что я, как с glocate-ом (adca349bb86d9ed357051d2452c1a4f9dff24f7c),
хочу странного и ищу себе новые проблемы. Зато теперь он ещё более
безопасный.

    [оставить комментарий]