27#include <openssl/err.h>
28#include <openssl/evp.h>
52#define ALWAYS_LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
53#ifdef DEBUG_CRYPTICAL_ENVELOPMENT
55 #define LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
62#define GET_SSL_ERROR() \
63 ERR_error_string(ERR_get_error(), NULL_POINTER)
65#ifdef DEBUG_CRYPTICAL_ENVELOPMENT
67 #define ERROR_BAILOUT(a, b, c) deadly_error(a, b, c)
69 #define ERROR_BAILOUT(a, b, c) continuable_error(a, b, c)
73#define DISCUSS_KEY_SIZE(key_size) \
74 if (key_size < minimum_key_size_in_bits()) { \
75 ERROR_BAILOUT(class_name(), func, \
76 a_sprintf("key size (%d bits) is less than minimum key size %d.", \
77 key_size, minimum_key_size_in_bits())); \
80 if (key_size > maximum_key_size_in_bits()) { \
81 ERROR_BAILOUT(class_name(), func, \
82 a_sprintf("key size (%d bits) is greater than maximum key size %d.", \
83 key_size, maximum_key_size_in_bits())); \
89#define DISCUSS_PROVIDED_KEY(key_size, key) \
90 if (key.length() * BITS_PER_BYTE < key_size) { \
91 ERROR_BAILOUT(class_name(), func, \
92 a_sprintf("key array length (%d) is less than required by key size " \
93 "(%d bits).", key.length(), key_size)); \
100 _cipher_type(cipher_type)
108 _key_size(to_copy._key_size),
113 LOG(
"after ssl static init");
119 LOG(
"prior to key whack");
121 LOG(
"after key whack");
128 LOG(
"prior to generate key");
131 LOG(
"after generate key");
141 if (
this == &to_copy)
return *
this;
142 _key_size = to_copy._key_size;
143 *_key = *to_copy._key;
144 _cipher_type = to_copy._cipher_type;
150 FUNCDEF(
"set_key(byte_array,int)");
159#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
160#define BYTE_TO_BINARY(byte) \
161 ((byte) & 0x80 ? '1' : '0'), \
162 ((byte) & 0x40 ? '1' : '0'), \
163 ((byte) & 0x20 ? '1' : '0'), \
164 ((byte) & 0x10 ? '1' : '0'), \
165 ((byte) & 0x08 ? '1' : '0'), \
166 ((byte) & 0x04 ? '1' : '0'), \
167 ((byte) & 0x02 ? '1' : '0'), \
168 ((byte) & 0x01 ? '1' : '0')
177 new_key.
reset(bytes);
178 for (
int i = 0; i < bytes; i++)
183#ifdef WIPE_UNUSED_BITS
193 mask <<= bits_to_wipe;
195 new_key[bytes - 1] &= mask;
215 static byte_array to_return(EVP_MAX_IV_LENGTH);
216 static bool initted =
false;
218 LOG(
">> actually creating init_vector >>");
220 for (
int i = 0; i < to_return.
length(); i++)
221 to_return[i] =
abyte(214 - i);
223 LOG(
"<< finished init_vector creation <<");
235 bool to_return =
true;
240 EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new();
241 EVP_CIPHER_CTX_init(session);
253 LOG(
a_sprintf(
" calling set key len with key size of %d", _key_size));
256 EVP_CIPHER_CTX_set_key_length(session, _key_size);
257 EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN,
init_vector().length(), NULL);
270 int enc_ret = EVP_EncryptUpdate(session, encoded.
access(), &encoded_len,
278 LOG(
a_sprintf(
" chopping extra bytes %d to %d.", encoded_len, encoded.
last()));
279 encoded.
zap(encoded_len, encoded.
last());
288 enc_ret = EVP_EncryptFinal_ex(session, encoded.
access(), &pad_len);
291 "failed, result=%d with error=%s.", enc_ret,
GET_SSL_ERROR()));
294 LOG(
a_sprintf(
" encryption padding added %d bytes.", pad_len));
295 encoded.
zap(pad_len, encoded.
last());
300 EVP_CIPHER_CTX_cleanup(session);
301 EVP_CIPHER_CTX_free(session);
313 bool to_return =
true;
314 EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new();
315 EVP_CIPHER_CTX_init(session);
316 LOG(
a_sprintf(
" using key size with %d bits.", _key_size));
324 EVP_CIPHER_CTX_set_key_length(session, _key_size);
325 EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN,
init_vector().length(), NULL);
336 int dec_ret = EVP_DecryptUpdate(session, decoded.
access(), &decoded_len,
342 LOG(
a_sprintf(
" first part decrypted size in bytes is %d.", decoded_len));
343 decoded.
zap(decoded_len, decoded.
last());
351 dec_ret = EVP_DecryptFinal_ex(session, decoded.
access(), &pad_len);
354 "failed, result=%d, padlen=%d, target had %d bytes, error=%s.", dec_ret,
358 LOG(
a_sprintf(
" decryption final had %d bytes padding.", pad_len));
359 decoded.
zap(pad_len, decoded.
last());
364 EVP_CIPHER_CTX_cleanup(session);
365 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.