diff options
Diffstat (limited to 'src/box.c')
-rw-r--r-- | src/box.c | 683 |
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); -} |