1use thiserror::Error;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum AeadBackend {
10 Native,
12 Swift,
14 Wasm,
16 Kotlin,
18}
19
20impl core::fmt::Display for AeadBackend {
21 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22 let name = match self {
23 AeadBackend::Native => "native",
24 AeadBackend::Swift => "swift",
25 AeadBackend::Wasm => "wasm",
26 AeadBackend::Kotlin => "kotlin",
27 };
28 write!(f, "{name}")
29 }
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum AeadFailureKind {
35 InvalidKeyMaterial,
37 LengthOverflow,
39 ShortCiphertext,
41 InvalidOutputLength,
43 AuthenticationFailed,
45 BackendFailure,
47}
48
49impl core::fmt::Display for AeadFailureKind {
50 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51 let detail = match self {
52 AeadFailureKind::InvalidKeyMaterial => "invalid key material",
53 AeadFailureKind::LengthOverflow => "length overflow",
54 AeadFailureKind::ShortCiphertext => "ciphertext shorter than tag",
55 AeadFailureKind::InvalidOutputLength => "backend returned invalid output length",
56 AeadFailureKind::AuthenticationFailed => "authentication failed",
57 AeadFailureKind::BackendFailure => "backend failure",
58 };
59 write!(f, "{detail}")
60 }
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum SignatureBackend {
66 Native,
68 Swift,
70 Wasm,
72 Kotlin,
74 SecureEnclave,
76}
77
78impl core::fmt::Display for SignatureBackend {
79 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
80 let name = match self {
81 SignatureBackend::Native => "native",
82 SignatureBackend::Swift => "swift",
83 SignatureBackend::Wasm => "wasm",
84 SignatureBackend::Kotlin => "kotlin",
85 SignatureBackend::SecureEnclave => "secure_enclave",
86 };
87 write!(f, "{name}")
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub enum SignatureOperation {
94 Sign,
96 Verify,
98 KeyManagement,
100}
101
102impl core::fmt::Display for SignatureOperation {
103 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
104 let op = match self {
105 SignatureOperation::Sign => "sign",
106 SignatureOperation::Verify => "verify",
107 SignatureOperation::KeyManagement => "key_management",
108 };
109 write!(f, "{op}")
110 }
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub enum SignatureFailureKind {
116 BackendFailure,
118 InvalidPrivateKey,
120 InvalidPublicKey,
122 InvalidSignature,
124 InvalidMessage,
126 KeyGenerationFailed,
128 SecureEnclaveUnavailable,
130 SecureEnclaveRejectedKey,
132}
133
134impl core::fmt::Display for SignatureFailureKind {
135 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
136 let detail = match self {
137 SignatureFailureKind::BackendFailure => "backend failure",
138 SignatureFailureKind::InvalidPrivateKey => "invalid private key",
139 SignatureFailureKind::InvalidPublicKey => "invalid public key",
140 SignatureFailureKind::InvalidSignature => "invalid signature",
141 SignatureFailureKind::InvalidMessage => "invalid message",
142 SignatureFailureKind::KeyGenerationFailed => "key generation failed",
143 SignatureFailureKind::SecureEnclaveUnavailable => "secure enclave unavailable",
144 SignatureFailureKind::SecureEnclaveRejectedKey => "secure enclave rejected key",
145 };
146 write!(f, "{detail}")
147 }
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
152pub enum KeyAgreementFailureKind {
153 DeriveSharedSecretFailed,
155 KeyGenerationFailed,
157}
158
159impl core::fmt::Display for KeyAgreementFailureKind {
160 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
161 let detail = match self {
162 KeyAgreementFailureKind::DeriveSharedSecretFailed => "derive shared secret failed",
163 KeyAgreementFailureKind::KeyGenerationFailed => "key generation failed",
164 };
165 write!(f, "{detail}")
166 }
167}
168
169#[derive(Debug, Clone, Copy, PartialEq, Eq)]
171pub enum KemFailureKind {
172 KeyGenerationFailed,
174 EncapsulateFailed,
176 DecapsulateFailed,
178}
179
180impl core::fmt::Display for KemFailureKind {
181 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
182 let detail = match self {
183 KemFailureKind::KeyGenerationFailed => "key generation failed",
184 KemFailureKind::EncapsulateFailed => "encapsulate failed",
185 KemFailureKind::DecapsulateFailed => "decapsulate failed",
186 };
187 write!(f, "{detail}")
188 }
189}
190
191#[derive(Debug, Clone, Copy, PartialEq, Eq)]
193pub enum KeyWrapAlgorithm {
194 Aes256Kw,
196}
197
198impl core::fmt::Display for KeyWrapAlgorithm {
199 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
200 let detail = match self {
201 KeyWrapAlgorithm::Aes256Kw => "AES-256-KW",
202 };
203 write!(f, "{detail}")
204 }
205}
206
207#[derive(Debug, Clone, Copy, PartialEq, Eq)]
209pub enum KeyWrapOperation {
210 Wrap,
212 Unwrap,
214}
215
216impl core::fmt::Display for KeyWrapOperation {
217 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
218 let op = match self {
219 KeyWrapOperation::Wrap => "wrap",
220 KeyWrapOperation::Unwrap => "unwrap",
221 };
222 write!(f, "{op}")
223 }
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq)]
228pub enum KeyWrapFailureKind {
229 InvalidKekLength,
231 InvalidPlaintextLength,
233 InvalidWrappedLength,
235 LengthOverflow,
237 IntegrityCheckFailed,
239 BackendFailure,
241}
242
243impl core::fmt::Display for KeyWrapFailureKind {
244 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
245 let detail = match self {
246 KeyWrapFailureKind::InvalidKekLength => "invalid key-encryption key length",
247 KeyWrapFailureKind::InvalidPlaintextLength => "invalid plaintext key length",
248 KeyWrapFailureKind::InvalidWrappedLength => "invalid wrapped key length",
249 KeyWrapFailureKind::LengthOverflow => "length overflow",
250 KeyWrapFailureKind::IntegrityCheckFailed => "integrity check failed",
251 KeyWrapFailureKind::BackendFailure => "backend failure",
252 };
253 write!(f, "{detail}")
254 }
255}
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq)]
259pub enum KdfAlgorithm {
260 Argon2id,
262 Pbkdf2,
264}
265
266impl core::fmt::Display for KdfAlgorithm {
267 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
268 let detail = match self {
269 KdfAlgorithm::Argon2id => "Argon2id",
270 KdfAlgorithm::Pbkdf2 => "PBKDF2",
271 };
272 write!(f, "{detail}")
273 }
274}
275
276#[derive(Debug, Clone, Copy, PartialEq, Eq)]
278pub enum KdfProfile {
279 Argon2idV1,
281 Argon2idV2,
283 Pbkdf2HmacSha256,
285 Pbkdf2HmacSha512,
287}
288
289impl core::fmt::Display for KdfProfile {
290 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
291 let detail = match self {
292 KdfProfile::Argon2idV1 => "Argon2id v1",
293 KdfProfile::Argon2idV2 => "Argon2id v2",
294 KdfProfile::Pbkdf2HmacSha256 => "PBKDF2-HMAC-SHA-256",
295 KdfProfile::Pbkdf2HmacSha512 => "PBKDF2-HMAC-SHA-512",
296 };
297 write!(f, "{detail}")
298 }
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303pub enum KdfFailureKind {
304 InvalidSecretLength,
306 InvalidSaltLength,
308 InvalidOutputLength,
310 InvalidIterationCount,
312 InvalidParams,
314 DerivationFailed,
316}
317
318impl core::fmt::Display for KdfFailureKind {
319 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
320 let detail = match self {
321 KdfFailureKind::InvalidSecretLength => "invalid secret length",
322 KdfFailureKind::InvalidSaltLength => "invalid salt length",
323 KdfFailureKind::InvalidOutputLength => "invalid output length",
324 KdfFailureKind::InvalidIterationCount => "invalid iteration count",
325 KdfFailureKind::InvalidParams => "invalid parameters",
326 KdfFailureKind::DerivationFailed => "derivation failed",
327 };
328 write!(f, "{detail}")
329 }
330}
331
332#[derive(Debug, Clone, Copy, PartialEq, Eq)]
334pub enum HkdfHash {
335 Sha2_256,
337 Sha3_256,
339}
340
341impl core::fmt::Display for HkdfHash {
342 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
343 let detail = match self {
344 HkdfHash::Sha2_256 => "SHA2-256",
345 HkdfHash::Sha3_256 => "SHA3-256",
346 };
347 write!(f, "{detail}")
348 }
349}
350
351#[derive(Debug, Clone, Copy, PartialEq, Eq)]
353pub enum HkdfFailureKind {
354 InvalidIkmLength,
356 InvalidDomainTagLength,
358 InvalidDomainTagByte,
360 LengthOverflow,
362 InvalidOutputLength,
364 ExpandFailed,
366}
367
368impl core::fmt::Display for HkdfFailureKind {
369 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
370 let detail = match self {
371 HkdfFailureKind::InvalidIkmLength => "invalid input key material length",
372 HkdfFailureKind::InvalidDomainTagLength => "invalid domain tag length",
373 HkdfFailureKind::InvalidDomainTagByte => "invalid domain tag byte",
374 HkdfFailureKind::LengthOverflow => "length overflow",
375 HkdfFailureKind::InvalidOutputLength => "invalid output length",
376 HkdfFailureKind::ExpandFailed => "expand failed",
377 };
378 write!(f, "{detail}")
379 }
380}
381
382#[derive(Debug, Clone, Copy, PartialEq, Eq)]
384pub enum MacHash {
385 Sha2_256,
387 Sha2_512,
389}
390
391impl core::fmt::Display for MacHash {
392 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
393 let detail = match self {
394 MacHash::Sha2_256 => "SHA-256",
395 MacHash::Sha2_512 => "SHA-512",
396 };
397 write!(f, "{detail}")
398 }
399}
400
401#[derive(Debug, Clone, Copy, PartialEq, Eq)]
403pub enum MacFailureKind {
404 InvalidKeyLength,
406 InvalidTagLength,
408 VerificationFailed,
410 BackendFailure,
412}
413
414impl core::fmt::Display for MacFailureKind {
415 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
416 let detail = match self {
417 MacFailureKind::InvalidKeyLength => "invalid key length",
418 MacFailureKind::InvalidTagLength => "invalid tag length",
419 MacFailureKind::VerificationFailed => "verification failed",
420 MacFailureKind::BackendFailure => "backend failure",
421 };
422 write!(f, "{detail}")
423 }
424}
425
426#[derive(Debug, Clone, Copy, PartialEq, Eq)]
428pub enum RngOutputKind {
429 Generic,
431 AeadNonce12,
433 Argon2Salt16,
435 Argon2Salt32,
437}
438
439impl core::fmt::Display for RngOutputKind {
440 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
441 let detail = match self {
442 RngOutputKind::Generic => "random bytes",
443 RngOutputKind::AeadNonce12 => "AEAD nonce",
444 RngOutputKind::Argon2Salt16 => "Argon2 16-byte salt",
445 RngOutputKind::Argon2Salt32 => "Argon2 32-byte salt",
446 };
447 write!(f, "{detail}")
448 }
449}
450
451#[derive(Debug, Clone, Copy, PartialEq, Eq)]
453pub enum RngFailureKind {
454 EntropyUnavailable,
456 InvalidOutputLength,
458}
459
460impl core::fmt::Display for RngFailureKind {
461 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
462 let detail = match self {
463 RngFailureKind::EntropyUnavailable => "entropy unavailable",
464 RngFailureKind::InvalidOutputLength => "invalid output length",
465 };
466 write!(f, "{detail}")
467 }
468}
469
470#[derive(Debug, Clone, Copy, PartialEq, Eq)]
472pub enum ConstantTimeFailureKind {
473 LengthMismatch,
475 NotEqual,
477}
478
479impl core::fmt::Display for ConstantTimeFailureKind {
480 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
481 let detail = match self {
482 ConstantTimeFailureKind::LengthMismatch => "length mismatch",
483 ConstantTimeFailureKind::NotEqual => "not equal",
484 };
485 write!(f, "{detail}")
486 }
487}
488
489#[derive(Debug, Error, Clone, PartialEq, Eq)]
491pub enum CryptoError {
492 #[error("invalid key material")]
494 InvalidKey,
495
496 #[error("invalid AEAD key length: expected {expected} bytes, got {actual} bytes")]
498 InvalidAeadKeyLength {
499 expected: usize,
501 actual: usize,
503 },
504
505 #[error("invalid AEAD nonce length: expected {expected} bytes, got {actual} bytes")]
507 InvalidAeadNonceLength {
508 expected: usize,
510 actual: usize,
512 },
513
514 #[error("invalid ciphertext length: minimum {minimum} bytes, got {actual} bytes")]
516 InvalidCiphertextLength {
517 minimum: usize,
519 actual: usize,
521 },
522
523 #[error("AEAD encryption failed in {backend} backend: {kind}")]
525 AeadEncrypt {
526 backend: AeadBackend,
528 kind: AeadFailureKind,
530 },
531
532 #[error("AEAD decryption failed in {backend} backend: {kind}")]
534 AeadDecrypt {
535 backend: AeadBackend,
537 kind: AeadFailureKind,
539 },
540
541 #[error("signature failed in {backend} backend during {operation}: {kind}")]
543 Signature {
544 backend: SignatureBackend,
546 operation: SignatureOperation,
548 kind: SignatureFailureKind,
550 },
551
552 #[error("key agreement failed: {kind}")]
554 KeyAgreementFailure {
555 kind: KeyAgreementFailureKind,
557 },
558
559 #[error("KEM operation failed: {kind}")]
561 KemFailure {
562 kind: KemFailureKind,
564 },
565
566 #[error("key wrap failed for {algorithm} during {operation}: {kind}")]
568 KeyWrap {
569 algorithm: KeyWrapAlgorithm,
571 operation: KeyWrapOperation,
573 kind: KeyWrapFailureKind,
575 },
576
577 #[error("KDF failed for {algorithm}/{profile}: {kind}")]
579 Kdf {
580 algorithm: KdfAlgorithm,
582 profile: KdfProfile,
584 kind: KdfFailureKind,
586 },
587
588 #[error("HKDF failed for {hash}: {kind}")]
590 Hkdf {
591 hash: HkdfHash,
593 kind: HkdfFailureKind,
595 },
596
597 #[error("HMAC failed for {hash}: {kind}")]
599 Mac {
600 hash: MacHash,
602 kind: MacFailureKind,
604 },
605
606 #[error("secure random generation failed for {output}: {kind}")]
608 Rng {
609 output: RngOutputKind,
611 kind: RngFailureKind,
613 },
614
615 #[error("constant-time comparison failed: {kind}")]
617 ConstantTimeComparison {
618 kind: ConstantTimeFailureKind,
620 left_len: usize,
622 right_len: usize,
624 },
625
626 #[error("unsupported operation")]
628 Unsupported,
629}