Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
CryptographyErrorFormatter.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "../Common/ResultErrorFormatter.h"
6#include "CryptographyError.h"
7
8namespace SC
9{
10namespace detail
11{
12inline bool appendCryptographyError(ResultErrorFormatter& formatter, CryptographyError error)
13{
14 switch (error)
15 {
16 case CryptographyError::OperationUnsupported: formatter.append("Cryptographic operation is unsupported"); break;
17 case CryptographyError::BackendUnavailable: formatter.append("Cryptographic backend is unavailable"); break;
18 case CryptographyError::InvalidAeadType: formatter.append("AEAD type is invalid"); break;
19 case CryptographyError::InvalidCipherType: formatter.append("Cipher type is invalid"); break;
20 case CryptographyError::InvalidHashType: formatter.append("Hash type is invalid"); break;
21 case CryptographyError::InvalidCipherOperation: formatter.append("Cipher operation is invalid"); break;
22 case CryptographyError::InvalidKeySize: formatter.append("Key size is invalid"); break;
23 case CryptographyError::InvalidNonceSize: formatter.append("Nonce size is invalid"); break;
24 case CryptographyError::InvalidInitializationVectorSize:
25 formatter.append("Initialization vector size is invalid");
26 break;
27 case CryptographyError::InvalidTagSize: formatter.append("Authentication tag size is invalid"); break;
28 case CryptographyError::SizeLimitExceeded: formatter.append("Cryptographic size limit exceeded"); break;
29 case CryptographyError::OutputCapacityExceeded: formatter.append("Output capacity exceeded"); break;
30 case CryptographyError::BufferOverlap: formatter.append("Buffer overlap is not allowed"); break;
31 case CryptographyError::SessionNotInitialized: formatter.append("Cryptographic session is not initialized"); break;
32 case CryptographyError::KeyNotSet: formatter.append("HMAC key is not set"); break;
33 case CryptographyError::InvalidCiphertext: formatter.append("Ciphertext is invalid"); break;
34 case CryptographyError::AuthenticationFailed: formatter.append("Authentication failed"); break;
35 case CryptographyError::RandomGenerationFailed: formatter.append("Secure random generation failed"); break;
36 case CryptographyError::BackendInitializationFailed:
37 formatter.append("Cryptographic backend initialization failed");
38 break;
39 case CryptographyError::BackendConfigurationFailed:
40 formatter.append("Cryptographic backend configuration failed");
41 break;
42 case CryptographyError::BackendOperationFailed: formatter.append("Cryptographic backend operation failed"); break;
43 case CryptographyError::InternalCapacityExceeded:
44 formatter.append("Cryptographic internal capacity exceeded");
45 break;
46 case CryptographyError::UnexpectedOutputSize: formatter.append("Cryptographic output size was unexpected"); break;
47 case CryptographyError::InvalidBlockInputSize: formatter.append("Cipher block input size is invalid"); break;
48 default: return false;
49 }
50 return true;
51}
52
53inline bool appendCryptographyErrorDetail(ResultErrorFormatter& formatter, CryptographyErrorDetail detail)
54{
55 switch (detail)
56 {
57 case CryptographyErrorDetail::None: return true;
58 case CryptographyErrorDetail::FillRandom: formatter.append("fill secure random bytes"); break;
59 case CryptographyErrorDetail::InitializeAead: formatter.append("initialize AEAD session"); break;
60 case CryptographyErrorDetail::SealAead: formatter.append("seal AEAD message"); break;
61 case CryptographyErrorDetail::OpenAead: formatter.append("open AEAD message"); break;
62 case CryptographyErrorDetail::StartCipher: formatter.append("start cipher session"); break;
63 case CryptographyErrorDetail::UpdateCipher: formatter.append("update cipher session"); break;
64 case CryptographyErrorDetail::FinishCipher: formatter.append("finish cipher session"); break;
65 case CryptographyErrorDetail::SetHmacType: formatter.append("select HMAC hash type"); break;
66 case CryptographyErrorDetail::SetHmacKey: formatter.append("set HMAC key"); break;
67 case CryptographyErrorDetail::AddHmacData: formatter.append("add HMAC data"); break;
68 case CryptographyErrorDetail::FinalizeHmac: formatter.append("finalize HMAC"); break;
69 case CryptographyErrorDetail::DeriveHkdf: formatter.append("derive HKDF output"); break;
70 case CryptographyErrorDetail::ValidateAeadKey: formatter.append("validate AEAD key"); break;
71 case CryptographyErrorDetail::ValidateAeadNonce: formatter.append("validate AEAD nonce"); break;
72 case CryptographyErrorDetail::ValidateAeadTag: formatter.append("validate AEAD authentication tag"); break;
73 case CryptographyErrorDetail::ValidateAeadMessageSize: formatter.append("validate AEAD message size"); break;
74 case CryptographyErrorDetail::ValidateAeadOutput: formatter.append("validate AEAD output capacity"); break;
75 case CryptographyErrorDetail::ValidateAeadPartialOverlap: formatter.append("validate AEAD partial overlap"); break;
76 case CryptographyErrorDetail::ValidateAeadSealCiphertextOverlap:
77 formatter.append("validate AEAD ciphertext overlap");
78 break;
79 case CryptographyErrorDetail::ValidateAeadSealTagOverlap:
80 formatter.append("validate AEAD authentication tag overlap");
81 break;
82 case CryptographyErrorDetail::ValidateAeadOpenPlaintextOverlap:
83 formatter.append("validate AEAD plaintext overlap");
84 break;
85 case CryptographyErrorDetail::ValidateCipherKey: formatter.append("validate cipher key"); break;
86 case CryptographyErrorDetail::ValidateCipherInitializationVector:
87 formatter.append("validate cipher initialization vector");
88 break;
89 case CryptographyErrorDetail::ValidateCipherOutput: formatter.append("validate cipher output capacity"); break;
90 case CryptographyErrorDetail::ValidateCipherOverlap: formatter.append("validate cipher buffer overlap"); break;
91 case CryptographyErrorDetail::ValidateCipherBlockInput: formatter.append("validate cipher block input"); break;
92 case CryptographyErrorDetail::ValidateCipherFinalBlock: formatter.append("validate cipher final block"); break;
93 case CryptographyErrorDetail::ValidateCipherPadding: formatter.append("validate cipher padding"); break;
94 case CryptographyErrorDetail::ValidateHkdfOutput: formatter.append("validate HKDF output size"); break;
95 case CryptographyErrorDetail::AppleCommonCryptoRandomGenerate:
96 formatter.append("Apple CommonCrypto generate random bytes");
97 break;
98 case CryptographyErrorDetail::AppleCommonCryptoAeadCreate:
99 formatter.append("Apple CommonCrypto create AEAD cryptor");
100 break;
101 case CryptographyErrorDetail::AppleCommonCryptoAeadEncrypt:
102 formatter.append("Apple CommonCrypto encrypt AEAD blocks");
103 break;
104 case CryptographyErrorDetail::AppleCommonCryptoCipherCreate:
105 formatter.append("Apple CommonCrypto create cipher");
106 break;
107 case CryptographyErrorDetail::AppleCommonCryptoCipherUpdate:
108 formatter.append("Apple CommonCrypto update cipher");
109 break;
110 case CryptographyErrorDetail::WindowsBCryptRandomGenerate:
111 formatter.append("Windows BCrypt generate random bytes");
112 break;
113 case CryptographyErrorDetail::WindowsBCryptAeadOpenAlgorithm:
114 formatter.append("Windows BCrypt open AEAD algorithm");
115 break;
116 case CryptographyErrorDetail::WindowsBCryptAeadSetGcmMode:
117 formatter.append("Windows BCrypt set AEAD GCM mode");
118 break;
119 case CryptographyErrorDetail::WindowsBCryptAeadQueryObjectLength:
120 formatter.append("Windows BCrypt query AEAD object length");
121 break;
122 case CryptographyErrorDetail::WindowsBCryptAeadKeyObjectCapacity:
123 formatter.append("Windows BCrypt validate AEAD key-object capacity");
124 break;
125 case CryptographyErrorDetail::WindowsBCryptAeadGenerateKey:
126 formatter.append("Windows BCrypt generate AEAD key");
127 break;
128 case CryptographyErrorDetail::WindowsBCryptAeadEncrypt:
129 formatter.append("Windows BCrypt encrypt AEAD message");
130 break;
131 case CryptographyErrorDetail::WindowsBCryptAeadDecrypt:
132 formatter.append("Windows BCrypt decrypt AEAD message");
133 break;
134 case CryptographyErrorDetail::WindowsBCryptCipherOpenAlgorithm:
135 formatter.append("Windows BCrypt open cipher algorithm");
136 break;
137 case CryptographyErrorDetail::WindowsBCryptCipherSetCbcMode:
138 formatter.append("Windows BCrypt set cipher CBC mode");
139 break;
140 case CryptographyErrorDetail::WindowsBCryptCipherQueryObjectLength:
141 formatter.append("Windows BCrypt query cipher object length");
142 break;
143 case CryptographyErrorDetail::WindowsBCryptCipherKeyObjectCapacity:
144 formatter.append("Windows BCrypt validate cipher key-object capacity");
145 break;
146 case CryptographyErrorDetail::WindowsBCryptCipherGenerateKey:
147 formatter.append("Windows BCrypt generate cipher key");
148 break;
149 case CryptographyErrorDetail::WindowsBCryptCipherEncrypt:
150 formatter.append("Windows BCrypt encrypt cipher blocks");
151 break;
152 case CryptographyErrorDetail::WindowsBCryptCipherDecrypt:
153 formatter.append("Windows BCrypt decrypt cipher blocks");
154 break;
155 case CryptographyErrorDetail::WindowsBCryptHmacOpenAlgorithm:
156 formatter.append("Windows BCrypt open HMAC algorithm");
157 break;
158 case CryptographyErrorDetail::WindowsBCryptHmacQueryObjectLength:
159 formatter.append("Windows BCrypt query HMAC object length");
160 break;
161 case CryptographyErrorDetail::WindowsBCryptHmacObjectCapacity:
162 formatter.append("Windows BCrypt validate HMAC object capacity");
163 break;
164 case CryptographyErrorDetail::WindowsBCryptHmacCreate: formatter.append("Windows BCrypt create HMAC"); break;
165 case CryptographyErrorDetail::WindowsBCryptHmacUpdate: formatter.append("Windows BCrypt update HMAC"); break;
166 case CryptographyErrorDetail::WindowsBCryptHmacFinalize: formatter.append("Windows BCrypt finalize HMAC"); break;
167 case CryptographyErrorDetail::LinuxGetRandom: formatter.append("Linux getrandom"); break;
168 case CryptographyErrorDetail::LinuxAFAlgCreateAlgorithmSocket:
169 formatter.append("Linux AF_ALG create algorithm socket");
170 break;
171 case CryptographyErrorDetail::LinuxAFAlgBindAlgorithmSocket:
172 formatter.append("Linux AF_ALG bind algorithm socket");
173 break;
174 case CryptographyErrorDetail::LinuxAFAlgAcceptOperationSocket:
175 formatter.append("Linux AF_ALG accept operation socket");
176 break;
177 case CryptographyErrorDetail::LinuxAFAlgSetKey: formatter.append("Linux AF_ALG set key"); break;
178 case CryptographyErrorDetail::LinuxAFAlgSetAeadAuthenticationSize:
179 formatter.append("Linux AF_ALG set AEAD authentication size");
180 break;
181 case CryptographyErrorDetail::LinuxAFAlgAeadSealSend: formatter.append("Linux AF_ALG send AEAD seal input"); break;
182 case CryptographyErrorDetail::LinuxAFAlgAeadSealReceive:
183 formatter.append("Linux AF_ALG receive AEAD seal output");
184 break;
185 case CryptographyErrorDetail::LinuxAFAlgAeadOpenSend: formatter.append("Linux AF_ALG send AEAD open input"); break;
186 case CryptographyErrorDetail::LinuxAFAlgAeadOpenReceive:
187 formatter.append("Linux AF_ALG receive AEAD open output");
188 break;
189 case CryptographyErrorDetail::LinuxAFAlgCipherSend: formatter.append("Linux AF_ALG send cipher input"); break;
190 case CryptographyErrorDetail::LinuxAFAlgCipherReceive:
191 formatter.append("Linux AF_ALG receive cipher output");
192 break;
193 case CryptographyErrorDetail::LinuxAFAlgHmacSend: formatter.append("Linux AF_ALG send HMAC input"); break;
194 case CryptographyErrorDetail::LinuxAFAlgHmacReceive: formatter.append("Linux AF_ALG receive HMAC output"); break;
195 case CryptographyErrorDetail::OpenSSL3RuntimeUnavailable: formatter.append("OpenSSL 3 load runtime"); break;
196 case CryptographyErrorDetail::OpenSSL3AeadFetchCipher: formatter.append("OpenSSL 3 fetch AEAD cipher"); break;
197 case CryptographyErrorDetail::OpenSSL3AeadCreateContext: formatter.append("OpenSSL 3 create AEAD context"); break;
198 case CryptographyErrorDetail::OpenSSL3AeadInitialize: formatter.append("OpenSSL 3 initialize AEAD context"); break;
199 case CryptographyErrorDetail::OpenSSL3AeadAssociatedDataUpdate:
200 formatter.append("OpenSSL 3 add AEAD associated data");
201 break;
202 case CryptographyErrorDetail::OpenSSL3AeadPayloadUpdate:
203 formatter.append("OpenSSL 3 transform AEAD payload");
204 break;
205 case CryptographyErrorDetail::OpenSSL3AeadSealFinalize: formatter.append("OpenSSL 3 finalize AEAD seal"); break;
206 case CryptographyErrorDetail::OpenSSL3AeadGetAuthenticationTag:
207 formatter.append("OpenSSL 3 get AEAD authentication tag");
208 break;
209 case CryptographyErrorDetail::OpenSSL3AeadSetAuthenticationTag:
210 formatter.append("OpenSSL 3 set AEAD authentication tag");
211 break;
212 case CryptographyErrorDetail::OpenSSL3AeadOpenFinalize: formatter.append("OpenSSL 3 finalize AEAD open"); break;
213 case CryptographyErrorDetail::OpenSSL3CipherFetch: formatter.append("OpenSSL 3 fetch cipher"); break;
214 case CryptographyErrorDetail::OpenSSL3CipherCreateContext:
215 formatter.append("OpenSSL 3 create cipher context");
216 break;
217 case CryptographyErrorDetail::OpenSSL3CipherInitialize:
218 formatter.append("OpenSSL 3 initialize cipher context");
219 break;
220 case CryptographyErrorDetail::OpenSSL3CipherSetPadding: formatter.append("OpenSSL 3 disable cipher padding"); break;
221 case CryptographyErrorDetail::OpenSSL3CipherUpdate: formatter.append("OpenSSL 3 update cipher"); break;
222 case CryptographyErrorDetail::OpenSSL3HmacFetch: formatter.append("OpenSSL 3 fetch HMAC"); break;
223 case CryptographyErrorDetail::OpenSSL3HmacCreateContext: formatter.append("OpenSSL 3 create HMAC context"); break;
224 case CryptographyErrorDetail::OpenSSL3HmacInitialize: formatter.append("OpenSSL 3 initialize HMAC context"); break;
225 case CryptographyErrorDetail::OpenSSL3HmacUpdate: formatter.append("OpenSSL 3 update HMAC"); break;
226 case CryptographyErrorDetail::OpenSSL3HmacFinalize: formatter.append("OpenSSL 3 finalize HMAC"); break;
227 default: return false;
228 }
229 return true;
230}
231
232inline void appendSignedCryptographyContext(ResultErrorFormatter& formatter, int32_t value)
233{
234 if (value < 0)
235 {
236 formatter.append("-");
237 formatter.append(static_cast<uint64_t>(-static_cast<int64_t>(value)));
238 }
239 else
240 formatter.append(static_cast<uint64_t>(value));
241}
242
243inline ResultErrorFormat formatCryptographyErrorWithContext(CryptographyError error, CryptographyErrorDetail detail,
245 CryptographyErrorContext context, Span<char> output)
246{
247 ResultErrorFormatter formatter(output);
248 if (not appendCryptographyError(formatter, error))
249 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
250 if (detail != CryptographyErrorDetail::None)
251 {
252 formatter.append(" (detail: ");
253 if (not appendCryptographyErrorDetail(formatter, detail))
254 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
255 formatter.append(")");
256 }
257 switch (contextKind)
258 {
259 case CryptographyErrorContextKind::None: break;
260 case CryptographyErrorContextKind::AppleCommonCryptoStatus:
261 formatter.append(" (CommonCrypto status: ");
262 appendSignedCryptographyContext(formatter, context.appleCommonCryptoStatus);
263 formatter.append(")");
264 break;
265 case CryptographyErrorContextKind::WindowsNtStatus:
266 formatter.append(" (NTSTATUS: ");
267 formatter.append(static_cast<uint64_t>(context.windowsNtStatus));
268 formatter.append(")");
269 break;
270 case CryptographyErrorContextKind::PosixErrno:
271 formatter.append(" (POSIX errno: ");
272 appendSignedCryptographyContext(formatter, context.posixErrno);
273 formatter.append(")");
274 break;
275 case CryptographyErrorContextKind::ExpectedBytes:
276 formatter.append(" (expected: ");
277 formatter.append(static_cast<uint64_t>(context.expectedBytes));
278 formatter.append(" bytes)");
279 break;
280 case CryptographyErrorContextKind::RequiredBytes:
281 formatter.append(" (required capacity: ");
282 formatter.append(static_cast<uint64_t>(context.requiredBytes));
283 formatter.append(" bytes)");
284 break;
285 case CryptographyErrorContextKind::MaximumBytes:
286 formatter.append(" (maximum: ");
287 formatter.append(static_cast<uint64_t>(context.maximumBytes));
288 formatter.append(" bytes)");
289 break;
290 case CryptographyErrorContextKind::ActualBytes:
291 formatter.append(" (actual: ");
292 formatter.append(static_cast<uint64_t>(context.actualBytes));
293 formatter.append(" bytes)");
294 break;
295 default: return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
296 }
297 return formatter.finish();
298}
299} // namespace detail
300
301inline ResultErrorFormat formatCryptographyError(CryptographyError error, Span<char> output)
302{
303 return detail::formatCryptographyErrorWithContext(error, CryptographyErrorDetail::None,
304 CryptographyErrorContextKind::None, {}, output);
305}
306
307inline ResultErrorFormat formatCryptographyError(Result result, Span<char> output)
308{
309 if (result)
310 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
311 if (result.category() != CryptographyResultCategory)
312 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
313 return formatCryptographyError(static_cast<CryptographyError>(result.errorValue()), output);
314}
315
316inline ResultErrorFormat formatCryptographyError(ResultCryptography result, Span<char> output)
317{
318 if (result)
319 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
320 if (result.result.category() != CryptographyResultCategory)
321 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
322 return detail::formatCryptographyErrorWithContext(static_cast<CryptographyError>(result.result.errorValue()),
323 result.detail, result.contextKind, result.context, output);
324}
325} // namespace SC
CryptographyErrorDetail
Stable operation or backend stage retained for a Cryptography failure.
Definition CryptographyError.h:43
CryptographyErrorContextKind
Kind of the scalar diagnostic context stored in ResultCryptography.
Definition CryptographyError.h:138
CryptographyError
Stable portable failures returned by the Cryptography library.
Definition CryptographyError.h:14