1use thiserror::Error;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum AeadBackend {
11 Native,
13 Swift,
15 Wasm,
17 Kotlin,
19}
20
21impl core::fmt::Display for AeadBackend {
22 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23 let name = match self {
24 AeadBackend::Native => "native",
25 AeadBackend::Swift => "swift",
26 AeadBackend::Wasm => "wasm",
27 AeadBackend::Kotlin => "kotlin",
28 };
29 write!(f, "{name}")
30 }
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35#[non_exhaustive]
36pub enum AeadFailureKind {
37 InvalidKeyMaterial,
39 LengthOverflow,
41 ShortCiphertext,
43 InvalidOutputLength,
45 AuthenticationFailed,
47 BackendFailure,
49}
50
51impl core::fmt::Display for AeadFailureKind {
52 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53 let detail = match self {
54 AeadFailureKind::InvalidKeyMaterial => "invalid key material",
55 AeadFailureKind::LengthOverflow => "length overflow",
56 AeadFailureKind::ShortCiphertext => "ciphertext shorter than tag",
57 AeadFailureKind::InvalidOutputLength => "backend returned invalid output length",
58 AeadFailureKind::AuthenticationFailed => "authentication failed",
59 AeadFailureKind::BackendFailure => "backend failure",
60 };
61 write!(f, "{detail}")
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67#[non_exhaustive]
68pub enum SignatureBackend {
69 Native,
71 Swift,
73 Wasm,
75 Kotlin,
77 SecureEnclave,
79}
80
81impl core::fmt::Display for SignatureBackend {
82 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 let name = match self {
84 SignatureBackend::Native => "native",
85 SignatureBackend::Swift => "swift",
86 SignatureBackend::Wasm => "wasm",
87 SignatureBackend::Kotlin => "kotlin",
88 SignatureBackend::SecureEnclave => "secure_enclave",
89 };
90 write!(f, "{name}")
91 }
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
96#[non_exhaustive]
97pub enum SignatureOperation {
98 Sign,
100 Verify,
102 KeyManagement,
104}
105
106impl core::fmt::Display for SignatureOperation {
107 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
108 let op = match self {
109 SignatureOperation::Sign => "sign",
110 SignatureOperation::Verify => "verify",
111 SignatureOperation::KeyManagement => "key_management",
112 };
113 write!(f, "{op}")
114 }
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq)]
119#[non_exhaustive]
120pub enum SignatureFailureKind {
121 BackendFailure,
123 InvalidPrivateKey,
125 InvalidPublicKey,
127 InvalidSignature,
129 InvalidMessage,
131 KeyGenerationFailed,
133 SecureEnclaveUnavailable,
135 SecureEnclaveRejectedKey,
137}
138
139impl core::fmt::Display for SignatureFailureKind {
140 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
141 let detail = match self {
142 SignatureFailureKind::BackendFailure => "backend failure",
143 SignatureFailureKind::InvalidPrivateKey => "invalid private key",
144 SignatureFailureKind::InvalidPublicKey => "invalid public key",
145 SignatureFailureKind::InvalidSignature => "invalid signature",
146 SignatureFailureKind::InvalidMessage => "invalid message",
147 SignatureFailureKind::KeyGenerationFailed => "key generation failed",
148 SignatureFailureKind::SecureEnclaveUnavailable => "secure enclave unavailable",
149 SignatureFailureKind::SecureEnclaveRejectedKey => "secure enclave rejected key",
150 };
151 write!(f, "{detail}")
152 }
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq)]
157#[non_exhaustive]
158pub enum KeyAgreementFailureKind {
159 DeriveSharedSecretFailed,
161 KeyGenerationFailed,
163}
164
165impl core::fmt::Display for KeyAgreementFailureKind {
166 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
167 let detail = match self {
168 KeyAgreementFailureKind::DeriveSharedSecretFailed => "derive shared secret failed",
169 KeyAgreementFailureKind::KeyGenerationFailed => "key generation failed",
170 };
171 write!(f, "{detail}")
172 }
173}
174
175#[derive(Debug, Clone, Copy, PartialEq, Eq)]
177#[non_exhaustive]
178pub enum KemFailureKind {
179 KeyGenerationFailed,
181 EncapsulateFailed,
183 DecapsulateFailed,
185}
186
187impl core::fmt::Display for KemFailureKind {
188 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
189 let detail = match self {
190 KemFailureKind::KeyGenerationFailed => "key generation failed",
191 KemFailureKind::EncapsulateFailed => "encapsulate failed",
192 KemFailureKind::DecapsulateFailed => "decapsulate failed",
193 };
194 write!(f, "{detail}")
195 }
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
200#[non_exhaustive]
201pub enum KeyWrapAlgorithm {
202 Aes256Kw,
204}
205
206impl core::fmt::Display for KeyWrapAlgorithm {
207 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
208 let detail = match self {
209 KeyWrapAlgorithm::Aes256Kw => "AES-256-KW",
210 };
211 write!(f, "{detail}")
212 }
213}
214
215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217#[non_exhaustive]
218pub enum KeyWrapOperation {
219 Wrap,
221 Unwrap,
223}
224
225impl core::fmt::Display for KeyWrapOperation {
226 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
227 let op = match self {
228 KeyWrapOperation::Wrap => "wrap",
229 KeyWrapOperation::Unwrap => "unwrap",
230 };
231 write!(f, "{op}")
232 }
233}
234
235#[derive(Debug, Clone, Copy, PartialEq, Eq)]
237#[non_exhaustive]
238pub enum KeyWrapFailureKind {
239 InvalidKekLength,
241 InvalidPlaintextLength,
243 InvalidWrappedLength,
245 LengthOverflow,
247 IntegrityCheckFailed,
249 BackendFailure,
251}
252
253impl core::fmt::Display for KeyWrapFailureKind {
254 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
255 let detail = match self {
256 KeyWrapFailureKind::InvalidKekLength => "invalid key-encryption key length",
257 KeyWrapFailureKind::InvalidPlaintextLength => "invalid plaintext key length",
258 KeyWrapFailureKind::InvalidWrappedLength => "invalid wrapped key length",
259 KeyWrapFailureKind::LengthOverflow => "length overflow",
260 KeyWrapFailureKind::IntegrityCheckFailed => "integrity check failed",
261 KeyWrapFailureKind::BackendFailure => "backend failure",
262 };
263 write!(f, "{detail}")
264 }
265}
266
267#[derive(Debug, Clone, Copy, PartialEq, Eq)]
269pub enum KdfAlgorithm {
270 Argon2id,
272 Pbkdf2,
274 ConcatKdf,
276}
277
278impl core::fmt::Display for KdfAlgorithm {
279 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
280 let detail = match self {
281 KdfAlgorithm::Argon2id => "Argon2id",
282 KdfAlgorithm::Pbkdf2 => "PBKDF2",
283 KdfAlgorithm::ConcatKdf => "Concat KDF",
284 };
285 write!(f, "{detail}")
286 }
287}
288
289#[derive(Debug, Clone, Copy, PartialEq, Eq)]
291pub enum KdfProfile {
292 Argon2idV1,
294 Argon2idV2,
296 Pbkdf2HmacSha256,
298 Pbkdf2HmacSha512,
300 JwaEcdhEsSha256,
302}
303
304impl core::fmt::Display for KdfProfile {
305 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
306 let detail = match self {
307 KdfProfile::Argon2idV1 => "Argon2id v1",
308 KdfProfile::Argon2idV2 => "Argon2id v2",
309 KdfProfile::Pbkdf2HmacSha256 => "PBKDF2-HMAC-SHA-256",
310 KdfProfile::Pbkdf2HmacSha512 => "PBKDF2-HMAC-SHA-512",
311 KdfProfile::JwaEcdhEsSha256 => "JWA ECDH-ES Concat KDF SHA-256",
312 };
313 write!(f, "{detail}")
314 }
315}
316
317#[derive(Debug, Clone, Copy, PartialEq, Eq)]
319#[non_exhaustive]
320pub enum KdfFailureKind {
321 InvalidSecretLength,
323 InvalidSaltLength,
325 InvalidOutputLength,
327 InvalidIterationCount,
329 InvalidParams,
331 DerivationFailed,
333}
334
335impl core::fmt::Display for KdfFailureKind {
336 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
337 let detail = match self {
338 KdfFailureKind::InvalidSecretLength => "invalid secret length",
339 KdfFailureKind::InvalidSaltLength => "invalid salt length",
340 KdfFailureKind::InvalidOutputLength => "invalid output length",
341 KdfFailureKind::InvalidIterationCount => "invalid iteration count",
342 KdfFailureKind::InvalidParams => "invalid parameters",
343 KdfFailureKind::DerivationFailed => "derivation failed",
344 };
345 write!(f, "{detail}")
346 }
347}
348
349#[derive(Debug, Clone, Copy, PartialEq, Eq)]
351pub enum HkdfHash {
352 Sha2_256,
354 Sha3_256,
356}
357
358impl core::fmt::Display for HkdfHash {
359 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
360 let detail = match self {
361 HkdfHash::Sha2_256 => "SHA2-256",
362 HkdfHash::Sha3_256 => "SHA3-256",
363 };
364 write!(f, "{detail}")
365 }
366}
367
368#[derive(Debug, Clone, Copy, PartialEq, Eq)]
370#[non_exhaustive]
371pub enum HkdfFailureKind {
372 InvalidIkmLength,
374 InvalidDomainTagLength,
376 InvalidDomainTagByte,
378 LengthOverflow,
380 InvalidOutputLength,
382 ExpandFailed,
384}
385
386impl core::fmt::Display for HkdfFailureKind {
387 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
388 let detail = match self {
389 HkdfFailureKind::InvalidIkmLength => "invalid input key material length",
390 HkdfFailureKind::InvalidDomainTagLength => "invalid domain tag length",
391 HkdfFailureKind::InvalidDomainTagByte => "invalid domain tag byte",
392 HkdfFailureKind::LengthOverflow => "length overflow",
393 HkdfFailureKind::InvalidOutputLength => "invalid output length",
394 HkdfFailureKind::ExpandFailed => "expand failed",
395 };
396 write!(f, "{detail}")
397 }
398}
399
400#[derive(Debug, Clone, Copy, PartialEq, Eq)]
402pub enum MacHash {
403 Sha2_256,
405 Sha2_512,
407}
408
409impl core::fmt::Display for MacHash {
410 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
411 let detail = match self {
412 MacHash::Sha2_256 => "SHA-256",
413 MacHash::Sha2_512 => "SHA-512",
414 };
415 write!(f, "{detail}")
416 }
417}
418
419#[derive(Debug, Clone, Copy, PartialEq, Eq)]
421#[non_exhaustive]
422pub enum MacFailureKind {
423 InvalidKeyLength,
425 InvalidTagLength,
427 VerificationFailed,
429 BackendFailure,
431}
432
433impl core::fmt::Display for MacFailureKind {
434 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
435 let detail = match self {
436 MacFailureKind::InvalidKeyLength => "invalid key length",
437 MacFailureKind::InvalidTagLength => "invalid tag length",
438 MacFailureKind::VerificationFailed => "verification failed",
439 MacFailureKind::BackendFailure => "backend failure",
440 };
441 write!(f, "{detail}")
442 }
443}
444
445#[derive(Debug, Clone, Copy, PartialEq, Eq)]
447pub enum RngOutputKind {
448 Generic,
450 AeadNonce12,
452 Argon2Salt16,
454 Argon2Salt32,
456}
457
458impl core::fmt::Display for RngOutputKind {
459 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
460 let detail = match self {
461 RngOutputKind::Generic => "random bytes",
462 RngOutputKind::AeadNonce12 => "AEAD nonce",
463 RngOutputKind::Argon2Salt16 => "Argon2 16-byte salt",
464 RngOutputKind::Argon2Salt32 => "Argon2 32-byte salt",
465 };
466 write!(f, "{detail}")
467 }
468}
469
470#[derive(Debug, Clone, Copy, PartialEq, Eq)]
472#[non_exhaustive]
473pub enum RngFailureKind {
474 EntropyUnavailable,
476 InvalidOutputLength,
478}
479
480impl core::fmt::Display for RngFailureKind {
481 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
482 let detail = match self {
483 RngFailureKind::EntropyUnavailable => "entropy unavailable",
484 RngFailureKind::InvalidOutputLength => "invalid output length",
485 };
486 write!(f, "{detail}")
487 }
488}
489
490#[derive(Debug, Clone, Copy, PartialEq, Eq)]
492#[non_exhaustive]
493pub enum ConstantTimeFailureKind {
494 LengthMismatch,
496 NotEqual,
498}
499
500impl core::fmt::Display for ConstantTimeFailureKind {
501 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
502 let detail = match self {
503 ConstantTimeFailureKind::LengthMismatch => "length mismatch",
504 ConstantTimeFailureKind::NotEqual => "not equal",
505 };
506 write!(f, "{detail}")
507 }
508}
509
510#[derive(Debug, Error, Clone, PartialEq, Eq)]
512#[non_exhaustive]
513pub enum CryptoError {
514 #[error("invalid key material")]
516 InvalidKey,
517
518 #[error("invalid AEAD key length: expected {expected} bytes, got {actual} bytes")]
520 InvalidAeadKeyLength {
521 expected: usize,
523 actual: usize,
525 },
526
527 #[error("invalid AEAD nonce length: expected {expected} bytes, got {actual} bytes")]
529 InvalidAeadNonceLength {
530 expected: usize,
532 actual: usize,
534 },
535
536 #[error("invalid ciphertext length: minimum {minimum} bytes, got {actual} bytes")]
538 InvalidCiphertextLength {
539 minimum: usize,
541 actual: usize,
543 },
544
545 #[error("AEAD encryption failed in {backend} backend: {kind}")]
547 AeadEncrypt {
548 backend: AeadBackend,
550 kind: AeadFailureKind,
552 },
553
554 #[error("AEAD decryption failed in {backend} backend: {kind}")]
556 AeadDecrypt {
557 backend: AeadBackend,
559 kind: AeadFailureKind,
561 },
562
563 #[error("signature failed in {backend} backend during {operation}: {kind}")]
565 Signature {
566 backend: SignatureBackend,
568 operation: SignatureOperation,
570 kind: SignatureFailureKind,
572 },
573
574 #[error("key agreement failed: {kind}")]
576 KeyAgreementFailure {
577 kind: KeyAgreementFailureKind,
579 },
580
581 #[error("KEM operation failed: {kind}")]
583 KemFailure {
584 kind: KemFailureKind,
586 },
587
588 #[error("key wrap failed for {algorithm} during {operation}: {kind}")]
590 KeyWrap {
591 algorithm: KeyWrapAlgorithm,
593 operation: KeyWrapOperation,
595 kind: KeyWrapFailureKind,
597 },
598
599 #[error("KDF failed for {algorithm}/{profile}: {kind}")]
601 Kdf {
602 algorithm: KdfAlgorithm,
604 profile: KdfProfile,
606 kind: KdfFailureKind,
608 },
609
610 #[error("HKDF failed for {hash}: {kind}")]
612 Hkdf {
613 hash: HkdfHash,
615 kind: HkdfFailureKind,
617 },
618
619 #[error("HMAC failed for {hash}: {kind}")]
621 Mac {
622 hash: MacHash,
624 kind: MacFailureKind,
626 },
627
628 #[error("secure random generation failed for {output}: {kind}")]
630 Rng {
631 output: RngOutputKind,
633 kind: RngFailureKind,
635 },
636
637 #[error("constant-time comparison failed: {kind}")]
639 ConstantTimeComparison {
640 kind: ConstantTimeFailureKind,
642 left_len: usize,
644 right_len: usize,
646 },
647
648 #[error("unsupported operation")]
650 Unsupported,
651}