Як відомо, у /dev/random, криптографічно стійкого генератора псевдовипадкових чисел (CSPRNG) є одна неприємна проблема - блокування. У цій статті розповідається, яким чином її можна вирішити.
За останні кілька місяців засоби генерації випадкових чисел у ядрі були трохи перероблені, але проблеми у цій підсистемі вирішувалися протягом ширших
Енді Лутомирскі (Andy Lutomirski) опублікував третю версію патчу наприкінці грудня. Він вносить «Дві основні семантичні зміни у випадкових API Linux». Патч додає новий прапор GRND_INSECURE до системного виклику getrandom() (хоча Лутомирський звертається до нього як до getentropy(), який реалізований glibc за допомогою getrandom() з фіксованими прапорами); цей прапор змушує виклик завжди повертати кількість даних, але без гарантії, що ці дані випадкові. Ядро просто докладе всіх зусиль, щоб дати найкращі випадкові дані, які він має на даний момент часу. «Ймовірно, найкраще, що можна зробити, це назвати його „INSECURE“ (небезпечним), щоб запобігти використанню цього API для речей, які потребують безпеки».
Патчі також видаляють блокуючий пул. В даний час ядро підтримує два пули випадкових даних, один з яких відповідає /dev/random, а інший - /dev/urandom, як описано в цій
Видалення пулу блокувань означає, що читання з /dev/random поводиться як getrandom() зі значенням flags рівним нулю (і перетворює прапор GRND_RANDOM на noop). Після ініціалізації криптографічного генератора випадкових чисел (CRNG), читання з /dev/random та виклики getrandom(…,0) не призведе до блокування та поверне запитану кількість випадкових даних.
Лутомирський каже: «Я вважаю, що блокуючий пул Linux зжив себе. CRNG Linux генерує вихідні дані, які є досить хорошими, щоб використовувати їх навіть для генерації ключів. Блокуючий пул не є сильнішим у будь-якому матеріальному відношенні, і для його підтримки потрібно багато інфраструктури сумнівної цінності».
Зміни були зроблені з прицілом на те, щоб існуючі програми дійсно не постраждали, і насправді проблем із тривалим очікуванням таких речей, як генерація ключів GnuPG, стане менше.
«Ці серії не повинні порушувати жодних програм. /dev/urandom залишається незмінним. /dev/random, як і раніше, блокується відразу після завантаження, але блокується менше, ніж раніше. getentropy() з існуючими прапорами поверне результат, який буде таким же підходящим для практичних цілей, як і раніше».
Лутомирський зазначив, що досі залишається відкритим питання про те, чи має ядро надавати так звані «справжні випадкові числа», що певною мірою й мало робити блокуюче ядро. Він бачить для цього лише одну причину: дотримання державних стандартів. Лутомирський припустив, що якщо вже ядро має це забезпечити, то це має бути зроблено через зовсім інший інтерфейс або має бути перенесене в простір користувача, надавши можливість витягувати необроблені зразки подій, які можуть бути використані для створення такого пулу блокування.
Штефан Мюллер (Stephan Müller) припустив, що його набір
Метью Гарретт (Matthew Garrett) заперечував проти терміна «справжні випадкові дані», відзначаючи, що пристрої, що вибираються, в принципі можуть бути змодельовані досить точно, щоб зробити їх передбачуваними: «ми тут не відбираємо квантові події».
Мюллер відповів, що цей термін походить від німецького стандарту AIS 31 для опису генератора випадкових чисел, який тільки видає результат «з такою ж швидкістю, як і базове джерело шуму виробляє ентропію».
Крім різночитань термінології, наявність пула блокування, як це пропонується патчами LRNG, просто призведе до різних проблем, принаймні якщо він доступний без привілеїв.
Як сказав Лутомирський: «Це не вирішує проблеми. Якщо два різних користувача запускають дурні програми, такі як gnupg, вони просто виснажать один одного. Я бачу, що в даний час існують дві основні проблеми з /dev/random: він схильний до DoS (тобто виснаження ресурсів, шкідливого впливу або чогось подібного), і оскільки жодних привілеїв для його використання не потрібно, він також схильний до зловживань. Gnupg – це неправильно, це повний колапс. Якщо ми додамо новий непривілейований інтерфейс, який використовуватимуть gnupg та аналогічні програми, ми знову програємо».
Мюллер зазначив, що додавання getrandom() тепер дозволить GnuPG використовувати цей інтерфейс, оскільки він забезпечить необхідну гарантію того, що пул був ініціалізований. На основі дискусій з розробником GnuPG Вернером Кохом (Werner Koch) Мюллер вважає, що гарантія - це єдина причина, через яку GnuPG в даний час читає безпосередньо з /dev/random. Але якщо є непривілейований інтерфейс, який схильний до відмови в обслуговуванні (як на сьогодні /dev/random), то за твердженням Лутомирського, він неправильно використовуватиметься деякими додатками.
Теодор Цао (Theodore Yue Tak Ts'o), розробник підсистеми випадкових чисел Linux, мабуть, змінив свою думку щодо необхідності блокуючого пулу. Він сказав, що видалення цього пулу дозволить ефективно позбутися ідеї, що Linux має справжній генератор випадкових чисел (TRNG): «це не є нісенітницею, тому що це саме те, що завжди робили * BSD».
Він також стурбований тим, що надання механізму TRNG буде просто служити принадою для розробників додатків і вважає, що насправді, враховуючи різні типи апаратного забезпечення, що підтримується Linux, неможливо гарантувати TRNG в ядрі. Проблему не вирішить навіть можливість роботи з обладнанням лише на основі root-привілеїв: «Розробники прикладних програм вказують, щоб їхня програма з метою безпеки була встановлена як root, тому тільки так ви можете отримати доступ до «дійсно хороших» випадкових чисел».
Мюллер запитав, чи Цао відмовився від реалізації блокуючого пулу, яку він сам давно запропонував. Цао відповів, що планує взяти патчі Лутомирського та активно заперечує проти додавання блокуючого інтерфейсу назад у ядро.
«Ядро не може дати жодних гарантій щодо того, чи належним чином охарактеризовано noise source. Єдине, що може отримати розробник GPG або OpenSSL — це невиразне відчуття, що TRUERANDOM «краще», а оскільки вони хочуть більшої безпеки, то, безперечно, спробують його використати. У певний момент він заблокується, і коли якийсь інший розумний користувач (можливо, фахівець із випуску дистрибутива) вставить його в init скрипт і системи перестануть працювати, користувачам залишиться лише скаржитися Лінусу Торвальдсу».
Цао також виступає за те, щоб надати криптографам і тим, хто дійсно потребує TRNG, спосіб збирати свою власну ентропію в просторі користувача, щоб використовувати її на свій розсуд. Він каже, що збирання ентропії — це той процес, який може виконуватися ядром на всіляких підтримуваних ним апаратних засобах, ще, саме ядро неспроможна оцінити кількість ентропії, забезпечуване різними джерелами.
«Ядро не повинно змішувати разом різні noise source, і воно, звичайно ж, не повинно намагатися стверджувати, що знає, скільки біт ентропії воно отримує, коли намагається грати в якусь «дерганну гру ентропії» на простий до неподобства архітектурі CPU для користувачів випадків IOT/Embedded, коли все розсинхронізовано з єдиним майстер-генератором, коли немає жодної інструкції CPU для переупорядкування чи перейменування регістру тощо».
«Можна говорити про надання інструментів, які намагаються зробити ці розрахунки, але такі речі мають проводитись на обладнанні кожного користувача, що для більшості користувачів дистрибутива просто непрактично. Якщо ж це призначено тільки для криптографів, то нехай буде зроблено в їхньому просторі користувача. І давайте не будемо спрощувати GPG, OpenSSL і т.д., щоб усі говорили: «ми хочемо «справжньої випадковості» і не погоджуємося на менше». Можна говорити про те, як ми надаємо інтерфейси криптографам, щоб вони могли отримати необхідну інформацію завдяки доступу до первинних noise sources, відокремлених і названих, і, можливо, якимось чином noise source зможе аутентифікувати себе в бібліотеці або додатку простору користувача».
Була невелика дискусія про те, як може виглядати такий інтерфейс, адже, наприклад, для деяких подій можуть бути наслідки щодо безпеки. Цао зазначив, що коди сканування клавіатури (тобто натискання клавіш) змішуються в пул як частина збору ентропії: «Перенесення цього в простір користувача, навіть через привілейований системний виклик, було б, щонайменше, нерозсудливо». Цілком можливо, що й інші таймінги подій можуть створити якийсь витік інформації по побічним каналам.
Таким чином виникає відчуття, що давня проблема підсистеми випадкових чисел Linux знаходиться на шляху до вирішення. Зміни, які підсистема випадкових чисел зазнала останнім часом, фактично призводили лише до проблем DoS у процесі її використання. Тепер з'явилися ефективні способи отримати найкращі випадкові числа, які тільки може надати ядро. Якщо ж TRNG все ще бажаний для Linux, цей недолік потрібно буде усунути в майбутньому, але, швидше за все, це не буде робитися всередині самого ядра.
Небагато реклами 🙂
Дякую, що залишаєтеся з нами. Вам подобаються наші статті? Бажаєте бачити більше цікавих матеріалів? Підтримайте нас, оформивши замовлення або порекомендувавши знайомим,
Dell R730xd вдвічі дешевше в дата-центрі Equinix Tier IV в Амстердамі? Тільки в нас
Джерело: habr.com