aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/box.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/box.c')
-rw-r--r--src/box.c683
1 files changed, 0 insertions, 683 deletions
diff --git a/src/box.c b/src/box.c
deleted file mode 100644
index c7e1e90..0000000
--- a/src/box.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com>
- * This file is part of the "AES tools" project.
- * For details, see https://github.com/egor-tensin/aes-tools.
- * Distributed under the MIT License.
- */
-
-#include <aes/all.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-static const AES_BoxAlgorithmInterface* aes_box_algorithms[] =
-{
- &aes_box_algorithm_aes128,
- &aes_box_algorithm_aes192,
- &aes_box_algorithm_aes256,
-};
-
-AES_StatusCode aes_box_init(
- AES_Box* box,
- AES_Algorithm algorithm,
- const AES_BoxKey* box_key,
- AES_Mode mode,
- const AES_BoxBlock* iv,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- box->algorithm = aes_box_algorithms[algorithm];
-
- if (aes_is_error(status = box->algorithm->calc_round_keys(
- box_key,
- &box->encryption_keys,
- &box->decryption_keys,
- err_details)))
- return status;
-
- box->mode = mode;
- if (iv != NULL)
- box->iv = *iv;
-
- return status;
-}
-
-static AES_StatusCode aes_box_encrypt_block_ecb(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- return box->algorithm->encrypt_block(
- input, &box->encryption_keys, output, err_details);
-}
-
-static AES_StatusCode aes_box_encrypt_block_cbc(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
- AES_BoxBlock xored_input = *input;
-
- if (aes_is_error(status = box->algorithm->xor_block(
- &xored_input, &box->iv, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->encrypt_block(
- &xored_input, &box->encryption_keys, output, err_details)))
- return status;
-
- box->iv = *output;
- return status;
-}
-
-static AES_StatusCode aes_box_encrypt_block_cfb(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (aes_is_error(status = box->algorithm->encrypt_block(
- &box->iv, &box->encryption_keys, output, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->xor_block(
- output, input, err_details)))
- return status;
-
- box->iv = *output;
- return status;
-}
-
-static AES_StatusCode aes_box_encrypt_block_ofb(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (aes_is_error(status = box->algorithm->encrypt_block(
- &box->iv, &box->encryption_keys, &box->iv, err_details)))
- return status;
-
- *output = box->iv;
-
- if (aes_is_error(status = box->algorithm->xor_block(
- output, input, err_details)))
- return status;
-
- return status;
-}
-
-static AES_StatusCode aes_box_encrypt_block_ctr(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (aes_is_error(status = box->algorithm->encrypt_block(
- &box->iv, &box->encryption_keys, output, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->xor_block(
- output, input, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->inc_block(
- &box->iv, err_details)))
- return status;
-
- return status;
-}
-
-typedef AES_StatusCode (*AES_BoxEncryptBlockInMode)(
- AES_Box*,
- const AES_BoxBlock*,
- AES_BoxBlock*,
- AES_ErrorDetails*);
-
-static AES_BoxEncryptBlockInMode aes_box_encrypt_block_in_mode[] =
-{
- &aes_box_encrypt_block_ecb,
- &aes_box_encrypt_block_cbc,
- &aes_box_encrypt_block_cfb,
- &aes_box_encrypt_block_ofb,
- &aes_box_encrypt_block_ctr,
-};
-
-AES_StatusCode aes_box_encrypt_block(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- return aes_box_encrypt_block_in_mode[box->mode](
- box, input, output, err_details);
-}
-
-static AES_StatusCode aes_box_decrypt_block_ecb(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- return box->algorithm->decrypt_block(
- input, &box->decryption_keys, output, err_details);
-}
-
-static AES_StatusCode aes_box_decrypt_block_cbc(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (aes_is_error(status = box->algorithm->decrypt_block(
- input, &box->decryption_keys, output, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->xor_block(
- output, &box->iv, err_details)))
- return status;
-
- box->iv = *input;
- return status;
-}
-
-static AES_StatusCode aes_box_decrypt_block_cfb(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (aes_is_error(status = box->algorithm->encrypt_block(
- &box->iv, &box->encryption_keys, output, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->xor_block(
- output, input, err_details)))
- return status;
-
- box->iv = *input;
- return status;
-}
-
-typedef AES_BoxEncryptBlockInMode AES_BoxDecryptBlockInMode;
-
-static AES_BoxDecryptBlockInMode aes_box_decrypt_block_in_mode[] =
-{
- &aes_box_decrypt_block_ecb,
- &aes_box_decrypt_block_cbc,
- &aes_box_decrypt_block_cfb,
- &aes_box_encrypt_block_ofb,
- &aes_box_encrypt_block_ctr,
-};
-
-AES_StatusCode aes_box_decrypt_block(
- AES_Box* box,
- const AES_BoxBlock* input,
- AES_BoxBlock* output,
- AES_ErrorDetails* err_details)
-{
- return aes_box_decrypt_block_in_mode[box->mode](
- box, input, output, err_details);
-}
-
-static AES_StatusCode aes_box_get_encrypted_buffer_size(
- AES_Box* box,
- size_t src_size,
- size_t* dest_size,
- size_t* padding_size,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- switch (box->mode)
- {
- case AES_ECB:
- case AES_CBC:
- {
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- *padding_size = block_size - src_size % block_size;
- *dest_size = src_size + *padding_size;
- return status;
- }
-
- case AES_CFB:
- case AES_OFB:
- case AES_CTR:
- *dest_size = src_size;
- *padding_size = 0;
- return status;
-
- default:
- return aes_error_not_implemented(
- err_details, "unsupported mode of operation");
- }
-}
-
-static AES_StatusCode aes_box_encrypt_buffer_block(
- AES_Box* box,
- const void* src,
- void* dest,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- AES_BoxBlock plaintext;
-
- if (aes_is_error(status = box->algorithm->load_block(
- &plaintext, src, err_details)))
- return status;
-
- AES_BoxBlock ciphertext;
-
- if (aes_is_error(status = aes_box_encrypt_block(
- box, &plaintext, &ciphertext, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->store_block(
- dest, &ciphertext, err_details)))
- return status;
-
- return status;
-}
-
-static AES_StatusCode aes_box_encrypt_buffer_partial_block_with_padding(
- AES_Box* box,
- const void* src,
- size_t src_size,
- void* dest,
- size_t padding_size,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- void* plaintext_buf = malloc(block_size);
-
- if (plaintext_buf == NULL)
- return status = aes_error_memory_allocation(err_details);
-
- memcpy(plaintext_buf, src, src_size);
-
- if (aes_is_error(status = aes_fill_with_padding(
- AES_PADDING_PKCS7,
- (char*) plaintext_buf + src_size,
- padding_size,
- err_details)))
- goto FREE_PLAINTEXT_BUF;
-
- if (aes_is_error(status = aes_box_encrypt_buffer_block(
- box, plaintext_buf, dest, err_details)))
- goto FREE_PLAINTEXT_BUF;
-
-FREE_PLAINTEXT_BUF:
- free(plaintext_buf);
-
- return status;
-}
-
-static AES_StatusCode aes_box_encrypt_buffer_partial_block(
- AES_Box* box,
- const void* src,
- size_t src_size,
- void* dest,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (src_size == 0)
- return status;
-
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- void* plaintext_buf = malloc(block_size);
-
- if (plaintext_buf == NULL)
- return status = aes_error_memory_allocation(err_details);
-
- memset(plaintext_buf, 0x00, block_size);
- memcpy(plaintext_buf, src, src_size);
-
- void* ciphertext_buf = malloc(block_size);
-
- if (ciphertext_buf == NULL)
- {
- status = aes_error_memory_allocation(err_details);
- goto FREE_PLAINTEXT_BUF;
- }
-
- if (aes_is_error(status = aes_box_encrypt_buffer_block(
- box, plaintext_buf, ciphertext_buf, err_details)))
- goto FREE_CIPHERTEXT_BUF;
-
- memcpy(dest, ciphertext_buf, src_size);
-
-FREE_CIPHERTEXT_BUF:
- free(ciphertext_buf);
-
-FREE_PLAINTEXT_BUF:
- free(plaintext_buf);
-
- return status;
-}
-
-AES_StatusCode aes_box_encrypt_buffer(
- AES_Box* box,
- const void* src,
- size_t src_size,
- void* dest,
- size_t* dest_size,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (box == NULL)
- return aes_error_null_argument(err_details, "box");
- if (dest_size == NULL)
- return aes_error_null_argument(err_details, "dest_size");
-
- size_t padding_size = 0;
-
- if (aes_is_error(status = aes_box_get_encrypted_buffer_size(
- box, src_size, dest_size, &padding_size, err_details)))
- return status;
-
- if (dest == NULL)
- return AES_SUCCESS;
- if (src == NULL && src_size != 0)
- return aes_error_null_argument(err_details, "src");
-
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- const size_t src_len = src_size / block_size;
-
- for (size_t i = 0; i < src_len; ++i)
- {
- if (aes_is_error(status = aes_box_encrypt_buffer_block(
- box, src, dest, err_details)))
- return status;
-
- src = (char*) src + block_size;
- dest = (char*) dest + block_size;
- }
-
- if (padding_size == 0)
- return aes_box_encrypt_buffer_partial_block(
- box, src, src_size % block_size, dest, err_details);
- else
- return aes_box_encrypt_buffer_partial_block_with_padding(
- box, src, src_size % block_size, dest, padding_size, err_details);
-}
-
-static AES_StatusCode aes_box_get_decrypted_buffer_size(
- AES_Box* box,
- size_t src_size,
- size_t* dest_size,
- size_t* max_padding_size,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- switch (box->mode)
- {
- case AES_ECB:
- case AES_CBC:
- {
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- if (src_size == 0 || src_size % block_size != 0)
- return aes_error_missing_padding(err_details);
-
- *dest_size = src_size;
- *max_padding_size = block_size;
- return status;
- }
-
- case AES_CFB:
- case AES_OFB:
- case AES_CTR:
- *dest_size = src_size;
- *max_padding_size = 0;
- return status;
-
- default:
- return aes_error_not_implemented(
- err_details, "unsupported mode of operation");
- }
-}
-
-static AES_StatusCode aes_box_decrypt_buffer_block(
- AES_Box* box,
- const void* src,
- void* dest,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- AES_BoxBlock ciphertext;
-
- if (aes_is_error(status = box->algorithm->load_block(
- &ciphertext, src, err_details)))
- return status;
-
- AES_BoxBlock plaintext;
-
- if (aes_is_error(status = aes_box_decrypt_block(
- box, &ciphertext, &plaintext, err_details)))
- return status;
-
- if (aes_is_error(status = box->algorithm->store_block(
- dest, &plaintext, err_details)))
- return status;
-
- return status;
-}
-
-static AES_StatusCode aes_box_decrypt_buffer_partial_block(
- AES_Box* box,
- const void* src,
- size_t src_size,
- void* dest,
- AES_ErrorDetails* err_details)
-{
- AES_StatusCode status = AES_SUCCESS;
-
- if (src_size == 0)
- return status;
-
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- void* ciphertext_buf = malloc(block_size);
-
- if (ciphertext_buf == NULL)
- return status = aes_error_memory_allocation(err_details);
-
- memset(ciphertext_buf, 0x00, block_size);
- memcpy(ciphertext_buf, src, src_size);
-
- void* plaintext_buf = malloc(block_size);
-
- if (plaintext_buf == NULL)
- {
- status = aes_error_memory_allocation(err_details);
- goto FREE_CIPHERTEXT_BUF;
- }
-
- if (aes_is_error(status = aes_box_decrypt_buffer_block(
- box, ciphertext_buf, plaintext_buf, err_details)))
- goto FREE_PLAINTEXT_BUF;
-
- memcpy(dest, plaintext_buf, src_size);
-
-FREE_PLAINTEXT_BUF:
- free(plaintext_buf);
-
-FREE_CIPHERTEXT_BUF:
- free(ciphertext_buf);
-
- return status;
-}
-
-AES_StatusCode aes_box_decrypt_buffer(
- AES_Box* box,
- const void* src,
- size_t src_size,
- void* dest,
- size_t* dest_size,
- AES_ErrorDetails* err_details)
-{
- if (box == NULL)
- return aes_error_null_argument(err_details, "box");
- if (dest_size == NULL)
- return aes_error_null_argument(err_details, "dest_size");
-
- AES_StatusCode status = AES_SUCCESS;
- size_t max_padding_size = 0;
-
- if (aes_is_error(status = aes_box_get_decrypted_buffer_size(
- box, src_size, dest_size, &max_padding_size, err_details)))
- return status;
-
- if (dest == NULL)
- return AES_SUCCESS;
- if (src == NULL)
- return aes_error_null_argument(err_details, "src");
-
- size_t block_size;
-
- if (aes_is_error(status = box->algorithm->get_block_size(
- &block_size, err_details)))
- return status;
-
- const size_t src_len = src_size / block_size;
-
- for (size_t i = 0; i < src_len; ++i)
- {
- if (aes_is_error(status = aes_box_decrypt_buffer_block(
- box, src, dest, err_details)))
- return status;
-
- src = (char*) src + block_size;
- dest = (char*) dest + block_size;
- }
-
- if (max_padding_size == 0)
- {
- return aes_box_decrypt_buffer_partial_block(
- box, src, src_size % block_size, dest, err_details);
- }
- else
- {
- size_t padding_size;
-
- if (aes_is_error(status = aes_extract_padding_size(
- AES_PADDING_PKCS7,
- (char*) dest - block_size,
- block_size,
- &padding_size,
- err_details)))
- return status;
-
- *dest_size -= padding_size;
- return status;
- }
-}
-
-AES_StatusCode aes_box_parse_block(
- AES_BoxBlock* dest,
- AES_Algorithm algorithm,
- const char* src,
- AES_ErrorDetails* err_details)
-{
- if (dest == NULL)
- return aes_error_null_argument(err_details, "dest");
- if (src == NULL)
- return aes_error_null_argument(err_details, "src");
-
- return aes_box_algorithms[algorithm]->parse_block(
- dest, src, err_details);
-}
-
-AES_StatusCode aes_box_parse_key(
- AES_BoxKey* dest,
- AES_Algorithm algorithm,
- const char* src,
- AES_ErrorDetails* err_details)
-{
- if (dest == NULL)
- return aes_error_null_argument(err_details, "dest");
- if (src == NULL)
- return aes_error_null_argument(err_details, "src");
-
- return aes_box_algorithms[algorithm]->parse_key(
- dest, src, err_details);
-}
-
-AES_StatusCode aes_box_format_block(
- AES_BoxBlockString* dest,
- AES_Algorithm algorithm,
- const AES_BoxBlock* src,
- AES_ErrorDetails* err_details)
-{
- if (dest == NULL)
- return aes_error_null_argument(err_details, "dest");
- if (src == NULL)
- return aes_error_null_argument(err_details, "src");
-
- return aes_box_algorithms[algorithm]->format_block(
- dest, src, err_details);
-}
-
-AES_StatusCode aes_box_format_key(
- AES_BoxKeyString* dest,
- AES_Algorithm algorithm,
- const AES_BoxKey* src,
- AES_ErrorDetails* err_details)
-{
- if (dest == NULL)
- return aes_error_null_argument(err_details, "dest");
- if (src == NULL)
- return aes_error_null_argument(err_details, "src");
-
- return aes_box_algorithms[algorithm]->format_key(
- dest, src, err_details);
-}