MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / encrypt

Function encrypt

src/Compression/CompressionCodecEncrypted.cpp:126–177  ·  view source on GitHub ↗

Encrypt plaintext with particular algorithm and put result into ciphertext_and_tag. This function get key and nonce and encrypt text with their help. If something went wrong (can't init context or can't encrypt data) it throws exception. It returns length of encrypted text.

Source from the content-addressed store, hash-verified

124/// If something went wrong (can't init context or can't encrypt data) it throws exception.
125/// It returns length of encrypted text.
126size_t encrypt(std::string_view plaintext, char * ciphertext_and_tag, EncryptionMethod method, const String & key, const String & nonce)
127{
128 int out_len = 0;
129 int ciphertext_len = 0;
130
131 using EVP_CIPHER_CTX_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)>;
132 const auto ctx = EVP_CIPHER_CTX_ptr(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
133 if (!ctx)
134 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_CIPHER_CTX_new failed: {}", getOpenSSLErrors());
135
136 using EVP_CIPHER_ptr = std::unique_ptr<EVP_CIPHER, decltype(&EVP_CIPHER_free)>;
137 const auto cipher = EVP_CIPHER_ptr(EVP_CIPHER_fetch(nullptr, getMethod(method), nullptr), EVP_CIPHER_free);
138 if (!cipher)
139 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_CIPHER_fetch failed: {}", getOpenSSLErrors());
140
141 if (EVP_EncryptInit_ex(ctx.get(), cipher.get(), nullptr, nullptr, nullptr) != 1)
142 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_EncryptInit_ex failed: {}", getOpenSSLErrors());
143
144 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, static_cast<int32_t>(nonce.size()), nullptr) != 1)
145 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_CIPHER_CTX_ctrl failed: {}", getOpenSSLErrors());
146
147 if (EVP_EncryptInit_ex(ctx.get(), nullptr, nullptr,
148 reinterpret_cast<const uint8_t*>(key.data()),
149 reinterpret_cast<const uint8_t *>(nonce.data())) != 1)
150 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_EncryptInit_ex failed: {}", getOpenSSLErrors());
151
152 if (EVP_EncryptUpdate(ctx.get(),
153 reinterpret_cast<uint8_t *>(ciphertext_and_tag),
154 &out_len,
155 reinterpret_cast<const uint8_t *>(plaintext.data()),
156 static_cast<int32_t>(plaintext.size())) != 1)
157 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_EncryptUpdate failed: {}", getOpenSSLErrors());
158
159 __msan_unpoison(ciphertext_and_tag, out_len); /// OpenSSL uses assembly which evades msan's analysis
160
161 ciphertext_len = out_len;
162
163 if (EVP_EncryptFinal_ex(ctx.get(),
164 reinterpret_cast<uint8_t *>(ciphertext_and_tag) + out_len,
165 reinterpret_cast<int32_t *>(&out_len)) != 1)
166 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_EncryptFinal_ex failed: {}", getOpenSSLErrors());
167
168 __msan_unpoison(ciphertext_and_tag, out_len); /// OpenSSL uses assembly which evades msan's analysis
169
170 ciphertext_len += out_len;
171
172 /// Get the tag
173 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, tag_size, reinterpret_cast<uint8_t *>(ciphertext_and_tag) + plaintext.size()) != 1)
174 throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_CIPHER_CTX_ctrl failed: {}", getOpenSSLErrors());
175
176 return ciphertext_len + tag_size;
177}
178
179/// Encrypt plaintext with particular algorithm and put result into ciphertext_and_tag.
180/// This function get key and nonce and encrypt text with their help.

Callers 1

doCompressDataMethod · 0.85

Calls 6

getOpenSSLErrorsFunction · 0.85
ExceptionClass · 0.70
getMethodFunction · 0.70
getMethod · 0.45
sizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected