Go to the documentation of this file.00001 #include "ibrcommon/ssl/AES128Stream.h"
00002 #include "ibrcommon/Logger.h"
00003 #include <openssl/rand.h>
00004 #include <cstring>
00005 #include <netinet/in.h>
00006
00007 namespace ibrcommon
00008 {
00009 AES128Stream::AES128Stream(const CipherMode mode, std::ostream& output, const unsigned char key[key_size_in_bytes], const u_int32_t salt)
00010 : CipherStream(output, mode)
00011 {
00012
00013 if (gcm_init_and_key(key, key_size_in_bytes, &_ctx))
00014 IBRCOMMON_LOGGER(critical) << "failed to initialize aes gcm context" << IBRCOMMON_LOGGER_ENDL;
00015
00016
00017 _gcm_iv.salt = htonl(salt);
00018
00019
00020 if (!RAND_bytes(_gcm_iv.initialisation_vector, iv_len))
00021 IBRCOMMON_LOGGER(critical) << "failed to create initialization vector" << IBRCOMMON_LOGGER_ENDL;
00022
00023
00024 for (unsigned int i = 0; i < iv_len; i++)
00025 _used_initialisation_vector[i] = _gcm_iv.initialisation_vector[i];
00026
00027
00028 gcm_init_message(reinterpret_cast<unsigned char *>(&_gcm_iv), sizeof(gcm_iv), &_ctx);
00029 }
00030
00031 AES128Stream::AES128Stream(const CipherMode mode, std::ostream& output, const unsigned char key[key_size_in_bytes], const u_int32_t salt, const unsigned char iv[iv_len])
00032 : CipherStream(output, mode)
00033 {
00034
00035 if (gcm_init_and_key(key, key_size_in_bytes, &_ctx))
00036 IBRCOMMON_LOGGER(critical) << "failed to initialize aes gcm context" << IBRCOMMON_LOGGER_ENDL;
00037
00038
00039 _gcm_iv.salt = htonl(salt);
00040
00041
00042 for (unsigned int i = 0; i < iv_len; i++)
00043 {
00044 _gcm_iv.initialisation_vector[i] = iv[i];
00045 _used_initialisation_vector[i] = iv[i];
00046 }
00047
00048
00049 gcm_init_message(reinterpret_cast<unsigned char *>(&_gcm_iv), sizeof(gcm_iv), &_ctx);
00050 }
00051
00052 AES128Stream::~AES128Stream()
00053 {
00054
00055 gcm_end(&_ctx);
00056 }
00057
00058 void AES128Stream::getIV(unsigned char (&to_iv)[iv_len]) const
00059 {
00060 for (unsigned int i = 0; i < iv_len; i++)
00061 to_iv[i] = _used_initialisation_vector[i];
00062 }
00063
00064 void AES128Stream::getTag(unsigned char (&to_tag)[tag_len])
00065 {
00066 ret_type rr = gcm_compute_tag((unsigned char*)to_tag, tag_len, &_ctx);
00067
00068 if (rr != RETURN_OK)
00069 throw ibrcommon::Exception("tag generation failed");
00070 }
00071
00072 bool AES128Stream::verify(const unsigned char (&verify_tag)[tag_len])
00073 {
00074 try {
00075
00076 unsigned char tag[tag_len]; getTag(tag);
00077
00078
00079 return (::memcmp(tag, verify_tag, tag_len) == 0);
00080 } catch (const ibrcommon::Exception&) {
00081 return false;
00082 }
00083 }
00084
00085 void AES128Stream::encrypt(char *buf, const size_t size)
00086 {
00087 gcm_encrypt(reinterpret_cast<unsigned char *>(buf), size, &_ctx);
00088 }
00089
00090 void AES128Stream::decrypt(char *buf, const size_t size)
00091 {
00092 gcm_decrypt(reinterpret_cast<unsigned char *>(buf), size, &_ctx);
00093 }
00094 }