#kdf — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #kdf, aggregated by home.social.
-
Пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript
Новый пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript. Ring-LWE, работа с ключами с использованием MAC и SHAKE-256, защита от основных видов атак и другие мысли в реализации протокола QuarkDash.
https://habr.com/ru/articles/1020092/
#криптография #криптографические_протоколы #алгоритмы #typescript #ring #lwe #shake256 #mac #kdf #безопасность_вебприложений
-
Пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript
Новый пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript. Ring-LWE, работа с ключами с использованием MAC и SHAKE-256, защита от основных видов атак и другие мысли в реализации протокола QuarkDash.
https://habr.com/ru/articles/1020092/
#криптография #криптографические_протоколы #алгоритмы #typescript #ring #lwe #shake256 #mac #kdf #безопасность_вебприложений
-
Пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript
Новый пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript. Ring-LWE, работа с ключами с использованием MAC и SHAKE-256, защита от основных видов атак и другие мысли в реализации протокола QuarkDash.
https://habr.com/ru/articles/1020092/
#криптография #криптографические_протоколы #алгоритмы #typescript #ring #lwe #shake256 #mac #kdf #безопасность_вебприложений
-
Пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript
Новый пост-квантовый гибридный алгоритм шифрования для высоко-нагруженных систем с реализацией на TypeScript. Ring-LWE, работа с ключами с использованием MAC и SHAKE-256, защита от основных видов атак и другие мысли в реализации протокола QuarkDash.
https://habr.com/ru/articles/1020092/
#криптография #криптографические_протоколы #алгоритмы #typescript #ring #lwe #shake256 #mac #kdf #безопасность_вебприложений
-
AfD Wagen
Der Ex VW Chef fordert mehr AfD zu wagen. Für den ehem. Leiter des von den Nazis zum Bau des Kraft durch Freude, kurz […]Zum Weiterlesen den Link benutzen.
https://cartoons.guido-kuehn.de/afd-wagen/
#KdF #vw -
https://www.europesays.com/africa/103125/ Defence Ministry seeks Sh241 billion to safeguard Kenya’s security, sovereignty #DCI #DefenceMinistrySeeksSh241BillionToSafeguardKenya’sSecurity #Headlines #KDF #Kenya #MInistryOfDefence #National #NationalIntelligenceService #news #nis #sovereignty
-
https://www.europesays.com/africa/65377/ KDF conducts health, environmental outreach in drought-hit Mandera #DamasaTown #DroughtInMandera #EnvironmentalOutreachInDroughtHitMandera #Headlines #InsecurityInMandera #KDF #KDFConductsHealth #Kenya #ManderaCounty #NorthernKenya
-
Hallo @marudor, bei https://bahn.expert/details/RE%2091595?journeyId=20250126-844b6efa-18a8-3064-8193-389a433e5298 stehen zwei Züge, auf die der 91595 wendet:
https://bahn.expert/details/RE%2091898/2025-01-26T16%3A03%3A00.000Z?journeyId=20250126-5da7619d-b3fd-35fd-a82b-0fd73d8fdf8c (der ist richtig oder mindestens plausibel) und https://bahn.expert/details/RE%2091893?journeyId=20250126-43ce8dec-014f-3352-896e-cf5d2613673f (diese Wende wäre #FKW -> #KDF). Andere Fahrten bei der Linie sind auch komisch mit verknüpften Zügen.Wahrscheinlich Daten kaputt, ich weiß, aber on the off-chance dass du da was drehen kannst wollte ich mal Bescheid geben.
-
Как и в любой сфере вокруг криптографии полно новостей из ничего. Претендующих не столько на сенсации, сколько выпускаемых в мир лишь для создания в дальнейшем псевдо-правдоподобного маркетинга. Как смешать всё в кучу и якобы обосновано объявить использование ряда алгоритмов небезопасными?
TL;DR: пост о том, чем именно определяется реально используемая на практике криптография. А крики и суета ориентированы на аудиторию понятия не имеющей о стандартах и регламентирующих документах.
Имеет ли смысл при всём этом раскладе ставить использование «Магма» в один ряд с использованием таких же «устаревших» #Triple-DES / #3DES и #Blowfish? Только потому, что они все используют при шифровании блоки длиной 64-бит, но при этом имеют более чем разумную длину ключа? Обосновывая это устаревание киванием в сторону #SWEET32 атаки?
Это определяется режимом использования любого из этих шифров:- какой режим шифрования выбран
- какой «padding mode»
- использование «key meshing» / KDF при этом.
Громогласно и с каждого утюга рассказывалось о чём-то вроде #SWEET32 атаки. Если что-то и пояснялось, то весьма путано и заумно, не для обывателей. Суть при этом сводилась и сводится к тому что:- Для получения возможности угадать содержимое HTTP-cookies надо мониторить долго существующее HTTPS-соединение между браузером и сайтом, сохранив 785 гигабайт трафика.
- Надо создавать внутри этого соединения большое число запросов для заранее предсказуемых данных в ответах, а токен аутентификации должен передаваться в каждом http-запросе.
- Подчёркивать, успешное подтверждение, мол исследователям удалось сделать это меньше чем за пару дней с помощью специального JavaScript-кода для генерации трафика.
А ничего, что никакие вменяемые библиотеки шифруют массивы данных постоянно меняя сессионный ключ?
В крайнем случае #TLS библиотеки ограничивают продолжительность сессий TLS-соединений вообще в целом, а не только для 64-битных шифров, заново устанавливая соединение.
А тот же #OpenVPN давно содержит принудительный повторный выпуск ключей (reneg-bytes 64000000).
Использование ротации ключей для ГОСТ 28147-89 / «Магма» регламентируются официальными документами (использование KDF определяется рекомендациями 1323565.1.022-2018 и 50.1.113-2016) без соответствия этим требованиям в РФ не получить сертификат о корректно реализованной криптографии.
Да и более скоростной вариант такой ротации — key meshing — изменении ключа каждые 1024 байта восходит аж к 2006 году и описан в RFC 4357.
Который именно про ГОСТ 28147-89 и в целом определяет:- режимы шифрования,
- алгоритм усложнения ключей (key meshing),
- режим заполнения (padding mode),
- S-box таблицы перестановок (S-преобразования);
Однако, про RFC 4357 чаще всего вспоминают в несколько ином контексте (см. в конце). И такие вещи как padding mode и key meshing из этого RFC на всём фоне суеты с узлами замены (S-Box) конечно же теряются. Однако, описанный key meshing является гораздо более производительным вариантом классической ротации ключей посредством KDF. Однако в инициативе #КриптоПро имеется одно упущение — не упомянуто каким именно образом изменяется вектор инициализации (IV) во время этого key meshing.
В тоже время, при использовании в TLS 1.2 российского алгоритма «Магма» необходимо реализовывать способ работы с ключами согласно рекомендациях по стандартизации 1323565.1.020-2018).
И сам по себе подход используемого key meshing выполняется исходя из режима шифрования. Для примера можно ознакомиться с режимами #CTR-ACPKM и #OMAC-ACPKM.
Т.е. ACPKM — это Advance Cryptographic Prolongation of Key Material
а CTR-ACPKM делает возможным работа блочного шифра в поточном режиме (вместо потокового).
и OMAC-ACPKM относится к обычным #MAC (выработка имитовставки) — средствам проверки и обеспечения целостности данных.
Эти режимы в России описаны в рекомендациях по стандартизации 1323565.1.017-2018.
И вот у кого после этого всего сохранится впечатление дремучей отсталости РФ в вопросах собственной криптографии на фоне работ прогрессивного мирового сообщества по выведению из эксплуатации устаревших блочных алгоритмов в 64-битными блоками?
«Кузнечик» появился в ГОСТ 34.12-2015 отнюдь не потому, что ГОСТ 28147-89 якобы устарел, потому что нужно вводить развиваться, вводя в обиход и оборот нечто более современное. Поскольку само собой на ровном месте не появится нечто способное когда-нибудь в дальнейшем заменить ГОСТ 28147-89 в лице «Магма».
—————————
Про суету вокруг RFC 4357 — именно в нём были обозначены параметры таблицы перестановок, предложенные #CryptoPro:- OID: 1.2.643.2.2.31.4 (id-Gost28147-89-CryptoPro-D-ParamSet)
- OID: 1.2.643.2.2.31.3 (id-Gost28147-89-CryptoPro-C-ParamSet)
- OID: 1.2.643.2.2.31.2 (id-Gost28147-89-CryptoPro-B-ParamSet)
- OID: 1.2.643.2.2.31.1 (id-Gost28147-89-CryptoPro-A-ParamSet)
Это восходит к тому, что сам по себе ГОСТ 28147-89 позволяет использование различных наборов S-Box'ов, описывая тем самым не один алгоритм, а целое семейство.
И только через десять лет после RFC 4357, уже в ГОСТ 34.12-2015, на государственном уровне оказался официально зафиксирован набор S-Box'ов для однозначного определения шифра «Магма» — один конкретный вариант из множества реализаций ГОСТ 28147-89.
Соответственно, так же создал и RFC 7836 хорошо известным ТК 26 Росстандарта (Техническим комитетом по стандартизации «Криптографическая защита информации»). Описываемый набор S-Box'ов получил обозначение OID: 1.2.643.7.1.2.5.1.1, id-tc26-gost-28147-param-Z.
#маркетинг #криптография #шифры #crypto #cryptography #KDF #инфобез #infosec @Russia -
@stekopf Die Aufregung bzgl Hoyer entsteht ja dadurch, dass sie die positiven Seiten auch erwähnt. Ohne geht es aber nicht. Ich habe jetzt angefangen, #Hoyer von vorn zu lesen. Da kommt was zum #GrossenTerror und den Kommunisten in Moskau. Ulbricht war ab 1933 im Exil. Er hat mit Kriegsgefangenen gesprochen und war ganz platt, dass die die Nazis gut fanden. Das kann man nur verstehen, wenn man von #KdF usw. weiß. Deshalb gehört das in eine Geschichte des dritten Reichs, genau so wie der #FDGB zur Geschichte der #DDR gehört.
-
@stekopf Die Aufregung bzgl Hoyer entsteht ja dadurch, dass sie die positiven Seiten auch erwähnt. Ohne geht es aber nicht. Ich habe jetzt angefangen, #Hoyer von vorn zu lesen. Da kommt was zum #GrossenTerror und den Kommunisten in Moskau. Ulbricht war ab 1933 im Exil. Er hat mit Kriegsgefangenen gesprochen und war ganz platt, dass die die Nazis gut fanden. Das kann man nur verstehen, wenn man von #KdF usw. weiß. Deshalb gehört das in eine Geschichte des dritten Reichs, genau so wie der #FDGB zur Geschichte der #DDR gehört.
-
@stekopf Die Aufregung bzgl Hoyer entsteht ja dadurch, dass sie die positiven Seiten auch erwähnt. Ohne geht es aber nicht. Ich habe jetzt angefangen, #Hoyer von vorn zu lesen. Da kommt was zum #GrossenTerror und den Kommunisten in Moskau. Ulbricht war ab 1933 im Exil. Er hat mit Kriegsgefangenen gesprochen und war ganz platt, dass die die Nazis gut fanden. Das kann man nur verstehen, wenn man von #KdF usw. weiß. Deshalb gehört das in eine Geschichte des dritten Reichs, genau so wie der #FDGB zur Geschichte der #DDR gehört.
-
@stekopf Die Aufregung bzgl Hoyer entsteht ja dadurch, dass sie die positiven Seiten auch erwähnt. Ohne geht es aber nicht. Ich habe jetzt angefangen, #Hoyer von vorn zu lesen. Da kommt was zum #GrossenTerror und den Kommunisten in Moskau. Ulbricht war ab 1933 im Exil. Er hat mit Kriegsgefangenen gesprochen und war ganz platt, dass die die Nazis gut fanden. Das kann man nur verstehen, wenn man von #KdF usw. weiß. Deshalb gehört das in eine Geschichte des dritten Reichs, genau so wie der #FDGB zur Geschichte der #DDR gehört.
-
@stekopf Die Aufregung bzgl Hoyer entsteht ja dadurch, dass sie die positiven Seiten auch erwähnt. Ohne geht es aber nicht. Ich habe jetzt angefangen, #Hoyer von vorn zu lesen. Da kommt was zum #GrossenTerror und den Kommunisten in Moskau. Ulbricht war ab 1933 im Exil. Er hat mit Kriegsgefangenen gesprochen und war ganz platt, dass die die Nazis gut fanden. Das kann man nur verstehen, wenn man von #KdF usw. weiß. Deshalb gehört das in eine Geschichte des dritten Reichs, genau so wie der #FDGB zur Geschichte der #DDR gehört.
-
If you’ve never heard of NIST SP 800-108 before, or NIST Special Publications in general, here’s a quick primer:
Special Publications are a type of publication issued by NIST. Specifically, the SP 800-series reports on the Information Technology Laboratory’s research, guidelines, and outreach efforts in computer security, and its collaborative activities with industry, government, and academic organizations. These documents often support FIPS (Federal Information Protection Standards).
Via NIST.gov
One of the NIST 800-series documents concerned with Key Derivation using Pseudorandom Functions is NIST SP 800-108, first published in 2009.
In October 2021, NIST published a draft update to NIST SP 800-108 and opened a comment period until January 2022. This update mostly included Keccak-based Message Authentication Codes (KMAC) in addition to the incumbent standardized designs (HMAC and CMAC).
Upon reviewing a proposal for NIST SP 800-108 revision 1 after its comment period opened, Amazon’s cryptographers discovered a novel security issue with the standard.
I was a co-author of the public comment that disclosed this issue, along with Matthew Campagna, Panos Kampanakis, and Adam Petcher, but take no credit for its discovery.
Consequently, Section 6.7 was added to the final revision 1 of the standard to address Key Control Security.
This post examines the attack against the initial SP 800-108 design when AES-CMAC is used as the PRF in KDF Counter mode.
This meme is the TL;DR of this blog postPreliminaries
(If you’re in a hurry, feel free to skip to the attack.)
NIST SP 800-108 specifies a “KDF in Counter Mode” that can be used with several PRFs, including AES-CMAC. It’s worth noting that this family of KDFs can be defined to use any arbitrary PRF, but only the PRFs approved by NIST for this use are recommended.
AES-CMAC is a one-key CBC-MAC construction. Some cryptographers, such as Matt Green, are famously not fond of CBC-MAC.
KDF Security and PRF Security
Yes, I will take any excuse to turn cryptography knowledge into wholesome memes.KDF stands for “Key Derivation Function”.
PRF stands for “Pseudo-Random Function”.
The security notion for KDF Security is stronger than PRF Security.
PRFs require a uniformly-distributed secret key, while KDFs can tolerate a key that is not uniformly random.
This matters if you’re, say, trying to derive symmetric encryption keys from a Diffie-Hellman shared secret of some sort, where the output of your DH() function has some algebraic structure.
Realistically, the difference between the two security notions matters a lot less in scenarios where you’re deriving sub-keys from a primary uniformly random cryptographic secret.
However, it does make your proofs nicer to achieve KDF security instead of merely PRF security.
Key Control Security
Let’s pretend, for simplicity, we have a generic
KDF()function that offers KDF Security. We don’t need to know how it works just yet.Because KDFs are thought of as PRFs, but stronger, it seems perfectly reasonable that you could use
KDF()in a setup where multiple inputs are provided, each from a different party, and the output would always be uniformly random.Further, even if all other parties’ inputs are known, it should remain computationally infeasible for one of the parties to influence the output of
KDF()to produce a specific value; e.g. a key with all bits zeroed.The assumption that this result is computationally infeasible when working with
KDF()is referred to as “Key Control Security”.Loss of Key Control Security in NIST SP 800-108
You already know where this is going…I’m going to explain the attack by way of example.
If you want a more formal treatment, I believe Appendix B of NIST SP 800-108 rev 1 has what you’re looking for.
Imagine that you’re designing an online two-party private messaging app. To ensure forward secrecy, you implement a forward-secure KDF ratchet, loosely inspired by Signal’s design.
For your KDF, you choose AES-CMAC in Counter Mode, because you’re designing for hardware that has accelerated AES instructions and want to avoid the overhead of hash functions.
(Aside: I guess this would also imply you’re most likely selecting AES-CCM for your actual message encryption.)
With each message, the sender commits some random bytes by encrypting them with their message. The recipient, after verifying the authentication tag and decrypting the message, possess knowledge of the same random bytes.
Both parties then use the random bytes and the current symmetric key to ratchet forward to a new 128-bit symmetric key.
The million dollar question is: Is this ratcheting protocol secure?
In the case of KDF in Counter Mode with AES-CMAC, if you have more than 16 bytes of input material, the answer is simply: No.
How The Attack Works
A two-block implementation of this KDF is normally computed as follows:
- Return
Don’t get intimidated by the notation. This is just AES encryption and XOR.
The messages and are defined in the KDF specification. In the scenario we sketched above, we assume the attacker can choose these arbitrarily.
To coerce a recipient to use an arbitrary 128-bit value (i.e., ) all an attacker needs to do is:
- Calculate
- Let some value
- Here, is the target value.
- Force
Notice that is the result of encrypting , and our attacker’s goal in step 3 can be achieved solely by manipulating (which exists independent of )?
That’s the vulnerability.
The public comments and Appendix B on the NIST document describe the actual steps of computing to force a chosen , which involve manipulating the structure of to achieve this result.
Feel free to check out both documents if you’re interested in the finer details.
What Can An Attacker Actually Do With This?
If an attacker controls both and …
Or if an attacker knows some and can control …
…then they can force the final KDF output to equal whatever 128-bit value they want you to use.
The most straightforward application of the loss of key control security is to introduce a backdoor into an application.
If the Underhanded Crypto Contest were still running this year, NIST SP 800-108 using AES-CMAC in Counter Mode would be an excellent basis for a contestant.
Does Anyone Actually Use NIST SP 800-108 This Way?
I’m not aware of any specific products or services that use this KDF in this way. I will update this section if someone finds any.
Is This A Deliberate Backdoor in a NIST Standard?
No.
I understand that, in the wake of Dual_EC_DRBG, there is a lot of distrust for NIST’s work on standardized cryptography.
However, I have no specific knowledge to indicate this was placed deliberately in the standard.
It is inaccurate to describe the loss of key control security in this context as a backdoor. Instead, it’s an unexpected property of the algorithms that can be used to create a clever backdoor. These are wildly different propositions.
At least, that was the case until it was disclosed to NIST in January 2022. 🙂
(I’m including an answer to this question, preemptively, in case someone overreacts when I publish this blog post. I hope it proves unnecessary, but I figured some caution was warranted.)
Mitigation Options
If you care about Key Control Security and use NIST SP 800-108, you should use HMAC or KMAC instead of CMAC. Only CMAC is impacted.
Revision 1 of NIST SP800-108 also outlines another mitigation that involves changing the inputs to include an additional (but reusable) PRF output for every block.
This tweak does change makes the KDF behave more like our intuition for PRFs, but in my opinion it’s better to avoid using CMAC entirely for KDFs.
Why Wasn’t This Widely Publicized?
As interesting and surprising as the loss of Key Control Security in a NIST standard is to cryptography nerds, it’s not exactly like Heartbleed or Log4shell.
That said, regardless of your personal feelings on NIST, if you’re interesting in not having findings like this slip through the cracks in the future, it’s generally worthwhile to pay attention to what NIST is up to.
https://scottarc.blog/2024/06/04/attacking-nist-sp-800-108/
#cybersecurity #framework #KDF #KDFSecurity #KeyDerivationFunctions #NIST #NISTSP800108 #PRFSecurity #security #standards #symmetricCryptography
-
If you’ve never heard of NIST SP 800-108 before, or NIST Special Publications in general, here’s a quick primer:
Special Publications are a type of publication issued by NIST. Specifically, the SP 800-series reports on the Information Technology Laboratory’s research, guidelines, and outreach efforts in computer security, and its collaborative activities with industry, government, and academic organizations. These documents often support FIPS (Federal Information Protection Standards).
Via NIST.gov
One of the NIST 800-series documents concerned with Key Derivation using Pseudorandom Functions is NIST SP 800-108, first published in 2009.
In October 2021, NIST published a draft update to NIST SP 800-108 and opened a comment period until January 2022. This update mostly included Keccak-based Message Authentication Codes (KMAC) in addition to the incumbent standardized designs (HMAC and CMAC).
Upon reviewing a proposal for NIST SP 800-108 revision 1 after its comment period opened, Amazon’s cryptographers discovered a novel security issue with the standard.
I was a co-author of the public comment that disclosed this issue, along with Matthew Campagna, Panos Kampanakis, and Adam Petcher, but take no credit for its discovery.
Consequently, Section 6.7 was added to the final revision 1 of the standard to address Key Control Security.
This post examines the attack against the initial SP 800-108 design when AES-CMAC is used as the PRF in KDF Counter mode.
This meme is the TL;DR of this blog postPreliminaries
(If you’re in a hurry, feel free to skip to the attack.)
NIST SP 800-108 specifies a “KDF in Counter Mode” that can be used with several PRFs, including AES-CMAC. It’s worth noting that this family of KDFs can be defined to use any arbitrary PRF, but only the PRFs approved by NIST for this use are recommended.
AES-CMAC is a one-key CBC-MAC construction. Some cryptographers, such as Matt Green, are famously not fond of CBC-MAC.
KDF Security and PRF Security
Yes, I will take any excuse to turn cryptography knowledge into wholesome memes.KDF stands for “Key Derivation Function”.
PRF stands for “Pseudo-Random Function”.
The security notion for KDF Security is stronger than PRF Security.
PRFs require a uniformly-distributed secret key, while KDFs can tolerate a key that is not uniformly random.
This matters if you’re, say, trying to derive symmetric encryption keys from a Diffie-Hellman shared secret of some sort, where the output of your DH() function has some algebraic structure.
Realistically, the difference between the two security notions matters a lot less in scenarios where you’re deriving sub-keys from a primary uniformly random cryptographic secret.
However, it does make your proofs nicer to achieve KDF security instead of merely PRF security.
Key Control Security
Let’s pretend, for simplicity, we have a generic
KDF()function that offers KDF Security. We don’t need to know how it works just yet.Because KDFs are thought of as PRFs, but stronger, it seems perfectly reasonable that you could use
KDF()in a setup where multiple inputs are provided, each from a different party, and the output would always be uniformly random.Further, even if all other parties’ inputs are known, it should remain computationally infeasible for one of the parties to influence the output of
KDF()to produce a specific value; e.g. a key with all bits zeroed.The assumption that this result is computationally infeasible when working with
KDF()is referred to as “Key Control Security”.Loss of Key Control Security in NIST SP 800-108
You already know where this is going…I’m going to explain the attack by way of example.
If you want a more formal treatment, I believe Appendix B of NIST SP 800-108 rev 1 has what you’re looking for.
Imagine that you’re designing an online two-party private messaging app. To ensure forward secrecy, you implement a forward-secure KDF ratchet, loosely inspired by Signal’s design.
For your KDF, you choose AES-CMAC in Counter Mode, because you’re designing for hardware that has accelerated AES instructions and want to avoid the overhead of hash functions.
(Aside: I guess this would also imply you’re most likely selecting AES-CCM for your actual message encryption.)
With each message, the sender commits some random bytes by encrypting them with their message. The recipient, after verifying the authentication tag and decrypting the message, possess knowledge of the same random bytes.
Both parties then use the random bytes and the current symmetric key to ratchet forward to a new 128-bit symmetric key.
The million dollar question is: Is this ratcheting protocol secure?
In the case of KDF in Counter Mode with AES-CMAC, if you have more than 16 bytes of input material, the answer is simply: No.
How The Attack Works
A two-block implementation of this KDF is normally computed as follows:
- Return
Don’t get intimidated by the notation. This is just AES encryption and XOR.
The messages and are defined in the KDF specification. In the scenario we sketched above, we assume the attacker can choose these arbitrarily.
To coerce a recipient to use an arbitrary 128-bit value (i.e., ) all an attacker needs to do is:
- Calculate
- Let some value
- Here, is the target value.
- Force
Notice that is the result of encrypting , and our attacker’s goal in step 3 can be achieved solely by manipulating (which exists independent of )?
That’s the vulnerability.
The public comments and Appendix B on the NIST document describe the actual steps of computing to force a chosen , which involve manipulating the structure of to achieve this result.
Feel free to check out both documents if you’re interested in the finer details.
What Can An Attacker Actually Do With This?
If an attacker controls both and …
Or if an attacker knows some and can control …
…then they can force the final KDF output to equal whatever 128-bit value they want you to use.
The most straightforward application of the loss of key control security is to introduce a backdoor into an application.
If the Underhanded Crypto Contest were still running this year, NIST SP 800-108 using AES-CMAC in Counter Mode would be an excellent basis for a contestant.
Does Anyone Actually Use NIST SP 800-108 This Way?
I’m not aware of any specific products or services that use this KDF in this way. I will update this section if someone finds any.
Is This A Deliberate Backdoor in a NIST Standard?
No.
I understand that, in the wake of Dual_EC_DRBG, there is a lot of distrust for NIST’s work on standardized cryptography.
However, I have no specific knowledge to indicate this was placed deliberately in the standard.
It is inaccurate to describe the loss of key control security in this context as a backdoor. Instead, it’s an unexpected property of the algorithms that can be used to create a clever backdoor. These are wildly different propositions.
At least, that was the case until it was disclosed to NIST in January 2022. 🙂
(I’m including an answer to this question, preemptively, in case someone overreacts when I publish this blog post. I hope it proves unnecessary, but I figured some caution was warranted.)
Mitigation Options
If you care about Key Control Security and use NIST SP 800-108, you should use HMAC or KMAC instead of CMAC. Only CMAC is impacted.
Revision 1 of NIST SP800-108 also outlines another mitigation that involves changing the inputs to include an additional (but reusable) PRF output for every block.
This tweak does change makes the KDF behave more like our intuition for PRFs, but in my opinion it’s better to avoid using CMAC entirely for KDFs.
Why Wasn’t This Widely Publicized?
As interesting and surprising as the loss of Key Control Security in a NIST standard is to cryptography nerds, it’s exactly not like Heartbleed or Log4shell.
That said, regardless of your personal feelings on NIST, if you’re interesting in not having findings like this slip through the cracks in the future, it’s generally worthwhile to pay attention to what NIST is up to.
https://scottarc.blog/2024/06/04/attacking-nist-sp-800-108/
#cybersecurity #framework #KDF #KDFSecurity #KeyDerivationFunctions #NIST #NISTSP800108 #PRFSecurity #security #standards #symmetricCryptography
-
If you’ve never heard of NIST SP 800-108 before, or NIST Special Publications in general, here’s a quick primer:
Special Publications are a type of publication issued by NIST. Specifically, the SP 800-series reports on the Information Technology Laboratory’s research, guidelines, and outreach efforts in computer security, and its collaborative activities with industry, government, and academic organizations. These documents often support FIPS (Federal Information Protection Standards).
Via NIST.gov
One of the NIST 800-series documents concerned with Key Derivation using Pseudorandom Functions is NIST SP 800-108, first published in 2009.
In October 2021, NIST published a draft update to NIST SP 800-108 and opened a comment period until January 2022. This update mostly included Keccak-based Message Authentication Codes (KMAC) in addition to the incumbent standardized designs (HMAC and CMAC).
Upon reviewing a proposal for NIST SP 800-108 revision 1 after its comment period opened, Amazon’s cryptographers discovered a novel security issue with the standard.
I was a co-author of the public comment that disclosed this issue, along with Matthew Campagna, Panos Kampanakis, and Adam Petcher, but take no credit for its discovery.
Consequently, Section 6.7 was added to the final revision 1 of the standard to address Key Control Security.
This post examines the attack against the initial SP 800-108 design when AES-CMAC is used as the PRF in KDF Counter mode.
This meme is the TL;DR of this blog postPreliminaries
(If you’re in a hurry, feel free to skip to the attack.)
NIST SP 800-108 specifies a “KDF in Counter Mode” that can be used with several PRFs, including AES-CMAC. It’s worth noting that this family of KDFs can be defined to use any arbitrary PRF, but only the PRFs approved by NIST for this use are recommended.
AES-CMAC is a one-key CBC-MAC construction. Some cryptographers, such as Matt Green, are famously not fond of CBC-MAC.
KDF Security and PRF Security
Yes, I will take any excuse to turn cryptography knowledge into wholesome memes.KDF stands for “Key Derivation Function”.
PRF stands for “Pseudo-Random Function”.
The security notion for KDF Security is stronger than PRF Security.
PRFs require a uniformly-distributed secret key, while KDFs can tolerate a key that is not uniformly random.
This matters if you’re, say, trying to derive symmetric encryption keys from a Diffie-Hellman shared secret of some sort, where the output of your DH() function has some algebraic structure.
Realistically, the difference between the two security notions matters a lot less in scenarios where you’re deriving sub-keys from a primary uniformly random cryptographic secret.
However, it does make your proofs nicer to achieve KDF security instead of merely PRF security.
Key Control Security
Let’s pretend, for simplicity, we have a generic
KDF()function that offers KDF Security. We don’t need to know how it works just yet.Because KDFs are thought of as PRFs, but stronger, it seems perfectly reasonable that you could use
KDF()in a setup where multiple inputs are provided, each from a different party, and the output would always be uniformly random.Further, even if all other parties’ inputs are known, it should remain computationally infeasible for one of the parties to influence the output of
KDF()to produce a specific value; e.g. a key with all bits zeroed.The assumption that this result is computationally infeasible when working with
KDF()is referred to as “Key Control Security”.Loss of Key Control Security in NIST SP 800-108
You already know where this is going…I’m going to explain the attack by way of example.
If you want a more formal treatment, I believe Appendix B of NIST SP 800-108 rev 1 has what you’re looking for.
Imagine that you’re designing an online two-party private messaging app. To ensure forward secrecy, you implement a forward-secure KDF ratchet, loosely inspired by Signal’s design.
For your KDF, you choose AES-CMAC in Counter Mode, because you’re designing for hardware that has accelerated AES instructions and want to avoid the overhead of hash functions.
(Aside: I guess this would also imply you’re most likely selecting AES-CCM for your actual message encryption.)
With each message, the sender commits some random bytes by encrypting them with their message. The recipient, after verifying the authentication tag and decrypting the message, possess knowledge of the same random bytes.
Both parties then use the random bytes and the current symmetric key to ratchet forward to a new 128-bit symmetric key.
The million dollar question is: Is this ratcheting protocol secure?
In the case of KDF in Counter Mode with AES-CMAC, if you have more than 16 bytes of input material, the answer is simply: No.
How The Attack Works
A two-block implementation of this KDF is normally computed as follows:
- Return
Don’t get intimidated by the notation. This is just AES encryption and XOR.
The messages and are defined in the KDF specification. In the scenario we sketched above, we assume the attacker can choose these arbitrarily.
To coerce a recipient to use an arbitrary 128-bit value (i.e., ) all an attacker needs to do is:
- Calculate
- Let some value
- Here, is the target value.
- Force
Notice that is the result of encrypting , and our attacker’s goal in step 3 can be achieved solely by manipulating (which exists independent of )?
That’s the vulnerability.
The public comments and Appendix B on the NIST document describe the actual steps of computing to force a chosen , which involve manipulating the structure of to achieve this result.
Feel free to check out both documents if you’re interested in the finer details.
What Can An Attacker Actually Do With This?
If an attacker controls both and …
Or if an attacker knows some and can control …
…then they can force the final KDF output to equal whatever 128-bit value they want you to use.
The most straightforward application of the loss of key control security is to introduce a backdoor into an application.
If the Underhanded Crypto Contest were still running this year, NIST SP 800-108 using AES-CMAC in Counter Mode would be an excellent basis for a contestant.
Does Anyone Actually Use NIST SP 800-108 This Way?
I’m not aware of any specific products or services that use this KDF in this way. I will update this section if someone finds any.
Is This A Deliberate Backdoor in a NIST Standard?
No.
I understand that, in the wake of Dual_EC_DRBG, there is a lot of distrust for NIST’s work on standardized cryptography.
However, I have no specific knowledge to indicate this was placed deliberately in the standard.
It is inaccurate to describe the loss of key control security in this context as a backdoor. Instead, it’s an unexpected property of the algorithms that can be used to create a clever backdoor. These are wildly different propositions.
At least, that was the case until it was disclosed to NIST in January 2022. 🙂
(I’m including an answer to this question, preemptively, in case someone overreacts when I publish this blog post. I hope it proves unnecessary, but I figured some caution was warranted.)
Mitigation Options
If you care about Key Control Security and use NIST SP 800-108, you should use HMAC or KMAC instead of CMAC. Only CMAC is impacted.
Revision 1 of NIST SP800-108 also outlines another mitigation that involves changing the inputs to include an additional (but reusable) PRF output for every block.
This tweak does change makes the KDF behave more like our intuition for PRFs, but in my opinion it’s better to avoid using CMAC entirely for KDFs.
Why Wasn’t This Widely Publicized?
As interesting and surprising as the loss of Key Control Security in a NIST standard is to cryptography nerds, it’s exactly not like Heartbleed or Log4shell.
That said, regardless of your personal feelings on NIST, if you’re interesting in not having findings like this slip through the cracks in the future, it’s generally worthwhile to pay attention to what NIST is up to.
https://scottarc.blog/2024/06/04/attacking-nist-sp-800-108/
#cybersecurity #framework #KDF #KDFSecurity #KeyDerivationFunctions #NIST #NISTSP800108 #PRFSecurity #security #standards #symmetricCryptography
-
If you’ve never heard of NIST SP 800-108 before, or NIST Special Publications in general, here’s a quick primer:
Special Publications are a type of publication issued by NIST. Specifically, the SP 800-series reports on the Information Technology Laboratory’s research, guidelines, and outreach efforts in computer security, and its collaborative activities with industry, government, and academic organizations. These documents often support FIPS (Federal Information Protection Standards).
Via NIST.gov
One of the NIST 800-series documents concerned with Key Derivation using Pseudorandom Functions is NIST SP 800-108, first published in 2009.
In October 2021, NIST published a draft update to NIST SP 800-108 and opened a comment period until January 2022. This update mostly included Keccak-based Message Authentication Codes (KMAC) in addition to the incumbent standardized designs (HMAC and CMAC).
Upon reviewing a proposal for NIST SP 800-108 revision 1 after its comment period opened, Amazon’s cryptographers discovered a novel security issue with the standard.
I was a co-author of the public comment that disclosed this issue, along with Matthew Campagna, Panos Kampanakis, and Adam Petcher, but take no credit for its discovery.
Consequently, Section 6.7 was added to the final revision 1 of the standard to address Key Control Security.
This post examines the attack against the initial SP 800-108 design when AES-CMAC is used as the PRF in KDF Counter mode.
This meme is the TL;DR of this blog postPreliminaries
(If you’re in a hurry, feel free to skip to the attack.)
NIST SP 800-108 specifies a “KDF in Counter Mode” that can be used with several PRFs, including AES-CMAC. It’s worth noting that this family of KDFs can be defined to use any arbitrary PRF, but only the PRFs approved by NIST for this use are recommended.
AES-CMAC is a one-key CBC-MAC construction. Some cryptographers, such as Matt Green, are famously not fond of CBC-MAC.
KDF Security and PRF Security
Yes, I will take any excuse to turn cryptography knowledge into wholesome memes.KDF stands for “Key Derivation Function”.
PRF stands for “Pseudo-Random Function”.
The security notion for KDF Security is stronger than PRF Security.
PRFs require a uniformly-distributed secret key, while KDFs can tolerate a key that is not uniformly random.
This matters if you’re, say, trying to derive symmetric encryption keys from a Diffie-Hellman shared secret of some sort, where the output of your DH() function has some algebraic structure.
Realistically, the difference between the two security notions matters a lot less in scenarios where you’re deriving sub-keys from a primary uniformly random cryptographic secret.
However, it does make your proofs nicer to achieve KDF security instead of merely PRF security.
Key Control Security
Let’s pretend, for simplicity, we have a generic
KDF()function that offers KDF Security. We don’t need to know how it works just yet.Because KDFs are thought of as PRFs, but stronger, it seems perfectly reasonable that you could use
KDF()in a setup where multiple inputs are provided, each from a different party, and the output would always be uniformly random.Further, even if all other parties’ inputs are known, it should remain computationally infeasible for one of the parties to influence the output of
KDF()to produce a specific value; e.g. a key with all bits zeroed.The assumption that this result is computationally infeasible when working with
KDF()is referred to as “Key Control Security”.Loss of Key Control Security in NIST SP 800-108
You already know where this is going…I’m going to explain the attack by way of example.
If you want a more formal treatment, I believe Appendix B of NIST SP 800-108 rev 1 has what you’re looking for.
Imagine that you’re designing an online two-party private messaging app. To ensure forward secrecy, you implement a forward-secure KDF ratchet, loosely inspired by Signal’s design.
For your KDF, you choose AES-CMAC in Counter Mode, because you’re designing for hardware that has accelerated AES instructions and want to avoid the overhead of hash functions.
(Aside: I guess this would also imply you’re most likely selecting AES-CCM for your actual message encryption.)
With each message, the sender commits some random bytes by encrypting them with their message. The recipient, after verifying the authentication tag and decrypting the message, possess knowledge of the same random bytes.
Both parties then use the random bytes and the current symmetric key to ratchet forward to a new 128-bit symmetric key.
The million dollar question is: Is this ratcheting protocol secure?
In the case of KDF in Counter Mode with AES-CMAC, if you have more than 16 bytes of input material, the answer is simply: No.
How The Attack Works
A two-block implementation of this KDF is normally computed as follows:
- Return
Don’t get intimidated by the notation. This is just AES encryption and XOR.
The messages and are defined in the KDF specification. In the scenario we sketched above, we assume the attacker can choose these arbitrarily.
To coerce a recipient to use an arbitrary 128-bit value (i.e., ) all an attacker needs to do is:
- Calculate
- Let some value
- Here, is the target value.
- Force
Notice that is the result of encrypting , and our attacker’s goal in step 3 can be achieved solely by manipulating (which exists independent of )?
That’s the vulnerability.
The public comments and Appendix B on the NIST document describe the actual steps of computing to force a chosen , which involve manipulating the structure of to achieve this result.
Feel free to check out both documents if you’re interested in the finer details.
What Can An Attacker Actually Do With This?
If an attacker controls both and …
Or if an attacker knows some and can control …
…then they can force the final KDF output to equal whatever 128-bit value they want you to use.
The most straightforward application of the loss of key control security is to introduce a backdoor into an application.
If the Underhanded Crypto Contest were still running this year, NIST SP 800-108 using AES-CMAC in Counter Mode would be an excellent basis for a contestant.
Does Anyone Actually Use NIST SP 800-108 This Way?
I’m not aware of any specific products or services that use this KDF in this way. I will update this section if someone finds any.
Is This A Deliberate Backdoor in a NIST Standard?
No.
I understand that, in the wake of Dual_EC_DRBG, there is a lot of distrust for NIST’s work on standardized cryptography.
However, I have no specific knowledge to indicate this was placed deliberately in the standard.
It is inaccurate to describe the loss of key control security in this context as a backdoor. Instead, it’s an unexpected property of the algorithms that can be used to create a clever backdoor. These are wildly different propositions.
At least, that was the case until it was disclosed to NIST in January 2022. 🙂
(I’m including an answer to this question, preemptively, in case someone overreacts when I publish this blog post. I hope it proves unnecessary, but I figured some caution was warranted.)
Mitigation Options
If you care about Key Control Security and use NIST SP 800-108, you should use HMAC or KMAC instead of CMAC. Only CMAC is impacted.
Revision 1 of NIST SP800-108 also outlines another mitigation that involves changing the inputs to include an additional (but reusable) PRF output for every block.
This tweak does change makes the KDF behave more like our intuition for PRFs, but in my opinion it’s better to avoid using CMAC entirely for KDFs.
Why Wasn’t This Widely Publicized?
As interesting and surprising as the loss of Key Control Security in a NIST standard is to cryptography nerds, it’s exactly not like Heartbleed or Log4shell.
That said, regardless of your personal feelings on NIST, if you’re interesting in not having findings like this slip through the cracks in the future, it’s generally worthwhile to pay attention to what NIST is up to.
https://scottarc.blog/2024/06/04/attacking-nist-sp-800-108/
#cybersecurity #framework #KDF #KDFSecurity #KeyDerivationFunctions #NIST #NISTSP800108 #PRFSecurity #security #standards #symmetricCryptography
-
If you’ve never heard of NIST SP 800-108 before, or NIST Special Publications in general, here’s a quick primer:
Special Publications are a type of publication issued by NIST. Specifically, the SP 800-series reports on the Information Technology Laboratory’s research, guidelines, and outreach efforts in computer security, and its collaborative activities with industry, government, and academic organizations. These documents often support FIPS (Federal Information Protection Standards).
Via NIST.gov
One of the NIST 800-series documents concerned with Key Derivation using Pseudorandom Functions is NIST SP 800-108, first published in 2009.
In October 2021, NIST published a draft update to NIST SP 800-108 and opened a comment period until January 2022. This update mostly included Keccak-based Message Authentication Codes (KMAC) in addition to the incumbent standardized designs (HMAC and CMAC).
Upon reviewing a proposal for NIST SP 800-108 revision 1 after its comment period opened, Amazon’s cryptographers discovered a novel security issue with the standard.
I was a co-author of the public comment that disclosed this issue, along with Matthew Campagna, Panos Kampanakis, and Adam Petcher, but take no credit for its discovery.
Consequently, Section 6.7 was added to the final revision 1 of the standard to address Key Control Security.
This post examines the attack against the initial SP 800-108 design when AES-CMAC is used as the PRF in KDF Counter mode.
This meme is the TL;DR of this blog postPreliminaries
(If you’re in a hurry, feel free to skip to the attack.)
NIST SP 800-108 specifies a “KDF in Counter Mode” that can be used with several PRFs, including AES-CMAC. It’s worth noting that this family of KDFs can be defined to use any arbitrary PRF, but only the PRFs approved by NIST for this use are recommended.
AES-CMAC is a one-key CBC-MAC construction. Some cryptographers, such as Matt Green, are famously not fond of CBC-MAC.
KDF Security and PRF Security
Yes, I will take any excuse to turn cryptography knowledge into wholesome memes.KDF stands for “Key Derivation Function”.
PRF stands for “Pseudo-Random Function”.
The security notion for KDF Security is stronger than PRF Security.
PRFs require a uniformly-distributed secret key, while KDFs can tolerate a key that is not uniformly random.
This matters if you’re, say, trying to derive symmetric encryption keys from a Diffie-Hellman shared secret of some sort, where the output of your DH() function has some algebraic structure.
Realistically, the difference between the two security notions matters a lot less in scenarios where you’re deriving sub-keys from a primary uniformly random cryptographic secret.
However, it does make your proofs nicer to achieve KDF security instead of merely PRF security.
Key Control Security
Let’s pretend, for simplicity, we have a generic
KDF()function that offers KDF Security. We don’t need to know how it works just yet.Because KDFs are thought of as PRFs, but stronger, it seems perfectly reasonable that you could use
KDF()in a setup where multiple inputs are provided, each from a different party, and the output would always be uniformly random.Further, even if all other parties’ inputs are known, it should remain computationally infeasible for one of the parties to influence the output of
KDF()to produce a specific value; e.g. a key with all bits zeroed.The assumption that this result is computationally infeasible when working with
KDF()is referred to as “Key Control Security”.Loss of Key Control Security in NIST SP 800-108
You already know where this is going…I’m going to explain the attack by way of example.
If you want a more formal treatment, I believe Appendix B of NIST SP 800-108 rev 1 has what you’re looking for.
Imagine that you’re designing an online two-party private messaging app. To ensure forward secrecy, you implement a forward-secure KDF ratchet, loosely inspired by Signal’s design.
For your KDF, you choose AES-CMAC in Counter Mode, because you’re designing for hardware that has accelerated AES instructions and want to avoid the overhead of hash functions.
(Aside: I guess this would also imply you’re most likely selecting AES-CCM for your actual message encryption.)
With each message, the sender commits some random bytes by encrypting them with their message. The recipient, after verifying the authentication tag and decrypting the message, possess knowledge of the same random bytes.
Both parties then use the random bytes and the current symmetric key to ratchet forward to a new 128-bit symmetric key.
The million dollar question is: Is this ratcheting protocol secure?
In the case of KDF in Counter Mode with AES-CMAC, if you have more than 16 bytes of input material, the answer is simply: No.
How The Attack Works
A two-block implementation of this KDF is normally computed as follows:
- Return
Don’t get intimidated by the notation. This is just AES encryption and XOR.
The messages and are defined in the KDF specification. In the scenario we sketched above, we assume the attacker can choose these arbitrarily.
To coerce a recipient to use an arbitrary 128-bit value (i.e., ) all an attacker needs to do is:
- Calculate
- Let some value
- Here, is the target value.
- Force
Notice that is the result of encrypting , and our attacker’s goal in step 3 can be achieved solely by manipulating (which exists independent of )?
That’s the vulnerability.
The public comments and Appendix B on the NIST document describe the actual steps of computing to force a chosen , which involve manipulating the structure of to achieve this result.
Feel free to check out both documents if you’re interested in the finer details.
What Can An Attacker Actually Do With This?
If an attacker controls both and …
Or if an attacker knows some and can control …
…then they can force the final KDF output to equal whatever 128-bit value they want you to use.
The most straightforward application of the loss of key control security is to introduce a backdoor into an application.
If the Underhanded Crypto Contest were still running this year, NIST SP 800-108 using AES-CMAC in Counter Mode would be an excellent basis for a contestant.
Does Anyone Actually Use NIST SP 800-108 This Way?
I’m not aware of any specific products or services that use this KDF in this way. I will update this section if someone finds any.
Is This A Deliberate Backdoor in a NIST Standard?
No.
I understand that, in the wake of Dual_EC_DRBG, there is a lot of distrust for NIST’s work on standardized cryptography.
However, I have no specific knowledge to indicate this was placed deliberately in the standard.
It is inaccurate to describe the loss of key control security in this context as a backdoor. Instead, it’s an unexpected property of the algorithms that can be used to create a clever backdoor. These are wildly different propositions.
At least, that was the case until it was disclosed to NIST in January 2022. 🙂
(I’m including an answer to this question, preemptively, in case someone overreacts when I publish this blog post. I hope it proves unnecessary, but I figured some caution was warranted.)
Mitigation Options
If you care about Key Control Security and use NIST SP 800-108, you should use HMAC or KMAC instead of CMAC. Only CMAC is impacted.
Revision 1 of NIST SP800-108 also outlines another mitigation that involves changing the inputs to include an additional (but reusable) PRF output for every block.
This tweak does change makes the KDF behave more like our intuition for PRFs, but in my opinion it’s better to avoid using CMAC entirely for KDFs.
Why Wasn’t This Widely Publicized?
As interesting and surprising as the loss of Key Control Security in a NIST standard is to cryptography nerds, it’s exactly not like Heartbleed or Log4shell.
That said, regardless of your personal feelings on NIST, if you’re interesting in not having findings like this slip through the cracks in the future, it’s generally worthwhile to pay attention to what NIST is up to.
https://scottarc.blog/2024/06/04/attacking-nist-sp-800-108/
#cybersecurity #framework #KDF #KDFSecurity #KeyDerivationFunctions #NIST #NISTSP800108 #PRFSecurity #security #standards #symmetricCryptography
-
I'm excited to announce the release of oct v0.11.0 🚀️
oct is a tool for inspecting, configuring and using #OpenPGP cards 🔒 (https://crates.io/crates/openpgp-card-tools)
oct can now set up cards in #KDF mode, the text output format was improved for readability, and some minor bugs were fixed.
Finally, version 0.11.0 uses #rPGP, a pure #Rust OpenPGP library 🦀.
As a result, the binary on #Linux links to four fewer dynamic libraries, while at the same time being 10% smaller. -
2/ #Prora rechts.
Der Plan war, dass beide Gebäudeteile rechts sein sollten. Das waren Ferienunterkünfte der Organisation #KraftDurchFreude. #KdF
Ein 4,7km langer (!!!) Block.
https://de.wikipedia.org/wiki/Prora
Für 20.000 Nazis. Ist aber nicht rechtzeitig fertig geworden. Dann kam der Krieg und die Gebäude wurden als Kasernen benutzt. Später dann von der #NVA. Bin froh, dass ich nicht da hinmusste.
Balkons waren damals natürlich nicht dran. Die Gebäude sind jetzt saniert worden. Für 20.000 gleiche Menschen.
-
There is, at the time of this writing, an ongoing debate in the Crypto Research Forum Group (CFRG) at the IETF about KEM combiners.
One of the participants, Deirdre Connolly, wrote a blog post titled How to Hold KEMs. The subtitle is refreshingly honest: “A living document on how to juggle these damned things.”
Deirdre also co-authored the paper describing a Hybrid KEM called X-Wing, which combines X25519 with ML-KEM-768 (which is the name for a standardized tweak of Kyber, which I happened to opine on a few years ago).
After sharing a link to Deirdre’s blog in a few places, several friendly folk expressed confusion about KEMs in general.
So very briefly, here’s an introduction to Key Encapsulation Mechanisms in general, to serve as a supplementary resource for any future discussion on KEMs.
You shouldn’t need to understand lattices or number theory, or even how to read a mathematics paper, to understand this stuff.
CMYKatBuilding Intuition for KEMs
For the moment, let’s suspend most real-world security risks and focus on a simplified, ideal setting.
To begin with, you need some kind of Asymmetric Encryption.
Asymmetric Encryption means, “Encrypt some data with a Public Key, then Decrypt the ciphertext with a Secret Key.” You don’t need to know, or even care, about how it works at the moment.
Your mental model for asymmetric encryption and decryption should look like this:
interface AsymmetricEncryption { encrypt(publicKey: CryptoKey, plaintext: Uint8Array); decrypt(secretKey: CryptoKey, ciphertext: Uint8Array);}As I’ve written previously, you never want to actually use asymmetric encryption directly.
Using asymmetric encryption safely means using it to exchange a key used for symmetric data encryption, like so:
// Alice sends an encrypted key to BobsymmetricKey = randomBytes(32)sendToBob = AsymmetricEncryption.encrypt( bobPublicKey, symmetricKey)// Bob decrypts the encrypted key from Alicedecrypted = AsymmetricEncryption.decrypt( bobSecretKey, sendToBob)assert(decrypted == symmetricKey) // true
You can then use
symmetricKeyto encrypt your actual messages and, unless something else goes wrong, only the other party can read them. Hooray!And, ideally, this is where the story would end. Asymmetric encryption is cool. Don’t look at the scroll bar.
CMYKatUnfortunately
The real world isn’t as nice as our previous imagination.
We just kind of hand-waved that asymmetric encryption is a thing that happens, without further examination. It turns out, you have to examine further in order to be secure.
The most common asymmetric encryption algorithm deployed on the Internet as of February 2024 is called RSA. It involves Number Theory. You can learn all about it from other articles if you’re curious. I’m only going to describe the essential facts here.
Keep in mind, the primary motivation for KEMs comes from post-quantum cryptography, not RSA.
CMYKatFrom Textbook RSA to Real World RSA
RSA is what we call a “trapdoor permutation”: It’s easy to compute encryption (one way), but decrypting is only easy if you have the correct secret key (the other way).
RSA operates on large blocks, related to the size of the public key. For example: 2048-bit RSA public keys operate on 2048-bit messages.
Encrypting with RSA involves exponents. The base of these exponents is your message. The outcome of the exponent operation is reduced, using the modulus operator, by the public key.
(The correct terminology is actually slightly different, but we’re aiming for intuition, not technical precision. Your public key is both the large modulus and exponent used for encryption. Don’t worry about it for the moment.)
If you have a very short message, and a tiny exponent (say,
3), you don’t need the secret key to decrypt it. You can just take the cube-root of the ciphertext and recover the message!That’s obviously not very good!
To prevent this very trivial weakness, cryptographers proposed standardized padding schemes to ensure that the output of the exponentiation is always larger than the public key. (We say, “it must wrap the modulus”.)
The most common padding mode is called PKCS#1 v1.5 padding. Almost everything that implements RSA uses this padding scheme. It’s also been publicly known to be insecure since 1998.
The other padding mode, which you should be using (if you even use RSA at all) is called OAEP. However, even OAEP isn’t fool proof: If you don’t implement it in constant-time, your application will be vulnerable to a slightly different attack.
This Padding Stinks; Can We Dispense Of It?
It turns out, yes, we can. Safely, too!
We need to change our relationship with our asymmetric encryption primitive.
Instead of encrypting the secret we actually want to use, let’s just encrypt some very large random value.
Then we can use the result with a Key Derivation Function (which you can think of, for the moment, like a hash function) to derive a symmetric encryption key.
class OversimplifiedKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return [c, kdf(r)] } function decaps(sk: CryptoKey, c: Uint8Array) { let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(r2) }}In the pseudocode above, the actual asymmetric encryption primitive doesn’t involve any sort of padding mode. It’s textbook RSA, or equivalent.
KEMs are generally constructed somewhat like this, but they’re all different in their own special, nuanced ways. Some will look like what I sketched out, others will look subtly different.
Understanding that KEMs are a construction on top of asymmetric encryption is critical to understanding them.
It’s just a slight departure from asymmetric encryption as most developers intuit it.
Cool, we’re almost there.
CMYKatThe one thing to keep in mind: While this transition from Asymmetric Encryption (also known as “Public Key Encryption”) to a Key Encapsulation Mechanism is easy to follow, the story isn’t as simple as “it lets you skip padding”. That’s an RSA specific implementation detail for this specific path into KEMs.
The main thing you get out of KEMs is called IND-CCA security, even when the underlying Public Key Encryption mechanism doesn’t offer that property.
CMYKatIND-CCA security is a formal notion that basically means “protection against an attacker that can alter ciphertexts and study the system’s response, and then learn something useful from that response”.
IND-CCA is short for “indistinguishability under chosen ciphertext attack”. There are several levels of IND-CCA security (1, 2, and 3). Most modern systems aim for IND-CCA2.
Most people reading this don’t have to know or even care what this means; it will not be on the final exam. But cryptographers and their adversaries do care about this.
What Are You Feeding That Thing?
Deirdre’s blog post touched on a bunch of formal security properties for KEMs, which have names like
X-BIND-K-PKorX-BIND-CT-PK.Most of this has to deal with, “What exactly gets hashed in the KEM construction at the KDF step?” (although some properties can hold even without being included; it gets complicated).
For example, from the pseudocode in the previous section, it’s more secure to not only hash
r, but alsocandpk, and any other relevant transcript data.class BetterKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return [c, kdf(pk, c, r)] } function decaps(sk: CryptoKey, c: Uint8Array) { let pk = sk.getPublickey() let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(pk, c, r2) }}In this example,
BetterKemis greatly more secure thanOversimplifiedKEM, for reasons that have nothing to do with the underlying asymmetric primitive. The thing it does better is commit more of its context into the KDF step, which means that there’s less pliability given to attackers while still targeting the same KDF output.If you think about KDFs like you do hash functions (which they’re usually built with), changing any of the values in the transcript will trigger the avalanche effect: The resulting calculation, which is not directly transmitted, is practically indistinguishable from random bytes. This is annoying to try to attack–even with collision attack strategies (birthday collision, Pollard’s rho, etc.).
However, if your hash function is very slow (i.e., SHA3-256), you might be worried about the extra computation and energy expenditure, especially if you’re working with larger keys.
Specifically, the size of keys you get from ML-KEM or other lattice-based cryptography.
That’s where X-Wing is actually very clever: It combines X25519 and ML-KEM-768 in such a way that binds the output to both keys without requiring the additional bytes of ML-KEM-768 ciphertext or public key.
From the X-Wing paper.However, it’s only secure to use it this way because of the specific properties of ML-KEM and X25519.
Some questions may come to mind:
- Does this additional performance hit actually matter, though?
- Would a general purpose KEM combiner be better than one that’s specially tailored to the primitives it uses?
- Is it secure to simply concatenate the output of multiple asymmetric operations to feed into a single KDF, or should a more specialized KDF be defined for this purpose?
Well, that’s exactly what the CFRG is debating!
CMYKatClosing Thoughts
KEMs aren’t nearly as arcane or unapproachable as you may suspect. You don’t really even need to know any of the mathematics to understand them, though it certainly does help.
I hope that others find this useful.
Header art by Harubaki and AJ.
https://soatok.blog/2024/02/26/kem-trails-understanding-key-encapsulation-mechanisms/
#asymmetricCryptography #cryptography #KDF #KEM #keyEncapsulationMechanism #postQuantumCryptography #RSA
-
There is, at the time of this writing, an ongoing debate in the Crypto Research Forum Group (CFRG) at the IETF about KEM combiners.
One of the participants, Deirdre Connolly, wrote a blog post titled How to Hold KEMs. The subtitle is refreshingly honest: “A living document on how to juggle these damned things.”
Deirdre also co-authored the paper describing a Hybrid KEM called X-Wing, which combines X25519 with ML-KEM-768 (which is the name for a standardized tweak of Kyber, which I happened to opine on a few years ago).
After sharing a link to Deirdre’s blog in a few places, several friendly folk expressed confusion about KEMs in general.
So very briefly, here’s an introduction to Key Encapsulation Mechanisms in general, to serve as a supplementary resource for any future discussion on KEMs.
You shouldn’t need to understand lattices or number theory, or even how to read a mathematics paper, to understand this stuff.
CMYKatBuilding Intuition for KEMs
For the moment, let’s suspend most real-world security risks and focus on a simplified, ideal setting.
To begin with, you need some kind of Asymmetric Encryption.
Asymmetric Encryption means, “Encrypt some data with a Public Key, then Decrypt the ciphertext with a Secret Key.” You don’t need to know, or even care, about how it works at the moment.
Your mental model for asymmetric encryption and decryption should look like this:
interface AsymmetricEncryption { encrypt(publicKey: CryptoKey, plaintext: Uint8Array); decrypt(secretKey: CryptoKey, ciphertext: Uint8Array);}As I’ve written previously, you never want to actually use asymmetric encryption directly.
Using asymmetric encryption safely means using it to exchange a key used for symmetric data encryption, like so:
// Alice sends an encrypted key to BobsymmetricKey = randomBytes(32)sendToBob = AsymmetricEncryption.encrypt( bobPublicKey, symmetricKey)// Bob decrypts the encrypted key from Alicedecrypted = AsymmetricEncryption.decrypt( bobSecretKey, sendToBob)assert(decrypted == symmetricKey) // true
You can then use
symmetricKeyto encrypt your actual messages and, unless something else goes wrong, only the other party can read them. Hooray!And, ideally, this is where the story would end. Asymmetric encryption is cool. Don’t look at the scroll bar.
CMYKatUnfortunately
The real world isn’t as nice as our previous imagination.
We just kind of hand-waved that asymmetric encryption is a thing that happens, without further examination. It turns out, you have to examine further in order to be secure.
The most common asymmetric encryption algorithm deployed on the Internet as of February 2024 is called RSA. It involves Number Theory. You can learn all about it from other articles if you’re curious. I’m only going to describe the essential facts here.
From Textbook RSA to Real World RSA
RSA is what we call a “trapdoor permutation”: It’s easy to compute encryption (one way), but decrypting is only easy if you have the correct secret key (the other way).
RSA operates on large blocks, related to the size of the public key. For example: 2048-bit RSA public keys operate on 2048-bit messages.
Encrypting with RSA involves exponents. The base of these exponents is your message. The outcome of the exponent operation is reduced, using the modulus operator, by the public key.
(The correct terminology is actually slightly different, but we’re aiming for intuition, not technical precision. Your public key is both the large modulus and exponent used for encryption. Don’t worry about it for the moment.)
If you have a very short message, and a tiny exponent (say,
3), you don’t need the secret key to decrypt it. You can just take the cube-root of the ciphertext and recover the message!That’s obviously not very good!
To prevent this very trivial weakness, cryptographers proposed standardized padding schemes to ensure that the output of the exponentiation is always larger than the public key. (We say, “it must wrap the modulus”.)
The most common padding mode is called PKCS#1 v1.5 padding. Almost everything that implements RSA uses this padding scheme. It’s also been publicly known to be insecure since 1998.
The other padding mode, which you should be using (if you even use RSA at all) is called OAEP. However, even OAEP isn’t full-proof: If you don’t implement it in constant-time, your application will be vulnerable to a slightly different attack.
This Padding Stinks; Can We Dispense Of It?
It turns out, yes, we can. Safely, too!
We need to change our relationship with our asymmetric encryption primitive.
Instead of encrypting the secret we actually want to use, let’s just encrypt some very large random value.
Then we can use the result with a Key Derivation Function (which you can think of, for the moment, like a hash function) to derive a symmetric encryption key.
class OversimplifiedKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return kdf(r) } function decaps(sk: CryptoKey, c: Uint8Array) { let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(r2) }}In the pseudocode above, the actual asymmetric encryption primitive doesn’t involve any sort of padding mode. It’s textbook RSA, or equivalent.
KEMs are generally constructed somewhat like this, but they’re all different in their own special, nuanced ways. Some will look like what I sketched out, others will look subtly different.
Understanding that KEMs are a construction on top of asymmetric encryption is critical to understanding them.
It’s just a slight departure from asymmetric encryption as most developers intuit it.
Cool, we’re almost there.
CMYKatWhat Are You Feeding That Thing?
Deirdre’s blog post touched on a bunch of formal security properties for KEMs, which have names like
X-BIND-K-PK.Most of this has to deal with, “What exactly gets hashed in the KEM construction at the KDF step?”
For example, from the pseudocode in the previous section, it’s more secure to not only hash
r, but alsocandpk, and any other relevant transcript data.class BetterKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return kdf(pk, c, r) } function decaps(sk: CryptoKey, c: Uint8Array) { let pk = sk.getPublickey() let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(pk, c, r2) }}However, if your hash function is very slow (i.e., SHA3-256), you might be worried about the extra computation and energy expenditure, especially if you’re working with larger keys.
Specifically, the size of keys you get from ML-KEM or other lattice-based cryptography.
That’s where X-Wing is actually very clever: It combines X25519 and ML-KEM-768 in such a way that binds the output to both keys without requiring the additional 2 KB of ML-KEM-768 public key be hashed too.
However, it’s only secure to use it this way because of the specific properties of ML-KEM and X25519.
Some questions may come to mind:
- Does this additional performance hit actually matter, though?
- Would a general purpose KEM combiner be better than one that’s specially tailored to the primitives it uses?
- Is it secure to simply concatenate the output of multiple asymmetric operations to feed into a single KDF, or should a more specialized KDF be defined for this purpose?
Well, that’s exactly what the CFRG is debating!
CMYKatClosing Thoughts
KEMs aren’t nearly as arcane or unapproachable as you may suspect. You don’t really even need to know any of the mathematics to understand them, though it certainly does help.
I hope that others find this useful.
Header art by Harubaki and AJ.
https://soatok.blog/2024/02/26/kem-trails-understanding-key-encapsulation-mechanisms/
#asymmetricCryptography #cryptography #KDF #KEM #keyEncapsulationMechanism #postQuantumCryptography #RSA
-
There is, at the time of this writing, an ongoing debate in the Crypto Research Forum Group (CFRG) at the IETF about KEM combiners.
One of the participants, Deirdre Connolly, wrote a blog post titled How to Hold KEMs. The subtitle is refreshingly honest: “A living document on how to juggle these damned things.”
Deirdre also co-authored the paper describing a Hybrid KEM called X-Wing, which combines X25519 with ML-KEM-768 (which is the name for a standardized tweak of Kyber, which I happened to opine on a few years ago).
After sharing a link to Deirdre’s blog in a few places, several friendly folk expressed confusion about KEMs in general.
So very briefly, here’s an introduction to Key Encapsulation Mechanisms in general, to serve as a supplementary resource for any future discussion on KEMs.
You shouldn’t need to understand lattices or number theory, or even how to read a mathematics paper, to understand this stuff.
CMYKatBuilding Intuition for KEMs
For the moment, let’s suspend most real-world security risks and focus on a simplified, ideal setting.
To begin with, you need some kind of Asymmetric Encryption.
Asymmetric Encryption means, “Encrypt some data with a Public Key, then Decrypt the ciphertext with a Secret Key.” You don’t need to know, or even care, about how it works at the moment.
Your mental model for asymmetric encryption and decryption should look like this:
interface AsymmetricEncryption { encrypt(publicKey: CryptoKey, plaintext: Uint8Array); decrypt(secretKey: CryptoKey, ciphertext: Uint8Array);}As I’ve written previously, you never want to actually use asymmetric encryption directly.
Using asymmetric encryption safely means using it to exchange a key used for symmetric data encryption, like so:
// Alice sends an encrypted key to BobsymmetricKey = randomBytes(32)sendToBob = AsymmetricEncryption.encrypt( bobPublicKey, symmetricKey)// Bob decrypts the encrypted key from Alicedecrypted = AsymmetricEncryption.decrypt( bobSecretKey, sendToBob)assert(decrypted == symmetricKey) // true
You can then use
symmetricKeyto encrypt your actual messages and, unless something else goes wrong, only the other party can read them. Hooray!And, ideally, this is where the story would end. Asymmetric encryption is cool. Don’t look at the scroll bar.
CMYKatUnfortunately
The real world isn’t as nice as our previous imagination.
We just kind of hand-waved that asymmetric encryption is a thing that happens, without further examination. It turns out, you have to examine further in order to be secure.
The most common asymmetric encryption algorithm deployed on the Internet as of February 2024 is called RSA. It involves Number Theory. You can learn all about it from other articles if you’re curious. I’m only going to describe the essential facts here.
Keep in mind, the primary motivation for KEMs comes from post-quantum cryptography, not RSA.
CMYKatFrom Textbook RSA to Real World RSA
RSA is what we call a “trapdoor permutation”: It’s easy to compute encryption (one way), but decrypting is only easy if you have the correct secret key (the other way).
RSA operates on large blocks, related to the size of the public key. For example: 2048-bit RSA public keys operate on 2048-bit messages.
Encrypting with RSA involves exponents. The base of these exponents is your message. The outcome of the exponent operation is reduced, using the modulus operator, by the public key.
(The correct terminology is actually slightly different, but we’re aiming for intuition, not technical precision. Your public key is both the large modulus and exponent used for encryption. Don’t worry about it for the moment.)
If you have a very short message, and a tiny exponent (say,
3), you don’t need the secret key to decrypt it. You can just take the cube-root of the ciphertext and recover the message!That’s obviously not very good!
To prevent this very trivial weakness, cryptographers proposed standardized padding schemes to ensure that the output of the exponentiation is always larger than the public key. (We say, “it must wrap the modulus”.)
The most common padding mode is called PKCS#1 v1.5 padding. Almost everything that implements RSA uses this padding scheme. It’s also been publicly known to be insecure since 1998.
The other padding mode, which you should be using (if you even use RSA at all) is called OAEP. However, even OAEP isn’t fool proof: If you don’t implement it in constant-time, your application will be vulnerable to a slightly different attack.
This Padding Stinks; Can We Dispense Of It?
It turns out, yes, we can. Safely, too!
We need to change our relationship with our asymmetric encryption primitive.
Instead of encrypting the secret we actually want to use, let’s just encrypt some very large random value.
Then we can use the result with a Key Derivation Function (which you can think of, for the moment, like a hash function) to derive a symmetric encryption key.
class OversimplifiedKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return [c, kdf(r)] } function decaps(sk: CryptoKey, c: Uint8Array) { let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(r2) }}In the pseudocode above, the actual asymmetric encryption primitive doesn’t involve any sort of padding mode. It’s textbook RSA, or equivalent.
KEMs are generally constructed somewhat like this, but they’re all different in their own special, nuanced ways. Some will look like what I sketched out, others will look subtly different.
Understanding that KEMs are a construction on top of asymmetric encryption is critical to understanding them.
It’s just a slight departure from asymmetric encryption as most developers intuit it.
Cool, we’re almost there.
CMYKatThe one thing to keep in mind: While this transition from Asymmetric Encryption (also known as “Public Key Encryption”) to a Key Encapsulation Mechanism is easy to follow, the story isn’t as simple as “it lets you skip padding”. That’s an RSA specific implementation detail for this specific path into KEMs.
The main thing you get out of KEMs is called IND-CCA security, even when the underlying Public Key Encryption mechanism doesn’t offer that property.
CMYKatIND-CCA security is a formal notion that basically means “protection against an attacker that can alter ciphertexts and study the system’s response, and then learn something useful from that response”.
IND-CCA is short for “indistinguishability under chosen ciphertext attack”. There are several levels of IND-CCA security (1, 2, and 3). Most modern systems aim for IND-CCA2.
Most people reading this don’t have to know or even care what this means; it will not be on the final exam. But cryptographers and their adversaries do care about this.
What Are You Feeding That Thing?
Deirdre’s blog post touched on a bunch of formal security properties for KEMs, which have names like
X-BIND-K-PKorX-BIND-CT-PK.Most of this has to deal with, “What exactly gets hashed in the KEM construction at the KDF step?” (although some properties can hold even without being included; it gets complicated).
For example, from the pseudocode in the previous section, it’s more secure to not only hash
r, but alsocandpk, and any other relevant transcript data.class BetterKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return [c, kdf(pk, c, r)] } function decaps(sk: CryptoKey, c: Uint8Array) { let pk = sk.getPublickey() let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(pk, c, r2) }}In this example,
BetterKemis greatly more secure thanOversimplifiedKEM, for reasons that have nothing to do with the underlying asymmetric primitive. The thing it does better is commit more of its context into the KDF step, which means that there’s less pliability given to attackers while still targeting the same KDF output.If you think about KDFs like you do hash functions (which they’re usually built with), changing any of the values in the transcript will trigger the avalanche effect: The resulting calculation, which is not directly transmitted, is practically indistinguishable from random bytes. This is annoying to try to attack–even with collision attack strategies (birthday collision, Pollard’s rho, etc.).
However, if your hash function is very slow (i.e., SHA3-256), you might be worried about the extra computation and energy expenditure, especially if you’re working with larger keys.
Specifically, the size of keys you get from ML-KEM or other lattice-based cryptography.
That’s where X-Wing is actually very clever: It combines X25519 and ML-KEM-768 in such a way that binds the output to both keys without requiring the additional bytes of ML-KEM-768 ciphertext or public key.
From the X-Wing paper.However, it’s only secure to use it this way because of the specific properties of ML-KEM and X25519.
Some questions may come to mind:
- Does this additional performance hit actually matter, though?
- Would a general purpose KEM combiner be better than one that’s specially tailored to the primitives it uses?
- Is it secure to simply concatenate the output of multiple asymmetric operations to feed into a single KDF, or should a more specialized KDF be defined for this purpose?
Well, that’s exactly what the CFRG is debating!
CMYKatClosing Thoughts
KEMs aren’t nearly as arcane or unapproachable as you may suspect. You don’t really even need to know any of the mathematics to understand them, though it certainly does help.
I hope that others find this useful.
Header art by Harubaki and AJ.
https://soatok.blog/2024/02/26/kem-trails-understanding-key-encapsulation-mechanisms/
#asymmetricCryptography #cryptography #KDF #KEM #keyEncapsulationMechanism #postQuantumCryptography #RSA
-
There is, at the time of this writing, an ongoing debate in the Crypto Research Forum Group (CFRG) at the IETF about KEM combiners.
One of the participants, Deirdre Connolly, wrote a blog post titled How to Hold KEMs. The subtitle is refreshingly honest: “A living document on how to juggle these damned things.”
Deirdre also co-authored the paper describing a Hybrid KEM called X-Wing, which combines X25519 with ML-KEM-768 (which is the name for a standardized tweak of Kyber, which I happened to opine on a few years ago).
After sharing a link to Deirdre’s blog in a few places, several friendly folk expressed confusion about KEMs in general.
So very briefly, here’s an introduction to Key Encapsulation Mechanisms in general, to serve as a supplementary resource for any future discussion on KEMs.
You shouldn’t need to understand lattices or number theory, or even how to read a mathematics paper, to understand this stuff.
CMYKatBuilding Intuition for KEMs
For the moment, let’s suspend most real-world security risks and focus on a simplified, ideal setting.
To begin with, you need some kind of Asymmetric Encryption.
Asymmetric Encryption means, “Encrypt some data with a Public Key, then Decrypt the ciphertext with a Secret Key.” You don’t need to know, or even care, about how it works at the moment.
Your mental model for asymmetric encryption and decryption should look like this:
interface AsymmetricEncryption { encrypt(publicKey: CryptoKey, plaintext: Uint8Array); decrypt(secretKey: CryptoKey, ciphertext: Uint8Array);}As I’ve written previously, you never want to actually use asymmetric encryption directly.
Using asymmetric encryption safely means using it to exchange a key used for symmetric data encryption, like so:
// Alice sends an encrypted key to BobsymmetricKey = randomBytes(32)sendToBob = AsymmetricEncryption.encrypt( bobPublicKey, symmetricKey)// Bob decrypts the encrypted key from Alicedecrypted = AsymmetricEncryption.decrypt( bobSecretKey, sendToBob)assert(decrypted == symmetricKey) // true
You can then use
symmetricKeyto encrypt your actual messages and, unless something else goes wrong, only the other party can read them. Hooray!And, ideally, this is where the story would end. Asymmetric encryption is cool. Don’t look at the scroll bar.
CMYKatUnfortunately
The real world isn’t as nice as our previous imagination.
We just kind of hand-waved that asymmetric encryption is a thing that happens, without further examination. It turns out, you have to examine further in order to be secure.
The most common asymmetric encryption algorithm deployed on the Internet as of February 2024 is called RSA. It involves Number Theory. You can learn all about it from other articles if you’re curious. I’m only going to describe the essential facts here.
Keep in mind, the primary motivation for KEMs comes from post-quantum cryptography, not RSA.
CMYKatFrom Textbook RSA to Real World RSA
RSA is what we call a “trapdoor permutation”: It’s easy to compute encryption (one way), but decrypting is only easy if you have the correct secret key (the other way).
RSA operates on large blocks, related to the size of the public key. For example: 2048-bit RSA public keys operate on 2048-bit messages.
Encrypting with RSA involves exponents. The base of these exponents is your message. The outcome of the exponent operation is reduced, using the modulus operator, by the public key.
(The correct terminology is actually slightly different, but we’re aiming for intuition, not technical precision. Your public key is both the large modulus and exponent used for encryption. Don’t worry about it for the moment.)
If you have a very short message, and a tiny exponent (say,
3), you don’t need the secret key to decrypt it. You can just take the cube-root of the ciphertext and recover the message!That’s obviously not very good!
To prevent this very trivial weakness, cryptographers proposed standardized padding schemes to ensure that the output of the exponentiation is always larger than the public key. (We say, “it must wrap the modulus”.)
The most common padding mode is called PKCS#1 v1.5 padding. Almost everything that implements RSA uses this padding scheme. It’s also been publicly known to be insecure since 1998.
The other padding mode, which you should be using (if you even use RSA at all) is called OAEP. However, even OAEP isn’t fool proof: If you don’t implement it in constant-time, your application will be vulnerable to a slightly different attack.
This Padding Stinks; Can We Dispense Of It?
It turns out, yes, we can. Safely, too!
We need to change our relationship with our asymmetric encryption primitive.
Instead of encrypting the secret we actually want to use, let’s just encrypt some very large random value.
Then we can use the result with a Key Derivation Function (which you can think of, for the moment, like a hash function) to derive a symmetric encryption key.
class OversimplifiedKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return [c, kdf(r)] } function decaps(sk: CryptoKey, c: Uint8Array) { let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(r2) }}In the pseudocode above, the actual asymmetric encryption primitive doesn’t involve any sort of padding mode. It’s textbook RSA, or equivalent.
KEMs are generally constructed somewhat like this, but they’re all different in their own special, nuanced ways. Some will look like what I sketched out, others will look subtly different.
Understanding that KEMs are a construction on top of asymmetric encryption is critical to understanding them.
It’s just a slight departure from asymmetric encryption as most developers intuit it.
Cool, we’re almost there.
CMYKatThe one thing to keep in mind: While this transition from Asymmetric Encryption (also known as “Public Key Encryption”) to a Key Encapsulation Mechanism is easy to follow, the story isn’t as simple as “it lets you skip padding”. That’s an RSA specific implementation detail for this specific path into KEMs.
The main thing you get out of KEMs is called IND-CCA security, even when the underlying Public Key Encryption mechanism doesn’t offer that property.
CMYKatIND-CCA security is a formal notion that basically means “protection against an attacker that can alter ciphertexts and study the system’s response, and then learn something useful from that response”.
IND-CCA is short for “indistinguishability under chosen ciphertext attack”. There are several levels of IND-CCA security (1, 2, and 3). Most modern systems aim for IND-CCA2.
Most people reading this don’t have to know or even care what this means; it will not be on the final exam. But cryptographers and their adversaries do care about this.
What Are You Feeding That Thing?
Deirdre’s blog post touched on a bunch of formal security properties for KEMs, which have names like
X-BIND-K-PKorX-BIND-CT-PK.Most of this has to deal with, “What exactly gets hashed in the KEM construction at the KDF step?” (although some properties can hold even without being included; it gets complicated).
For example, from the pseudocode in the previous section, it’s more secure to not only hash
r, but alsocandpk, and any other relevant transcript data.class BetterKEM { function encaps(pk: CryptoKey) { let N = pk.getModulus() let r = randomNumber(1, N-1) let c = AsymmetricEncryption.encrypt(pk, r) return [c, kdf(pk, c, r)] } function decaps(sk: CryptoKey, c: Uint8Array) { let pk = sk.getPublickey() let r2 = AsymmetricEncryption.decrypt(sk, c) return kdf(pk, c, r2) }}In this example,
BetterKemis greatly more secure thanOversimplifiedKEM, for reasons that have nothing to do with the underlying asymmetric primitive. The thing it does better is commit more of its context into the KDF step, which means that there’s less pliability given to attackers while still targeting the same KDF output.If you think about KDFs like you do hash functions (which they’re usually built with), changing any of the values in the transcript will trigger the avalanche effect: The resulting calculation, which is not directly transmitted, is practically indistinguishable from random bytes. This is annoying to try to attack–even with collision attack strategies (birthday collision, Pollard’s rho, etc.).
However, if your hash function is very slow (i.e., SHA3-256), you might be worried about the extra computation and energy expenditure, especially if you’re working with larger keys.
Specifically, the size of keys you get from ML-KEM or other lattice-based cryptography.
That’s where X-Wing is actually very clever: It combines X25519 and ML-KEM-768 in such a way that binds the output to both keys without requiring the additional bytes of ML-KEM-768 ciphertext or public key.
From the X-Wing paper.However, it’s only secure to use it this way because of the specific properties of ML-KEM and X25519.
Some questions may come to mind:
- Does this additional performance hit actually matter, though?
- Would a general purpose KEM combiner be better than one that’s specially tailored to the primitives it uses?
- Is it secure to simply concatenate the output of multiple asymmetric operations to feed into a single KDF, or should a more specialized KDF be defined for this purpose?
Well, that’s exactly what the CFRG is debating!
CMYKatClosing Thoughts
KEMs aren’t nearly as arcane or unapproachable as you may suspect. You don’t really even need to know any of the mathematics to understand them, though it certainly does help.
I hope that others find this useful.
Header art by Harubaki and AJ.
https://soatok.blog/2024/02/26/kem-trails-understanding-key-encapsulation-mechanisms/
#asymmetricCryptography #cryptography #KDF #KEM #keyEncapsulationMechanism #postQuantumCryptography #RSA
-
Ever wondered how @bitwarden keeps your passwords safe? It's all about Key Derivation Functions (#KDF), turning your master password into a secure encryption key.
Account Settings -> Security -> Keys
-
Sollte der Antrieb mit Ferromagneten gebaut sein, könnte die #Magnetschwebebahn #Berlin als "Kraftverkehr durch Ferromagneten" (kurz: #KdF) bezeichnet werden.
Ich schlage zudem eine Strecke Richtung #Olympiastadion vor, wo dann 2036 glorreiche olympische Sommerspiele stattfinden können.
-
-
This one, like last time, skip to the jam please #KDF #phish #jamdevilfalls
-
Tails - Weak cryptographic parameters in LUKS1 https://tails.boum.org/security/argon2id/index.en.html #cryptsetup #parameter #dm-crypt #argon2id #weakness #crypto #pbkdf2 #tails #luks #kdf
-
@Ihazchaos Hey Terri, zu dem Thema LUKS hat mein @ct_Magazin-Kollege Sylvester Tremmel (@syt) was auf @heiseonline geschrieben.
-
Many of you have been asking for my thoughts on the #LastPass breach, and I apologize that I'm a couple days late delivering.
Apart from all of the other commentary out there, here's what you need to know from a #password cracker's perspective!
Your vault is encrypted with #AES256 using a key that is derived from your master password, which is hashed using a minimum of 100,100 rounds of PBKDF2-HMAC-SHA256 (can be configured to use more rounds, but most people don't). #PBKDF2 is the minimum acceptable standard in key derivation functions (KDFs); it is compute-hard only and fits entirely within registers, so it is highly amenable to acceleration. However, it is the only #KDF that is FIPS/NIST approved, so it's the best (or only) KDF available to many applications. So while there are LOTS of things wrong with LastPass, key derivation isn't necessarily one of them.
Using #Hashcat with the top-of-the-line RTX 4090, you can crack PBKDF2-HMAC-SHA256 with 100,100 rounds at about 88 KH/s. At this speed an attacker could test ~7.6 billion passwords per day, which may sound like a lot, but it really isn't. By comparison, the same GPU can test Windows NT hashes at a rate of 288.5 GH/s, or ~25 quadrillion passwords per day. So while LastPass's hashing is nearly two orders of magnitude faster than the < 10 KH/s that I recommend, it's still more than 3 million times slower than cracking Windows/Active Directory passwords. In practice, it would take you about 3.25 hours to run through rockyou.txt + best64.rule, and a little under two months to exhaust rockyou.txt + rockyou-30000.rule.
Keep in mind these are the speeds for cracking a single vault; for an attacker to achieve this speed, they would have to single out your vault and dedicate their resources to cracking only your vault. If they're trying 1,000 vaults simultaneously, the speed would drop to just 88 H/s. With 1 million vaults, the speed drops to an abysmal 0.088 H/s, or 11.4 seconds to test just one password. Practically speaking, what this means is the attackers will target four groups of users:
1. users for which they have previously-compromised passwords (password reuse, credential stuffing)
2. users with laughably weak master passwords (think top20k)
3. users they can phish
4. high value targets (celebs, .gov, .mil, fortune 100)If you are not in this list / you don't get phished, then it is highly unlikely your vault will be targeted. And due to the fairly expensive KDF, even passwords of moderate complexity should be safe.
I've seen several people recommend changing your master password as a mitigation for this breach. While changing your master password will help mitigate future breaches should you continue to use LastPass (you shouldn't), it does literally nothing to mitigate this current breach. The attacker has your vault, which was encrypted using a key derived from your master password. That's done, that's in the past. Changing your password will re-encrypt your vault with the new password, but of course it won't re-encrypt the copy of the vault the attacker has with your new password. That would be impossible unless you somehow had access to the attacker's copy of the vault, which if you do, please let me know?
A proper mitigation would be to migrate to #Bitwarden or #1Password, change the passwords for each of your accounts as you migrate over, and also review the MFA status of each of your accounts as well. The perfect way to spend your holiday vacation! Start the new year fresh with proper password hygiene.
For more password insights like this, give me a follow!
-
High @sc00bz and @epixoip, I recently came across your recommendations not to (blindly) use #Argon2 as a #PHF (but it's a good #KDF) due to this requiring runtimes that make it (usually) inapplicable for password hashing. Or, phrased differently, would require lowering security parameters in order to stay performant, that the security of the hashing would be compromised.
The #Bcrypt article on Wikipedia put forth a similar claim but without any citations and phrased a bit misleading (IMO). I've adjusted the article and added two citations. If you have time, I'd be glad if you could give some feedback on this, as there are only few citable sources on this and I'm by far no expert on the matter:
https://en.wikipedia.org/w/index.php?title=Bcrypt&diff=prev&oldid=1157855165
Thank you!
-
adieu, christian! möge es Dir gutgehen, wo auch immer Du jetzt bist. 🖤 #KdF
-
Little Man 1 is going on an Orchestra/Band trip to Chicago this weekend. So I told him he should take a Pegasus Pin for Derby spirit.
I unpeeled the envelope and saw a gold Pegasus Pin for the first time ever in the wild.
Winner = you can register for a special grand prize drawing. No more instant winners like the 20th century era.
-
@epixoip btw. #Bitwarden uses the same #KDF but has the advantage of self-hosting. So a breach to Bitwardens infrastructure would not leak self-hosted instances.
-
What is #HEMA?
5/6But it's not all #KdF. There were others like #Fiore de'i Liberi, who wrote the #FlosDuellatorum (#FlowerOfBattle), where he explores basically the same weapons, but with a different style.
In the following centuries we have a bunchload of treatises: #saber and #smallsword from the napoleonic era, #staff and pole weapon systems from the late middle ages, #rapier from the Iberian and Italian, #boxing and #bartitsu from the late victorian Britain... take your pick.