JEP 246: Leverage CPU Instructions for GHASH and RSA
Использование инструкций процессора для GHASH и RSA
| Ответственный | Anthony Scarpino |
| Тип | Feature |
| Область | JDK |
| Статус | Closed / Delivered |
| Выпуск | 9 |
| Компонент | security-libs / javax.crypto |
| Обсуждение | security dash dev at openjdk dot java dot net |
| Трудоёмкость | L |
| Длительность | L |
| Рецензенты | Brian Goetz, Sean Mullan |
| Одобрен | Brian Goetz |
| Создан | 2014/06/16 17:18 |
| Обновлён | 2017/03/06 11:36 |
| Задача | 8046943 |
Аннотация
Повысить производительность криптографических операций GHASH и RSA за счёт недавно появившихся инструкций процессоров SPARC и Intel x64.
Критерии успеха
Поддержка AES-CBC, добавленная в JDK 8 (см. JEP 164), работает примерно в 8 раз быстрее чисто программной реализации. Для разных алгоритмов результаты будут отличаться, но мы должны получить такой же значительный прирост производительности.
Мотивация
Чем меньше мы используем нативные библиотеки, например PKCS#11, тем меньше возникает сложностей с кодом и проблем с памятью из-за взаимодействия со сложными нативными API. Чем меньше вызовов JNI к нативным библиотекам, тем быстрее работает криптография. Реализуя криптографические операции непосредственно в JVM, мы можем управлять их реализацией и использованием через встроенный провайдер и тем самым обеспечить поддержку «из коробки».
Описание
Никакие существующие API не будут изменены или расширены.
Алгоритмы
Существующая реализация вызывает инструкции AES в HotSpot, если эти инструкции поддерживаются. Помимо режима CBC, есть оптимизации, которые помогают AES и CBC быстро работать вместе. Эти инструкции и оптимизации заменяют текущие методы SunJCE на байт-коде. Планируется реализовать аналогичные оптимизации для GCM и RSA, которые могут получить большой выигрыш от аппаратной поддержки. И AES-GCM, и RSA входят в наборы шифров TLS.
GHASH, входящий в GCM, будет ускорен с помощью pclmulqdq на Intel x64 и xmul/xmulhi на SPARC.
RSA будет ускорен с помощью набора инструкций Bit Manipulation Instruction Set 2. Вероятно, эти изменения пойдут на пользу и другим асимметричным алгоритмам, но оцениваться они будут по RSA. Инструкции SPARC не добавлены из-за их сложности и ограничений инструкций 'montmul' и 'montsqr'. Нативная библиотека даёт полную функциональность RSA без этих недостатков. Кроме того, поскольку RSA — медленная операция, слои JNI и нативного API, скорее всего, мало влияют на общую картину производительности.
Провайдеры
Управление алгоритмами — важный вопрос, который со временем стал сложнее. Крайний случай — конфигурация провайдеров по умолчанию в Solaris. Провайдер SunPKCS11 стоит в списке провайдеров перед SunJCE. Провайдер SunPKCS11 поддерживает все аппаратно ускоренные и оптимизированные алгоритмы для Solaris. Чтобы использовать поддержку AES-CBC из JDK 8, SunJCE нужно переместить перед SunPKCS11. Для приложения, которому нужен только AES-CBC, например для теста производительности, другие алгоритмы не нужны, поэтому такой подход работает. Однако в приложениях, которые используют несколько алгоритмов, другие алгоритмы будут выполняться в неускоренных программных реализациях вместо аппаратно ускоренных реализаций из SunPKCS11. В других ОС эта проблема тоже может возникнуть, если используется NSS (настроенный через провайдер SunPKCS11).
Поэтому в файл java.security добавлено новое свойство безопасности jdk.security.provider.preferred, которое позволяет направлять определённые алгоритмы и группы алгоритмов к конкретному провайдеру до проверки упорядоченного списка провайдеров. Это свойство предназначено для опытных пользователей и по умолчанию не задано. Поскольку сейчас используется множество разных версий процессоров x86 и SPARC, значение по умолчанию, скорее всего, привело бы к снижению производительности на старых системах и потребовало бы постоянной поддержки по мере того, как новые процессоры предоставляют больше возможностей. Кроме того, существующие конфигурации JDK, например FIPS 140 или другие специализированные провайдеры, могли бы незаметно для пользователя оказаться перенаправлены к другому провайдеру. Таким образом, лучше всего оставить свойство jdk.security.provider.preferred по умолчанию незаданным, но позволить поставщикам и опытным пользователям задавать в нём то, что поддерживают их процессоры.
Тестирование
Для функционального тестирования должно быть достаточно существующих тестов с известными ответами (Known Answer Tests, KAT). Будет проведён значительный объём тестирования производительности с использованием существующих бенчмарков и внутренних тестов.