1use super::{
6 BufferOwner, DestructionPolicy, ExportPolicy, OutputMaterial, RetentionPolicy,
7 SecretSensitivity, ZeroizationPolicy,
8};
9use crypto_core::RngOutputKind;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13#[non_exhaustive]
14pub enum SecretMaterialOperation {
15 AeadSeal,
17 AeadOpen,
19 ConstantTimeCompare,
21 Hash,
23 MacAuthenticate,
25 MacVerify,
27 KeyDerivation,
29 KeyWrap,
31 KeyUnwrap,
33 SignatureKeyGeneration,
35 SignatureKeyDerivation,
37 SignatureSign,
39 SignatureVerify,
41 KeyAgreementKeyGeneration,
43 KeyAgreementKeyDerivation,
45 KeyAgreementSharedSecret,
47 KemKeyGeneration,
49 KemKeyDerivation,
51 KemEncapsulate,
53 KemDecapsulate,
55 HpkeKeyGeneration,
57 HpkeKeyDerivation,
59 HpkeSenderSetup,
61 HpkeReceiverSetup,
63 HpkeSeal,
65 HpkeOpen,
67 HpkeExport,
69 RandomFill,
71 RandomNonce,
73 RandomSalt,
75 PublicKeyEncoding,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81#[non_exhaustive]
82pub struct MaterialPolicy {
83 pub owner: BufferOwner,
85 pub sensitivity: SecretSensitivity,
87 pub retention: RetentionPolicy,
89 pub zeroization: ZeroizationPolicy,
91 pub export: ExportPolicy,
93 pub destruction: DestructionPolicy,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99#[non_exhaustive]
100pub struct OperationSecretMaterialPolicy {
101 pub input: MaterialPolicy,
103 pub output: MaterialPolicy,
105 pub request_wire: MaterialPolicy,
107 pub response_wire: MaterialPolicy,
109 pub output_material: OutputMaterial,
111}
112
113#[must_use]
115pub const fn operation_secret_material_policy(
116 operation: SecretMaterialOperation,
117) -> OperationSecretMaterialPolicy {
118 match operation {
119 SecretMaterialOperation::AeadSeal | SecretMaterialOperation::KeyWrap => {
120 secret_input_sensitive_output(OutputMaterial::SensitivePublic)
121 }
122 SecretMaterialOperation::AeadOpen
123 | SecretMaterialOperation::KeyUnwrap
124 | SecretMaterialOperation::KeyDerivation
125 | SecretMaterialOperation::KeyAgreementSharedSecret
126 | SecretMaterialOperation::KemDecapsulate
127 | SecretMaterialOperation::HpkeOpen
128 | SecretMaterialOperation::HpkeExport => secret_output(OutputMaterial::Secret),
129 SecretMaterialOperation::RandomFill => caller_owned_secret_output(),
130 SecretMaterialOperation::RandomNonce => public_operation(),
131 SecretMaterialOperation::RandomSalt => {
132 public_input_sensitive_output(OutputMaterial::SensitivePublic)
133 }
134 SecretMaterialOperation::SignatureKeyGeneration
135 | SecretMaterialOperation::KeyAgreementKeyGeneration
136 | SecretMaterialOperation::KemKeyGeneration
137 | SecretMaterialOperation::KemEncapsulate
138 | SecretMaterialOperation::HpkeKeyGeneration => {
139 public_input_secret_output(OutputMaterial::Mixed)
140 }
141 SecretMaterialOperation::SignatureKeyDerivation
142 | SecretMaterialOperation::KeyAgreementKeyDerivation
143 | SecretMaterialOperation::KemKeyDerivation
144 | SecretMaterialOperation::HpkeKeyDerivation => secret_output(OutputMaterial::Mixed),
145 SecretMaterialOperation::HpkeSenderSetup | SecretMaterialOperation::HpkeReceiverSetup => {
146 secret_input_non_exportable_output(OutputMaterial::Mixed)
147 }
148 SecretMaterialOperation::HpkeSeal => {
149 secret_input_sensitive_output(OutputMaterial::SensitivePublic)
150 }
151 SecretMaterialOperation::Hash
152 | SecretMaterialOperation::ConstantTimeCompare
153 | SecretMaterialOperation::MacAuthenticate
154 | SecretMaterialOperation::MacVerify
155 | SecretMaterialOperation::SignatureSign => {
156 secret_input_public_output(OutputMaterial::Public)
157 }
158 SecretMaterialOperation::SignatureVerify | SecretMaterialOperation::PublicKeyEncoding => {
159 public_operation()
160 }
161 }
162}
163
164#[must_use]
166pub const fn random_fill_secret_material_policy(
167 kind: RngOutputKind,
168) -> OperationSecretMaterialPolicy {
169 match kind {
170 RngOutputKind::AeadNonce12 => caller_owned_public_output(),
171 RngOutputKind::Argon2Salt16 | RngOutputKind::Argon2Salt32 => {
172 caller_owned_sensitive_output()
173 }
174 RngOutputKind::Generic
175 | RngOutputKind::Aes256GcmKey
176 | RngOutputKind::MlKem1024Seed
177 | RngOutputKind::MlDsa87Seed
178 | RngOutputKind::Ed25519Seed
179 | RngOutputKind::SlhDsaSha2_128sSeed => caller_owned_secret_output(),
180 _ => caller_owned_secret_output(),
181 }
182}
183
184#[inline]
189pub(crate) const fn bind_operation_policy(
190 operation: SecretMaterialOperation,
191) -> OperationSecretMaterialPolicy {
192 operation_secret_material_policy(operation)
193}
194
195#[inline]
196#[cfg(feature = "csprng")]
197pub(crate) const fn bind_random_fill_policy(kind: RngOutputKind) -> OperationSecretMaterialPolicy {
198 random_fill_secret_material_policy(kind)
199}
200
201const fn secret_input_public_output(
202 output_material: OutputMaterial,
203) -> OperationSecretMaterialPolicy {
204 operation_policy(
205 borrowed_secret(),
206 public_result(),
207 secret_wire(),
208 public_wire(),
209 output_material,
210 )
211}
212
213const fn secret_input_sensitive_output(
214 output_material: OutputMaterial,
215) -> OperationSecretMaterialPolicy {
216 operation_policy(
217 borrowed_secret(),
218 sensitive_result(),
219 secret_wire(),
220 sensitive_wire(),
221 output_material,
222 )
223}
224
225const fn secret_output(output_material: OutputMaterial) -> OperationSecretMaterialPolicy {
226 operation_policy(
227 borrowed_secret(),
228 owned_secret(),
229 secret_wire(),
230 secret_wire(),
231 output_material,
232 )
233}
234
235const fn secret_input_non_exportable_output(
236 output_material: OutputMaterial,
237) -> OperationSecretMaterialPolicy {
238 operation_policy(
239 borrowed_secret(),
240 MaterialPolicy {
241 owner: BufferOwner::OperationLayer,
242 sensitivity: SecretSensitivity::Secret,
243 retention: RetentionPolicy::ResultLifetime,
244 zeroization: ZeroizationPolicy::OwnerZeroizesOnDrop,
245 export: ExportPolicy::NonExportable,
246 destruction: DestructionPolicy::ZeroizeOnDrop,
247 },
248 public_wire(),
249 public_wire(),
250 output_material,
251 )
252}
253
254const fn public_input_secret_output(
255 output_material: OutputMaterial,
256) -> OperationSecretMaterialPolicy {
257 operation_policy(
258 borrowed_public(),
259 owned_secret(),
260 public_wire(),
261 secret_wire(),
262 output_material,
263 )
264}
265
266const fn public_input_sensitive_output(
267 output_material: OutputMaterial,
268) -> OperationSecretMaterialPolicy {
269 operation_policy(
270 borrowed_public(),
271 sensitive_result(),
272 public_wire(),
273 sensitive_wire(),
274 output_material,
275 )
276}
277
278const fn caller_owned_secret_output() -> OperationSecretMaterialPolicy {
279 operation_policy(
280 borrowed_public(),
281 MaterialPolicy {
282 owner: BufferOwner::Caller,
283 sensitivity: SecretSensitivity::Secret,
284 retention: RetentionPolicy::ResultLifetime,
285 zeroization: ZeroizationPolicy::CallerRetainsResponsibility,
286 export: ExportPolicy::SecretOwnerRequired,
287 destruction: DestructionPolicy::CallerControlled,
288 },
289 public_wire(),
290 secret_wire(),
291 OutputMaterial::Secret,
292 )
293}
294
295const fn caller_owned_sensitive_output() -> OperationSecretMaterialPolicy {
296 operation_policy(
297 borrowed_public(),
298 MaterialPolicy {
299 owner: BufferOwner::Caller,
300 sensitivity: SecretSensitivity::Sensitive,
301 retention: RetentionPolicy::ResultLifetime,
302 zeroization: ZeroizationPolicy::OwnerZeroizesOnDrop,
303 export: ExportPolicy::Public,
304 destruction: DestructionPolicy::ZeroizeOnDrop,
305 },
306 public_wire(),
307 sensitive_wire(),
308 OutputMaterial::SensitivePublic,
309 )
310}
311
312const fn caller_owned_public_output() -> OperationSecretMaterialPolicy {
313 operation_policy(
314 borrowed_public(),
315 MaterialPolicy {
316 owner: BufferOwner::Caller,
317 sensitivity: SecretSensitivity::Public,
318 retention: RetentionPolicy::ResultLifetime,
319 zeroization: ZeroizationPolicy::NotRequired,
320 export: ExportPolicy::Public,
321 destruction: DestructionPolicy::NoneRequired,
322 },
323 public_wire(),
324 public_wire(),
325 OutputMaterial::Public,
326 )
327}
328
329const fn public_operation() -> OperationSecretMaterialPolicy {
330 operation_policy(
331 borrowed_public(),
332 public_result(),
333 public_wire(),
334 public_wire(),
335 OutputMaterial::Public,
336 )
337}
338
339const fn operation_policy(
340 input: MaterialPolicy,
341 output: MaterialPolicy,
342 request_wire: MaterialPolicy,
343 response_wire: MaterialPolicy,
344 output_material: OutputMaterial,
345) -> OperationSecretMaterialPolicy {
346 OperationSecretMaterialPolicy {
347 input,
348 output,
349 request_wire,
350 response_wire,
351 output_material,
352 }
353}
354
355const fn borrowed_secret() -> MaterialPolicy {
356 MaterialPolicy {
357 owner: BufferOwner::Caller,
358 sensitivity: SecretSensitivity::Secret,
359 retention: RetentionPolicy::BorrowedForCall,
360 zeroization: ZeroizationPolicy::CallerRetainsResponsibility,
361 export: ExportPolicy::SecretOwnerRequired,
362 destruction: DestructionPolicy::CallerControlled,
363 }
364}
365
366const fn borrowed_public() -> MaterialPolicy {
367 MaterialPolicy {
368 owner: BufferOwner::Caller,
369 sensitivity: SecretSensitivity::Public,
370 retention: RetentionPolicy::BorrowedForCall,
371 zeroization: ZeroizationPolicy::NotRequired,
372 export: ExportPolicy::Public,
373 destruction: DestructionPolicy::NoneRequired,
374 }
375}
376
377const fn owned_secret() -> MaterialPolicy {
378 MaterialPolicy {
379 owner: BufferOwner::OperationLayer,
380 sensitivity: SecretSensitivity::Secret,
381 retention: RetentionPolicy::ResultLifetime,
382 zeroization: ZeroizationPolicy::OwnerZeroizesOnDrop,
383 export: ExportPolicy::SecretOwnerRequired,
384 destruction: DestructionPolicy::ZeroizeOnDrop,
385 }
386}
387
388const fn public_result() -> MaterialPolicy {
389 MaterialPolicy {
390 owner: BufferOwner::OperationLayer,
391 sensitivity: SecretSensitivity::Public,
392 retention: RetentionPolicy::ResultLifetime,
393 zeroization: ZeroizationPolicy::NotRequired,
394 export: ExportPolicy::Public,
395 destruction: DestructionPolicy::NoneRequired,
396 }
397}
398
399const fn sensitive_result() -> MaterialPolicy {
400 MaterialPolicy {
401 owner: BufferOwner::OperationLayer,
402 sensitivity: SecretSensitivity::Sensitive,
403 retention: RetentionPolicy::ResultLifetime,
404 zeroization: ZeroizationPolicy::NotRequired,
405 export: ExportPolicy::Public,
406 destruction: DestructionPolicy::NoneRequired,
407 }
408}
409
410const fn secret_wire() -> MaterialPolicy {
411 MaterialPolicy {
412 owner: BufferOwner::OperationContract,
413 sensitivity: SecretSensitivity::Secret,
414 retention: RetentionPolicy::OperationTemporary,
415 zeroization: ZeroizationPolicy::OwnerZeroizesOnDrop,
416 export: ExportPolicy::SecretOwnerRequired,
417 destruction: DestructionPolicy::ZeroizeOnDrop,
418 }
419}
420
421const fn public_wire() -> MaterialPolicy {
422 MaterialPolicy {
423 owner: BufferOwner::OperationContract,
424 sensitivity: SecretSensitivity::Public,
425 retention: RetentionPolicy::OperationTemporary,
426 zeroization: ZeroizationPolicy::NotRequired,
427 export: ExportPolicy::Public,
428 destruction: DestructionPolicy::NoneRequired,
429 }
430}
431
432const fn sensitive_wire() -> MaterialPolicy {
433 MaterialPolicy {
434 owner: BufferOwner::OperationContract,
435 sensitivity: SecretSensitivity::Sensitive,
436 retention: RetentionPolicy::OperationTemporary,
437 zeroization: ZeroizationPolicy::NotRequired,
438 export: ExportPolicy::Public,
439 destruction: DestructionPolicy::NoneRequired,
440 }
441}