26#include <openssl/err.h>
27#include <openssl/evp.h>
45#define ALWAYS_LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
46#ifdef DEBUG_CRYPTICAL_ENVELOPMENT
48 #define LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
55#define GET_SSL_ERROR() \
56 ERR_error_string(ERR_get_error(), NULL_POINTER)
58#ifdef DEBUG_CRYPTICAL_ENVELOPMENT
60 #define ERROR_BAILOUT(a, b, c) deadly_error(a, b, c)
62 #define ERROR_BAILOUT(a, b, c) continuable_error(a, b, c)
66#define DISCUSS_KEY_SIZE(key_size) \
67 if (key_size < minimum_key_size_in_bits()) { \
68 ERROR_BAILOUT(class_name(), func, \
69 a_sprintf("key size (%d bits) is less than minimum key size %d.", \
70 key_size, minimum_key_size_in_bits())); \
73 if (key_size > maximum_key_size_in_bits()) { \
74 ERROR_BAILOUT(class_name(), func, \
75 a_sprintf("key size (%d bits) is greater than maximum key size %d.", \
76 key_size, maximum_key_size_in_bits())); \
82#define DISCUSS_PROVIDED_KEY(key_size, key) \
83 if (key.length() * BITS_PER_BYTE < key_size) { \
84 ERROR_BAILOUT(class_name(), func, \
85 a_sprintf("key array length (%d) is less than required by key size " \
86 "(%d bits).", key.length(), key_size)); \
93 _cipher_type(cipher_type)
101 _key_size(to_copy._key_size),
106 LOG(
"after ssl static init");
112 LOG(
"prior to key whack");
114 LOG(
"after key whack");
121 LOG(
"prior to generate key");
124 LOG(
"after generate key");
134 if (
this == &to_copy)
return *
this;
135 _key_size = to_copy._key_size;
136 *_key = *to_copy._key;
137 _cipher_type = to_copy._cipher_type;
143 FUNCDEF(
"set_key(byte_array,int)");
152#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
153#define BYTE_TO_BINARY(byte) \
154 ((byte) & 0x80 ? '1' : '0'), \
155 ((byte) & 0x40 ? '1' : '0'), \
156 ((byte) & 0x20 ? '1' : '0'), \
157 ((byte) & 0x10 ? '1' : '0'), \
158 ((byte) & 0x08 ? '1' : '0'), \
159 ((byte) & 0x04 ? '1' : '0'), \
160 ((byte) & 0x02 ? '1' : '0'), \
161 ((byte) & 0x01 ? '1' : '0')
170 new_key.
reset(bytes);
171 for (
int i = 0; i < bytes; i++)
181#ifdef WIPE_UNUSED_BITS
191 mask <<= bits_to_wipe;
193 new_key[bytes - 1] &= mask;
213 static byte_array to_return(EVP_MAX_IV_LENGTH);
214 static bool initted =
false;
216 LOG(
">> actually creating init_vector >>");
218 for (
int i = 0; i < to_return.
length(); i++)
219 to_return[i] =
abyte(214 - i);
221 LOG(
"<< finished init_vector creation <<");
233 bool to_return =
true;
238 EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new();
239 EVP_CIPHER_CTX_init(session);
251 LOG(
a_sprintf(
" calling set key len with key size of %d", _key_size));
254 EVP_CIPHER_CTX_set_key_length(session, _key_size);
255 EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN,
init_vector().length(), NULL);
268 int enc_ret = EVP_EncryptUpdate(session, encoded.
access(), &encoded_len,
276 LOG(
a_sprintf(
" chopping extra bytes %d to %d.", encoded_len, encoded.
last()));
277 encoded.
zap(encoded_len, encoded.
last());
286 enc_ret = EVP_EncryptFinal_ex(session, encoded.
access(), &pad_len);
289 "failed, result=%d with error=%s.", enc_ret,
GET_SSL_ERROR()));
292 LOG(
a_sprintf(
" encryption padding added %d bytes.", pad_len));
293 encoded.
zap(pad_len, encoded.
last());
298 EVP_CIPHER_CTX_cleanup(session);
299 EVP_CIPHER_CTX_free(session);
311 bool to_return =
true;
312 EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new();
313 EVP_CIPHER_CTX_init(session);
314 LOG(
a_sprintf(
" using key size with %d bits.", _key_size));
322 EVP_CIPHER_CTX_set_key_length(session, _key_size);
323 EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN,
init_vector().length(), NULL);
334 int dec_ret = EVP_DecryptUpdate(session, decoded.
access(), &decoded_len,
340 LOG(
a_sprintf(
" first part decrypted size in bytes is %d.", decoded_len));
341 decoded.
zap(decoded_len, decoded.
last());
349 dec_ret = EVP_DecryptFinal_ex(session, decoded.
access(), &pad_len);
352 "failed, result=%d, padlen=%d, target had %d bytes, error=%s.", dec_ret,
356 LOG(
a_sprintf(
" decryption final had %d bytes padding.", pad_len));
357 decoded.
zap(pad_len, decoded.
last());
362 EVP_CIPHER_CTX_cleanup(session);
363 EVP_CIPHER_CTX_free(session);
a_sprintf is a specialization of astring that provides printf style support.
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
const contents * observe() const
Returns a pointer to the underlying C array of data.
int length() const
Returns the current reported length of the allocated C array.
outcome zap(int start, int end)
Deletes from "this" the objects inclusively between "start" and "end".
int last() const
Returns the last valid element in the array.
auto_synchronizer simplifies concurrent code by automatically unlocking.
A very common template for a dynamic array of bytes.
virtual const char * class_name() const =0
Returns the bare name of this class as a constant character pointer.
bool set_key(int key_size)
this will create a new random key of the "key_size", in bits.
bool encrypt(const basis::byte_array &source, basis::byte_array &target) const
encrypts the "source" array into the "target" array.
bool decrypt(const basis::byte_array &source, basis::byte_array &target) const
decrypts the "target" array from the encrypted "source" array.
virtual ~cryptical_envelopment()
bool generate_key(int size, basis::byte_array &new_key)
creates a "new_key" of the "size" (in bits) specified.
cryptical_envelopment(const EVP_CIPHER *cipher_type)
constructor requires the type of encryption to use.
cryptical_envelopment & operator=(const cryptical_envelopment &to_copy)
static const basis::byte_array & init_vector()
returns the initialization vector that is used by this class.
const basis::byte_array & get_key() const
returns our current key.
const mathematics::chaos & randomizer() const
provides a random number generator for any encryption routines.
int inclusive(int low, int high) const
< Returns a pseudo-random number r, such that "low" <= r <= "high".
#define DISCUSS_KEY_SIZE(key_size)
#define ERROR_BAILOUT(a, b, c)
#define DISCUSS_PROVIDED_KEY(key_size, key)
#define BYTE_TO_BINARY(byte)
#define BYTE_TO_BINARY_PATTERN
struct evp_cipher_st EVP_CIPHER
#define BITS_PER_BYTE
A fundamental constant measuring the number of bits in a byte.
#define NULL_POINTER
The value representing a pointer to nothing.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
unsigned char abyte
A fairly important unit which is seldom defined...
const ssl_init & static_ssl_initializer()
the main method for accessing the SSL initialization support.
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
A dynamic container class that holds any kind of object via pointers.
#define SAFE_STATIC(type, func_name, parms)
Statically defines a singleton object whose scope is the program's lifetime.