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 ConcatKdf,
266}
267
268impl core::fmt::Display for KdfAlgorithm {
269 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
270 let detail = match self {
271 KdfAlgorithm::Argon2id => "Argon2id",
272 KdfAlgorithm::Pbkdf2 => "PBKDF2",
273 KdfAlgorithm::ConcatKdf => "Concat KDF",
274 };
275 write!(f, "{detail}")
276 }
277}
278
279#[derive(Debug, Clone, Copy, PartialEq, Eq)]
281pub enum KdfProfile {
282 Argon2idV1,
284 Argon2idV2,
286 Pbkdf2HmacSha256,
288 Pbkdf2HmacSha512,
290 JwaEcdhEsSha256,
292}
293
294impl core::fmt::Display for KdfProfile {
295 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
296 let detail = match self {
297 KdfProfile::Argon2idV1 => "Argon2id v1",
298 KdfProfile::Argon2idV2 => "Argon2id v2",
299 KdfProfile::Pbkdf2HmacSha256 => "PBKDF2-HMAC-SHA-256",
300 KdfProfile::Pbkdf2HmacSha512 => "PBKDF2-HMAC-SHA-512",
301 KdfProfile::JwaEcdhEsSha256 => "JWA ECDH-ES Concat KDF SHA-256",
302 };
303 write!(f, "{detail}")
304 }
305}
306
307#[derive(Debug, Clone, Copy, PartialEq, Eq)]
309pub enum KdfFailureKind {
310 InvalidSecretLength,
312 InvalidSaltLength,
314 InvalidOutputLength,
316 InvalidIterationCount,
318 InvalidParams,
320 DerivationFailed,
322}
323
324impl core::fmt::Display for KdfFailureKind {
325 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
326 let detail = match self {
327 KdfFailureKind::InvalidSecretLength => "invalid secret length",
328 KdfFailureKind::InvalidSaltLength => "invalid salt length",
329 KdfFailureKind::InvalidOutputLength => "invalid output length",
330 KdfFailureKind::InvalidIterationCount => "invalid iteration count",
331 KdfFailureKind::InvalidParams => "invalid parameters",
332 KdfFailureKind::DerivationFailed => "derivation failed",
333 };
334 write!(f, "{detail}")
335 }
336}
337
338#[derive(Debug, Clone, Copy, PartialEq, Eq)]
340pub enum HkdfHash {
341 Sha2_256,
343 Sha3_256,
345}
346
347impl core::fmt::Display for HkdfHash {
348 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
349 let detail = match self {
350 HkdfHash::Sha2_256 => "SHA2-256",
351 HkdfHash::Sha3_256 => "SHA3-256",
352 };
353 write!(f, "{detail}")
354 }
355}
356
357#[derive(Debug, Clone, Copy, PartialEq, Eq)]
359pub enum HkdfFailureKind {
360 InvalidIkmLength,
362 InvalidDomainTagLength,
364 InvalidDomainTagByte,
366 LengthOverflow,
368 InvalidOutputLength,
370 ExpandFailed,
372}
373
374impl core::fmt::Display for HkdfFailureKind {
375 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
376 let detail = match self {
377 HkdfFailureKind::InvalidIkmLength => "invalid input key material length",
378 HkdfFailureKind::InvalidDomainTagLength => "invalid domain tag length",
379 HkdfFailureKind::InvalidDomainTagByte => "invalid domain tag byte",
380 HkdfFailureKind::LengthOverflow => "length overflow",
381 HkdfFailureKind::InvalidOutputLength => "invalid output length",
382 HkdfFailureKind::ExpandFailed => "expand failed",
383 };
384 write!(f, "{detail}")
385 }
386}
387
388#[derive(Debug, Clone, Copy, PartialEq, Eq)]
390pub enum MacHash {
391 Sha2_256,
393 Sha2_512,
395}
396
397impl core::fmt::Display for MacHash {
398 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
399 let detail = match self {
400 MacHash::Sha2_256 => "SHA-256",
401 MacHash::Sha2_512 => "SHA-512",
402 };
403 write!(f, "{detail}")
404 }
405}
406
407#[derive(Debug, Clone, Copy, PartialEq, Eq)]
409pub enum MacFailureKind {
410 InvalidKeyLength,
412 InvalidTagLength,
414 VerificationFailed,
416 BackendFailure,
418}
419
420impl core::fmt::Display for MacFailureKind {
421 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
422 let detail = match self {
423 MacFailureKind::InvalidKeyLength => "invalid key length",
424 MacFailureKind::InvalidTagLength => "invalid tag length",
425 MacFailureKind::VerificationFailed => "verification failed",
426 MacFailureKind::BackendFailure => "backend failure",
427 };
428 write!(f, "{detail}")
429 }
430}
431
432#[derive(Debug, Clone, Copy, PartialEq, Eq)]
434pub enum RngOutputKind {
435 Generic,
437 AeadNonce12,
439 Argon2Salt16,
441 Argon2Salt32,
443}
444
445impl core::fmt::Display for RngOutputKind {
446 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
447 let detail = match self {
448 RngOutputKind::Generic => "random bytes",
449 RngOutputKind::AeadNonce12 => "AEAD nonce",
450 RngOutputKind::Argon2Salt16 => "Argon2 16-byte salt",
451 RngOutputKind::Argon2Salt32 => "Argon2 32-byte salt",
452 };
453 write!(f, "{detail}")
454 }
455}
456
457#[derive(Debug, Clone, Copy, PartialEq, Eq)]
459pub enum RngFailureKind {
460 EntropyUnavailable,
462 InvalidOutputLength,
464}
465
466impl core::fmt::Display for RngFailureKind {
467 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
468 let detail = match self {
469 RngFailureKind::EntropyUnavailable => "entropy unavailable",
470 RngFailureKind::InvalidOutputLength => "invalid output length",
471 };
472 write!(f, "{detail}")
473 }
474}
475
476#[derive(Debug, Clone, Copy, PartialEq, Eq)]
478pub enum ConstantTimeFailureKind {
479 LengthMismatch,
481 NotEqual,
483}
484
485impl core::fmt::Display for ConstantTimeFailureKind {
486 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
487 let detail = match self {
488 ConstantTimeFailureKind::LengthMismatch => "length mismatch",
489 ConstantTimeFailureKind::NotEqual => "not equal",
490 };
491 write!(f, "{detail}")
492 }
493}
494
495#[derive(Debug, Error, Clone, PartialEq, Eq)]
497pub enum CryptoError {
498 #[error("invalid key material")]
500 InvalidKey,
501
502 #[error("invalid AEAD key length: expected {expected} bytes, got {actual} bytes")]
504 InvalidAeadKeyLength {
505 expected: usize,
507 actual: usize,
509 },
510
511 #[error("invalid AEAD nonce length: expected {expected} bytes, got {actual} bytes")]
513 InvalidAeadNonceLength {
514 expected: usize,
516 actual: usize,
518 },
519
520 #[error("invalid ciphertext length: minimum {minimum} bytes, got {actual} bytes")]
522 InvalidCiphertextLength {
523 minimum: usize,
525 actual: usize,
527 },
528
529 #[error("AEAD encryption failed in {backend} backend: {kind}")]
531 AeadEncrypt {
532 backend: AeadBackend,
534 kind: AeadFailureKind,
536 },
537
538 #[error("AEAD decryption failed in {backend} backend: {kind}")]
540 AeadDecrypt {
541 backend: AeadBackend,
543 kind: AeadFailureKind,
545 },
546
547 #[error("signature failed in {backend} backend during {operation}: {kind}")]
549 Signature {
550 backend: SignatureBackend,
552 operation: SignatureOperation,
554 kind: SignatureFailureKind,
556 },
557
558 #[error("key agreement failed: {kind}")]
560 KeyAgreementFailure {
561 kind: KeyAgreementFailureKind,
563 },
564
565 #[error("KEM operation failed: {kind}")]
567 KemFailure {
568 kind: KemFailureKind,
570 },
571
572 #[error("key wrap failed for {algorithm} during {operation}: {kind}")]
574 KeyWrap {
575 algorithm: KeyWrapAlgorithm,
577 operation: KeyWrapOperation,
579 kind: KeyWrapFailureKind,
581 },
582
583 #[error("KDF failed for {algorithm}/{profile}: {kind}")]
585 Kdf {
586 algorithm: KdfAlgorithm,
588 profile: KdfProfile,
590 kind: KdfFailureKind,
592 },
593
594 #[error("HKDF failed for {hash}: {kind}")]
596 Hkdf {
597 hash: HkdfHash,
599 kind: HkdfFailureKind,
601 },
602
603 #[error("HMAC failed for {hash}: {kind}")]
605 Mac {
606 hash: MacHash,
608 kind: MacFailureKind,
610 },
611
612 #[error("secure random generation failed for {output}: {kind}")]
614 Rng {
615 output: RngOutputKind,
617 kind: RngFailureKind,
619 },
620
621 #[error("constant-time comparison failed: {kind}")]
623 ConstantTimeComparison {
624 kind: ConstantTimeFailureKind,
626 left_len: usize,
628 right_len: usize,
630 },
631
632 #[error("unsupported operation")]
634 Unsupported,
635}