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