1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
use NonZeroU64;
/// The context in which some data is encrypted.
///
/// The main purpose of encrypting data before storing it in the database is to preserve data
/// confidentiality even if an attacker gains access to the database. In order to check whether or
/// not the encryption is efficient, we must therefore consider the database as compromised. A
/// typical scenario is to have an application that encrypts data given by the user before storing
/// it and decrypts it before displaying it back to the user. In this scenario, an user should
/// access its own data only.
///
/// In such a scenario, if the application does not include adequate protections, an attacker
/// having access to the database and having a legitimate user account can trick the application
/// into decrypting and displaying the data of other users. This can be done in several ways. A
/// first way of doing it, is by copying and pasting the victim's encrypted data, at cell level,
/// into the attacker's own data cell. A second way of doing it is for the attacker to edit the
/// list of users having access to the victim's data by adding himself. There may be others way to
/// edit the database in such a way that the application is tricked into thinking the attacker's
/// user account has a legitimate access to the victim's data. This is one of the many forms of the
/// [confused deputy problem](https://en.wikipedia.org/wiki/Confused_deputy_problem).
///
/// In order to solve this vulnerability, a solution is to use additional authenticated data (AAD)
/// which is a feature commonly provided by modern authenticated encryption schemes. Such a feature
/// allows, on encryption, to provide some data that will be used during the computation of the
/// encrypted data's checksum. The exact same AAD must be given upon decryption, otherwise the
/// checksum will be invalid and the decryption process will not take place, resulting in an error.
/// To use this feature to solve the confused deputy problem, you must therefore use the
/// appropriate data in the AAD, which Coffio presents you under the name of DataContext.
///
/// <div class="warning">
/// The ADD, and therefore the DataContext, cannot replace the secret encryption key. If the
/// encrypted data and the encryption key has leaked, an attacker can use a modified version of a
/// cryptographic library to decrypt the data even without having access to the AAD.
/// </div>
///
/// The choice of the data that should be set as DataContext is crucial and depends on how your
/// application works. Please carefully study how your application may be abused before deciding
/// which data will be used. This step may require professional advice from your cryptographer. The
/// most common data used in the DataContext are the encrypted data's row ID as well as the access
/// list.
///
/// <div class="warning">
/// If some data used in the DataContext changes, you have to decrypt the encrypted data before
/// changing it and then re-encrypt it. Failing to do so will result in an error when trying to
/// decrypt the data.
/// </div>
///
/// <div class="warning">
/// The concatenation of the different data parts used in the DataContext may lead to weaknesses if
/// done in a naive way. Coffio does concatenate the different parts in a safe way, which is why
/// you should always give as an array of individual parts instead of a single element.
/// </div>
///
/// # Examples
///
/// ```
/// use coffio::DataContext;
///
/// let my_data_ctx: DataContext = [
/// "0a13e260-6d77-4748-ac53-fd7961a513a1", // row's ID
/// "2b84ecf4-5697-40df-a4cd-627fdccfd09d", // owner's ID
/// ].into();
/// ```
/// The context in which a key is used.
///
/// A good practice is to use a different encryption keys for each kind of data you wish to
/// encrypt. For instance, when encrypting fields in a database, you might want to use a different
/// key for each table, or maybe for each column. It is your responsibility to define the
/// granularity. Considering the key are automatically derived from the
/// [InputKeyMaterial][crate::InputKeyMaterial] (IKM), you should go for a high granularity.
///
/// In order to achieve this, coffio uses the concept of [KeyContext]. The main component of this
/// struct is an array of strings which represents the context in which a key is derived, which
/// means that an IKM will derive different keys if this context is different. Therefore, in order
/// to derive a different key for each column of your database, you should use a key context
/// composed of at least 3 elements: the database name, the table name and the column name.
///
/// ```
/// use coffio::KeyContext;
///
/// let my_key_ctx: KeyContext = [
/// "db name",
/// "table name",
/// "column name",
/// ].into();
/// ```
///
/// As shown in the above example, it is highly recommended to use a separated array elements and
/// let coffio concatenate them in a safe way. Not doing so may result in canonicalization issues
/// and therefore the use of the same context (and encryption key) for different use cases.
///
/// Another element of context can be the date and time of the encryption. To achieve this, coffio
/// allows to set a key periodicity. In this concept, the time is divided in periods of a defined
/// length and a different encryption key will be generated for each of those periods. Therefore,
/// the lower is the period, the more frequently the encryption key will change.
///
/// The default period is set to the value of
/// [DEFAULT_KEY_CTX_PERIODICITY][crate::DEFAULT_KEY_CTX_PERIODICITY].
///
/// In order to be able to derive the correct decryption key, the key period is stored along with
/// the encrypted data. An attacker having access to the encrypted data would therefore be able to
/// know the time period when the data has been encrypted.