aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--include/aesni/all.h1
-rw-r--r--include/aesni/buffer.h14
-rw-r--r--include/aesni/error.h50
-rw-r--r--src/buffer.c76
-rw-r--r--src/error.c66
-rw-r--r--utils/CMakeLists.txt2
-rw-r--r--utils/aes128ecb_decrypt_file.cpp36
-rw-r--r--utils/aes128ecb_encrypt_file.cpp30
-rw-r--r--utils/common.hpp38
9 files changed, 271 insertions, 42 deletions
diff --git a/include/aesni/all.h b/include/aesni/all.h
index 1360320..4653eca 100644
--- a/include/aesni/all.h
+++ b/include/aesni/all.h
@@ -11,4 +11,5 @@
#include "block.h"
#include "buffer.h"
#include "data.h"
+#include "error.h"
#include "raw.h"
diff --git a/include/aesni/buffer.h b/include/aesni/buffer.h
index daafc3e..13f19da 100644
--- a/include/aesni/buffer.h
+++ b/include/aesni/buffer.h
@@ -8,6 +8,8 @@
#pragma once
+#include "error.h"
+
#include <stdlib.h>
#ifdef __cplusplus
@@ -15,16 +17,20 @@ extern "C"
{
#endif
-size_t aesni_encrypt_buffer_ecb128(
+int aesni_encrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
- AesNI_KeySchedule128* key_schedule);
-size_t aesni_decrypt_buffer_ecb128(
+ size_t* dest_size,
+ AesNI_KeySchedule128* key_schedule,
+ AesNI_ErrorDetails*);
+int aesni_decrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
- AesNI_KeySchedule128* inverted_schedule);
+ size_t* dest_size,
+ AesNI_KeySchedule128* inverted_schedule,
+ AesNI_ErrorDetails*);
#ifdef __cplusplus
}
diff --git a/include/aesni/error.h b/include/aesni/error.h
new file mode 100644
index 0000000..54d3d34
--- /dev/null
+++ b/include/aesni/error.h
@@ -0,0 +1,50 @@
+/**
+ * \file
+ * \author Egor Tensin <Egor.Tensin@gmail.com>
+ * \date 2015
+ * \copyright This file is licensed under the terms of the MIT License.
+ * See LICENSE.txt for details.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ AESNI_ERROR_SUCCESS,
+
+ AESNI_ERROR_NULL_ARGUMENT,
+
+ AESNI_ERROR_INVALID_PKCS7_PADDING,
+}
+AesNI_ErrorCode;
+
+const char* aesni_strerror(AesNI_ErrorCode);
+
+typedef struct
+{
+ AesNI_ErrorCode ec;
+
+ union
+ {
+ struct
+ {
+ char arg_name[32];
+ }
+ null_arg;
+ }
+ params;
+}
+AesNI_ErrorDetails;
+
+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*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/buffer.c b/src/buffer.c
index b4896f7..71ebad2 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -13,20 +13,40 @@
static unsigned char FULL_BLOCK_PADDING[16] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
-size_t aesni_encrypt_buffer_ecb128(
+int aesni_encrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
- AesNI_KeySchedule128* key_schedule)
+ size_t* dest_size,
+ AesNI_KeySchedule128* key_schedule,
+ AesNI_ErrorDetails* err_details)
{
- size_t rem_size = src_size % 16;
- size_t padding_size = 16 - rem_size;
- size_t dest_size = src_size + padding_size;
+ if (dest_size == NULL)
+ {
+ aesni_make_error_null_argument(err_details, "dest_size");
+ return 1;
+ }
+
+ 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 dest_size;
+ return 0;
- size_t src_len = src_size / 16;
+ if (src == NULL)
+ {
+ aesni_make_error_null_argument(err_details, "src");
+ return 1;
+ }
+
+ if (key_schedule == NULL)
+ {
+ aesni_make_error_null_argument(err_details, "key_schedule");
+ return 1;
+ }
+
+ const size_t src_len = src_size / 16;
for (size_t i = 0; i < src_len; ++i, (char*) src += 16, (char*) dest += 16)
{
@@ -51,10 +71,10 @@ size_t aesni_encrypt_buffer_ecb128(
AesNI_Block128 ciphertext = aesni_encrypt_block_ecb128(plaintext, key_schedule);
aesni_store_block128(dest, ciphertext);
- return dest_size;
+ return 0;
}
-static unsigned char get_padding_size(const unsigned char* padding)
+static unsigned char get_pkcs7_padding_size(const unsigned char* padding)
{
if (padding[15] < 0x01 || padding[15] > 0x10)
return 0;
@@ -66,18 +86,38 @@ static unsigned char get_padding_size(const unsigned char* padding)
return padding[15];
}
-size_t aesni_decrypt_buffer_ecb128(
+int aesni_decrypt_buffer_ecb128(
const void* src,
size_t src_size,
void* dest,
- AesNI_KeySchedule128* inverted_schedule)
+ size_t* dest_size,
+ AesNI_KeySchedule128* inverted_schedule,
+ AesNI_ErrorDetails* err_details)
{
- size_t dest_size = src_size;
+ if (dest_size == NULL)
+ {
+ aesni_make_error_null_argument(err_details, "dest_size");
+ return 1;
+ }
+
+ *dest_size = src_size;
if (dest == NULL)
- return dest_size;
+ return 0;
+
+ if (src == NULL)
+ {
+ aesni_make_error_null_argument(err_details, "src");
+ return 1;
+ }
- size_t src_len = src_size / 16;
+ if (inverted_schedule == NULL)
+ {
+ aesni_make_error_null_argument(err_details, "inverted_schedule");
+ return 1;
+ }
+
+ const size_t src_len = src_size / 16;
for (size_t i = 0; i < src_len - 1; ++i, (char*) src += 16, (char*) dest += 16)
{
@@ -91,15 +131,17 @@ size_t aesni_decrypt_buffer_ecb128(
unsigned char padding[16];
aesni_store_block128(padding, plaintext);
- unsigned char padding_size = get_padding_size(padding);
+ unsigned char padding_size = get_pkcs7_padding_size(padding);
if (padding_size == 0)
{
- return dest_size - 16;
+ aesni_make_error_invalid_pkcs7_padding(err_details);
+ return 1;
}
else
{
memcpy(dest, padding, 16 - padding_size);
- return dest_size - padding_size;
+ *dest_size -= padding_size;
+ return 0;
}
}
diff --git a/src/error.c b/src/error.c
new file mode 100644
index 0000000..c4af82c
--- /dev/null
+++ b/src/error.c
@@ -0,0 +1,66 @@
+/**
+ * \file
+ * \author Egor Tensin <Egor.Tensin@gmail.com>
+ * \date 2015
+ * \copyright This file is licensed under the terms of the MIT License.
+ * See LICENSE.txt for details.
+ */
+
+#include <aesni/all.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static const char* err_msgs[] =
+{
+ "Success",
+ "Invalid argument value NULL",
+ "Invalid PKCS7 padding (wrong key?)",
+};
+
+const char* aesni_strerror(AesNI_ErrorCode ec)
+{
+ return err_msgs[ec];
+}
+
+static void aesni_make_error(
+ AesNI_ErrorDetails* err_details,
+ AesNI_ErrorCode ec)
+{
+ if (err_details == NULL)
+ return;
+
+ err_details->ec = ec;
+}
+
+void aesni_make_error_success(
+ AesNI_ErrorDetails* err_details)
+{
+ if (err_details == NULL)
+ return;
+
+ aesni_make_error(err_details, AESNI_ERROR_SUCCESS);
+}
+
+void 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);
+
+ 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';
+}
+
+void 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);
+}
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index f6ca7d1..a667663 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,5 +1,5 @@
macro(util prefix)
- add_executable(util_${prefix} ${prefix}.cpp)
+ add_executable(util_${prefix} ${prefix}.cpp common.hpp)
target_link_libraries(util_${prefix} libaesni)
set_target_properties(util_${prefix} PROPERTIES OUTPUT_NAME ${prefix})
endmacro()
diff --git a/utils/aes128ecb_decrypt_file.cpp b/utils/aes128ecb_decrypt_file.cpp
index 33e0515..23545f9 100644
--- a/utils/aes128ecb_decrypt_file.cpp
+++ b/utils/aes128ecb_decrypt_file.cpp
@@ -6,10 +6,13 @@
* See LICENSE.txt for details.
*/
+#include "common.hpp"
+
#include <aesni/all.h>
-#include <cstdio>
+#include <cstdlib>
+#include <exception>
#include <iostream>
#include <fstream>
#include <string>
@@ -51,27 +54,40 @@ int main(int argc, char** argv)
const std::string src_path(argv[2]);
const std::string dest_path(argv[3]);
- const auto src_size = get_file_size(src_path);
+ const auto src_size = static_cast<std::size_t>(get_file_size(src_path));
std::ifstream src_ifs;
src_ifs.exceptions(std::ifstream::badbit | std::ifstream::failbit);
src_ifs.open(src_path, std::ifstream::binary);
std::vector<char> src_buf;
- src_buf.reserve(static_cast<std::vector<char>::size_type>(src_size));
+ src_buf.reserve(src_size);
src_buf.assign(std::istreambuf_iterator<char>(src_ifs),
std::istreambuf_iterator<char>());
aesni_expand_key_schedule128(key, &key_schedule);
aesni_invert_key_schedule128(&key_schedule, &inverted_schedule);
- auto dest_size = aesni_decrypt_buffer_ecb128(
- src_buf.data(), static_cast<std::size_t>(src_size), NULL, &inverted_schedule);
-
- std::vector<char> dest_buf(static_cast<std::vector<char>::size_type>(dest_size));
-
- dest_size = aesni_decrypt_buffer_ecb128(
- src_buf.data(), static_cast<std::size_t>(src_size), dest_buf.data(), &inverted_schedule);
+ std::size_t dest_size;
+
+ aesni_decrypt_buffer_ecb128(
+ src_buf.data(),
+ src_size,
+ NULL,
+ &dest_size,
+ &inverted_schedule,
+ aesni::ErrorDetailsThrowsInDestructor());
+
+ std::vector<char> dest_buf;
+ dest_buf.reserve(dest_size);
+
+ aesni_decrypt_buffer_ecb128(
+ src_buf.data(),
+ src_size,
+ dest_buf.data(),
+ &dest_size,
+ &inverted_schedule,
+ aesni::ErrorDetailsThrowsInDestructor());
std::ofstream dest_ofs;
dest_ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit);
diff --git a/utils/aes128ecb_encrypt_file.cpp b/utils/aes128ecb_encrypt_file.cpp
index 07c3e91..42e297c 100644
--- a/utils/aes128ecb_encrypt_file.cpp
+++ b/utils/aes128ecb_encrypt_file.cpp
@@ -6,10 +6,13 @@
* See LICENSE.txt for details.
*/
+#include "common.hpp"
+
#include <aesni/all.h>
-#include <cstdio>
+#include <cstdlib>
+#include <exception>
#include <iostream>
#include <fstream>
#include <string>
@@ -51,37 +54,44 @@ int main(int argc, char** argv)
const std::string src_path(argv[2]);
const std::string dest_path(argv[3]);
- const auto src_size = get_file_size(src_path);
+ const auto src_size = static_cast<std::size_t>(get_file_size(src_path));
std::ifstream src_ifs;
src_ifs.exceptions(std::ifstream::badbit | std::ifstream::failbit);
src_ifs.open(src_path, std::ifstream::binary);
std::vector<char> src_buf;
- src_buf.reserve(static_cast<std::vector<char>::size_type>(src_size));
+ src_buf.reserve(src_size);
src_buf.assign(std::istreambuf_iterator<char>(src_ifs),
std::istreambuf_iterator<char>());
aesni_expand_key_schedule128(key, &key_schedule);
- const auto dest_size = aesni_encrypt_buffer_ecb128(
+ std::size_t dest_size;
+
+ aesni_encrypt_buffer_ecb128(
src_buf.data(),
- static_cast<std::size_t>(src_size),
+ src_size,
NULL,
- &key_schedule);
+ &dest_size,
+ &key_schedule,
+ aesni::ErrorDetailsThrowsInDestructor());
- std::vector<char> dest_buf(static_cast<std::vector<char>::size_type>(dest_size));
+ std::vector<char> dest_buf;
+ dest_buf.reserve(dest_size);
aesni_encrypt_buffer_ecb128(
src_buf.data(),
- static_cast<std::size_t>(src_size),
+ src_size,
dest_buf.data(),
- &key_schedule);
+ &dest_size,
+ &key_schedule,
+ aesni::ErrorDetailsThrowsInDestructor());
std::ofstream dest_ofs;
dest_ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit);
dest_ofs.open(dest_path, std::ofstream::binary);
- dest_ofs.write(dest_buf.data(), dest_buf.size());
+ dest_ofs.write(dest_buf.data(), dest_size);
}
catch (const std::exception& e)
{
diff --git a/utils/common.hpp b/utils/common.hpp
new file mode 100644
index 0000000..af61a32
--- /dev/null
+++ b/utils/common.hpp
@@ -0,0 +1,38 @@
+/**
+ * \file
+ * \author Egor Tensin <Egor.Tensin@gmail.com>
+ * \date 2015
+ * \copyright This file is licensed under the terms of the MIT License.
+ * See LICENSE.txt for details.
+ */
+
+#pragma once
+
+#include <aesni/all.h>
+
+#include <stdexcept>
+
+namespace aesni
+{
+ class ErrorDetailsThrowsInDestructor
+ {
+ public:
+ ErrorDetailsThrowsInDestructor()
+ {
+ aesni_make_error_success(get());
+ }
+
+ ~ErrorDetailsThrowsInDestructor()
+ {
+ if (m_impl.ec != AESNI_ERROR_SUCCESS)
+ throw std::runtime_error(aesni_strerror(m_impl.ec));
+ }
+
+ AesNI_ErrorDetails* get() { return &m_impl; }
+
+ operator AesNI_ErrorDetails*() { return get(); }
+
+ private:
+ AesNI_ErrorDetails m_impl;
+ };
+}