From 3acfe018b122a9e07388166d08a9cc531d8dbafa Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 25 Aug 2013 01:24:07 -0400 Subject: [PATCH] various updates --- include/fc/crypto/aes.hpp | 26 +++++++++++-- include/fc/crypto/openssl.hpp | 3 +- src/crypto/aes.cpp | 71 ++++++++++++++++++++++++++++++++--- src/crypto/hex.cpp | 5 ++- 4 files changed, 93 insertions(+), 12 deletions(-) diff --git a/include/fc/crypto/aes.hpp b/include/fc/crypto/aes.hpp index f6d6778..befeec8 100644 --- a/include/fc/crypto/aes.hpp +++ b/include/fc/crypto/aes.hpp @@ -1,12 +1,30 @@ #pragma once #include +#include +#include +#include #include namespace fc { -int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, - unsigned char *iv, unsigned char *ciphertext); -std::vector aes_encrypt( const fc::sha512& key, const std::vector& plain_text ); -std::vector aes_decrypt( const fc::sha512& key, const std::vector& cipher_text ); + class aes_encoder + { + public: + aes_encoder( const fc::sha256& key, const fc::uint128& init_value ); + ~aes_encoder(); + + uint32_t encode( const char* plaintxt, uint32_t len, const char* ciphertxt ); + uint32_t final_encode( const char* ciphertxt ); + + private: + struct impl; + fc::fwd my; + }; + + int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, + unsigned char *iv, unsigned char *ciphertext); + + std::vector aes_encrypt( const fc::sha512& key, const std::vector& plain_text ); + std::vector aes_decrypt( const fc::sha512& key, const std::vector& cipher_text ); } diff --git a/include/fc/crypto/openssl.hpp b/include/fc/crypto/openssl.hpp index bb42788..f21ee3c 100644 --- a/include/fc/crypto/openssl.hpp +++ b/include/fc/crypto/openssl.hpp @@ -33,10 +33,11 @@ namespace fc #define SSL_TYPE(name, ssl_type, free_func) \ struct name : public ssl_wrapper \ { \ - name(ssl_type* obj) \ + name(ssl_type* obj=nullptr) \ : ssl_wrapper(obj) {} \ ~name() \ { \ + if( obj != nullptr ) \ free_func(obj); \ } \ }; diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp index a771035..5f1b2e6 100644 --- a/src/crypto/aes.cpp +++ b/src/crypto/aes.cpp @@ -1,11 +1,72 @@ -#include +#include #include #include +#include namespace fc { static int init = init_openssl(); +struct aes_encoder::impl +{ + evp_cipher_ctx ctx; +}; + +aes_encoder::aes_encoder( const fc::sha256& key, const fc::uint128& init_value ) +{ + my->ctx.obj = EVP_CIPHER_CTX_new(); + /* Create and initialise the context */ + if(!my->ctx) + { + FC_THROW_EXCEPTION( exception, "error allocating evp cipher context", + ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); + } + + /* Initialise the encryption operation. IMPORTANT - ensure you use a key + * and IV size appropriate for your cipher + * In this example we are using 256 bit AES (i.e. a 256 bit key). The + * IV size for *most* modes is the same as the block size. For AES this + * is 128 bits */ + if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value)) + { + FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption init", + ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); + } +} +aes_encoder::~aes_encoder() +{ +} + +uint32_t aes_encoder::encode( const char* plaintxt, uint32_t plaintext_len, const char* ciphertxt ) +{ + int ciphertext_len = 0; + /* Provide the message to be encrypted, and obtain the encrypted output. + * * EVP_EncryptUpdate can be called multiple times if necessary + * */ + if(1 != EVP_EncryptUpdate(my->ctx, (unsigned char*)ciphertxt, &ciphertext_len, (const unsigned char*)plaintxt, plaintext_len)) + { + FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption update", + ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); + } + return ciphertext_len; +} +uint32_t aes_encoder::final_encode( const char* ciphertxt ) +{ + int ciphertext_len = 0; + /* Finalise the encryption. Further ciphertext bytes may be written at + * * this stage. + * */ + if(1 != EVP_EncryptFinal_ex(my->ctx, (unsigned char*)ciphertxt, &ciphertext_len)) + { + FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption final", + ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); + } + return ciphertext_len; +} + + + + /** example method from wiki.opensslfoundation.com */ int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) @@ -23,10 +84,10 @@ int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, } /* Initialise the encryption operation. IMPORTANT - ensure you use a key - * * and IV size appropriate for your cipher - * * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * * IV size for *most* modes is the same as the block size. For AES this - * * is 128 bits */ + * and IV size appropriate for your cipher + * In this example we are using 256 bit AES (i.e. a 256 bit key). The + * IV size for *most* modes is the same as the block size. For AES this + * is 128 bits */ if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption init", diff --git a/src/crypto/hex.cpp b/src/crypto/hex.cpp index 375726a..41690fe 100644 --- a/src/crypto/hex.cpp +++ b/src/crypto/hex.cpp @@ -14,8 +14,9 @@ namespace fc { return 0; } - fc::string to_hex( const char* d, uint32_t s ) { - fc::string r; + std::string to_hex( const char* d, uint32_t s ) + { + std::string r; const char* to_hex="0123456789abcdef"; uint8_t* c = (uint8_t*)d; for( uint32_t i = 0; i < s; ++i )