1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License
17 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19 * @brief Crypto module implementation.
25 #include <openssl/evp.h>
27 #include <dpl/log/log.h>
28 #include <dpl/raw-buffer.h>
30 #include <generic-backend/exception.h>
40 : m_ctx(EVP_CIPHER_CTX_new())
42 static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside conatainer.");
44 Base(const Base&) = delete;
45 Base(Base &&) = delete;
46 Base<T>& operator=(const Base&) = delete;
47 Base<T>& operator=(Base &&) = delete;
50 // Allows various cipher specific parameters to be determined and set.
51 int Control(int type, int arg, void *ptr) {
52 return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr);
55 virtual T Append(const T&) = 0;
56 virtual T Finalize() = 0;
58 EVP_CIPHER_CTX_free(m_ctx);
61 EVP_CIPHER_CTX *m_ctx;
65 class EvpCipherWrapper : public Base<T> {
69 EvpCipherWrapper(const EVP_CIPHER *type, const T &key, const T &iv, bool encryption)
71 if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type)) {
72 ThrowErr(Exc::Crypto::InternalError, "Wrong key size! Expected: ", EVP_CIPHER_key_length(type) ," Get: ", key.size());
75 if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type)) {
76 ThrowErr(Exc::Crypto::InternalError, "Wrong iv size! Expected: ", EVP_CIPHER_iv_length(type) , " Get: ", iv.size());
79 if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), encryption ? 1 : 0)) {
80 ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherInit");
83 EVP_CIPHER_CTX_set_padding(m_ctx, 1);
86 T Append(const T& data) {
87 static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container.");
88 int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx));
90 if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), data.size())) {
91 ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherUpdate");
93 output.resize(bytesLen);
98 int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx);
100 if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)) {
101 ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherFinal");
103 output.resize(bytesLen);
108 #define DEFINE_CIPHER(__classname, __type, __evpcipher, __encryption) \
109 class __classname : public EvpCipherWrapper<__type> { \
111 __classname(const __type &key, const __type &iv) \
112 : EvpCipherWrapper(__evpcipher, key, iv, __encryption) \
116 DEFINE_CIPHER(AesCbcEncryption128, RawBuffer, EVP_aes_128_cbc(), true);
117 DEFINE_CIPHER(AesCbcDecryption128, RawBuffer, EVP_aes_128_cbc(), false);
118 DEFINE_CIPHER(AesCbcEncryption192, RawBuffer, EVP_aes_192_cbc(), true);
119 DEFINE_CIPHER(AesCbcDecryption192, RawBuffer, EVP_aes_192_cbc(), false);
120 DEFINE_CIPHER(AesCbcEncryption256, RawBuffer, EVP_aes_256_cbc(), true);
121 DEFINE_CIPHER(AesCbcDecryption256, RawBuffer, EVP_aes_256_cbc(), false);
123 DEFINE_CIPHER(AesGcmEncryption128, RawBuffer, EVP_aes_128_gcm(), true);
124 DEFINE_CIPHER(AesGcmDecryption128, RawBuffer, EVP_aes_128_gcm(), false);
125 DEFINE_CIPHER(AesGcmEncryption192, RawBuffer, EVP_aes_192_gcm(), true);
126 DEFINE_CIPHER(AesGcmDecryption192, RawBuffer, EVP_aes_192_gcm(), false);
127 DEFINE_CIPHER(AesGcmEncryption256, RawBuffer, EVP_aes_256_gcm(), true);
128 DEFINE_CIPHER(AesGcmDecryption256, RawBuffer, EVP_aes_256_gcm(), false);
130 DEFINE_CIPHER(AesCtrEncryption128, RawBuffer, EVP_aes_128_ctr(), true);
131 DEFINE_CIPHER(AesCtrDecryption128, RawBuffer, EVP_aes_128_ctr(), false);
132 DEFINE_CIPHER(AesCtrEncryption192, RawBuffer, EVP_aes_192_ctr(), true);
133 DEFINE_CIPHER(AesCtrDecryption192, RawBuffer, EVP_aes_192_ctr(), false);
134 DEFINE_CIPHER(AesCtrEncryption256, RawBuffer, EVP_aes_256_ctr(), true);
135 DEFINE_CIPHER(AesCtrDecryption256, RawBuffer, EVP_aes_256_ctr(), false);
137 DEFINE_CIPHER(AesCfbEncryption128, RawBuffer, EVP_aes_128_cfb(), true);
138 DEFINE_CIPHER(AesCfbDecryption128, RawBuffer, EVP_aes_128_cfb(), false);
139 DEFINE_CIPHER(AesCfbEncryption192, RawBuffer, EVP_aes_192_cfb(), true);
140 DEFINE_CIPHER(AesCfbDecryption192, RawBuffer, EVP_aes_192_cfb(), false);
141 DEFINE_CIPHER(AesCfbEncryption256, RawBuffer, EVP_aes_256_cfb(), true);
142 DEFINE_CIPHER(AesCfbDecryption256, RawBuffer, EVP_aes_256_cfb(), false);
146 } // namespace Cipher
148 } // namespace Crypto