RFC 8645
Re-keying Mechanisms for Symmetric Keys
Re-keying Mechanisms for Symmetric Keys ๐
Part 1 of 13
Title block tea โ: This one is from the Internet Research Task Force (IRTF), with S. Smyshlyaev, Ed. (from CryptoPro) as the editor. It's RFC 8645, the category is Informational, and it was published in August 2019. The ISSN is 2070-1721. It doesn't obsolete or update any other RFCs, so it's just here doing its own thing ๐
Abstract โจ
okay so bestie, every key has a limit on how much data you can safely encrypt with it before things start getting risky ๐ญ That limit is called the "key lifetime" ๐ This spec is all about ways to make that lifetime longer! It gives us two kinds of re-keying mechanisms, one based on hash functions and one based on block ciphers, and they play nicely with modes like CTR, GCM, CBC, CFB, and OMAC ๐ฆ
This doc is a product of the Crypto Forum Research Group (CFRG) in the IRTF, so the crypto nerds really cooked here ๐ฅ
Status of This Memo ๐ธ
Real talk: this is not an Internet Standards Track spec. It's published just for information ๐
It's a product of the Internet Research Task Force (IRTF), which shares Internet-related research and development results. Those results might not be ready for deployment, so don't just yolo them into production ๐ This RFC represents the consensus of the Crypto Forum Research Group of the IRTF. Documents approved for publication by the IRSG are not candidates for any level of Internet Standard, see Section 2 of RFC 7841 ๐ง
If you want the latest status, errata, or a way to send feedback, check https://www.rfc-editor.org/info/rfc8645 ๐
Copyright Notice ๐
Copyright (c) 2019 IETF Trust and the persons identified as the document authors. All rights reserved. ๐
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they are in effect on the date this document was published. Please read these carefully, bestie, because they spell out your rights and restrictions for this document ๐ซถ
Table of Contents ๐ง
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Conventions Used in This Document . . . . . . . . . . . . . . 7
3. Basic Terms and Definitions . . . . . . . . . . . . . . . . . 7
4. Choosing Constructions and Security Parameters . . . . . . . 9
5. External Re-keying Mechanisms . . . . . . . . . . . . . . . . 11
5.1. Methods of Key Lifetime Control . . . . . . . . . . . . . 14
5.2. Parallel Constructions . . . . . . . . . . . . . . . . . 14
5.2.1. Parallel Construction Based on a KDF on a Block
Cipher . . . . . . . . . . . . . . . . . . . . . . . 15
5.2.2. Parallel Construction Based on a KDF on a Hash
Function . . . . . . . . . . . . . . . . . . . . . . 16
5.2.3. Tree-Based Construction . . . . . . . . . . . . . . . 16
5.3. Serial Constructions . . . . . . . . . . . . . . . . . . 17
5.3.1. Serial Construction Based on a KDF on a Block Cipher 19
5.3.2. Serial Construction Based on a KDF on a Hash Function 19
5.4. Using Additional Entropy during Re-keying . . . . . . . . 19
6. Internal Re-keying Mechanisms . . . . . . . . . . . . . . . . 20
6.1. Methods of Key Lifetime Control . . . . . . . . . . . . . 22
6.2. Constructions that Do Not Require a Master Key . . . . . 23
6.2.1. ACPKM Re-keying Mechanisms . . . . . . . . . . . . . 23
6.2.2. CTR-ACPKM Encryption Mode . . . . . . . . . . . . . . 25
6.2.3. GCM-ACPKM Authenticated Encryption Mode . . . . . . . 26
6.3. Constructions that Require a Master Key . . . . . . . . . 29
6.3.1. ACPKM-Master Key Derivation from the Master Key . . . 29
6.3.2. CTR-ACPKM-Master Encryption Mode . . . . . . . . . . 31
6.3.3. GCM-ACPKM-Master Authenticated Encryption Mode . . . 33
6.3.4. CBC-ACPKM-Master Encryption Mode . . . . . . . . . . 37
6.3.5. CFB-ACPKM-Master Encryption Mode . . . . . . . . . . 39
6.3.6. OMAC-ACPKM-Master Authentication Mode . . . . . . . . 40
7. Joint Usage of External and Internal Re-keying . . . . . . . 42
8. Security Considerations . . . . . . . . . . . . . . . . . . . 43
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 43
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 44
10.1. Normative References . . . . . . . . . . . . . . . . . . 44
10.2. Informative References . . . . . . . . . . . . . . . . . 45
Appendix A. Test Examples . . . . . . . . . . . . . . . . . . . 48
A.1. Test Examples for External Re-keying . . . . . . . . . . 48
A.1.1. External Re-keying with a Parallel Construction . . . 48
A.1.2. External Re-keying with a Serial Construction . . . . 49
A.2. Test Examples for Internal Re-keying . . . . . . . . . . 52
A.2.1. Internal Re-keying Mechanisms that Do Not
Require a Master Key . . . . . . . . . . . . . . . . 52
A.2.2. Internal Re-keying Mechanisms with a Master Key . . . 56
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 69
Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 69
Part 1 is done, and the actual technical stuff starts in Section 1, Introduction ๐
1. Introduction โจ
okay bestie, let's talk about key lifetime ๐. It's the max amount of data you can safely encrypt under a single key before things start getting risky. We call it the "key lifetime" ๐ , and it exists because of three kinds of cryptanalysis (fancy codebreaking ๐ต๏ธโโ๏ธ):
- Methods based on the combinatorial properties of the used block cipher mode of operation
These don't care what the underlying block cipher is ๐. The mode restrictions that come out of them are of order 2^{n/2}, where n is the block size defined in Section 3. [Sweet32] has an attack example built on this kind of method, and it's giving scary ๐.
- Methods based on side-channel analysis issues
These mostly don't care about the encryption mode, and they only weakly depend on the cipher's features. The limits from these are usually the strictest ones ๐ญ. [TEMPEST] is an example of an attack based on these methods.
- Methods based on the properties of the used block cipher
The big ones here are linear and differential cryptanalysis [LDC]. Mostly these don't depend on the modes of operation either. For secure block ciphers, the bounds from these methods are roughly the same as the natural bounds of 2^n, and they're dominated by the other bounds above ๐ธ. So we can leave them out of the considerations here.
So the vibe is: replace your key ๐ when the total size of the processed plaintext under that key starts getting close to the lifetime limit. The exact key lifetime value should be set with some safety margin for protocol security and the methods above ๐ซถ.
Let's say L is a key lifetime limit in some protocol P. To keep it simple, assume every message has the same length m. That means the number of messages q you can process with one key K should satisfy m * q <= L โจ. You can picture it as a rectangle with sides m and q sitting inside an area L (see Figure 1) ๐ฆ.
+------------------------+
| L |
| +--------m---------+ |
| |==================| |
| |==================| |
| q==================| | m * q <= L
| |==================| |
| |==================| |
| +------------------+ |
+------------------------+
Figure 1: Graphic Display of the Key Lifetime Limitation
In real life, the amount of data that fits under limit L might not be enough ๐ฉ. The simplest, most obvious fix is to regularly renegotiate an initial key once you've processed that threshold amount of data. The catch is that it kills performance, since it usually means stopping application data transmission, sending extra service messages, using a random number generator, and lots of other extra calculations, including resource-intensive public key cryptography ๐.
For protocols built on block ciphers or stream ciphers, a more efficient way to stretch the key lifetime is to use various re-keying mechanisms ๐ง. This specification only looks at re-keying mechanisms for block ciphers. The re-keying mechanisms typical for stream ciphers (e.g., [Pietrzak2009], [FPS2012]) are out of scope for this document.
Re-keying mechanisms can show up at different protocol levels: the block cipher level (this is called fresh re-keying and is described, for instance, in [FRESHREKEYING]), the block cipher mode of operation level (see Section 6), and the protocol level above the block cipher mode of operation (see Section 5). The first approach is highly inefficient, because the key changes after every single message block is processed ๐ฅด. On top of that, fresh re-keying mechanisms can change the block cipher's internal structure, which can mean extra security analysis for each particular block cipher ๐. So this approach depends on particular primitive properties and can't just be slapped onto any arbitrary block cipher without additional security analysis. That's why fresh re-keying mechanisms are beyond the scope of this document.
So this document is basically a list of recommended re-keying mechanisms you can use in symmetric encryption schemes based on block ciphers ๐. These mechanisms are independent of the particular block cipher specification, and their security properties rely only on the standard block cipher security assumption ๐.
This specification presents two basic approaches to extending the lifetime of a key without renegotiating, which were introduced in [AAOS2017]:
- External re-keying
External re-keying is done by a protocol, and it's independent of the underlying block cipher and the mode of operation ๐
. It can use parallel and serial constructions. In the parallel case, data processing keys K^1, K^2, ... are generated directly from the initial key K, independently of each other. In the serial case, every data-processing key depends on the state that gets updated after each new data-processing key is generated ๐.
As a generalization of external parallel re-keying, you can consider an external tree-based mechanism. It's specified in Section 5.2.3 and can be seen as the tree generalization in [GGM]. Similar constructions show up in the one-way tree mechanism ([OWT]) and the [AESDUKPT] standard ๐ณ.
- Internal re-keying
Internal re-keying is built right into the mode, and it depends heavily on the properties of the mode of operation and the block size ๐งฉ.
Both approaches stretch the key lifetime for a single initial key by limiting leakages (via side channels) and by improving the combinatorial properties of the block cipher mode of operation you're using ๐.
In practice, re-keying is useful for protocols that have to run in hostile environments or under restricted resource conditions. Think lightweight cryptography, where ciphers have a small block size that brings strict combinatorial limits ๐ฃ. Mechanisms that use external or internal re-keying can also help protect against possible future attacks (by limiting how many plaintext-ciphertext pairs an adversary can collect) and give some forward or backward security properties. That means past or future data-processing keys stay secure even if the current key gets compromised (see [AbBell] for more details) ๐ก๏ธ. External or internal re-keying can be used in network protocols, and also in systems for data-at-rest encryption ๐พ.
Depending on the protocol, there might be situations where both external and internal re-keying mechanisms (see Section 7) can be applied ๐ช. For example, a similar approach was used in Taha's tree construction (see [TAHA]) ๐ฟ.
Now, there are key-updating (key regression) algorithms (e.g., [FKK2005] and [KMNT2003]) that also get called "re-keying" ๐. But they're going after goals other than extending the key lifetime, so key regression algorithms are excluded from the considerations here.
This document represents the consensus of the Crypto Forum Research Group (CFRG) ๐ซถ๐ธ.
2. Conventions Used in This Document
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here ๐โจ.
3. Basic Terms and Definitions
Okay, this part is the glossary ๐, so let's get the sets and operations straight. This document uses the following terms and definitions for the sets and operations on the elements of these sets ๐:
V* the set of all bit strings of a finite length (hereinafter
referred to as strings), including the empty string;
V_s the set of all bit strings of length s, where s is a
non-negative integer;
|X| the bit length of the bit string X;
A | B the concatenation of strings A and B both belonging to V*,
i.e., a string in V_{|A|+|B|}, where the left substring in
V_|A| is equal to A and the right substring in V_|B| is equal
to B;
(xor) the exclusive-or of two bit strings of the same length;
Z_{2^n} the ring of residues modulo 2^n;
Int_s: V_s -> Z_{2^s}
the transformation that maps the string a = (a_s, ... , a_1)
in V_s into the integer Int_s(a) = 2^{s-1} * a_s + ... + 2 *
a_2 + a_1 (the interpretation of the binary string as an
integer);
Vec_s: Z_{2^s} -> V_s
the transformation inverse to the mapping Int_s (the
interpretation of an integer as a binary string);
MSB_i: V_s -> V_i
the transformation that maps the string a = (a_s, ... , a_1)
in V_s into the string MSB_i(a) = (a_s, ... , a_{s-i+1}) in
V_i (most significant bits);
LSB_i: V_s -> V_i
the transformation that maps the string a = (a_s, ... , a_1)
in V_s into the string LSB_i(a) = (a_i, ... , a_1) in V_i
(least significant bits);
Inc_c: V_s -> V_s
the transformation that maps the string a = (a_s, ... , a_1)
in V_s into the string Inc_c(a) = MSB_{|a|-c}(a) |
Vec_c(Int_c(LSB_c(a)) + 1(mod 2^c)) in V_s (incrementing the
least significant c bits of the bit string, regarded as the
binary representation of an integer);
a^s the string in V_s that consists of s 'a' bits;
E_{K}: V_n -> V_n
the block cipher permutation under the key K in V_k;
ceil(x) the smallest integer that is greater than or equal to x;
floor(x)
the biggest integer that is less than or equal to x;
k the bit length of the K; k is assumed to be divisible by 8;
n the block size of the block cipher (in bits); n is assumed to
be divisible by 8;
b the number of data blocks in the plaintext P (b =
ceil(|P|/n));
N the section size (the number of bits that are processed with
one section key before this key is transformed).
Last but not least, the plaintext message P and its ciphertext C get split into b = ceil(|P|/n) blocks ๐ง. We write them as P = P_1 | P_2 | ... | P_b and C = C_1 | C_2 | ... | C_b. The first b-1 blocks P_i and C_i are in V_n for i = 1, 2, ... , b-1. The last blocks P_b and C_b might be incomplete, meaning they're in V_r, where r <= n, unless specified otherwise ๐
โจ.
4. Choosing Constructions and Security Parameters โจ
okay so external re-keying is when a key gets transformed after you've encrypted a limited number of entire messages ๐. the method gets picked at the protocol level, no matter which block cipher or encryption mode you're using ๐ . it's recommended for protocols that handle relatively short messages, or protocols that can chop a long message into manageable pieces ๐งฉ. with external re-keying, the number of messages you can securely process under a single initial key K goes up way more, and you don't lose any message length ๐ธ
External re-keying has the following advantages:
- It increases the lifetime of an initial key by increasing the number of messages processed with this key.
- It has minimal impact on performance when the number of messages processed under one initial key is sufficiently large.
- It provides forward and backward security of data-processing keys.
However, there's a catch ๐ with restrictive key lifetime limits, the message sizes can get in the way, because you can't process really big messages. so you might need to do extra fragmentation at the protocol level. for example, if the key lifetime L is 1 GB and the message length m = 3 GB, then that message can't be processed as a whole, and it should be split into three fragments that get processed separately ๐
Internal re-keying is when a key gets transformed during each separate message being processed ๐ฆ. these procedures are built right into the base modes of operation, so every internal re-keying mechanism is defined for the particular operation mode and the block size of the cipher being used. internal re-keying is recommended for protocols that process long messages. the size of each single message can get way bigger without losing anything in how many messages you can securely process under one initial key ๐
Internal re-keying has the following advantages:
- It increases the lifetime of an initial key by increasing the size of the messages processed with one initial key.
- It has minimal impact on performance.
- Internal re-keying mechanisms without a master key do not affect short-message transformation at all.
- It is transparent (works like any mode of operation): it does not require changes of initialization vectors (IVs) and a restart of MACing.
Internal re-keying has the following disadvantages:
- a specific method must not be chosen independently of a mode of operation.
- internal re-keying mechanisms without a master key do not provide backward security of data-processing keys.
Any block cipher modes of operation with internal re-keying can be jointly used with any external re-keying mechanisms. that combo boosts both the number of messages processed with one initial key and their maximum possible size ๐ฅ
If the adversary has access to the data-processing interface, using the same cryptographic primitives for both data processing and re-keying transformation shrinks the code size, but it can lead to some possible vulnerabilities ๐ญ (mounting a chosen-plaintext attack may lead to the compromise of the following keys). the fix is to use different primitives for data processing and re-keying, e.g., a block cipher for data processing and a hash for re-keying (see Section 5.2.2 and Section 5.3.2). but then the security of the whole scheme can't be reduced to standard notions like a pseudorandom function (PRF) or pseudorandom permutation (PRP), so security estimates get harder and way less clear ๐
Summing up the issues above, briefly:
- If a protocol assumes processing of long records (e.g., [CMS]), internal re-keying should be used. If a protocol assumes processing of a significant number of ordered records, which can be considered as a single data stream (e.g., [TLS], [SSH]), internal re-keying may also be used.
- For protocols that allow out-of-order delivery and lost records (e.g., [DTLS], [ESP]), external re-keying should be used, because in this case, records cannot be considered as a single data stream. If the records are also long enough, internal re-keying should also be used during each separate message processing.
For external re-keying:
- If it is desirable to separate transformations used for data processing and key updates, hash function-based re-keying should be used.
- If parallel data processing is required, then parallel external re-keying should be used.
- If restrictive key lifetime limitations are present, external tree-based re-keying should be used.
For internal re-keying:
- If the property of forward and backward security is desirable for data-processing keys, and if additional key material can be easily obtained for the data-processing stage, internal re-keying with a master key should be used.
5. External Re-keying Mechanisms ๐
this section is all about boosting the initial key lifetime by transforming a data-processing key (the frame key) after a limited number of entire messages (frames) get processed ๐ง. the approach gives you external parallel and serial re-keying mechanisms (see [AbBell]). these mechanisms only use the initial key K to generate frame keys, and they never use it directly for data processing. they run outside the base modes of operation and don't change them at all, which is why this document calls them "external re-keying" mechanisms โจ
External re-keying mechanisms are recommended for protocols that process quite small messages, since the biggest gain in initial key lifetime comes from having more messages ๐
here's how external re-keying stretches the initial key lifetime. say there's a protocol P with some mode of operation (a base encryption or authentication mode). let L1 be a key lifetime limit set by side-channel analysis methods (the side-channel limitation), let L2 be a key lifetime limit set by methods based on the combinatorial properties of the mode of operation being used (the combinatorial limitation), and let q1, q2 be the total numbers of messages of length m that can safely be processed with an initial key K under these limits, respectively ๐
Let L = min(L1, L2), q = min(q1, q2), and q * m <= L. since the L1 limit is usually way stricter than the L2 limit (L1 < L2), the final key lifetime restriction is basically the most restrictive limit, L1. so, as Figure 2 shows, without re-keying you can only safely process q1 messages (q1 * m <= L1) ๐ซถ
<--------m------->
+----------------+ ^ ^
|================| | |
|================| | |
K-->|================| q1|
|================| | |
|==============L1| | |
+----------------+ v |
| | |
| | |
| | q2
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| L2| |
+----------------+ v
Figure 2: Basic Principles of Message Processing without External Re-keying
Suppose the safety margin for protocol P is fixed, and the external re-keying approach is applied to the initial key K to generate a sequence of frame keys. the frame keys get generated so that leaking a previous frame key has no impact on the next one, which means the side-channel limitation L1 is switched off ๐ฆ. that means the resulting key lifetime limit for the initial key K can be worked out from a new combinatorial limitation, L2'. it's proven (see [AbBell]) that the security of a mode of operation using external re-keying goes up compared to the base mode without re-keying (so, L2 < L2'). therefore, as Figure 3 shows, the resulting key lifetime limit with external re-keying can be pushed up to L2' ๐
<--------m------->
K +----------------+
| |================|
v |================|
K^1--> |================|
| |================|
| |==============L1|
| +----------------+
| |================|
v |================|
K^2--> |================|
| |================|
| |==============L1|
| +----------------+
| |================|
v |================|
... | . . . |
| |
| |
| L2|
+----------------+
| |
... ...
| L2'|
+----------------+
Figure 3: Basic Principles of Message Processing with External Re-keying
Note: The key transformation process is shown in a simplified form. A specific approach (parallel and serial) is described below.
Let's look at an example ๐ Say the message size in protocol P is 1 KB. Suppose L1 = 128 MB and L2 = 1 TB. so, without an external re-keying mechanism, the initial key K has to be renegotiated after processing 128 MB / 1 KB = 131072 messages.
With an external re-keying mechanism, the key lifetime limit L1 goes off. so the resulting key lifetime limit L2' can be set to more than 1 TB ๐ธ That means that with external re-keying, more than 1 TB / 1 KB = 2^30 messages can be processed before the initial key K gets renegotiated. that's 8192 times more messages than you can process without an external re-keying mechanism ๐
5.1. Methods of Key Lifetime Control ๐
okay so, imagine L is how much data you can safely push through with one frame key ๐. For i in {1, 2, ... , t}, the frame key K^i (check Figures 4 and 6 ๐ ) should get swapped out after it's handled q_i messages. And q_i can be worked out with one of these three approaches ๐
Explicit approach:
q_i is such that |M^{i,1}| + ... + |M^{i,q_i}| <= L, |M^{i,1}| +
... + |M^{i,q_i+1}| > L.
This is almost the perfect use of the frame key โจ, but it only works when messages can't get lost or reordered (think TLS records ๐งพ).
Implicit approach:
q_i = L / m_max, i = 1, ... , t.
Here we assume every message is the biggest possible size, m_max ๐ฆ. So the data you actually get through one key can be way less than L ๐ญ. The upside is that this one works even when messages can get lost or reordered (like DTLS records ๐ธ).
Dynamic key changes:
We can run the key change through the Protected Point to Point ([P3]) solution ๐ฆ. That means building a protected tunnel between the endpoints, so the info about updating the frame key can be passed along safely. This is useful when you want the adversary to not notice the key change while the protocol is being evaluated ๐.
5.2. Parallel Constructions ๐ง
External parallel re-keying mechanisms make frame keys K^1, K^2, ... straight from the initial key K, and each one is made independently of the others. It's giving independence ๐.
The big idea behind external re-keying with a parallel construction is in Figure 4 ๐
Maximum message size = m_max.
_____________________________________________________________
m_max
<---------------->
M^{1,1} |=== |
M^{1,2} |=============== |
+->K^1--> ... ...
| M^{1,q_1} |======== |
|
|
| M^{2,1} |================|
| M^{2,2} |===== |
K-----|->K^2--> ... ...
| M^{2,q_2} |========== |
|
...
| M^{t,1} |============ |
| M^{t,2} |============= |
+->K^t--> ... ...
M^{t,q_t} |========== |
_____________________________________________________________
Figure 4: External Parallel Re-keying Mechanisms ๐
The frame key K^i, i = 1, ... , t - 1 gets updated after a certain number of messages have been processed (see Section 5.1 ๐).
5.2.1. Parallel Construction Based on a KDF on a Block Cipher ๐
The ExtParallelC re-keying mechanism is built on a key derivation function that runs on a block cipher โจ. It's used to make t frame keys like this:
K^1 | K^2 | ... | K^t = ExtParallelC(K, t * k) = MSB_{t *
k}(E_{K}(Vec_n(0)) |
E_{K}(Vec_n(1)) | ... | E_{K}(Vec_n(R - 1))),
where R = ceil(t * k/n) ๐งฎ.
5.2.2. Parallel Construction Based on a KDF on a Hash Function ๐ซง
The ExtParallelH re-keying mechanism is built on the key derivation function HKDF-Expand, described in [RFC5869] ๐. It's used to make t frame keys like this:
K^1 | K^2 | ... | K^t = ExtParallelH(K, t * k) = HKDF-Expand(K,
label, t * k),
where label is a string (it can be a zero-length string ๐ซถ) that a specific protocol defines.
5.2.3. Tree-Based Construction ๐ณ
Using an external tree-based mechanism builds a key tree ๐ฒ. The initial key K is the root key at level 0, and the frame keys K^1, K^2, ... sit at the last level, like in Figure 5 ๐.
K_root = K
___________|___________
| ... |
V V
K{1,1} K{1,W1}
______|______ ______|______
| ... | | ... |
V V V V
K{2,1} K{2,W2} K{2,(W1-1)*W2+1} K{2,W1*W2}
__|__ __|__ __|__ __|__
| ... | | ... | | ... | | ... |
V V V V V V V V
K{3,1} ... ... ... ... ... ... K{3,W1*W2*W3}
... ...
__|__ ... __|__
| ... | | ... |
V V V V
K{h,1} K{h,Wh} K{h,(W1*...*W{h-1}-1)*Wh+1} K{h,W1*...*Wh}
// \\ // \\
K^1 K^{Wh} K^{(W1*...*W{h-1}-1)*Wh+1} K^{W1*...*Wh}
____________________________________________________________________
Figure 5: External Tree-Based Mechanism ๐ธ
The tree height h, and the number of keys Wj, j in {1, ... , h}, that can be split off from a "parent" key are defined by a specific protocol and the key lifetime limits for the derivation functions being used ๐.
Each j-level key K{j,w}, where j in {1, ... , h} and w in {1, ... , W1 * ... * Wj}, comes from the (j-1)-level "parent" key K{j-1, ceil(w/Wi)} (plus any other relevant input data) ๐. It uses the j-th level derivation function, which can be built on a block cipher or a hash function. A specific protocol defines which one ๐ง.
The i-th frame K^i, i in {1, 2, ... , W1*...*Wh}, can be calculated like this:
K^i = ExtKeyTree(K, i) = KDF_h(KDF_{h-1}(... KDF_1(K, ceil(i / (W2
* ... * Wh)) ... , ceil(i / Wh)), i),
where KDF_j is the j-th level derivation function. It takes two arguments, the parent key value and an integer from 1 to W1 * ... * Wj, and it outputs the j-th level key value ๐ .
The frame key K^i gets updated after a certain number of messages have been processed (see Section 5.1 โฐ).
To make an efficient implementation, the derivation functions KDF_j, j in {1, ... , h-1}, should only be used when ceil(i / (W{j+1} * ... * Wh)) != ceil((i - 1) / (W{j+1} * ... * Wh)) during frame key K^i generation. Otherwise, you need to reuse a value you already generated ๐. This approach also lets you take countermeasures against side-channel attacks ๐ก๏ธ.
Let's look at an example ๐. Suppose h = 3, W1 = W2 = W3 = W, and KDF_1, KDF_2, KDF_3 are key derivation functions based on the KDF_GOSTR3411_2012_256 (hereafter simply KDF) function described in [RFC7836] โจ. The resulting ExtKeyTree function can be defined like this:
ExtKeyTree(K, i) = KDF(KDF(KDF(K, "level1", ceil(i / W^2)),
"level2", ceil(i / W)), "level3", i).
where i in {1, 2, ... , W^3} ๐ฅน.
A structure similar to the external tree-based mechanism can be found in Section 6 of [NISTSP800-108] ๐.
5.3. Serial Constructions ๐
External serial re-keying mechanisms make frame keys, and each one depends on a secret state (K*_1, K*_2, ...) that gets updated after every new frame key is generated. See Figure 6 ๐. Similar approaches show up in the [SIGNAL] protocol and the [TLS] updating traffic key mechanism, and they were proposed for use in the [U2F] protocol ๐ฆ.
External serial re-keying mechanisms have an obvious downside: they can't be done in parallel ๐ฉ. But they might be the preferred option if you want extra forward secrecy ๐ง. If every key is securely deleted after use, then compromising the current secret state at some point doesn't compromise all the previous secret states and frame keys ๐ช. In [TLS] terms, compromising application_traffic_secret_N doesn't compromise all the previous application_traffic_secret_i, i < N ๐ซถ.
The big idea behind external re-keying with a serial construction is in Figure 6 ๐
Maximum message size = m_max.
_____________________________________________________________
m_max
<---------------->
M^{1,1} |=== |
M^{1,2} |=============== |
K*_1 = K --->K^1--> ... ...
| M^{1,q_1} |======== |
|
|
| M^{2,1} |================|
v M^{2,2} |===== |
K*_2 ------->K^2--> ... ...
| M^{2,q_2} |========== |
|
...
| M^{t,1} |============ |
v M^{t,2} |============= |
K*_t ------->K^t--> ... ...
M^{t,q_t} |========== |
_____________________________________________________________
Figure 6: External Serial Re-keying Mechanisms ๐
The frame key K^i, i = 1, ... , t - 1, gets updated after a certain number of messages have been processed (see Section 5.1 ๐).
5.3.1. Serial Construction Based on a KDF on a Block Cipher ๐
The frame key K^i is calculated with the ExtSerialC transformation like this:
K^i = ExtSerialC(K, i) =
MSB_k(E_{K*_i}(Vec_n(0)) |E_{K*_i}(Vec_n(1)) | ... |
E_{K*_i}(Vec_n(J - 1))),
where J = ceil(k / n), i = 1, ... , t, and K*_i is calculated like this:
K*_1 = K,
K*_{j+1} = MSB_k(E_{K*_j}(Vec_n(J)) | E_{K*_j}(Vec_n(J + 1)) |
... |
E_{K*_j}(Vec_n(2 * J - 1))),
where j = 1, ... , t - 1 ๐ง .
5.3.2. Serial Construction Based on a KDF on a Hash Function ๐ซง
The frame key K^i is calculated with the ExtSerialH transformation like this:
K^i = ExtSerialH(K, i) = HKDF-Expand(K*_i, label1, k),
where i = 1, ... , t. HKDF-Expand is the HMAC-based key derivation function, as described in [RFC5869] ๐. K*_i is calculated like this:
K*_1 = K,
K*_{j+1} = HKDF-Expand(K*_j, label2, k), where j = 1, ... , t - 1,
where label1 and label2 are different strings from V* that a specific protocol defines. For example, check the algorithm for updating traffic keys in TLS 1.3 [TLS] ๐ธ.
5.4. Using Additional Entropy during Re-keying ๐ฒ
Honestly? In lots of cases, using extra entropy during re-keying won't make things more secure, but it can give you a false sense of security ๐. So you should only rely on additional entropy after doing a deep security analysis ๐. For example, good PRF constructions don't need extra entropy for key quality, so most of the time there's no need to add extra entropy to external re-keying mechanisms that use secure KDFs ๐ . However, in some situations mixed-in entropy can still boost security. That's when there's a time-limited but complete breach of the system, and an adversary can reach the frame-key generation interface but can't reveal the master keys (for example, when the master keys live in a Hardware Security Module (HSM)) ๐.
For example, an external parallel construction based on a KDF on a hash function with mixed-in entropy can be described like this:
K^i = HKDF-Expand(K, label_i, k),
where label_i is additional entropy that must be sent to the recipient (for example, sent together with an encrypted message ๐). The entropy label_i and the corresponding key K^i must be generated right before message processing โณ.
6. Internal Re-keying Mechanisms โจ
okay bestie, this section is about stretching out how long a key can last by transforming the data-processing key, called the section key, during each message ๐. Every message starts with the same key (the first section key), and then each section key gets updated after N bits of the message (that chunk is called a section) ๐ฆ
This section gives us internal re-keying mechanisms called ACPKM (Advanced Cryptographic Prolongation of Key Material) and ACPKM-Master. ACPKM doesn't use a master key, and ACPKM-Master does. They get built right into the base modes of operation, so they actually become new modes of operation ๐ธ That's why this document calls them "internal re-keying" mechanisms.
Internal re-keying is recommended for protocols that process large single messages (like CMS messages) ๐ The biggest key-lifetime boost comes from making a message longer, and it barely helps if you're just trying to push more messages through one initial key ๐
Here's how internal re-keying bumps up the key lifetime. Say protocol P uses some base mode of operation. Let L1 and L2 be a side-channel limitation and a combinatorial limitation, respectively. For some fixed number of messages q, let m1 and m2 be the lengths of messages that can be safely processed with one initial key K under those limits.
So without re-keying (kinda like Section 5), the final key lifetime restriction is just L1, and only q messages of length m1 can be safely processed. Check out Figure 7 ๐ง
K
|
v
^ +----------------+------------------------------------+
| |==============L1| L2|
| |================| |
q |================| |
| |================| |
| |================| |
v +----------------+------------------------------------+
<-------m1------->
<----------------------------m2----------------------->
Figure 7: Basic Principles of Message Processing
without Internal Re-keying
Now suppose the safety margin for protocol P is fixed and we apply internal re-keying to the base mode. Every message gets processed with a section key that transforms after every N bits, where N is a parameter. If q * N doesn't exceed L1, then the side-channel limit L1 goes off ๐ The key lifetime of the initial key K can then be worked out from a new combinatorial limit, L2'. The mode with internal re-keying is more secure than the base mode without re-keying (so L2 < L2'). That means, as Figure 8 shows, the key lifetime limit with internal re-keying can climb up to L2' ๐
K-----> K^1-------------> K^2 -----------> . . .
| |
v v
^ +---------------+---------------+------------------+--...--+
| |=============L1|=============L1|====== L2| L2'|
| |===============|===============|====== | |
q |===============|===============|====== . . . | |
| |===============|===============|====== | |
| |===============|===============|====== | |
v +---------------+---------------+------------------+--...--+
<-------N------->
Figure 8: Basic Principles of Message Processing
with Internal Re-keying
Note: the key transformation is drawn in a simplified way here. The actual approach (the ACPKM and ACPKM-Master re-keying mechanisms) is described below ๐
Performance can dip a little when N is pretty small, so for a given protocol the biggest possible N should be picked to get the key lifetime you need for the security models you're looking at ๐
Let's do an example! Say L1 = 128 MB and L2 = 10 TB. If messages in the protocol are large or unlimited (which could use up the whole L2 lifetime), the most restrictive limit is 128 MB ๐ญ
That means we need a cap on the maximum message size, m_max. For instance, if m_max = 32 MB, you might have to renegotiate initial key K after only four messages ๐
But if you use an internal re-keying mechanism with section size N = 1 MB, more than L1 / N = 128 MB / 1 MB = 128 messages can get processed before initial key K needs renegotiating. Without internal re-keying you'd only get four messages! Since only one section of each message is processed with section key K^i, the L1 limit goes off ๐ฅ So the resulting key lifetime limit L2' can be set to more than 10 TB (when a single large message is processed under the initial key K) ๐
6.1. Methods of Key Lifetime Control
Let L be the amount of data that can be safely processed with one section key, and let N be the section size (a fixed parameter). Let M^{i}_1 be the first section of message M^{i}, for i = 1, ... , q (see Figures 9 and 10). The parameter q can then be computed with one of two approaches ๐
- Explicit approach:
q_iis such that|M^{1}_1| + ... + |M^{q}_1| <= Land|M^{1}_1| + ... + |M^{q+1}_1| > L. This approach lets you use the section key K^i in an almost optimal way, but it only works when messages can't be lost or reordered (for example, TLS records) ๐ซถ - Implicit approach:
q = L / N. The amount of data processed with one section key K^i is calculated assuming every message is at least as long as the section size N, so it can end up way less than the key lifetime limit L. On the flip side, this approach works when messages may be lost or reordered (for example, DTLS records) ๐ฆ
6.2. Constructions that Do Not Require a Master Key
This section covers the block cipher modes that use the ACPKM re-keying mechanism, which doesn't use a master key. The initial key is used directly for data encryption ๐
6.2.1. ACPKM Re-keying Mechanisms
This section defines a periodic key transformation without a master key, called the ACPKM re-keying mechanism โจ It can be applied to one of the base encryption modes (the CTR and GCM block cipher modes) to get an extended version of that encryption mode, which does periodic key transformation without a master key. That extension can be treated as a brand-new encryption mode ๐
One more parameter defines how base encryption modes work with the ACPKM re-keying mechanism: the section size N. N is measured in bits and is fixed within a specific protocol, based on the system capacity requirements and the key lifetime. The section size N MUST be divisible by the block size n ๐
The big idea behind internal re-keying without a master key is shown in Figure 9 ๐ง
Section size = const = N,
maximum message size = m_max.
____________________________________________________________________
ACPKM ACPKM ACPKM
K^1 = K ---> K^2 ---...-> K^{l_max-1} ----> K^{l_max}
| | | |
| | | |
v v v v
M^{1} |==========|==========| ... |==========|=======: |
M^{2} |==========|==========| ... |=== | : |
. . . . . . :
: : : : : : :
M^{q} |==========|==========| ... |==========|===== : |
section :
<----------> m_max
N bit
___________________________________________________________________
l_max = ceil(m_max/N).
Figure 9: Internal Re-keying without a Master Key
When a message M of length m is processed in some encryption mode that uses the ACPKM key transformation of initial key K, the message is split into l = ceil(m / N) sections. These are written as M = M_1 | M_2 | ... | M_l, where M_i is in V_N for i in {1, 2, ... , l - 1}, and M_l is in V_r with r <= N. The first section of each message is processed with section key K^1 = K. To process the (i + 1)-th section of each message, the section key K^{i+1} is worked out with the ACPKM transformation like this:
K^{i+1} = ACPKM(K^i) = MSB_k(E_{K^i}(D_1) | ... | E_{K^i}(D_J))
where J = ceil(k/n), and D_1, D_2, ... , D_J are in V_n and are calculated like this:
D_1 | D_2 | ... | D_J = MSB_{J * n}(D)
and D is this constant in V_{1024}:
D = ( 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87
| 88 | 89 | 8a | 8b | 8c | 8d | 8e | 8f
| 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97
| 98 | 99 | 9a | 9b | 9c | 9d | 9e | 9f
| a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7
| a8 | a9 | aa | ab | ac | ad | ae | af
| b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7
| b8 | b9 | ba | bb | bc | bd | be | bf
| c0 | c1 | c2 | c3 | c4 | c5 | c6 | c7
| c8 | c9 | ca | cb | cc | cd | ce | cf
| d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7
| d8 | d9 | da | db | dc | dd | de | df
| e0 | e1 | e2 | e3 | e4 | e5 | e6 | e7
| e8 | e9 | ea | eb | ec | ed | ee | ef
| f0 | f1 | f2 | f3 | f4 | f5 | f6 | f7
| f8 | f9 | fa | fb | fc | fd | fe | ff)
Note: the constant D is built so that D_1, ... , D_J are pairwise different for any allowed values of n and k ๐
Note: the highest bit of every octet of the constant D is equal to 1. This condition matters because, together with a certain mode message length limitation, it helps prevent collisions of block cipher permutation inputs during key transformation and message processing (for more details, see Section 4.4 of [AAOS2017]) ๐ฅ
6.2.2. CTR-ACPKM Encryption Mode โจ
Okay so this section defines CTR-ACPKM ๐, an encryption mode that uses the ACPKM internal re-keying mechanism for the periodical key transformation. It's basically plain old CTR (see [MODES]) with the ACPKM re-keying glow-up added on top ๐ .
The CTR-ACPKM encryption mode can be used with these parameters ๐ธ:
64 <= n <= 512.128 <= k <= 512.- The number c of bits in the specific part of the block that gets incremented is such that
32 <= c <= 3 / 4 n, and c is a multiple of 8 ๐. - The maximum message size is
m_max = n * 2^{c-1}.
Here's how the CTR-ACPKM encryption and decryption procedures go ๐ฆ:
+----------------------------------------------------------------+
| CTR-ACPKM-Encrypt(N, K, ICN, P) |
|----------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - initial counter nonce ICN in V_{n-c}, |
| - plaintext P = P_1 | ... | P_b, |P| <= m_max. |
| Output: |
| - ciphertext C. |
|----------------------------------------------------------------|
| 1. CTR_1 = ICN | 0^c |
| 2. For j = 2, 3, ... , b do |
| CTR_{j} = Inc_c(CTR_{j-1}) |
| 3. K^1 = K |
| 4. For i = 2, 3, ... , ceil(|P| / N) |
| K^i = ACPKM(K^{i-1}) |
| 5. For j = 1, 2, ... , b do |
| i = ceil(j * n / N), |
| G_j = E_{K^i}(CTR_j) |
| 6. C = P (xor) MSB_{|P|}(G_1 | ... | G_b) |
| 7. Return C |
+----------------------------------------------------------------+
+----------------------------------------------------------------+
| CTR-ACPKM-Decrypt(N, K, ICN, C) |
|----------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - initial counter nonce ICN in V_{n-c}, |
| - ciphertext C = C_1 | ... | C_b, |C| <= m_max. |
| Output: |
| - plaintext P. |
|----------------------------------------------------------------|
| 1. P = CTR-ACPKM-Encrypt(N, K, ICN, C) |
| 2. Return P |
+----------------------------------------------------------------+
The initial counter nonce (ICN) value for each message that is encrypted under the given initial key K must be chosen in a unique manner ๐ซถ.
6.2.3. GCM-ACPKM Authenticated Encryption Mode ๐
This section defines the GCM-ACPKM authenticated encryption mode, which uses the ACPKM internal re-keying mechanism for the periodical key transformation. It's giving GCM (see [GCM]) with the ACPKM re-keying mechanism stacked on top ๐.
The GCM-ACPKM authenticated encryption mode can be used with these parameters โจ:
n in {128, 256}.128 <= k <= 512.- The number c of bits in the specific part of the block that gets incremented is such that
1 / 4 n <= c <= 1 / 2 n, and c is a multiple of 8 ๐. - Authentication tag length t.
- The maximum message size is
m_max = min{n * (2^{c-1} - 2), 2^{n/2} - 1}.
The GCM-ACPKM mode encryption and decryption procedures are defined like this ๐ง:
+-------------------------------------------------------------------+
| GHASH(X, H) |
|-------------------------------------------------------------------|
| Input: |
| - bit string X = X_1 | ... | X_m, X_1, ... , X_m in V_n. |
| Output: |
| - block GHASH(X, H) in V_n. |
|-------------------------------------------------------------------|
| 1. Y_0 = 0^n |
| 2. For i = 1, ... , m do |
| Y_i = (Y_{i-1} (xor) X_i) * H |
| 3. Return Y_m |
+-------------------------------------------------------------------+
+-------------------------------------------------------------------+
| GCTR(N, K, ICB, X) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - initial counter block ICB, |
| - X = X_1 | ... | X_b. |
| Output: |
| - Y in V_{|X|}. |
|-------------------------------------------------------------------|
| 1. If X in V_0, then return Y, where Y in V_0 |
| 2. GCTR_1 = ICB |
| 3. For i = 2, ... , b do |
| GCTR_i = Inc_c(GCTR_{i-1}) |
| 4. K^1 = K |
| 5. For j = 2, ... , ceil(|X| / N) |
| K^j = ACPKM(K^{j-1}) |
| 6. For i = 1, ... , b do |
| j = ceil(i * n / N), |
| G_i = E_{K_j}(GCTR_i) |
| 7. Y = X (xor) MSB_{|X|}(G_1 | ... | G_b) |
| 8. Return Y |
+-------------------------------------------------------------------+
+-------------------------------------------------------------------+
| GCM-ACPKM-Encrypt(N, K, ICN, P, A) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - initial counter nonce ICN in V_{n-c}, |
| - plaintext P = P_1 | ... | P_b, |P| <= m_max, |
| - additional authenticated data A. |
| Output: |
| - ciphertext C, |
| - authentication tag T. |
|-------------------------------------------------------------------|
| 1. H = E_{K}(0^n) |
| 2. ICB_0 = ICN | 0^{c-1} | 1 |
| 3. C = GCTR(N, K, Inc_c(ICB_0), P) |
| 4. u = n * ceil(|C| / n) - |C| |
| v = n * ceil(|A| / n) - |A| |
| 5. S = GHASH(A | 0^v | C | 0^u | Vec_{n/2}(|A|) | |
| | Vec_{n/2}(|C|), H) |
| 6. T = MSB_t(E_{K}(ICB_0) (xor) S) |
| 7. Return C | T |
+-------------------------------------------------------------------+
+-------------------------------------------------------------------+
| GCM-ACPKM-Decrypt(N, K, ICN, A, C, T) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - initial counter block ICN, |
| - additional authenticated data A, |
| - ciphertext C = C_1 | ... | C_b, |C| <= m_max, |
| - authentication tag T. |
| Output: |
| - plaintext P or FAIL. |
|-------------------------------------------------------------------|
| 1. H = E_{K}(0^n) |
| 2. ICB_0 = ICN | 0^{c-1} | 1 |
| 3. P = GCTR(N, K, Inc_c(ICB_0), C) |
| 4. u = n * ceil(|C| / n) - |C| |
| v = n * ceil(|A| / n) - |A| |
| 5. S = GHASH(A | 0^v | C | 0^u | Vec_{n/2}(|A|) | |
| | Vec_{n/2}(|C|), H) |
| 6. T' = MSB_t(E_{K}(ICB_0) (xor) S) |
| 7. If T = T', then return P; else return FAIL |
+-------------------------------------------------------------------+
The * operation on (pairs of) the 2^n possible blocks corresponds to the multiplication operation for the binary Galois (finite) field of 2^n elements defined by the polynomial f as follows (analogous to [GCM]) ๐ฅ:
n = 128: f = a^128 + a^7 + a^2 + a^1 + 1,
n = 256: f = a^256 + a^10 + a^5 + a^2 + 1.
The initial counter nonce ICN value for each message that is encrypted under the given initial key K must be chosen in a unique manner ๐ .
The key for computing values E_{K}(ICB_0) and H is not updated and is equal to the initial key K ๐ธ.
6.3. Constructions that Require a Master Key ๐
This section describes the block cipher modes that use the ACPKM-Master re-keying mechanism. These modes use the initial key K as a master key, so K is never used directly for data processing and is only used for key derivation โจ.
6.3.1. ACPKM-Master Key Derivation from the Master Key
okay so this section is all about periodical key transformation with a master key ๐, aka the ACPKM-Master re-keying mechanism ๐. it can be slapped onto one of the base modes of operation (CTR, GCM, CBC, CFB, OMAC modes) to get an extension that does periodical key transformation with a master key, and honestly that extension is giving "brand new mode of operation" energy โจ
the extra parameters that control how these modes work are the section size N, the change frequency T* of the master keys K*_1, K*_2, ... (see Figure 10), and the size d of the section key material. N and T* are measured in bits and get fixed within a specific protocol based on the system capacity and the key lifetime ๐ธ two rules to remember bestie: the section size N MUST be divisible by the block size n, and the master key frequency T* MUST be divisible by d and by n ๐ซถ
here's the big picture of internal re-keying with a master key, in Figure 10 ๐ฆ
Master key frequency T*,
section size N,
maximum message size = m_max.
_____________________________________________________________________
ACPKM ACPKM
K*_1 = K----------> K*_2 ---------...-----> K*_l_max
___|___ ___|___ ___|___
| | | | | |
v ... v v ... v v ... v
K[1] K[t] K[t+1] K[2*t] K[(l_max-1)t+1] K[l_max*t]
| | | | | |
| | | | | |
v v v v v v
M^{1}||======|...|======||======|...|======||...||======|...|== : ||
M^{2}||======|...|======||======|...|======||...||======|...|====: ||
... || | | || | | || || | | : ||
M^{q}||======|...|======||==== |...| ||...|| |...| : ||
section :
<------> :
N bit m_max
_____________________________________________________________________
|K[i]| = d,
t = T* / d,
l_max = ceil(m_max / (N * t)).
Figure 10: Internal Re-keying with a Master Key
so when a message M of length m gets processed in a mode using ACPKM-Master key transformation, with initial key K and master key frequency T*, the message is chopped into l = ceil(m / N) sections. that's written as M = M_1 | M_2 | ... | M_l, where M_i is in V_N for i in {1, 2, ... , l - 1} and M_l is in V_r, r <= N. ๐
each section j gets its own key material K[j] (for j in {1, ... , l}, with |K[j]| = d), worked out by the ACPKM-Master algorithm like this:
K[1] | ... | K[l] = ACPKM-Master(T*, K, d, l) = CTR-ACPKM-Encrypt
(T*, K, 1^{n/2}, 0^{d*l}).
Note: The parametersdandlMUST be such thatd * l <= n * 2^{n/2-1}. ๐ this one is non-negotiable, no cap.
6.3.2. CTR-ACPKM-Master Encryption Mode
this part defines the CTR-ACPKM-Master encryption mode ๐, which uses the ACPKM-Master internal re-keying mechanism for the periodical key transformation. โจ
it can be thought of as the base encryption mode CTR (see [MODES]) with the ACPKM-Master re-keying mechanism bolted on. it's like the classic CTR glow-up ๐
you can use CTR-ACPKM-Master with these parameters:
64 <= n <= 512.128 <= k <= 512.- The number
cof bits in a specific part of the block to be incremented is such that32 <= c <= 3 / 4 n, andcis a multiple of 8. - The maximum message size
m_max = min{N * (n * 2^{n/2-1} / k), n * 2^c}.
the key material K[j] used for one-section processing is equal to K^j, where |K^j| = k bits. ๐
here are the encryption and decryption procedures for the CTR-ACPKM-Master mode, verbatim:
+----------------------------------------------------------------+
| CTR-ACPKM-Master-Encrypt(N, K, T*, ICN, P) |
|----------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initial counter nonce ICN in V_{n-c}, |
| - plaintext P = P_1 | ... | P_b, |P| <= m_max. |
| Output: |
| - ciphertext C. |
|----------------------------------------------------------------|
| 1. CTR_1 = ICN | 0^c |
| 2. For j = 2, 3, ... , b do |
| CTR_{j} = Inc_c(CTR_{j-1}) |
| 3. l = ceil(|P| / N) |
| 4. K^1 | ... | K^l = ACPKM-Master(T*, K, k, l) |
| 5. For j = 1, 2, ... , b do |
| i = ceil(j * n / N), |
| G_j = E_{K^i}(CTR_j) |
| 6. C = P (xor) MSB_{|P|}(G_1 | ... |G_b) |
| 7. Return C |
|----------------------------------------------------------------+
+----------------------------------------------------------------+
| CTR-ACPKM-Master-Decrypt(N, K, T*, ICN, C) |
|----------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initial counter nonce ICN in V_{n-c}, |
| - ciphertext C = C_1 | ... | C_b, |C| <= m_max. |
| Output: |
| - plaintext P. |
|----------------------------------------------------------------|
| 1. P = CTR-ACPKM-Master-Encrypt(N, K, T*, ICN, C) |
| 1. Return P |
+----------------------------------------------------------------+
๐ซถ last but not least: the initial counter nonce ICN value for each message encrypted under a given initial key must be chosen in a unique manner. no repeats, periodt ๐
6.3.3. GCM-ACPKM-Master Authenticated Encryption Mode
okay so this section is where we glue โจ GCM-ACPKM-Master ๐ together, and bestie, it's giving main character energy ๐ ๐ฆ
this mode is basically the classic authenticated encryption mode GCM (see [GCM]) ๐ with the ACPKM-Master re-keying mechanism ๐ฅ bolted on for the periodical key transformation. no cap, it's GCM with a glow-up ๐ธ
here are the parameters you can use ๐ซถ :
- n in {128, 256}.
- 128 <= k <= 512.
- The number c of bits in a specific part of the block to be incremented is such that 1 / 4 n <= c <= 1 / 2 n, c is a multiple of 8.
- authentication tag length t.
- the maximum message size m_max = min{N * ( n * 2^{n/2-1} / k), n * (2^c - 2), 2^{n/2} - 1}.
the key material K[j] used for the j-th section processing is equal to K^j, and |K^j| = k bits ๐ง
the GCM-ACPKM-Master encryption and decryption procedures are laid out in the boxes below ๐ (they're shown verbatim, no cap, because implementers need every single character ๐)
+-------------------------------------------------------------------+
| GHASH(X, H) |
|-------------------------------------------------------------------|
| Input: |
| - bit string X = X_1 | ... | X_m, X_i in V_n for i in {1, ... ,m}|
| Output: |
| - block GHASH(X, H) in V_n |
|-------------------------------------------------------------------|
| 1. Y_0 = 0^n |
| 2. For i = 1, ... , m do |
| Y_i = (Y_{i-1} (xor) X_i) * H |
| 3. Return Y_m |
+-------------------------------------------------------------------+
+-------------------------------------------------------------------+
| GCTR(N, K, T*, ICB, X) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initial counter block ICB, |
| - X = X_1 | ... | X_b. |
| Output: |
| - Y in V_{|X|}. |
|-------------------------------------------------------------------|
| 1. If X in V_0, then return Y, where Y in V_0 |
| 2. GCTR_1 = ICB |
| 3. For i = 2, ... , b do |
| GCTR_i = Inc_c(GCTR_{i-1}) |
| 4. l = ceil(|X| / N) |
| 5. K^1 | ... | K^l = ACPKM-Master(T*, K, k, l) |
| 6. For j = 1, ... , b do |
| i = ceil(j * n / N), |
| G_j = E_{K^i}(GCTR_j) |
| 7. Y = X (xor) MSB_{|X|}(G_1 | ... | G_b) |
| 8. Return Y |
+-------------------------------------------------------------------+
+-------------------------------------------------------------------+
| GCM-ACPKM-Master-Encrypt(N, K, T*, ICN, P, A) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initial counter nonce ICN in V_{n-c}, |
| - plaintext P = P_1 | ... | P_b, |P| <= m_max. |
| - additional authenticated data A. |
| Output: |
| - ciphertext C, |
| - authentication tag T. |
|-------------------------------------------------------------------|
| 1. K^1 = ACPKM-Master(T*, K, k, 1) |
| 2. H = E_{K^1}(0^n) |
| 3. ICB_0 = ICN | 0^{c-1} | 1 |
| 4. C = GCTR(N, K, T*, Inc_c(ICB_0), P) |
| 5. u = n * ceil(|C| / n) - |C| |
| v = n * ceil(|A| / n) - |A| |
| 6. S = GHASH(A | 0^v | C | 0^u | Vec_{n/2}(|A|) | |
| | Vec_{n/2}(|C|), H) |
| 7. T = MSB_t(E_{K^1}(ICB_0) (xor) S) |
| 8. Return C | T |
+-------------------------------------------------------------------+
+-------------------------------------------------------------------+
| GCM-ACPKM-Master-Decrypt(N, K, T*, ICN, A, C, T) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initial counter nonce ICN in V_{n-c}, |
| - additional authenticated data A. |
| - ciphertext C = C_1 | ... | C_b, |C| <= m_max, |
| - authentication tag T. |
| Output: |
| - plaintext P or FAIL. |
|-------------------------------------------------------------------|
| 1. K^1 = ACPKM-Master(T*, K, k, 1) |
| 2. H = E_{K^1}(0^n) |
| 3. ICB_0 = ICN | 0^{c-1} | 1 |
| 4. P = GCTR(N, K, T*, Inc_c(ICB_0), C) |
| 5. u = n * ceil(|C| / n) - |C| |
| v = n * ceil(|A| / n) - |A| |
| 6. S = GHASH(A | 0^v | C | 0^u | Vec_{n/2}(|A|) | |
| | Vec_{n/2}(|C|), H) |
| 7. T' = MSB_t(E_{K^1}(ICB_0) (xor) S) |
| 8. If T = T', then return P; else return FAIL. |
+-------------------------------------------------------------------+
the * operation on (pairs of) the 2^n possible blocks corresponds to the multiplication operation for the binary Galois (finite) field of 2^n elements defined by the polynomial f as follows (by analogy with [GCM]) ๐
- n = 128: f = a^128 + a^7 + a^2 + a^1 + 1,
- n = 256: f = a^256 + a^10 + a^5 + a^2 + 1.
one last thing, and it's a big one ๐จ the initial counter nonce ICN value for each message that is encrypted under the given initial key must be chosen in a unique manner ๐ no reusing, no copy-pasting, bestie, every single message gets its own ICN ๐ฅ ๐ญ
6.3.4. CBC-ACPKM-Master Encryption Mode ๐
okay so this section defines CBC-ACPKM-Master ๐ which uses the ACPKM-Master internal re-keying mechanism for the periodical key transformation. the key keeps getting refreshed on a schedule while the mode keeps going.
ngl this one is basically the base CBC mode (see [MODES]) with the ACPKM-Master re-keying mechanism stapled on. main character energy ๐
CBC-ACPKM-Master can be used with these parameters:
64 <= n <= 512.128 <= k <= 512.- The maximum message size
m_max = N * (n * 2^{n/2-1} / k).
bestie, the plaintext and ciphertext have to be a sequence of one or more complete data blocks ๐งฑ. if your data doesn't already fit that, it MUST be padded to form complete data blocks. the padding methods are out of scope for this doc, but there's an example in Appendix A of [MODES] if you're curious ๐ธ
the key material K[j] for the j-th section processing is K^j, with |K^j| = k bits ๐
we use D_{K} to mean the decryption function, which is the permutation inverse to E_{K} ๐ง
here's how the CBC-ACPKM-Master encryption and decryption procedures go ๐
+----------------------------------------------------------------+
| CBC-ACPKM-Master-Encrypt(N, K, T*, IV, P) |
|----------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initialization vector IV in V_n, |
| - plaintext P = P_1 | ... | P_b, |P_b| = n, |P| <= m_max. |
| Output: |
| - ciphertext C. |
|----------------------------------------------------------------|
| 1. l = ceil(|P| / N) |
| 2. K^1 | ... | K^l = ACPKM-Master(T*, K, k, l) |
| 3. C_0 = IV |
| 4. For j = 1, 2, ... , b do |
| i = ceil(j * n / N), |
| C_j = E_{K^i}(P_j (xor) C_{j-1}) |
| 5. Return C = C_1 | ... | C_b |
|----------------------------------------------------------------+
+----------------------------------------------------------------+
| CBC-ACPKM-Master-Decrypt(N, K, T*, IV, C) |
|----------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initialization vector IV in V_n, |
| - ciphertext C = C_1 | ... | C_b, |C_b| = n, |C| <= m_max. |
| Output: |
| - plaintext P. |
|----------------------------------------------------------------|
| 1. l = ceil(|C| / N) |
| 2. K^1 | ... | K^l = ACPKM-Master(T*, K, k, l) |
| 3. C_0 = IV |
| 4. For j = 1, 2, ... , b do |
| i = ceil(j * n / N) |
| P_j = D_{K^i}(C_j) (xor) C_{j-1} |
| 5. Return P = P_1 | ... | P_b |
+----------------------------------------------------------------+
the IV for any single run of the encryption process must be unpredictable ๐ no shortcuts here, bestie ๐ซถ
6.3.5. CFB-ACPKM-Master Encryption Mode ๐ฆ
this section defines CFB-ACPKM-Master ๐ which uses the ACPKM-Master internal re-keying mechanism for the periodical key transformation. same energy as the last one, just with CFB as the base.
so the CFB-ACPKM-Master encryption mode is the base CFB mode (see [MODES]) extended by the ACPKM-Master re-keying mechanism โจ
CFB-ACPKM-Master can be used with these parameters:
64 <= n <= 512.128 <= k <= 512.- The maximum message size
m_max = N * (n * 2^{n/2-1} / k).
the key material K[j] for the j-th section processing is K^j, with |K^j| = k bits ๐
and here are the CFB-ACPKM-Master encryption and decryption procedures ๐
+-------------------------------------------------------------+
| CFB-ACPKM-Master-Encrypt(N, K, T*, IV, P) |
|-------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initialization vector IV in V_n, |
| - plaintext P = P_1 | ... | P_b, |P| <= m_max. |
| Output: |
| - ciphertext C. |
|-------------------------------------------------------------|
| 1. l = ceil(|P| / N) |
| 2. K^1 | ... | K^l = ACPKM-Master(T*, K, k, l) |
| 3. C_0 = IV |
| 4. For j = 1, 2, ... , b - 1 do |
| i = ceil(j * n / N), |
| C_j = E_{K^i}(C_{j-1}) (xor) P_j |
| 5. C_b = MSB_{|P_b|}(E_{K^l}(C_{b-1})) (xor) P_b |
| 6. Return C = C_1 | ... | C_b |
|-------------------------------------------------------------+
+-------------------------------------------------------------+
| CFB-ACPKM-Master-Decrypt(N, K, T*, IV, C) |
|-------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - initialization vector IV in V_n, |
| - ciphertext C = C_1 | ... | C_b, |C| <= m_max. |
| Output: |
| - plaintext P. |
|-------------------------------------------------------------|
| 1. l = ceil(|C| / N) |
| 2. K^1 | ... | K^l = ACPKM-Master(T*, K, k, l) |
| 3. C_0 = IV |
| 4. For j = 1, 2, ... , b - 1 do |
| i = ceil(j * n / N), |
| P_j = E_{K^i}(C_{j-1}) (xor) C_j |
| 5. P_b = MSB_{|C_b|}(E_{K^l}(C_{b-1})) (xor) C_b |
| 6. Return P = P_1 | ... | P_b |
+-------------------------------------------------------------+
same rule as before: the IV for any particular execution of the encryption process must be unpredictable ๐
6.3.6. OMAC-ACPKM-Master Authentication Mode ๐
this section defines an OMAC-ACPKM-Master message authentication code calculation mode ๐ which uses the ACPKM-Master internal re-keying mechanism for the periodical key transformation.
the OMAC-ACPKM-Master mode is the base message authentication code calculation mode OMAC1, which is also known as CMAC (see [RFC4493]), extended by the ACPKM-Master re-keying mechanism ๐ธ
OMAC-ACPKM-Master can be used with these parameters:
n in {64, 128, 256}.128 <= k <= 512.- The maximum message size
m_max = N * (n * 2^{n/2-1} / (k + n)).
the key material K[j] for one-section processing is K^j | K^j_1, where |K^j| = k bits and |K^j_1| = n bits ๐
here's the subkey generation process for OMAC ๐ง
+-------------------------------------------------------------------+
| Generate_Subkey(K1, r) |
|-------------------------------------------------------------------|
| Input: |
| - key K1. |
| Output: |
| - key SK. |
|-------------------------------------------------------------------|
| 1. If r = n, then return K1 |
| 2. If r < n, then |
| if MSB_1(K1) = 0 |
| return K1 << 1 |
| else |
| return (K1 << 1) (xor) R_n |
+-------------------------------------------------------------------+
here, R_n takes these values ๐
- n = 64:
R_{64} = 0^{59} | 11011. - n = 128:
R_{128} = 0^{120} | 10000111. - n = 256:
R_{256} = 0^{145} | 10000100101.
and this is how the OMAC-ACPKM-Master message authentication code calculation mode is defined ๐ฆ
+-------------------------------------------------------------------+
| OMAC-ACPKM-Master(K, N, T*, M) |
|-------------------------------------------------------------------|
| Input: |
| - section size N, |
| - initial key K, |
| - master key frequency T*, |
| - plaintext M = M_1 | ... | M_b, |M| <= m_max. |
| Output: |
| - message authentication code T. |
|-------------------------------------------------------------------|
| 1. C_0 = 0^n |
| 2. l = ceil(|M| / N) |
| 3. K^1 | K^1_1 | ... | K^l | K^l_1 = |
= ACPKM-Master(T*, K, (k + n), l) |
| 4. For j = 1, 2, ... , b - 1 do |
| i = ceil(j * n / N), |
| C_j = E_{K^i}(M_j (xor) C_{j-1}) |
| 5. SK = Generate_Subkey(K^l_1, |M_b|) |
| 6. If |M_b| = n, then M*_b = M_b |
| else M*_b = M_b | 1 | 0^{n - 1 -|M_b|} |
| 7. T = E_{K^l}(M*_b (xor) C_{b-1} (xor) SK) |
| 8. Return T |
+-------------------------------------------------------------------+
7. Joint Usage of External and Internal Re-keying ๐
okay so external re-keying and internal re-keying both have their own pros and cons (we covered those in Section 1 ๐ ). external re-keying can basically limit the message length, while with internal re-keying the section size (picked as big as your operational properties allow) limits how many separate messages you can send. so which one you pick depends on your protocol's features ๐ง but ngl some protocols need the best of both worlds. like, the protocol mostly sends short messages but also has to handle really long ones. in that case you use external and internal re-keying together, because they cancel out each other's downsides โจ
any mechanism from Section 5 can be combined with any mechanism from Section 6 ๐ฆ
let's look at an example: the GCM-ACPKM mode with external serial re-keying based on a KDF on a hash function. we call the number of messages in each frame (for the implicit approach to key lifetime control) the frame size for external re-keying. ๐
let L be the key lifetime limitation. the section size N for internal re-keying and the frame size q for external re-keying must be chosen so that q * N must not exceed L ๐
now say t messages (ICN_i, P_i, A_i) are going to be processed before renegotiation, where each one has its own initial counter nonce ICN_i, plaintext P_i, and additional authenticated data A_i. for authenticated encryption of each message, with i = 1, ..., t, you can use this algorithm:
1. j = ceil(i / q),
2. K^j = ExtSerialH(K, j),
3. C_i | T_i = GCM-ACPKM-Encrypt(N, K^j, ICN_i, P_i, A_i).
heads up bestie: nonces ICN_i that are used under the same frame key must be unique for each message ๐จ
8. Security Considerations ๐
okay this section is the serious part so read it carefully ๐ซถ re-keying should be used to boost the a priori security properties of ciphers in hostile environments (e.g., with side-channel adversaries). if efficient attacks on a cipher are already known, the cipher must not be used. so re-keying cannot be used as a patch for vulnerable ciphers, periodt ๐ base cipher properties must be well analyzed, because the security of re-keying mechanisms is based on the security of a block cipher as a pseudorandom function.
re-keying is not intended to solve any postquantum security issues for symmetric cryptography. the reduction of security caused by Grover's algorithm isn't connected to the size of the plaintext transformed by a cipher (only a negligible amount of material, enough for key uniqueness, is needed). the whole point of re-keying is to limit the size of plaintext transformed under one initial key, so it's a different problem ๐ฅ
re-keying can provide backward security only if previous key material is securely deleted after usage by all parties. ๐ญ
9. IANA Considerations ๐ธ
this document has no IANA actions. nothing to register, nothing to update, we're literally chilling ๐ง
10. References ๐
10.1. Normative References
these are the must-read sources the spec leans on ๐
[CMS]Housley, R., "Cryptographic Message Syntax (CMS)", STD 70, RFC 5652, DOI 10.17487/RFC5652, September 2009,https://www.rfc-editor.org/info/rfc5652.[DTLS]Rescorla, E. and N. Modadugu, "Datagram Transport Layer Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347, January 2012,https://www.rfc-editor.org/info/rfc6347.[ESP]Kent, S., "IP Encapsulating Security Payload (ESP)", RFC 4303, DOI 10.17487/RFC4303, December 2005,https://www.rfc-editor.org/info/rfc4303.[GCM]Dworkin, M., "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC", NIST Special Publication 800-38D, DOI 10.6028/NIST.SP.800-38D, November 2007,http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf.[MODES]Dworkin, M., "Recommendation for Block Cipher Modes of Operation: Methods and Techniques", NIST Special Publication 800-38A, DOI 10.6028/NIST.SP.800-38A, December 2001.[NISTSP800-108]National Institute of Standards and Technology, "Recommendation for Key Derivation Using Pseudorandom Functions", NIST Special Publication 800-108, October 2009,http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-108.pdf.[RFC2119]Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,https://www.rfc-editor.org/info/rfc2119.[RFC4493]Song, JH., Poovendran, R., Lee, J., and T. Iwata, "The AES-CMAC Algorithm", RFC 4493, DOI 10.17487/RFC4493, June 2006,https://www.rfc-editor.org/info/rfc4493.[RFC5869]Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)", RFC 5869, DOI 10.17487/RFC5869, May 2010,https://www.rfc-editor.org/info/rfc5869.[RFC7836]Smyshlyaev, S., Ed., Alekseev, E., Oshkin, I., Popov, V., Leontiev, S., Podobaev, V., and D. Belyavsky, "Guidelines on the Cryptographic Algorithms to Accompany the Usage of Standards GOST R 34.10-2012 and GOST R 34.11-2012", RFC 7836, DOI 10.17487/RFC7836, March 2016,https://www.rfc-editor.org/info/rfc7836.[RFC8174]Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017,https://www.rfc-editor.org/info/rfc8174.[SSH]Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH) Transport Layer Protocol", RFC 4253, DOI 10.17487/RFC4253, January 2006,https://www.rfc-editor.org/info/rfc4253.[TLS]Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,https://www.rfc-editor.org/info/rfc8446.
10.2. Informative References
these are the extra reading bits for the curious ๐ฆ๐ง
[AAOS2017]Ahmetzyanova, L., Alekseev, E., Oshkin, I., and S. Smyshlyaev, "Increasing the Lifetime of Symmetric Keys for the GCM Mode by Internal Re-keying", Cryptology ePrint Archive, Report 2017/697, 2017,https://eprint.iacr.org/2017/697.pdf.[AbBell]Abdalla, M. and M. Bellare, "Increasing the Lifetime of a Key: A Comparative Analysis of the Security of Re-keying Techniques", ASIACRYPT 2000, Lecture Notes in Computer Science, Volume 1976, pp. 546-559, DOI 10.1007/3-540-44448-3_42, October 2000.[AESDUKPT]American National Standards Institute, "Retail Financial Services Symmetric Key Management - Part 3: Derived Unique Key Per Transaction", ANSI X9.24-3-2017, October 2017.[FKK2005]Fu, K., Kamara, S., and T. Kohno, "Key Regression: Enabling Efficient Key Distribution for Secure Distributed Storage", November 2005,https://homes.cs.washington.edu/~yoshi/papers/KR/NDSS06.pdf.[FPS2012]Faust, S., Pietrzak, K., and J. Schipper, "Practical Leakage-Resilient Symmetric Cryptography", Cryptographic Hardware and Embedded Systems (CHES), Lecture Notes in Computer Science, Volume 7428, pp. 213-232, DOI 10.1007/978-3-642-33027-8_13, 2012,https://link.springer.com/content/pdf/10.1007%2F978-3-642-33027-8_13.pdf.[FRESHREKEYING]Dziembowski, S., Faust, S., Herold, G., Journault, A., Masny, D., and F. Standaert, "Towards Sound Fresh Re-Keying with Hard (Physical) Learning Problems", Cryptology ePrint Archive, Report 2016/573, June 2016,https://eprint.iacr.org/2016/573.[GGM]Goldreich, O., Goldwasser, S., and S. Micali, "How to Construct Random Functions", Journal of the Association for Computing Machinery, Volume 33, No. 4, pp. 792-807, DOI 10.1145/6490.6503, October 1986,https://dl.acm.org/citation.cfm?doid=6490.6503.[KMNT2003]Kim, Y., Maino, F., Narasimha, M., and G. Tsudik, "Secure Group Services for Storage Area Networks", IEEE Communications Magazine 41, Number 8, pp. 92-99, DOI 10.1109/SISW.2002.1183514, August 2003,https://ieeexplore.ieee.org/document/1183514.[LDC]Heys, H., "A Tutorial on Linear and Differential Cryptanalysis", 2001,https://citeseerx.ist.psu.edu/viewdoc/citations?doi=10.1.1.2.2759.[OWT]Joye, M. and S. Yen, "One-Way Cross-Trees and Their Applications", Public Key Cryptography (PKC), Lecture Notes in Computer Science, Volume 2274, DOI 10.1007/3-540-45664-3_25, February 2002,https://link.springer.com/content/pdf/10.1007%2F3-540-45664-3_25.pdf.[P3]Alexander, P., "Subject: [Cfrg] Dynamic Key Changes on Encrypted Sessions. - Draft I-D Attached", message to the CFRG mailing list, 4 November 2017,https://mailarchive.ietf.org/arch/msg/cfrg/ecTR3Hb-DFfrPCVmY0ghyYOEcxU.[Pietrzak2009]Pietrzak, K., "A Leakage-Resilient Mode of Operation", EUROCRYPT 2009, Lecture Notes in Computer Science, Volume 5479, pp. 462-482, DOI 10.1007/978-3-642-01001-9_27, April 2009,https://iacr.org/archive/eurocrypt2009/54790461/54790461.pdf.[SIGNAL]Perrin, T., Ed. and M. Marlinspike, "The Double Ratchet Algorithm", November 2016,https://signal.org/docs/specifications/doubleratchet/doubleratchet.pdf.[Sweet32]Bhargavan, K. and G. Leurent, "On the Practical (In-)Security of 64-bit Block Ciphers: Collision Attacks on HTTP over TLS and OpenVPN", Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security, pp. 456-467, DOI 10.1145/2976749.2978423, October 2016,https://sweet32.info/SWEET32_CCS16.pdf.[TAHA]Taha, M. and P. Schaumont, "Key Updating for Leakage Resiliency With Application to AES Modes of Operation", IEEE Transactions on Information Forensics and Security, DOI 10.1109/TIFS.2014.2383359, December 2014,http://ieeexplore.ieee.org/document/6987331/.[TEMPEST]Ramsay, C. and J. Lohuis, "TEMPEST attacks against AES. Covertly stealing keys for 200 euro", June 2017,https://www.fox-it.com/en/wp-content/uploads/sites/11/Tempest_attacks_against_AES.pdf.[U2F]Chang, D., Mishra, S., Sanadhya, S., and A. Singh, "On Making U2F Protocol Leakage-Resilient via Re-keying", Cryptology ePrint Archive, Report 2017/721, August 2017,https://eprint.iacr.org/2017/721.pdf.
Appendix A. Test Examples ๐งช
A.1. Test Examples for External Re-keying ๐
A.1.1. External Re-keying with a Parallel Construction โจ
okay bestie, first up is the parallel construction ๐ here's the AES-256 one:
External re-keying with a parallel construction based on AES-256
****************************************************************
k = 256
t = 128
Initial key:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
K^1:
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
64 7D 5C D5 1C 3D 62 98 BC 09 B1 D8 64 EC D9 B1
K^2:
6F ED F5 D3 77 57 48 75 35 2B 5F 4D B6 5B E0 15
B8 02 92 32 D8 D3 8D 73 FE DC DD C6 C8 36 78 BD
K^3:
B6 40 24 85 A4 24 BD 35 B4 26 43 13 76 26 70 B6
5B F3 30 3D 3B 20 EB 14 D1 3B B7 91 74 E3 DB EC
...
K^126:
2F 3F 15 1B 53 88 23 CD 7D 03 FC 3D FD B3 57 5E
23 E4 1C 4E 46 FF 6B 33 34 12 27 84 EF 5D 82 23
K^127:
8E 51 31 FB 0B 64 BB D0 BC D4 C5 7B 1C 66 EF FD
97 43 75 10 6C AF 5D 5E 41 E0 17 F4 05 63 05 ED
K^128:
77 4F BF B3 22 60 C5 3B A3 8E FE B1 96 46 76 41
94 49 AF 84 2D 84 65 A7 F4 F7 2C DC A4 9D 84 F9
and now the SHA-256 version, which is very much giving ๐
External re-keying with a parallel construction based on SHA-256
****************************************************************
k = 256
t = 128
label:
SHA2label
Initial key:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
K^1:
C1 A1 4C A0 30 29 BE 43 9F 35 3C 79 1A 51 48 57
26 7A CD 5A E8 7D E7 D1 B2 E2 C7 AF A4 29 BD 35
K^2:
03 68 BB 74 41 2A 98 ED C4 7B 94 CC DF 9C F4 9E
A9 B8 A9 5F 0E DC 3C 1E 3B D2 59 4D D1 75 82 D4
K^3:
2F D3 68 D3 A7 8F 91 E6 3B 68 DC 2B 41 1D AC 80
0A C3 14 1D 80 26 3E 61 C9 0D 24 45 2A BD B1 AE
...
K^126:
55 AC 2B 25 00 78 3E D4 34 2B 65 0E 75 E5 8B 76
C8 04 E9 D3 B6 08 7D C0 70 2A 99 A4 B5 85 F1 A1
K^127:
77 4D 15 88 B0 40 90 E5 8C 6A D7 5D 0F CF 0A 4A
6C 23 F1 B3 91 B1 EF DF E5 77 64 CD 09 F5 BC AF
K^128:
E5 81 FF FB 0C 90 88 CD E5 F4 A5 57 B6 AB D2 2E
94 C3 42 06 41 AB C1 72 66 CC 2F 59 74 9C 86 B3
A.1.2. External Re-keying with a Serial Construction ๐ฆ
here's the serial one! AES-256 first:
External re-keying with a serial construction based on AES-256
**************************************************************
AES 256 examples:
k = 256
t = 128
Initial key:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
K*_1:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
K^1:
66 B8 BD E5 90 6C EC DF FA 8A B2 FD 92 84 EB F0
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
K*_2:
64 7D 5C D5 1C 3D 62 98 BC 09 B1 D8 64 EC D9 B1
6F ED F5 D3 77 57 48 75 35 2B 5F 4D B6 5B E0 15
K^2:
66 B8 BD E5 90 6C EC DF FA 8A B2 FD 92 84 EB F0
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
K*_3:
64 7D 5C D5 1C 3D 62 98 BC 09 B1 D8 64 EC D9 B1
6F ED F5 D3 77 57 48 75 35 2B 5F 4D B6 5B E0 15
K^3:
66 B8 BD E5 90 6C EC DF FA 8A B2 FD 92 84 EB F0
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
...
K*_126:
64 7D 5C D5 1C 3D 62 98 BC 09 B1 D8 64 EC D9 B1
6F ED F5 D3 77 57 48 75 35 2B 5F 4D B6 5B E0 15
K^126:
66 B8 BD E5 90 6C EC DF FA 8A B2 FD 92 84 EB F0
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
K*_127:
64 7D 5C D5 1C 3D 62 98 BC 09 B1 D8 64 EC D9 B1
6F ED F5 D3 77 57 48 75 35 2B 5F 4D B6 5B E0 15
K^127:
66 B8 BD E5 90 6C EC DF FA 8A B2 FD 92 84 EB F0
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
K*_128:
64 7D 5C D5 1C 3D 62 98 BC 09 B1 D8 64 EC D9 B1
6F ED F5 D3 77 57 48 75 35 2B 5F 4D B6 5B E0 15
K^128:
66 B8 BD E5 90 6C EC DF FA 8A B2 FD 92 84 EB F0
51 16 8A B6 C8 A8 38 65 54 85 31 A5 D2 BA C3 86
and the SHA-256 serial version, which is an absolute mood ๐
External re-keying with a serial construction based on SHA-256
**************************************************************
k = 256
t = 128
Initial key:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
label1:
SHA2label1
label2:
SHA2label2
K*_1:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
K^1:
2D A8 D1 37 6C FD 52 7F F7 36 A4 E2 81 C6 0A 9B
F3 8E 66 97 ED 70 4F B5 FB 10 33 CC EC EE D5 EC
K*_2:
14 65 5A D1 7C 19 86 24 9B D3 56 DF CC BE 73 6F
52 62 4A 9D E3 CC 40 6D A9 48 DA 5C D0 68 8A 04
K^2:
2F EA 8D 57 2B EF B8 89 42 54 1B 8C 1B 3F 8D B1
84 F9 56 C7 FE 01 11 99 1D FB 98 15 FE 65 85 CF
K*_3:
18 F0 B5 2A D2 45 E1 93 69 53 40 55 43 70 95 8D
70 F0 20 8C DF B0 5D 67 CD 1B BF 96 37 D3 E3 EB
K^3:
53 C7 4E 79 AE BC D1 C8 24 04 BF F6 D7 B1 AC BF
F9 C0 0E FB A8 B9 48 29 87 37 E1 BA E7 8F F7 92
...
K*_126:
A3 6D BF 02 AA 0B 42 4A F2 C0 46 52 68 8B C7 E6
5E F1 62 C3 B3 2F DD EF E4 92 79 5D BB 45 0B CA
K^126:
6C 4B D6 22 DC 40 48 0F 29 C3 90 B8 E5 D7 A7 34
23 4D 34 65 2C CE 4A 76 2C FE 2A 42 C8 5B FE 9A
K*_127:
84 5F 49 3D B8 13 1D 39 36 2B BE D3 74 8F 80 A1
05 A7 07 37 BA 15 72 E0 73 49 C2 67 5D 0A 28 A1
K^127:
57 F0 BD 5A B8 2A F3 6B 87 33 CF F7 22 62 B4 D0
F0 EE EF E1 50 74 E5 BA 13 C1 23 68 87 36 29 A2
K*_128:
52 F2 0F 56 5C 9C 56 84 AF 69 AD 45 EE B8 DA 4E
7A A6 04 86 35 16 BA 98 E4 CB 46 D2 E8 9A C1 09
K^128:
9B DD 24 7D F3 25 4A 75 E0 22 68 25 68 DA 9D D5
C1 6D 2D 2B 4F 3F 1F 2B 5E 99 82 7F 15 A1 4F A4
A.2. Test Examples for Internal Re-keying ๐ธ
now we're getting into the internal re-keying vibes, and the test vectors are sooo detailed ๐ญ
A.2.1. Internal Re-keying Mechanisms that Do Not Require a Master Key ๐
first up is CTR-ACPKM with AES-256:
CTR-ACPKM mode with AES-256
***************************
k = 256
n = 128
c = 64
N = 256
Initial key K:
00000: 88 99 AA BB CC DD EE FF 00 11 22 33 44 55 66 77
00010: FE DC BA 98 76 54 32 10 01 23 45 67 89 AB CD EF
Plaintext P:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
00010: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
00020: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
00030: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
00040: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
00050: 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
00060: 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44
ICN:
12 34 56 78 90 AB CE F0 A1 B2 C3 D4 E5 F0 01 12
23 34 45 56 67 78 89 90 12 13 14 15 16 17 18 19
D_1:
00000: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
D_2:
00000: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
Section_1
Section key K^1:
00000: 88 99 AA BB CC DD EE FF 00 11 22 33 44 55 66 77
00010: FE DC BA 98 76 54 32 10 01 23 45 67 89 AB CD EF
Input block CTR_1:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 00
Output block G_1:
00000: FD 7E F8 9A D9 7E A4 B8 8D B8 B5 1C 1C 9D 6D D0
Input block CTR_2:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 01
Output block G_2:
00000: 19 98 C5 71 76 37 FB 17 11 E4 48 F0 0C 0D 60 B2
Section_2
Section key K^2:
00000: F6 80 D1 21 2F A4 3D F4 EC 3A 91 DE 2A B1 6F 1B
00010: 36 B0 48 8A 4F C1 2E 09 98 D2 E4 A8 88 E8 4F 3D
Input block CTR_3:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 02
Output block G_3:
00000: E4 88 89 4F B6 02 87 DB 77 5A 07 D9 2C 89 46 EA
Input block CTR_4:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 03
Output block G_4:
00000: BC 4F 87 23 DB F0 91 50 DD B4 06 C3 1D A9 7C A4
Section_3
Section key K^3:
00000: 8E B9 7E 43 27 1A 42 F1 CA 8E E2 5F 5C C7 C8 3B
00010: 1A CE 9E 5E D0 6A A5 3B 57 B9 6A CF 36 5D 24 B8
Input block CTR_5:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 04
Output block G_5:
00000: 68 6F 22 7D 8F B2 9C BD 05 C8 C3 7D 22 FE 3B B7
Input block CTR_6:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 05
Output block G_6:
00000: C0 1B F9 7F 75 6E 12 2F 80 59 55 BD DE 2D 45 87
Section_4
Section key K^4:
00000: C5 71 6C C9 67 98 BC 2D 4A 17 87 B7 8A DF 94 AC
00010: E8 16 F8 0B DB BC AD 7D 60 78 12 9C 0C B4 02 F5
Block number 7:
Input block CTR_7:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 06
Output block G_7:
00000: 03 DE 34 74 AB 9B 65 8A 3B 54 1E F8 BD 2B F4 7D
The result G = G_1 | G_2 | G_3 | G_4 | G_5 | G_6 | G_7:
00000: FD 7E F8 9A D9 7E A4 B8 8D B8 B5 1C 1C 9D 6D D0
00010: 19 98 C5 71 76 37 FB 17 11 E4 48 F0 0C 0D 60 B2
00020: E4 88 89 4F B6 02 87 DB 77 5A 07 D9 2C 89 46 EA
00030: BC 4F 87 23 DB F0 91 50 DD B4 06 C3 1D A9 7C A4
00040: 68 6F 22 7D 8F B2 9C BD 05 C8 C3 7D 22 FE 3B B7
00050: C0 1B F9 7F 75 6E 12 2F 80 59 55 BD DE 2D 45 87
00060: 03 DE 34 74 AB 9B 65 8A 3B 54 1E F8 BD 2B F4 7D
The result ciphertext C = P (xor) MSB_{|P|}(G):
00000: EC 5C CB DE 8C 18 D3 B8 72 56 68 D0 A7 37 F4 58
00010: 19 89 E7 42 32 62 9D 60 99 7D E2 4B C0 E3 9F B8
00020: F5 AA BA 0B E3 64 F0 53 EE F0 BC 15 C2 76 4C EA
00030: 9E 7C C3 76 BD 87 19 C9 77 0F CA 2D E2 A3 7C B5
00040: 5B 2B 77 1B F8 3A 05 17 BE 04 2D 82 28 FE 2A 95
00050: 84 4E 9F 08 FD F7 B8 94 4C B7 AA B7 DE 3C 67 B4
00060: 56 B8 43 FC 32 31 DE 46 D5 AB 14 F8 AC 09 C7 39
and then GCM-ACPKM with AES-128, which is sooo pretty ๐ง
GCM-ACPKM mode with AES-128
***************************
k = 128
n = 128
c = 32
N = 256
Initial key K:
00000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Additional data A:
00000: 11 22 33
Plaintext:
00000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ICN:
00000: 00 00 00 00 00 00 00 00 00 00 00 00
Number of sections: 2
Section key K^1:
00000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Section key K^2:
00000: 15 1A 9F B0 B6 AC C5 97 6A FB 50 31 D1 DE C8 41
Encrypted GCTR_1 | GCTR_2 | GCTR_3:
00000: 03 88 DA CE 60 B6 A3 92 F3 28 C2 B9 71 B2 FE 78
00010: F7 95 AA AB 49 4B 59 23 F7 FD 89 FF 94 8B C1 E0
00020: D6 B3 12 46 E9 CE 9F F1 3A B3 42 7E E8 91 96 AD
Ciphertext C:
00000: 03 88 DA CE 60 B6 A3 92 F3 28 C2 B9 71 B2 FE 78
00010: F7 95 AA AB 49 4B 59 23 F7 FD 89 FF 94 8B C1 E0
00020: D6 B3 12 46 E9 CE 9F F1 3A B3 42 7E E8 91 96 AD
GHASH input:
00000: 11 22 33 00 00 00 00 00 00 00 00 00 00 00 00 00
00010: 03 88 DA CE 60 B6 A3 92 F3 28 C2 B9 71 B2 FE 78
00020: F7 95 AA AB 49 4B 59 23 F7 FD 89 FF 94 8B C1 E0
00030: D6 B3 12 46 E9 CE 9F F1 3A B3 42 7E E8 91 96 AD
00040: 00 00 00 00 00 00 00 18 00 00 00 00 00 00 01 80
GHASH output S:
00000: E8 ED E9 94 9A DD 55 30 B0 F4 4E F5 00 FC 3E 3C
Authentication tag T:
00000: B0 0F 15 5A 60 A3 65 51 86 8B 53 A2 A4 1B 7B 66
The result C | T:
00000: 03 88 DA CE 60 B6 A3 92 F3 28 C2 B9 71 B2 FE 78
00010: F7 95 AA AB 49 4B 59 23 F7 FD 89 FF 94 8B C1 E0
00020: D6 B3 12 46 E9 CE 9F F1 3A B3 42 7E E8 91 96 AD
00030: B0 0F 15 5A 60 A3 65 51 86 8B 53 A2 A4 1B 7B 66
A.2.2. Internal Re-keying Mechanisms with a Master Key ๐
last but not least, the master key one! CTR-ACPKM-Master with AES-256:
CTR-ACPKM-Master mode with AES-256
**********************************
k = 256
n = 128
c for CTR-ACPKM mode = 64
c for CTR-ACPKM-Master mode = 64
N = 256
T* = 512
Initial key K:
00000: 88 99 AA BB CC DD EE FF 00 11 22 33 44 55 66 77
00010: FE DC BA 98 76 54 32 10 01 23 45 67 89 AB CD EF
Initial vector ICN:
00000: 12 34 56 78 90 AB CE F0 A1 B2 C3 D4 E5 F0 01 12
Plaintext P:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
00010: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
00020: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
00030: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
00040: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
00050: 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
00060: 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44
Okay bestie, the keys are about to get SO cute ๐๐
K^1 | K^2 | K^3 | K^4:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
00020: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00030: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
00040: E8 76 2B 30 8B 08 EB CE 3E 93 9A C2 C0 3E 76 D4
00050: 60 9A AB D9 15 33 13 D3 CF D3 94 E7 75 DF 3A 94
00060: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00070: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
Section_1
K^1:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
Input block CTR_1:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 00
Output block G_1:
00000: 8C A2 B6 82 A7 50 65 3F 8E BF 08 E7 9F 99 4D 5C
Input block CTR_2:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 01
Output block G_2:
00000: F6 A6 A5 BA 58 14 1E ED 23 DC 31 68 D2 35 89 A1
Section_2
K^2:
00000: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00010: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
Input block CTR_3:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 02
Output block G_3:
00000: 4A 07 5F 86 05 87 72 94 1D 8E 7D F8 32 F4 23 71
Input block CTR_4:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 03
Output block G_4:
00000: 23 35 66 AF 61 DD FE A7 B1 68 3F BA B0 52 4A D7
Section_3
K^3:
00000: E8 76 2B 30 8B 08 EB CE 3E 93 9A C2 C0 3E 76 D4
00010: 60 9A AB D9 15 33 13 D3 CF D3 94 E7 75 DF 3A 94
Input block CTR_5:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 04
Output block G_5:
00000: A8 09 6D BC E8 BB 52 FC DE 6E 03 70 C1 66 95 E8
Input block CTR_6:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 05
Output block G_6:
00000: C6 E3 6E 8E 5B 82 AA C4 A6 6C 14 8D B1 F6 9B EF
Section_4
K^4:
00000: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00010: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
Input block CTR_7:
00000: 12 34 56 78 90 AB CE F0 00 00 00 00 00 00 00 06
Output block G_7:
00000: 82 2B E9 07 96 37 44 95 75 36 3F A7 07 F8 40 22
The result G = G_1 | G_2 | G_3 | G_4 | G_5 | G_6 | G_7:
00000: 8C A2 B6 82 A7 50 65 3F 8E BF 08 E7 9F 99 4D 5C
00010: F6 A6 A5 BA 58 14 1E ED 23 DC 31 68 D2 35 89 A1
00020: 4A 07 5F 86 05 87 72 94 1D 8E 7D F8 32 F4 23 71
00030: 23 35 66 AF 61 DD FE A7 B1 68 3F BA B0 52 4A D7
00040: A8 09 6D BC E8 BB 52 FC DE 6E 03 70 C1 66 95 E8
00050: C6 E3 6E 8E 5B 82 AA C4 A6 6C 14 8D B1 F6 9B EF
00060: 82 2B E9 07 96 37 44 95 75 36 3F A7 07 F8 40 22
The result ciphertext C = P (xor) MSB_{|P|}(G):
00000: 9D 80 85 C6 F2 36 12 3F 71 51 D5 2B 24 33 D4 D4
00010: F6 B7 87 89 1C 41 78 9A AB 45 9B D3 1E DB 76 AB
00020: 5B 25 6C C2 50 E1 05 1C 84 24 C6 34 DC 0B 29 71
00030: 01 06 22 FA 07 AA 76 3E 1B D3 F3 54 4F 58 4A C6
00040: 9B 4D 38 DA 9F 33 CB 56 65 A2 ED 8F CB 66 84 CA
00050: 82 B6 08 F9 D3 1B 00 7F 6A 82 EB 87 B1 E7 B9 DC
00060: D7 4D 9E 8F 0F 9D FF 59 9B C9 35 A7 16 DA 73 66
Next up is GCM-ACPKM-Master with AES-256, and this part is giving main character energy โจ๐ฆ
GCM-ACPKM-Master mode with AES-256
**********************************
k = 192
n = 128
c for the CTR-ACPKM mode = 64
c for the GCM-ACPKM-Master mode = 32
T* = 384
N = 256
Initial key K:
00000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00010: 00 00 00 00 00 00 00 00
Additional data A:
00000: 11 22 33
Plaintext:
00000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ICN:
00000: 00 00 00 00 00 00 00 00 00 00 00 00
Number of sections: 3
K^1 | K^2 | K^3:
00000: 93 BA AF FB 35 FB E7 39 C1 7C 6A C2 2E EC F1 8F
00010: 7B 89 F0 BF 8B 18 07 05 96 48 68 9F 36 A7 65 CC
00020: CD 5D AC E2 0D 47 D9 18 D7 86 D0 41 A8 3B AB 99
00030: F5 F8 B1 06 D2 71 78 B1 B0 08 C9 99 0B 72 E2 87
00040: 5A 2D 3C BE F1 6E 67 3C
Encrypted GCTR_1 | ... | GCTR_5
00000: 43 FA 71 81 64 B1 E3 D7 1E 7B 65 39 A7 02 1D 52
00010: 69 9B 9E 1B 43 24 B7 52 95 74 E7 90 F2 BE 60 E8
00020: 11 62 C9 90 2A 2B 77 7F D9 6A D6 1A 99 E0 C6 DE
00030: 4B 91 D4 29 E3 1A 8C 11 AF F0 BC 47 F6 80 AF 14
00040: 40 1C C1 18 14 63 8E 76 24 83 37 75 16 34 70 08
Ciphertext C:
00000: 43 FA 71 81 64 B1 E3 D7 1E 7B 65 39 A7 02 1D 52
00010: 69 9B 9E 1B 43 24 B7 52 95 74 E7 90 F2 BE 60 E8
00020: 11 62 C9 90 2A 2B 77 7F D9 6A D6 1A 99 E0 C6 DE
00030: 4B 91 D4 29 E3 1A 8C 11 AF F0 BC 47 F6 80 AF 14
00040: 40 1C C1 18 14 63 8E 76 24 83 37 75 16 34 70 08
GHASH input:
00000: 11 22 33 00 00 00 00 00 00 00 00 00 00 00 00 00
00010: 43 FA 71 81 64 B1 E3 D7 1E 7B 65 39 A7 02 1D 52
00020: 69 9B 9E 1B 43 24 B7 52 95 74 E7 90 F2 BE 60 E8
00030: 11 62 C9 90 2A 2B 77 7F D9 6A D6 1A 99 E0 C6 DE
00040: 4B 91 D4 29 E3 1A 8C 11 AF F0 BC 47 F6 80 AF 14
00050: 40 1C C1 18 14 63 8E 76 24 83 37 75 16 34 70 08
00060: 00 00 00 00 00 00 00 18 00 00 00 00 00 00 02 80
GHASH output S:
00000: 6E A3 4B D5 6A C5 40 B7 3E 55 D5 86 D1 CC 09 7D
Authentication tag T:
00050: CC 3A BA 11 8C E7 85 FD 77 78 94 D4 B5 20 69 F8
The result C | T:
00000: 43 FA 71 81 64 B1 E3 D7 1E 7B 65 39 A7 02 1D 52
00010: 69 9B 9E 1B 43 24 B7 52 95 74 E7 90 F2 BE 60 E8
00020: 11 62 C9 90 2A 2B 77 7F D9 6A D6 1A 99 E0 C6 DE
00030: 4B 91 D4 29 E3 1A 8C 11 AF F0 BC 47 F6 80 AF 14
00040: 40 1C C1 18 14 63 8E 76 24 83 37 75 16 34 70 08
00050: CC 3A BA 11 8C E7 85 FD 77 78 94 D4 B5 20 69 F8
Now CBC-ACPKM-Master with AES-256, and it's a whole vibe ๐ ๐ธ
CBC-ACPKM-Master mode with AES-256
**********************************
k = 256
n = 128
c for the CTR-ACPKM mode = 64
N = 256
T* = 512
Initial key K:
00000: 88 99 AA BB CC DD EE FF 00 11 22 33 44 55 66 77
00010: FE DC BA 98 76 54 32 10 01 23 45 67 89 AB CD EF
Initial vector IV:
00000: 12 34 56 78 90 AB CE F0 A1 B2 C3 D4 E5 F0 01 12
Plaintext P:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
00010: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
00020: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
00030: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
00040: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
00050: 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
00060: 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44
K^1 | K^2 | K^3 | K^4:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
00020: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00030: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
00040: E8 76 2B 30 8B 08 EB CE 3E 93 9A C2 C0 3E 76 D4
00050: 60 9A AB D9 15 33 13 D3 CF D3 94 E7 75 DF 3A 94
00060: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00070: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
Section_1
K^1:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
Plaintext block P_1:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
Input block P_1 (xor) C_0:
00000: 03 16 65 3C C5 CD B9 F0 5E 5C 1E 18 5E 5A 98 9A
Output block C_1:
00000: 59 CB 5B CA C2 69 2C 60 0D 46 03 A0 C7 40 C9 7C
Plaintext block P_2:
00000: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
Input block P_2 (xor) C_1:
00000: 59 DA 79 F9 86 3C 4A 17 85 DF A9 1B 0B AE 36 76
Output block C_2:
00000: 80 B6 02 74 54 8B F7 C9 78 1F A1 05 8B F6 8B 42
Section_2
K^2:
00000: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00010: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
Plaintext block P_3:
00000: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
Input block P_3 (xor) C_2:
00000: 91 94 31 30 01 ED 80 41 E1 B5 1A C9 65 09 81 42
Output block C_3:
00000: 8C 24 FB CF 68 15 B1 AF 65 FE 47 75 95 B4 97 59
Plaintext block P_4:
00000: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
Input block P_4 (xor) C_3:
00000: AE 17 BF 9A 0E 62 39 36 CF 45 8B 9B 6A BE 97 48
Output block C_4:
00000: 19 65 A5 00 58 0D 50 23 72 1B E9 90 E1 83 30 E9
Section_3
K^3:
00000: E8 76 2B 30 8B 08 EB CE 3E 93 9A C2 C0 3E 76 D4
00010: 60 9A AB D9 15 33 13 D3 CF D3 94 E7 75 DF 3A 94
Plaintext block P_5:
00000: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
Input block P_5 (xor) C_4:
00000: 2A 21 F0 66 2F 85 C9 89 C9 D7 07 6F EB 83 21 CB
Output block C_5:
00000: 56 D8 34 F4 6F 0F 4D E6 20 53 A9 5C B5 F6 3C 14
Plaintext block P_6:
00000: 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
Input block P_6 (xor) C_5:
00000: 12 8D 52 83 E7 96 E7 5D EC BD 56 56 B5 E7 1E 27
Output block C_6:
00000: 66 68 2B 8B DD 6E B2 7E DE C7 51 D6 2F 45 A5 45
Section_4
K^4:
00000: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00010: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
Plaintext block P_7:
00000: 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33 44
Input block P_7 (xor) C_6:
00000: 33 0E 5C 03 44 C4 09 B2 30 38 5B D6 3E 67 96 01
Output block C_7:
00000: 7F 4D 87 F9 CA E9 56 09 79 C4 FA FE 34 0B 45 34
Ciphertext C:
00000: 59 CB 5B CA C2 69 2C 60 0D 46 03 A0 C7 40 C9 7C
00010: 80 B6 02 74 54 8B F7 C9 78 1F A1 05 8B F6 8B 42
00020: 8C 24 FB CF 68 15 B1 AF 65 FE 47 75 95 B4 97 59
00030: 19 65 A5 00 58 0D 50 23 72 1B E9 90 E1 83 30 E9
00040: 56 D8 34 F4 6F 0F 4D E6 20 53 A9 5C B5 F6 3C 14
00050: 66 68 2B 8B DD 6E B2 7E DE C7 51 D6 2F 45 A5 45
00060: 7F 4D 87 F9 CA E9 56 09 79 C4 FA FE 34 0B 45 34
Last bit of this part: CFB-ACPKM-Master with AES-256, and it's giving pure elegance ๐ง๐
CFB-ACPKM-Master mode with AES-256
**********************************
k = 256
n = 128
c for the CTR-ACPKM mode = 64
N = 256
T* = 512
Initial key K:
00000: 88 99 AA BB CC DD EE FF 00 11 22 33 44 55 66 77
00010: FE DC BA 98 76 54 32 10 01 23 45 67 89 AB CD EF
Initial vector IV:
00000: 12 34 56 78 90 AB CE F0 A1 B2 C3 D4 E5 F0 01 12
Plaintext P:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
00010: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
00020: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
00030: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
00040: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
00050: 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
00060: 55 66 77 88 99 AA BB CC
K^1 | K^2 | K^3 | K^4
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
00020: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00030: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
00040: E8 76 2B 30 8B 08 EB CE 3E 93 9A C2 C0 3E 76 D4
00050: 60 9A AB D9 15 33 13 D3 CF D3 94 E7 75 DF 3A 94
00060: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00070: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
Section_1
K^1:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
Plaintext block P_1:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
Encrypted block E_{K^1}(C_0):
00000: 1C 39 9D 59 F8 5D 91 91 A9 D2 12 9F 63 15 90 03
Output block C_1 = E_{K^1}(C_0) (xor) P_1:
00000: 0D 1B AE 1D AD 3B E6 91 56 3C CF 53 D8 BF 09 8B
Plaintext block P_2:
00000: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
Encrypted block E_{K^1}(C_1):
00000: 6B A2 C5 42 52 69 C6 0B 15 14 06 87 90 46 F6 2E
Okay, the test vectors keep going, and the numbers are giving me chills ๐ฆ
Output block C_2 = E_{K^1}(C_1) (xor) P_2:
00000: 6B B3 E7 71 16 3C A0 7C 9D 8D AC 3C 5C A8 09 24
Section_2
K^2:
00000: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00010: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
Plaintext block P_3:
00000: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
Encrypted block E_{K^2}(C_2):
00000: 95 45 5F DB C3 9E 0A 13 9F CB 10 F5 BD 79 A3 88
Output block C_3 = E_{K^2}(C_2) (xor) P_3:
00000: 84 67 6C 9F 96 F8 7D 9B 06 61 AB 39 53 86 A9 88
Plaintext block P_4:
00000: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
Encrypted block E_{K^2}(C_3):
00000: E0 AA 32 5D 80 A4 47 95 BA 42 BF 63 F8 4A C8 B2
Output block C_4 = E_{K^2}(C_3) (xor) P_4:
00000: C2 99 76 08 E6 D3 CF 0C 10 F9 73 8D 07 40 C8 A3
Section_3
K^3:
00000: E8 76 2B 30 8B 08 EB CE 3E 93 9A C2 C0 3E 76 D4
00010: 60 9A AB D9 15 33 13 D3 CF D3 94 E7 75 DF 3A 94
Plaintext block P_5:
00000: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
Encrypted block E_{K^3}(C_4):
00000: FE 42 8C 70 C2 51 CE 13 36 C1 BF 44 F8 49 66 89
Output block C_5 = E_{K^3}(C_4) (xor) P_5:
00000: CD 06 D9 16 B5 D9 57 B9 8D 0D 51 BB F2 49 77 AB
Plaintext block P_6:
00000: 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22 33
Encrypted block E_{K^3}(C_5):
00000: 01 24 80 87 86 18 A5 43 11 0A CC B5 0A E5 02 A3
Output block C_6 = E_{K^3}(C_5) (xor) P_6:
00000: 45 71 E6 F0 0E 81 0F F8 DD E4 33 BF 0A F4 20 90
Section_4
K^4:
00000: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00010: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
Plaintext block P_7:
00000: 55 66 77 88 99 AA BB CC
Encrypted block MSB_{|P_7|}(E_{K^4}(C_6)):
00000: 97 5C 96 37 55 1E 8C 7F
Output block C_7 = MSB_{|P_7|}(E_{K^4}(C_6)) (xor) P_7
00000: C2 3A E1 BF CC B4 37 B3
Ciphertext C:
00000: 0D 1B AE 1D AD 3B E6 91 56 3C CF 53 D8 BF 09 8B
00010: 6B B3 E7 71 16 3C A0 7C 9D 8D AC 3C 5C A8 09 24
00020: 84 67 6C 9F 96 F8 7D 9B 06 61 AB 39 53 86 A9 88
00030: C2 99 76 08 E6 D3 CF 0C 10 F9 73 8D 07 40 C8 A3
00040: CD 06 D9 16 B5 D9 57 B9 8D 0D 51 BB F2 49 77 AB
00050: 45 71 E6 F0 0E 81 0F F8 DD E4 33 BF 0A F4 20 90
00060: C2 3A E1 BF CC B4 37 B3
Now the OMAC-ACPKM-Master run with AES-256 setup, which is the parameter list and all the starting inputs bestie needs ๐
OMAC-ACPKM-Master mode with AES-256
***********************************
k = 256
n = 128
c for the CTR-ACPKM mode = 64
N = 256
T* = 768
Initial key K:
00000: 88 99 AA BB CC DD EE FF 00 11 22 33 44 55 66 77
00010: FE DC BA 98 76 54 32 10 01 23 45 67 89 AB CD EF
Plaintext M:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
00010: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
00020: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
00030: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
00040: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
K^1 | K^1_1 | K^2 | K^2_1 | K^3 | K^3_1:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
00020: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
00030: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
00040: 9D CC 66 42 0D FF 45 5B 21 F3 93 F0 D4 D6 6E 67
00050: BB 1B 06 0B 87 66 6D 08 7A 9D A7 49 55 C3 5B 48
00060: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00070: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
00080: 78 21 C7 C7 6C BD 79 63 56 AC F8 8E 69 6A 00 07
Section_1
K^1:
00000: 9F 10 BB F1 3A 79 FB BD 4A 4C A8 64 C4 90 74 64
00010: 39 FE 50 6D 4B 86 9B 21 03 A3 B6 A4 79 28 3C 60
K^1_1:
00000: 77 91 17 50 E0 D1 77 E5 9A 13 78 2B F1 89 08 D0
Plaintext block M_1:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
Input block M_1 (xor) C_0:
00000: 11 22 33 44 55 66 77 00 FF EE DD CC BB AA 99 88
Output block C_1:
00000: 0B A5 89 BF 55 C1 15 42 53 08 89 76 A0 FE 24 3E
Plaintext block M_2:
00000: 00 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A
Input block M_2 (xor) C_1:
00000: 0B B4 AB 8C 11 94 73 35 DB 91 23 CD 6C 10 DB 34
Output block C_2:
00000: 1C 53 DD A3 6D DC E1 17 ED 1F 14 09 D8 6A F3 2C
Section_2 is next, and the key schedule gets spicy here ๐ฅ
Section_2
K^2:
00000: AB 6B 59 EE 92 49 05 B3 AB C7 A4 E3 69 65 76 C3
00010: 9D CC 66 42 0D FF 45 5B 21 F3 93 F0 D4 D6 6E 67
K^2_1:
00000: BB 1B 06 0B 87 66 6D 08 7A 9D A7 49 55 C3 5B 48
Plaintext block M_3:
00000: 11 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00
Input block M_3 (xor) C_2:
00000: 0D 71 EE E7 38 BA 96 9F 74 B5 AF C5 36 95 F9 2C
Output block C_3:
00000: 4E D4 BC A6 CE 6D 6D 16 F8 63 85 13 E0 48 59 75
Plaintext block M_4:
00000: 22 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11
Input block M_4 (xor) C_3:
00000: 6C E7 F8 F3 A8 1A E5 8F 52 D8 49 FD 1F 42 59 64
Output block C_4:
00000: B6 83 E3 96 FD 30 CD 46 79 C1 8B 24 03 82 1D 81
Section_3, and this is the last stretch of the message-authentication part ๐ฆ
Section_3
K^3:
00000: F2 EE 91 45 6B DC 3D E4 91 2C 87 C3 29 CF 31 A9
00010: 2F 20 2E 5A C4 9A 2A 65 31 33 D6 74 8C 4F F9 12
K^3_1:
00000: 78 21 C7 C7 6C BD 79 63 56 AC F8 8E 69 6A 00 07
MSB1(K1) == 0 -> K2 = K1 << 1
K1:
00000: 78 21 C7 C7 6C BD 79 63 56 AC F8 8E 69 6A 00 07
K2:
00000: F0 43 8F 8E D9 7A F2 C6 AD 59 F1 1C D2 D4 00 0E
Plaintext M_5:
00000: 33 44 55 66 77 88 99 AA BB CC EE FF 0A 00 11 22
Using K1, padding is not required
Input block M_5 (xor) C_4:
00000: FD E6 71 37 E6 05 2D 8F 94 A1 9D 55 60 E8 0C A4
Output block C_5:
00000: B3 AD B8 92 18 32 05 4C 09 21 E7 B8 08 CF A0 B8
Message authentication code T:
00000: B3 AD B8 92 18 32 05 4C 09 21 E7 B8 08 CF A0 B8
Acknowledgments ๐ซถ
Huge thank-yous to Mihir Bellare, Scott Fluhrer, Dorothy Cooley, Yoav Nir, Jim Schaad, Paul Hoffman, Dmitry Belyavsky, Yaron Sheffer, Alexey Melnikov, and Spencer Dawkins for their useful comments. You all made this better, literally iconic ๐
Contributors ๐
These are the people who helped write the thing. Their details are below, exactly as they appear:
Russ Housley
Vigil Security, LLC
housley@vigilsec.com
Evgeny Alekseev
CryptoPro
alekseev@cryptopro.ru
Ekaterina Smyshlyaeva
CryptoPro
ess@cryptopro.ru
Shay Gueron
University of Haifa, Israel
Intel Corporation, Israel Development Center, Israel
shay.gueron@gmail.com
Daniel Fox Franke
Akamai Technologies
dfoxfranke@gmail.com
Lilia Ahmetzyanova
CryptoPro
lah@cryptopro.ru
Author's Address ๐ฆ
The editor, who did a lot of the heavy lifting, is listed here with contact details. Everything is exact, no cap โจ
Stanislav Smyshlyaev (editor)
CryptoPro
18, Suschevskiy val
Moscow 127018
Russian Federation
Phone: +7 (495) 995-48-20
Email: svs@cryptopro.ru
๐ฆ where this page comes from
- ietf: rfc8645 2019-08
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms