crypto/
error.rs

1// SPDX-FileCopyrightText: 2024 Foundation Devices, Inc. <hello@foundation.xyz>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4use server::{xous, AsScalar, FromScalar};
5
6#[derive(
7    Debug, Clone, Copy, thiserror::Error, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, PartialEq,
8)]
9pub enum CryptoError {
10    #[error("OS error: {:?}", xous::Error::from_usize(*.0))]
11    XousError(usize),
12
13    #[error("Unknown internal error")]
14    UnknownError,
15
16    // These are errors that can't really happen through the API.
17    #[error("Invalid parameter")]
18    InvalidParameter,
19
20    #[cfg(keyos)]
21    #[error("There was a problem with the DMA engine")]
22    DmaError,
23
24    #[error("The source or destination address points to somewhere it shouldn't")]
25    InvalidAddress,
26
27    #[error("The length did not fit into the buffer or was 0")]
28    InvalidDataLength,
29
30    #[error("The lent buffer didn't contain contigous pages (use POPULATE)")]
31    BufferNotContiguous,
32
33    #[error("The process allocated more AES contexts than available")]
34    TooManyAesContexts,
35
36    #[error("No more SECURAM key slots left")]
37    TooManySecuramKeys,
38
39    #[error("The supplied key was a supported size")]
40    InvalidKeyLength,
41
42    #[error("The buffer length was not divisible by block length")]
43    UnalignedDataLength,
44
45    #[error("The AES context is in invalid operation mode for the method")]
46    InvalidMode,
47
48    #[error("The AES context is in a state that does not allow this operation")]
49    InvalidState,
50}
51
52impl From<xous::Error> for CryptoError {
53    fn from(value: xous::Error) -> Self { CryptoError::XousError(value.to_usize()) }
54}
55
56impl From<()> for CryptoError {
57    fn from(_: ()) -> Self { CryptoError::UnknownError }
58}
59
60impl From<CryptoError> for usize {
61    fn from(value: CryptoError) -> usize {
62        match value {
63            CryptoError::XousError(e) => e,
64            CryptoError::UnknownError => 0x80000001,
65            CryptoError::InvalidParameter => 0x80000002,
66            #[cfg(keyos)]
67            CryptoError::DmaError => 0x80000003,
68            CryptoError::InvalidAddress => 0x80000004,
69            CryptoError::InvalidDataLength => 0x80000005,
70            CryptoError::BufferNotContiguous => 0x80000006,
71            CryptoError::TooManyAesContexts => 0x80000007,
72            CryptoError::TooManySecuramKeys => 0x80000008,
73            CryptoError::InvalidKeyLength => 0x80000009,
74            CryptoError::UnalignedDataLength => 0x8000000b,
75            CryptoError::InvalidMode => 0x8000000c,
76            CryptoError::InvalidState => 0x8000000d,
77        }
78    }
79}
80
81impl From<usize> for CryptoError {
82    fn from(value: usize) -> Self {
83        match value {
84            0x80000001 => CryptoError::UnknownError,
85            0x80000002 => CryptoError::InvalidParameter,
86            #[cfg(keyos)]
87            0x80000003 => CryptoError::DmaError,
88            0x80000004 => CryptoError::InvalidAddress,
89            0x80000005 => CryptoError::InvalidDataLength,
90            0x80000006 => CryptoError::BufferNotContiguous,
91            0x80000007 => CryptoError::TooManyAesContexts,
92            0x80000008 => CryptoError::TooManySecuramKeys,
93            0x80000009 => CryptoError::InvalidKeyLength,
94            0x8000000b => CryptoError::UnalignedDataLength,
95            0x8000000c => CryptoError::InvalidMode,
96            0x8000000d => CryptoError::InvalidState,
97            _ => CryptoError::XousError(value),
98        }
99    }
100}
101
102impl AsScalar<1> for CryptoError {
103    fn as_scalar(&self) -> [u32; 1] { [usize::from(*self) as u32] }
104}
105
106impl FromScalar<1> for CryptoError {
107    fn from_scalar([value]: [u32; 1]) -> Self { Self::from(value as usize) }
108}
109
110#[derive(Debug, Clone, Copy, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, PartialEq)]
111pub enum ShamirError {
112    SecretTooLong,
113    TooManyShares,
114    InterpolationFailure,
115    ChecksumFailure,
116    SecretTooShort,
117    SecretNotEvenLen,
118    InvalidThreshold,
119    SharesUnequalLength,
120}
121
122impl AsScalar<1> for ShamirError {
123    fn as_scalar(&self) -> [u32; 1] {
124        match self {
125            Self::SecretTooLong => [1],
126            Self::TooManyShares => [2],
127            Self::InterpolationFailure => [3],
128            Self::ChecksumFailure => [4],
129            Self::SecretTooShort => [5],
130            Self::SecretNotEvenLen => [6],
131            Self::InvalidThreshold => [7],
132            Self::SharesUnequalLength => [8],
133        }
134    }
135}
136
137impl FromScalar<1> for ShamirError {
138    fn from_scalar([value]: [u32; 1]) -> Self {
139        match value {
140            1 => Self::SecretTooLong,
141            2 => Self::TooManyShares,
142            3 => Self::InterpolationFailure,
143            4 => Self::ChecksumFailure,
144            5 => Self::SecretTooShort,
145            6 => Self::SecretNotEvenLen,
146            7 => Self::InvalidThreshold,
147            8 => Self::SharesUnequalLength,
148            _ => unreachable!(),
149        }
150    }
151}