aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--include/aesni/algorithm.h17
-rw-r--r--include/aesni/all.h3
-rw-r--r--include/aesni/box.h83
-rw-r--r--include/aesni/mode.h19
-rw-r--r--src/box.c442
5 files changed, 564 insertions, 0 deletions
diff --git a/include/aesni/algorithm.h b/include/aesni/algorithm.h
new file mode 100644
index 0000000..8aacfdc
--- /dev/null
+++ b/include/aesni/algorithm.h
@@ -0,0 +1,17 @@
+/**
+ * \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
+
+typedef enum
+{
+ AESNI_AES128,
+ AESNI_AES192,
+ AESNI_AES256,
+}
+AesNI_Algorithm;
diff --git a/include/aesni/all.h b/include/aesni/all.h
index 350e4dd..70f5e7e 100644
--- a/include/aesni/all.h
+++ b/include/aesni/all.h
@@ -15,8 +15,11 @@
* \defgroup aesni AesNI
*/
+#include "algorithm.h"
#include "block.h"
+#include "box.h"
#include "buffer.h"
#include "data.h"
#include "error.h"
+#include "mode.h"
#include "raw.h"
diff --git a/include/aesni/box.h b/include/aesni/box.h
new file mode 100644
index 0000000..2ae6533
--- /dev/null
+++ b/include/aesni/box.h
@@ -0,0 +1,83 @@
+/**
+ * \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 "algorithm.h"
+#include "data.h"
+#include "error.h"
+#include "mode.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef union
+{
+ AesNI_KeySchedule128 aes128_key_schedule;
+ AesNI_KeySchedule192 aes192_key_schedule;
+ AesNI_KeySchedule256 aes256_key_schedule;
+}
+AesNI_EncryptionParams;
+
+typedef union
+{
+ AesNI_KeySchedule128 aes128_key_schedule;
+ AesNI_KeySchedule192 aes192_key_schedule;
+ AesNI_KeySchedule256 aes256_key_schedule;
+}
+AesNI_DecryptionParams;
+
+typedef union
+{
+ AesNI_Block128 aes_block;
+}
+AesNI_State;
+
+typedef union
+{
+ AesNI_Block128 aes128_key;
+ AesNI_Block192 aes192_key;
+ AesNI_Block256 aes256_key;
+}
+AesNI_AlgorithmParams;
+
+typedef struct
+{
+ AesNI_Algorithm algorithm;
+ AesNI_EncryptionParams encrypt_params;
+ AesNI_DecryptionParams decrypt_params;
+ AesNI_Mode mode;
+ AesNI_State iv;
+}
+AesNI_Box;
+
+AesNI_StatusCode aesni_box_init(
+ AesNI_Box*,
+ AesNI_Algorithm,
+ const AesNI_AlgorithmParams*,
+ AesNI_Mode,
+ const AesNI_State* iv,
+ AesNI_ErrorDetails*);
+
+AesNI_StatusCode aesni_box_encrypt(
+ AesNI_Box*,
+ const AesNI_State*,
+ AesNI_State*,
+ AesNI_ErrorDetails*);
+
+AesNI_StatusCode aesni_box_decrypt(
+ AesNI_Box*,
+ const AesNI_State*,
+ AesNI_State*,
+ AesNI_ErrorDetails*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/aesni/mode.h b/include/aesni/mode.h
new file mode 100644
index 0000000..fc00e9c
--- /dev/null
+++ b/include/aesni/mode.h
@@ -0,0 +1,19 @@
+/**
+ * \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
+
+typedef enum
+{
+ AESNI_ECB,
+ AESNI_CBC,
+ AESNI_CFB,
+ AESNI_OFB,
+ AESNI_CTR,
+}
+AesNI_Mode;
diff --git a/src/box.c b/src/box.c
new file mode 100644
index 0000000..01f3b20
--- /dev/null
+++ b/src/box.c
@@ -0,0 +1,442 @@
+/**
+ * \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>
+
+static AesNI_StatusCode aesni_box_xor_state_aes(
+ AesNI_State* dest,
+ const AesNI_State* src,
+ AesNI_ErrorDetails* err_details)
+{
+ dest->aes_block = _mm_xor_si128(dest->aes_block, src->aes_block);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_aes128(
+ const AesNI_State* input,
+ const AesNI_EncryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ output->aes_block = aesni_raw_encrypt_block128(
+ input->aes_block,
+ &params->aes128_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_decrypt_aes128(
+ const AesNI_State* input,
+ const AesNI_DecryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ output->aes_block = aesni_raw_decrypt_block128(
+ input->aes_block,
+ &params->aes128_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_aes192(
+ const AesNI_State* input,
+ const AesNI_EncryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ output->aes_block = aesni_raw_encrypt_block192(
+ input->aes_block,
+ &params->aes192_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_decrypt_aes192(
+ const AesNI_State* input,
+ const AesNI_DecryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ output->aes_block = aesni_raw_decrypt_block192(
+ input->aes_block,
+ &params->aes192_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_aes256(
+ const AesNI_State* input,
+ const AesNI_EncryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ output->aes_block = aesni_raw_encrypt_block256(
+ input->aes_block,
+ &params->aes256_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_decrypt_aes256(
+ const AesNI_State* input,
+ const AesNI_DecryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ output->aes_block = aesni_raw_decrypt_block256(
+ input->aes_block,
+ &params->aes256_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+typedef AesNI_StatusCode (*AesNI_BoxEncrypt)(
+ const AesNI_State*,
+ const AesNI_EncryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details);
+
+static AesNI_BoxEncrypt aesni_box_encrypt_algorithm[] =
+{
+ &aesni_box_encrypt_aes128,
+ &aesni_box_encrypt_aes192,
+ &aesni_box_encrypt_aes256,
+};
+
+typedef AesNI_StatusCode (*AesNI_BoxDecrypt)(
+ const AesNI_State*,
+ const AesNI_DecryptionParams* params,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details);
+
+static AesNI_BoxDecrypt aesni_box_decrypt_algorithm[] =
+{
+ &aesni_box_decrypt_aes128,
+ &aesni_box_decrypt_aes192,
+ &aesni_box_decrypt_aes256,
+};
+
+typedef AesNI_StatusCode (*AesNI_BoxXorState)(
+ AesNI_State*,
+ const AesNI_State*,
+ AesNI_ErrorDetails*);
+
+static AesNI_BoxXorState aesni_box_xor_state[] =
+{
+ &aesni_box_xor_state_aes,
+ &aesni_box_xor_state_aes,
+ &aesni_box_xor_state_aes,
+};
+
+static AesNI_StatusCode aesni_box_init_aes128(
+ AesNI_Box* box,
+ const AesNI_AlgorithmParams* algorithm_params,
+ AesNI_ErrorDetails* err_details)
+{
+ aesni_raw_expand_key_schedule128(
+ algorithm_params->aes128_key,
+ &box->encrypt_params.aes128_key_schedule);
+ aesni_raw_invert_key_schedule128(
+ &box->encrypt_params.aes128_key_schedule,
+ &box->decrypt_params.aes128_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_init_aes192(
+ AesNI_Box* box,
+ const AesNI_AlgorithmParams* algorithm_params,
+ AesNI_ErrorDetails* err_details)
+{
+ aesni_raw_expand_key_schedule192(
+ algorithm_params->aes192_key.lo,
+ algorithm_params->aes192_key.hi,
+ &box->encrypt_params.aes192_key_schedule);
+ aesni_raw_invert_key_schedule192(
+ &box->encrypt_params.aes192_key_schedule,
+ &box->decrypt_params.aes192_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+static AesNI_StatusCode aesni_box_init_aes256(
+ AesNI_Box* box,
+ const AesNI_AlgorithmParams* algorithm_params,
+ AesNI_ErrorDetails* err_details)
+{
+ aesni_raw_expand_key_schedule256(
+ algorithm_params->aes256_key.lo,
+ algorithm_params->aes256_key.hi,
+ &box->encrypt_params.aes256_key_schedule);
+ aesni_raw_invert_key_schedule256(
+ &box->encrypt_params.aes256_key_schedule,
+ &box->decrypt_params.aes256_key_schedule);
+ return AESNI_SUCCESS;
+}
+
+typedef AesNI_StatusCode (*AesNI_BoxInitializeAlgorithm)(
+ AesNI_Box*,
+ const AesNI_AlgorithmParams*,
+ AesNI_ErrorDetails*);
+
+static AesNI_BoxInitializeAlgorithm aesni_box_init_algorithm[] =
+{
+ &aesni_box_init_aes128,
+ &aesni_box_init_aes192,
+ &aesni_box_init_aes256,
+};
+
+AesNI_StatusCode aesni_box_init(
+ AesNI_Box* box,
+ AesNI_Algorithm algorithm,
+ const AesNI_AlgorithmParams* algorithm_params,
+ AesNI_Mode mode,
+ const AesNI_State* iv,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = AESNI_SUCCESS;
+
+ box->algorithm = algorithm;
+ if (aesni_is_error(status = aesni_box_init_algorithm[algorithm](box, algorithm_params, err_details)))
+ return status;
+ box->mode = mode;
+ if (iv != NULL)
+ box->iv = *iv;
+
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_ecb(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ return aesni_box_encrypt_algorithm[box->algorithm](
+ input,
+ &box->encrypt_params,
+ output,
+ err_details);
+}
+
+static AesNI_StatusCode aesni_box_encrypt_cbc(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = AESNI_SUCCESS;
+
+ AesNI_State xored_input = *input;
+ status = aesni_box_xor_state[box->algorithm](
+ &xored_input,
+ &box->iv,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ status = aesni_box_encrypt_algorithm[box->algorithm](
+ &xored_input,
+ &box->encrypt_params,
+ output,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ box->iv = *output;
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_cfb(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = aesni_box_encrypt_algorithm[box->algorithm](
+ &box->iv,
+ &box->encrypt_params,
+ output,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ status = aesni_box_xor_state[box->algorithm](output, input, err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ box->iv = *output;
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_ofb(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = aesni_box_encrypt_algorithm[box->algorithm](
+ &box->iv,
+ &box->encrypt_params,
+ &box->iv,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ *output = box->iv;
+
+ status = aesni_box_xor_state[box->algorithm](output, input, err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_encrypt_ctr(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ return aesni_error_not_implemented(err_details);
+}
+
+typedef AesNI_StatusCode (*AesNI_BoxEncryptMode)(
+ AesNI_Box*,
+ const AesNI_State*,
+ AesNI_State*,
+ AesNI_ErrorDetails*);
+
+static AesNI_BoxEncryptMode aesni_box_encrypt_mode[] =
+{
+ &aesni_box_encrypt_ecb,
+ &aesni_box_encrypt_cbc,
+ &aesni_box_encrypt_cfb,
+ &aesni_box_encrypt_ofb,
+ &aesni_box_encrypt_ctr,
+};
+
+AesNI_StatusCode aesni_box_encrypt(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ return aesni_box_encrypt_mode[box->mode](box, input, output, err_details);
+}
+
+static AesNI_StatusCode aesni_box_decrypt_ecb(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ return aesni_box_decrypt_algorithm[box->algorithm](
+ input,
+ &box->decrypt_params,
+ output,
+ err_details);
+}
+
+static AesNI_StatusCode aesni_box_decrypt_cbc(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = aesni_box_decrypt_algorithm[box->algorithm](
+ input,
+ &box->decrypt_params,
+ output,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ status = aesni_box_xor_state[box->algorithm](
+ output,
+ &box->iv,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ box->iv = *input;
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_decrypt_cfb(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = aesni_box_encrypt_algorithm[box->algorithm](
+ &box->iv,
+ &box->encrypt_params,
+ output,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ status = aesni_box_xor_state[box->algorithm](
+ output,
+ input,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ box->iv = *input;
+
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_decrypt_ofb(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ AesNI_StatusCode status = aesni_box_encrypt_algorithm[box->algorithm](
+ &box->iv,
+ &box->encrypt_params,
+ output,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ box->iv = *output;
+
+ status = aesni_box_xor_state[box->algorithm](
+ output,
+ input,
+ err_details);
+ if (aesni_is_error(status))
+ return status;
+
+ return status;
+}
+
+static AesNI_StatusCode aesni_box_decrypt_ctr(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ return aesni_error_not_implemented(err_details);
+}
+
+typedef AesNI_BoxEncryptMode AesNI_BoxDecryptMode;
+
+static AesNI_BoxDecryptMode aesni_box_decrypt_mode[] =
+{
+ &aesni_box_decrypt_ecb,
+ &aesni_box_decrypt_cbc,
+ &aesni_box_decrypt_cfb,
+ &aesni_box_decrypt_ofb,
+ &aesni_box_decrypt_ctr,
+};
+
+AesNI_StatusCode aesni_box_decrypt(
+ AesNI_Box* box,
+ const AesNI_State* input,
+ AesNI_State* output,
+ AesNI_ErrorDetails* err_details)
+{
+ return aesni_box_decrypt_mode[box->mode](box, input, output, err_details);
+}