Skip to main content

cocoon_tpm_crypto/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2023-2025 SUSE LLC
3// Author: Nicolai Stange <nstange@suse.de>
4
5//! Crypto related error type definitions.
6
7use crate::utils_common;
8use core::convert;
9
10const CRYPTO_ERROR_CODE_MEMORY_ALLOCATION_FAILURE: isize = 1;
11const CRYPTO_ERROR_CODE_INTERNAL: isize = 2;
12const CRYPTO_ERROR_CODE_BUFFER_STATE_INDETERMINATE: isize = 3;
13const CRYPTO_ERROR_CODE_RNG_FAILURE: isize = 4;
14const CRYPTO_ERROR_CODE_INSUFFICIENT_SEED_LENGTH: isize = 5;
15const CRYPTO_ERROR_CODE_RANDOM_SAMPLING_RETRIES_EXCEEDED: isize = 6;
16const CRYPTO_ERROR_CODE_REQUEST_TOO_BIG: isize = 7;
17const CRYPTO_ERROR_CODE_NO_KEY: isize = 8;
18const CRYPTO_ERROR_CODE_KEY_SIZE: isize = 9;
19const CRYPTO_ERROR_CODE_KEY_BINDING: isize = 10;
20const CRYPTO_ERROR_CODE_SIGNATURE_VERIFICATION_FAILURE: isize = 11;
21const CRYPTO_ERROR_CODE_UNSUPPORTED_SECURITY_STRENGTH: isize = 12;
22const CRYPTO_ERROR_CODE_UNSUPPORTED_PARAMS: isize = 13;
23const CRYPTO_ERROR_CODE_UNSPECIFIED_FAILURE: isize = 14;
24const CRYPTO_ERROR_CODE_INVALID_PARAMS: isize = 15;
25const CRYPTO_ERROR_CODE_INVALID_IV: isize = 16;
26const CRYPTO_ERROR_CODE_INVALID_MESSAGE_LENGTH: isize = 17;
27const CRYPTO_ERROR_CODE_INVALID_PADDING: isize = 18;
28const CRYPTO_ERROR_CODE_INVALID_POINT: isize = 19;
29const CRYPTO_ERROR_CODE_INVALID_RESULT: isize = 20;
30
31/// Common error returned by cryptographic primitives.
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum CryptoError {
34    /// Memory allocation failure.
35    MemoryAllocationFailure = CRYPTO_ERROR_CODE_MEMORY_ALLOCATION_FAILURE,
36    /// Internal logic error.
37    Internal = CRYPTO_ERROR_CODE_INTERNAL,
38    /// A source or destination buffer was found in indeterminate state.
39    ///
40    /// To be returned from operand [IO slice
41    /// iterators](utils_common::io_slices) when encountering a buffer in
42    /// indeterminate state. Indicates an internal logic error.
43    BufferStateIndeterminate = CRYPTO_ERROR_CODE_BUFFER_STATE_INDETERMINATE,
44    /// Unspecified random number generator failure condition.
45    RngFailure = CRYPTO_ERROR_CODE_RNG_FAILURE,
46    /// Attempt to seed a random number generator with a seed of insufficient
47    /// length.
48    InsufficientSeedLength = CRYPTO_ERROR_CODE_INSUFFICIENT_SEED_LENGTH,
49    /// Some probabilistic sampling algorithm exceeded the maximum number of
50    /// retries.
51    RandomSamplingRetriesExceeded = CRYPTO_ERROR_CODE_RANDOM_SAMPLING_RETRIES_EXCEEDED,
52    /// Request size is not supported.
53    RequestTooBig = CRYPTO_ERROR_CODE_REQUEST_TOO_BIG,
54    /// Private key required for some operation is missing.
55    NoKey = CRYPTO_ERROR_CODE_NO_KEY,
56    /// Key size is not supported by an algorithm.
57    KeySize = CRYPTO_ERROR_CODE_KEY_SIZE,
58    /// Inconsistency between parts of a key.
59    ///
60    /// This most commonly indicates a mismatch between the public and private
61    /// parts of an asymmetric key pair, but could also get returned for
62    /// impossible private keys not in the expected domain.
63    KeyBinding = CRYPTO_ERROR_CODE_KEY_BINDING,
64    /// Signature verification failure.
65    SignatureVerificationFailure = CRYPTO_ERROR_CODE_SIGNATURE_VERIFICATION_FAILURE,
66    /// Requested security strength is not supported.
67    UnsupportedSecurityStrength = CRYPTO_ERROR_CODE_UNSUPPORTED_SECURITY_STRENGTH,
68    /// Request parameters not supported.
69    UnsupportedParams = CRYPTO_ERROR_CODE_UNSUPPORTED_PARAMS,
70
71    /// Some unspecified failure.
72    UnspecifiedFailure = CRYPTO_ERROR_CODE_UNSPECIFIED_FAILURE,
73
74    /// Invalid parameters.
75    InvalidParams = CRYPTO_ERROR_CODE_INVALID_PARAMS,
76
77    /// Invalid block cipher mode IV length.
78    InvalidIV = CRYPTO_ERROR_CODE_INVALID_IV,
79    /// Invalid message length.
80    InvalidMessageLength = CRYPTO_ERROR_CODE_INVALID_MESSAGE_LENGTH,
81    /// Invalid padding in message.
82    InvalidPadding = CRYPTO_ERROR_CODE_INVALID_PADDING,
83    /// A point is not in the expected domain.
84    InvalidPoint = CRYPTO_ERROR_CODE_INVALID_POINT,
85    /// A computation resulted in an invalid result.
86    InvalidResult = CRYPTO_ERROR_CODE_INVALID_RESULT,
87}
88
89impl CryptoError {
90    const fn from_int(value: isize) -> Self {
91        match value {
92            CRYPTO_ERROR_CODE_MEMORY_ALLOCATION_FAILURE => Self::MemoryAllocationFailure,
93            CRYPTO_ERROR_CODE_INTERNAL => Self::Internal,
94            CRYPTO_ERROR_CODE_BUFFER_STATE_INDETERMINATE => Self::BufferStateIndeterminate,
95            CRYPTO_ERROR_CODE_RNG_FAILURE => Self::RngFailure,
96            CRYPTO_ERROR_CODE_INSUFFICIENT_SEED_LENGTH => Self::InsufficientSeedLength,
97            CRYPTO_ERROR_CODE_RANDOM_SAMPLING_RETRIES_EXCEEDED => Self::RandomSamplingRetriesExceeded,
98            CRYPTO_ERROR_CODE_REQUEST_TOO_BIG => Self::RequestTooBig,
99            CRYPTO_ERROR_CODE_NO_KEY => Self::NoKey,
100            CRYPTO_ERROR_CODE_KEY_SIZE => Self::KeySize,
101            CRYPTO_ERROR_CODE_KEY_BINDING => Self::KeyBinding,
102            CRYPTO_ERROR_CODE_SIGNATURE_VERIFICATION_FAILURE => Self::SignatureVerificationFailure,
103            CRYPTO_ERROR_CODE_UNSUPPORTED_SECURITY_STRENGTH => Self::UnsupportedSecurityStrength,
104            CRYPTO_ERROR_CODE_UNSUPPORTED_PARAMS => Self::UnsupportedParams,
105            CRYPTO_ERROR_CODE_UNSPECIFIED_FAILURE => Self::UnspecifiedFailure,
106            CRYPTO_ERROR_CODE_INVALID_PARAMS => Self::InvalidParams,
107            CRYPTO_ERROR_CODE_INVALID_IV => Self::InvalidIV,
108            CRYPTO_ERROR_CODE_INVALID_MESSAGE_LENGTH => Self::InvalidMessageLength,
109            CRYPTO_ERROR_CODE_INVALID_PADDING => Self::InvalidPadding,
110            CRYPTO_ERROR_CODE_INVALID_POINT => Self::InvalidPoint,
111            CRYPTO_ERROR_CODE_INVALID_RESULT => Self::InvalidResult,
112            _ => {
113                debug_assert!(false);
114                Self::Internal
115            }
116        }
117    }
118
119    pub fn anonymize_any_sensitive(self, anonymized_value: Self) -> Self {
120        const UNFILTERED_SET: [CryptoError; 13] = [
121            CryptoError::MemoryAllocationFailure,
122            CryptoError::BufferStateIndeterminate,
123            CryptoError::RngFailure,
124            CryptoError::InsufficientSeedLength,
125            CryptoError::RandomSamplingRetriesExceeded,
126            CryptoError::RequestTooBig,
127            CryptoError::NoKey,
128            CryptoError::KeySize,
129            CryptoError::KeyBinding,
130            CryptoError::SignatureVerificationFailure,
131            CryptoError::UnsupportedSecurityStrength,
132            CryptoError::UnsupportedParams,
133            CryptoError::UnspecifiedFailure,
134        ];
135        let value = self as cmpa::LimbType;
136        let mut is_unfiltered = cmpa::LimbChoice::new(0);
137        for unfiltered in UNFILTERED_SET {
138            is_unfiltered |= cmpa::ct_eq_l_l(value, unfiltered as cmpa::LimbType);
139        }
140        Self::from_int(is_unfiltered.select(anonymized_value as cmpa::LimbType, value) as isize)
141    }
142
143    pub fn map(self, from_code: Self, to_code: Self) -> Self {
144        Self::from_int(
145            cmpa::ct_eq_l_l(self as cmpa::LimbType, from_code as cmpa::LimbType)
146                .select(self as cmpa::LimbType, to_code as cmpa::LimbType) as isize,
147        )
148    }
149}
150
151impl convert::From<convert::Infallible> for CryptoError {
152    fn from(value: convert::Infallible) -> Self {
153        match value {}
154    }
155}
156
157impl convert::From<utils_common::alloc::TryNewError> for CryptoError {
158    fn from(value: utils_common::alloc::TryNewError) -> Self {
159        match value {
160            utils_common::alloc::TryNewError::MemoryAllocationFailure => CryptoError::MemoryAllocationFailure,
161        }
162    }
163}
164
165impl convert::From<utils_common::alloc::TryNewWithError<CryptoError>> for CryptoError {
166    fn from(value: utils_common::alloc::TryNewWithError<CryptoError>) -> Self {
167        match value {
168            utils_common::alloc::TryNewWithError::TryNew(e) => match e {
169                utils_common::alloc::TryNewError::MemoryAllocationFailure => CryptoError::MemoryAllocationFailure,
170            },
171            utils_common::alloc::TryNewWithError::With(e) => e,
172        }
173    }
174}
175
176impl convert::From<utils_common::alloc::TryNewWithError<convert::Infallible>> for CryptoError {
177    fn from(value: utils_common::alloc::TryNewWithError<convert::Infallible>) -> Self {
178        match value {
179            utils_common::alloc::TryNewWithError::TryNew(e) => match e {
180                utils_common::alloc::TryNewError::MemoryAllocationFailure => CryptoError::MemoryAllocationFailure,
181            },
182            utils_common::alloc::TryNewWithError::With(e) => match e {},
183        }
184    }
185}
186
187impl convert::From<utils_common::fixed_vec::FixedVecMemoryAllocationFailure> for CryptoError {
188    fn from(_value: utils_common::fixed_vec::FixedVecMemoryAllocationFailure) -> Self {
189        Self::MemoryAllocationFailure
190    }
191}
192
193impl convert::From<utils_common::fixed_vec::FixedVecNewFromFnError<CryptoError>> for CryptoError {
194    fn from(value: utils_common::fixed_vec::FixedVecNewFromFnError<CryptoError>) -> Self {
195        match value {
196            utils_common::fixed_vec::FixedVecNewFromFnError::MemoryAllocationFailure => Self::MemoryAllocationFailure,
197            utils_common::fixed_vec::FixedVecNewFromFnError::FnError(e) => e,
198        }
199    }
200}
201
202impl convert::From<utils_common::fixed_vec::FixedVecNewFromFnError<convert::Infallible>> for CryptoError {
203    fn from(value: utils_common::fixed_vec::FixedVecNewFromFnError<convert::Infallible>) -> Self {
204        Self::from(utils_common::fixed_vec::FixedVecMemoryAllocationFailure::from(value))
205    }
206}
207
208impl<BackendIteratorError> convert::From<utils_common::io_slices::IoSlicesIterError<BackendIteratorError>>
209    for CryptoError
210where
211    CryptoError: convert::From<BackendIteratorError>,
212{
213    fn from(value: utils_common::io_slices::IoSlicesIterError<BackendIteratorError>) -> Self {
214        match value {
215            utils_common::io_slices::IoSlicesIterError::IoSlicesError(e) => match e {
216                utils_common::io_slices::IoSlicesError::BuffersExhausted => CryptoError::Internal,
217            },
218            utils_common::io_slices::IoSlicesIterError::BackendIteratorError(e) => Self::from(e),
219        }
220    }
221}