aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2015-06-15 01:04:48 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2015-06-15 01:04:48 +0300
commitc11a0bd2abef4c9536432664600ce6b6ed6ccbe4 (patch)
tree91b8a928c82aeabc48788752944c2269d4c63b79
parentupdate the docs (diff)
downloadaes-tools-c11a0bd2abef4c9536432664600ce6b6ed6ccbe4.tar.gz
aes-tools-c11a0bd2abef4c9536432664600ce6b6ed6ccbe4.zip
error handling refactoring + more docs
-rw-r--r--include/aesni/buffer.h8
-rw-r--r--include/aesni/error.h120
-rw-r--r--src/buffer.c57
-rw-r--r--src/error.c41
-rw-r--r--utils/cxx/include/aesnixx/error.hpp2
5 files changed, 144 insertions, 84 deletions
diff --git a/include/aesni/buffer.h b/include/aesni/buffer.h
index 6222f4f..fff616f 100644
--- a/include/aesni/buffer.h
+++ b/include/aesni/buffer.h
@@ -18,20 +18,20 @@ extern "C"
{
#endif
-int aesni_encrypt_buffer_ecb128(
+AesNI_StatusCode aesni_encrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
size_t* dest_size,
AesNI_KeySchedule128* key_schedule,
- AesNI_ErrorDetails*);
-int aesni_decrypt_buffer_ecb128(
+ AesNI_ErrorDetails* err_details);
+AesNI_StatusCode aesni_decrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
size_t* dest_size,
AesNI_KeySchedule128* inverted_schedule,
- AesNI_ErrorDetails*);
+ AesNI_ErrorDetails* err_details);
#ifdef __cplusplus
}
diff --git a/include/aesni/error.h b/include/aesni/error.h
index 91bf168..56a1da1 100644
--- a/include/aesni/error.h
+++ b/include/aesni/error.h
@@ -9,6 +9,28 @@
#pragma once
+/**
+ * \defgroup aesni_error_handling Error handling
+ * \ingroup aesni
+ * \brief Error data structures and formatting functions.
+ *
+ * Some library functions cannot fail, which is simple.
+ * Other functions return an error code.
+ * You can check if a function exited with an error by passing the returned
+ * error code to aesni_is_error().
+ *
+ * Some possibly-may-fail functions accept a pointer to an "error details"
+ * structure.
+ * This pointer can always be `NULL`.
+ * In this case, simply an error code is returned.
+ * Otherwise, the error details structure is filled with appropriate info about
+ * the error, possibly including a few details like invalid arguments names,
+ * etc.
+ *
+ * You can format an error details structure using the formatting functions.
+ * \{
+ */
+
#include <stdlib.h>
#ifdef __cplusplus
@@ -16,45 +38,117 @@ extern "C"
{
#endif
+/**
+ * \brief API status codes.
+ */
typedef enum
{
- AESNI_ERROR_SUCCESS,
+ AESNI_SUCCESS, ///< Indicates an operation
+
+ AESNI_ERROR_NULL_ARGUMENT, ///< Invalid argument value NULL
- AESNI_ERROR_NULL_ARGUMENT,
+ AESNI_ERROR_INVALID_PKCS7_PADDING, ///< Invalid PKCS7 padding
+}
+AesNI_StatusCode;
- AESNI_ERROR_INVALID_PKCS7_PADDING,
+static __inline int aesni_is_error(AesNI_StatusCode ec)
+{
+ return ec != AESNI_SUCCESS;
}
-AesNI_ErrorCode;
-const char* aesni_strerror(AesNI_ErrorCode);
+/**
+ * \brief Retrieves a simple error message for an error code.
+ *
+ * For example,
+ * \code{.c}
+ * printf("%s\n", aesni_strerror(AESNI_ERROR_NULL_ARGUMENT));
+ * \endcode
+ * would print
+ * \code
+ * Invalid argument value NULL
+ * \endcode
+ *
+ * \param[in] ec The error code.
+ * \return A pointer to a statically-allocated C string.
+ */
+const char* aesni_strerror(AesNI_StatusCode ec);
+/**
+ * \brief Stores error details: error code & possibly a few parameters.
+ */
typedef struct
{
- AesNI_ErrorCode ec;
+ AesNI_StatusCode ec; ///< Error code
union
{
struct
{
- char arg_name[32];
+ char arg_name[32]; ///< Name of the NULL argument
}
- null_arg;
+ null_arg; ///< `NULL` argument error parameters
}
params;
}
AesNI_ErrorDetails;
-static __inline AesNI_ErrorCode aesni_get_error_code(const AesNI_ErrorDetails* err_details)
+/**
+ * \brief Extracts an error code from error details.
+ *
+ * \param[in] err_details The error details structure. Must not be `NULL`.
+ * \return The error code stored in the error details.
+ */
+static __inline AesNI_StatusCode aesni_get_error_code(
+ const AesNI_ErrorDetails* err_details)
{
return err_details->ec;
}
-size_t aesni_format_error(const AesNI_ErrorDetails*, char*, size_t);
+/**
+ * \brief Formats a pretty error message, including error parameters.
+ *
+ * \param[in] err_details The pointer to error details. Must not be `NULL`.
+ * \param[out] dest The pointer to the destination string buffer.
+ * \param[in] dest_size The size of the destination buffer, in bytes.
+ * \return If `dest` is NULL, the number of bytes required to store the full
+ * error message, and the number of characters written (excluding the
+ * terminating '\0' character) otherwise.
+ */
+size_t aesni_format_error(
+ const AesNI_ErrorDetails* err_details,
+ char* dest,
+ size_t dest_size);
-void aesni_make_error_success(AesNI_ErrorDetails*);
-void aesni_make_error_null_argument(AesNI_ErrorDetails*, const char* arg_name);
-void aesni_make_error_invalid_pkcs7_padding(AesNI_ErrorDetails*);
+/**
+ * \brief Initializes error details structure.
+ *
+ * \param[out] err_details The error details structure to fill.
+ */
+AesNI_StatusCode aesni_make_error_success(
+ AesNI_ErrorDetails* err_details);
+
+/**
+ * \brief Builds error details from a `NULL` argument error.
+ *
+ * \param[out] err_details The error details structure to fill.
+ * \param[in] arg_name The `NULL` argument name. Must not be `NULL`.
+ */
+AesNI_StatusCode aesni_make_error_null_argument(
+ AesNI_ErrorDetails* err_details,
+ const char* arg_name);
+
+/**
+ * \brief Builds error details from an invalid PKCS7 padding error.
+ *
+ * \param[out] err_details The error details structure to fill.
+ */
+AesNI_StatusCode aesni_make_error_invalid_pkcs7_padding(
+ AesNI_ErrorDetails* err_details);
#ifdef __cplusplus
}
#endif
+
+/**
+ * \}
+ */
diff --git a/src/buffer.c b/src/buffer.c
index 71ebad2..74ff519 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -13,7 +13,7 @@
static unsigned char FULL_BLOCK_PADDING[16] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
-int aesni_encrypt_buffer_ecb128(
+AesNI_StatusCode aesni_encrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
@@ -22,29 +22,18 @@ int aesni_encrypt_buffer_ecb128(
AesNI_ErrorDetails* err_details)
{
if (dest_size == NULL)
- {
- aesni_make_error_null_argument(err_details, "dest_size");
- return 1;
- }
+ return aesni_make_error_null_argument(err_details, "dest_size");
const size_t rem_size = src_size % 16;
const size_t padding_size = 16 - rem_size;
*dest_size = src_size + padding_size;
if (dest == NULL)
- return 0;
-
+ return AESNI_SUCCESS;
if (src == NULL)
- {
- aesni_make_error_null_argument(err_details, "src");
- return 1;
- }
-
+ return aesni_make_error_null_argument(err_details, "src");
if (key_schedule == NULL)
- {
- aesni_make_error_null_argument(err_details, "key_schedule");
- return 1;
- }
+ return aesni_make_error_null_argument(err_details, "key_schedule");
const size_t src_len = src_size / 16;
@@ -71,7 +60,7 @@ int aesni_encrypt_buffer_ecb128(
AesNI_Block128 ciphertext = aesni_encrypt_block_ecb128(plaintext, key_schedule);
aesni_store_block128(dest, ciphertext);
- return 0;
+ return AESNI_SUCCESS;
}
static unsigned char get_pkcs7_padding_size(const unsigned char* padding)
@@ -86,7 +75,7 @@ static unsigned char get_pkcs7_padding_size(const unsigned char* padding)
return padding[15];
}
-int aesni_decrypt_buffer_ecb128(
+AesNI_StatusCode aesni_decrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
@@ -95,27 +84,16 @@ int aesni_decrypt_buffer_ecb128(
AesNI_ErrorDetails* err_details)
{
if (dest_size == NULL)
- {
- aesni_make_error_null_argument(err_details, "dest_size");
- return 1;
- }
+ return aesni_make_error_null_argument(err_details, "dest_size");
*dest_size = src_size;
if (dest == NULL)
return 0;
-
if (src == NULL)
- {
- aesni_make_error_null_argument(err_details, "src");
- return 1;
- }
-
+ return aesni_make_error_null_argument(err_details, "src");
if (inverted_schedule == NULL)
- {
- aesni_make_error_null_argument(err_details, "inverted_schedule");
- return 1;
- }
+ return aesni_make_error_null_argument(err_details, "inverted_schedule");
const size_t src_len = src_size / 16;
@@ -134,14 +112,9 @@ int aesni_decrypt_buffer_ecb128(
unsigned char padding_size = get_pkcs7_padding_size(padding);
if (padding_size == 0)
- {
- aesni_make_error_invalid_pkcs7_padding(err_details);
- return 1;
- }
- else
- {
- memcpy(dest, padding, 16 - padding_size);
- *dest_size -= padding_size;
- return 0;
- }
+ return aesni_make_error_invalid_pkcs7_padding(err_details);
+
+ memcpy(dest, padding, 16 - padding_size);
+ *dest_size -= padding_size;
+ return AESNI_SUCCESS;
}
diff --git a/src/error.c b/src/error.c
index e52cd4d..034aa72 100644
--- a/src/error.c
+++ b/src/error.c
@@ -20,17 +20,17 @@ static const char* err_msgs[] =
"Invalid PKCS7 padding (wrong key?)",
};
-const char* aesni_strerror(AesNI_ErrorCode ec)
+const char* aesni_strerror(AesNI_StatusCode ec)
{
return err_msgs[ec];
}
-static size_t aesni_format_error_simple(
+static size_t aesni_format_error_strerror(
const AesNI_ErrorDetails* err_details,\
char* dest,
size_t dest_size)
{
- const AesNI_ErrorCode ec = aesni_get_error_code(err_details);
+ const AesNI_StatusCode ec = aesni_get_error_code(err_details);
const char* const msg = aesni_strerror(ec);
if (dest == NULL && dest_size == 0)
@@ -60,9 +60,9 @@ typedef size_t (*AesNI_ErrorFormatter)(const AesNI_ErrorDetails*, char*, size_t)
static AesNI_ErrorFormatter err_formatters[] =
{
- &aesni_format_error_simple,
+ &aesni_format_error_strerror,
&aesni_format_error_null_argument,
- &aesni_format_error_simple,
+ &aesni_format_error_strerror,
};
size_t aesni_format_error(
@@ -75,44 +75,37 @@ size_t aesni_format_error(
return err_formatters[err_details->ec](err_details, dest, dest_size);
}
-static void aesni_make_error(
+static AesNI_StatusCode aesni_make_error(
AesNI_ErrorDetails* err_details,
- AesNI_ErrorCode ec)
+ AesNI_StatusCode ec)
{
if (err_details == NULL)
- return;
+ return ec;
- err_details->ec = ec;
+ return err_details->ec = ec;
}
-void aesni_make_error_success(
+AesNI_StatusCode aesni_make_error_success(
AesNI_ErrorDetails* err_details)
{
- if (err_details == NULL)
- return;
-
- aesni_make_error(err_details, AESNI_ERROR_SUCCESS);
+ return aesni_make_error(err_details, AESNI_SUCCESS);
}
-void aesni_make_error_null_argument(
+AesNI_StatusCode aesni_make_error_null_argument(
AesNI_ErrorDetails* err_details,
const char* arg_name)
{
- if (err_details == NULL)
- return;
-
- aesni_make_error(err_details, AESNI_ERROR_NULL_ARGUMENT);
+ AesNI_StatusCode status = aesni_make_error(err_details, AESNI_ERROR_NULL_ARGUMENT);
const size_t arg_name_size = sizeof(err_details->params.null_arg.arg_name);
strncpy(err_details->params.null_arg.arg_name, arg_name, arg_name_size);
err_details->params.null_arg.arg_name[arg_name_size - 1] = '\0';
+
+ return status;
}
-void aesni_make_error_invalid_pkcs7_padding(
+AesNI_StatusCode aesni_make_error_invalid_pkcs7_padding(
AesNI_ErrorDetails* err_details)
{
- if (err_details == NULL)
- return;
-
- aesni_make_error(err_details, AESNI_ERROR_INVALID_PKCS7_PADDING);
+ return aesni_make_error(err_details, AESNI_ERROR_INVALID_PKCS7_PADDING);
}
diff --git a/utils/cxx/include/aesnixx/error.hpp b/utils/cxx/include/aesnixx/error.hpp
index db390ea..81e63c6 100644
--- a/utils/cxx/include/aesnixx/error.hpp
+++ b/utils/cxx/include/aesnixx/error.hpp
@@ -28,7 +28,7 @@ namespace aesni
~ErrorDetailsThrowsInDestructor()
{
- if (aesni_get_error_code(get()) != AESNI_ERROR_SUCCESS)
+ if (aesni_is_error(aesni_get_error_code(get())))
{
std::vector<char> msg;
msg.resize(aesni_format_error(get(), NULL, 0));