Coverage Report

Created: 2024-11-21 20:24

/root/doris/be/src/util/encryption_util.cpp
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "util/encryption_util.h"
19
20
#include <openssl/err.h>
21
#include <openssl/evp.h>
22
#include <openssl/ossl_typ.h>
23
#include <sys/types.h>
24
25
#include <algorithm>
26
#include <cstring>
27
#include <string>
28
#include <unordered_map>
29
30
namespace doris {
31
32
static const int ENCRYPTION_MAX_KEY_LENGTH = 256;
33
34
620
const EVP_CIPHER* get_evp_type(const EncryptionMode mode) {
35
620
    switch (mode) {
36
96
    case EncryptionMode::AES_128_ECB:
37
96
        return EVP_aes_128_ecb();
38
4
    case EncryptionMode::AES_128_CBC:
39
4
        return EVP_aes_128_cbc();
40
0
    case EncryptionMode::AES_128_CFB:
41
0
        return EVP_aes_128_cfb();
42
0
    case EncryptionMode::AES_128_CFB1:
43
0
        return EVP_aes_128_cfb1();
44
0
    case EncryptionMode::AES_128_CFB8:
45
0
        return EVP_aes_128_cfb8();
46
0
    case EncryptionMode::AES_128_CFB128:
47
0
        return EVP_aes_128_cfb128();
48
0
    case EncryptionMode::AES_128_CTR:
49
0
        return EVP_aes_128_ctr();
50
85
    case EncryptionMode::AES_128_OFB:
51
85
        return EVP_aes_128_ofb();
52
0
    case EncryptionMode::AES_192_ECB:
53
0
        return EVP_aes_192_ecb();
54
0
    case EncryptionMode::AES_192_CBC:
55
0
        return EVP_aes_192_cbc();
56
0
    case EncryptionMode::AES_192_CFB:
57
0
        return EVP_aes_192_cfb();
58
0
    case EncryptionMode::AES_192_CFB1:
59
0
        return EVP_aes_192_cfb1();
60
0
    case EncryptionMode::AES_192_CFB8:
61
0
        return EVP_aes_192_cfb8();
62
0
    case EncryptionMode::AES_192_CFB128:
63
0
        return EVP_aes_192_cfb128();
64
0
    case EncryptionMode::AES_192_CTR:
65
0
        return EVP_aes_192_ctr();
66
0
    case EncryptionMode::AES_192_OFB:
67
0
        return EVP_aes_192_ofb();
68
85
    case EncryptionMode::AES_256_ECB:
69
85
        return EVP_aes_256_ecb();
70
0
    case EncryptionMode::AES_256_CBC:
71
0
        return EVP_aes_256_cbc();
72
0
    case EncryptionMode::AES_256_CFB:
73
0
        return EVP_aes_256_cfb();
74
0
    case EncryptionMode::AES_256_CFB1:
75
0
        return EVP_aes_256_cfb1();
76
0
    case EncryptionMode::AES_256_CFB8:
77
0
        return EVP_aes_256_cfb8();
78
0
    case EncryptionMode::AES_256_CFB128:
79
0
        return EVP_aes_256_cfb128();
80
0
    case EncryptionMode::AES_256_CTR:
81
0
        return EVP_aes_256_ctr();
82
0
    case EncryptionMode::AES_256_OFB:
83
0
        return EVP_aes_256_ofb();
84
0
    case EncryptionMode::AES_128_GCM:
85
0
        return EVP_aes_128_gcm();
86
0
    case EncryptionMode::AES_192_GCM:
87
0
        return EVP_aes_192_gcm();
88
0
    case EncryptionMode::AES_256_GCM:
89
0
        return EVP_aes_256_gcm();
90
4
    case EncryptionMode::SM4_128_CBC:
91
4
        return EVP_sm4_cbc();
92
176
    case EncryptionMode::SM4_128_ECB:
93
176
        return EVP_sm4_ecb();
94
0
    case EncryptionMode::SM4_128_CFB128:
95
0
        return EVP_sm4_cfb128();
96
85
    case EncryptionMode::SM4_128_OFB:
97
85
        return EVP_sm4_ofb();
98
85
    case EncryptionMode::SM4_128_CTR:
99
85
        return EVP_sm4_ctr();
100
0
    default:
101
0
        return nullptr;
102
620
    }
103
620
}
104
105
static std::unordered_map<EncryptionMode, uint> mode_key_sizes = {
106
        {EncryptionMode::AES_128_ECB, 128},    {EncryptionMode::AES_192_ECB, 192},
107
        {EncryptionMode::AES_256_ECB, 256},    {EncryptionMode::AES_128_CBC, 128},
108
        {EncryptionMode::AES_192_CBC, 192},    {EncryptionMode::AES_256_CBC, 256},
109
        {EncryptionMode::AES_128_CFB, 128},    {EncryptionMode::AES_192_CFB, 192},
110
        {EncryptionMode::AES_256_CFB, 256},    {EncryptionMode::AES_128_CFB1, 128},
111
        {EncryptionMode::AES_192_CFB1, 192},   {EncryptionMode::AES_256_CFB1, 256},
112
        {EncryptionMode::AES_128_CFB8, 128},   {EncryptionMode::AES_192_CFB8, 192},
113
        {EncryptionMode::AES_256_CFB8, 256},   {EncryptionMode::AES_128_CFB128, 128},
114
        {EncryptionMode::AES_192_CFB128, 192}, {EncryptionMode::AES_256_CFB128, 256},
115
        {EncryptionMode::AES_128_CTR, 128},    {EncryptionMode::AES_192_CTR, 192},
116
        {EncryptionMode::AES_256_CTR, 256},    {EncryptionMode::AES_128_OFB, 128},
117
        {EncryptionMode::AES_192_OFB, 192},    {EncryptionMode::AES_256_OFB, 256},
118
        {EncryptionMode::AES_128_GCM, 128},    {EncryptionMode::AES_192_GCM, 192},
119
        {EncryptionMode::AES_256_GCM, 256},
120
121
        {EncryptionMode::SM4_128_ECB, 128},    {EncryptionMode::SM4_128_CBC, 128},
122
        {EncryptionMode::SM4_128_CFB128, 128}, {EncryptionMode::SM4_128_OFB, 128},
123
        {EncryptionMode::SM4_128_CTR, 128}};
124
125
static void create_key(const unsigned char* origin_key, uint32_t key_length, uint8_t* encrypt_key,
126
620
                       EncryptionMode mode) {
127
620
    const uint key_size = mode_key_sizes[mode] / 8;
128
620
    uint8_t* origin_key_end = ((uint8_t*)origin_key) + key_length; /* origin key boundary*/
129
130
620
    uint8_t* encrypt_key_end; /* encrypt key boundary */
131
620
    encrypt_key_end = encrypt_key + key_size;
132
133
620
    std::memset(encrypt_key, 0, key_size); /* initialize key  */
134
135
620
    uint8_t* ptr;        /* Start of the encrypt key*/
136
620
    uint8_t* origin_ptr; /* Start of the origin key */
137
5.58k
    for (ptr = encrypt_key, origin_ptr = (uint8_t*)origin_key; origin_ptr < origin_key_end;
138
4.96k
         ptr++, origin_ptr++) {
139
4.96k
        if (ptr == encrypt_key_end) {
140
            /* loop over origin key until we used all key */
141
0
            ptr = encrypt_key;
142
0
        }
143
4.96k
        *ptr ^= *origin_ptr;
144
4.96k
    }
145
620
}
146
147
static int do_encrypt(EVP_CIPHER_CTX* cipher_ctx, const EVP_CIPHER* cipher,
148
                      const unsigned char* source, uint32_t source_length,
149
                      const unsigned char* encrypt_key, const unsigned char* iv, bool padding,
150
324
                      unsigned char* encrypt, int* length_ptr) {
151
324
    int ret = EVP_EncryptInit(cipher_ctx, cipher, encrypt_key, iv);
152
324
    if (ret == 0) {
153
0
        return ret;
154
0
    }
155
324
    ret = EVP_CIPHER_CTX_set_padding(cipher_ctx, padding);
156
324
    if (ret == 0) {
157
0
        return ret;
158
0
    }
159
324
    int u_len = 0;
160
324
    ret = EVP_EncryptUpdate(cipher_ctx, encrypt, &u_len, source, source_length);
161
324
    if (ret == 0) {
162
0
        return ret;
163
0
    }
164
324
    int f_len = 0;
165
324
    ret = EVP_EncryptFinal(cipher_ctx, encrypt + u_len, &f_len);
166
324
    *length_ptr = u_len + f_len;
167
324
    return ret;
168
324
}
169
170
static int do_gcm_encrypt(EVP_CIPHER_CTX* cipher_ctx, const EVP_CIPHER* cipher,
171
                          const unsigned char* source, uint32_t source_length,
172
                          const unsigned char* encrypt_key, const unsigned char* iv, int iv_length,
173
                          unsigned char* encrypt, int* length_ptr, const unsigned char* aad,
174
0
                          uint32_t aad_length) {
175
0
    int ret = EVP_EncryptInit_ex(cipher_ctx, cipher, nullptr, nullptr, nullptr);
176
0
    if (ret != 1) {
177
0
        return ret;
178
0
    }
179
0
    ret = EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, iv_length, nullptr);
180
0
    if (ret != 1) {
181
0
        return ret;
182
0
    }
183
0
    ret = EVP_EncryptInit_ex(cipher_ctx, nullptr, nullptr, encrypt_key, iv);
184
0
    if (ret != 1) {
185
0
        return ret;
186
0
    }
187
0
    if (aad) {
188
0
        int tmp_len = 0;
189
0
        ret = EVP_EncryptUpdate(cipher_ctx, nullptr, &tmp_len, aad, aad_length);
190
0
        if (ret != 1) {
191
0
            return ret;
192
0
        }
193
0
    }
194
195
0
    std::memcpy(encrypt, iv, iv_length);
196
0
    encrypt += iv_length;
197
198
0
    int u_len = 0;
199
0
    ret = EVP_EncryptUpdate(cipher_ctx, encrypt, &u_len, source, source_length);
200
0
    if (ret != 1) {
201
0
        return ret;
202
0
    }
203
0
    encrypt += u_len;
204
205
0
    int f_len = 0;
206
0
    ret = EVP_EncryptFinal_ex(cipher_ctx, encrypt, &f_len);
207
0
    if (ret != 1) {
208
0
        return ret;
209
0
    }
210
0
    encrypt += f_len;
211
212
0
    ret = EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_GET_TAG, EncryptionUtil::GCM_TAG_SIZE,
213
0
                              encrypt);
214
0
    *length_ptr = iv_length + u_len + f_len + EncryptionUtil::GCM_TAG_SIZE;
215
0
    return ret;
216
0
}
217
218
int EncryptionUtil::encrypt(EncryptionMode mode, const unsigned char* source,
219
                            uint32_t source_length, const unsigned char* key, uint32_t key_length,
220
                            const char* iv_str, int iv_input_length, bool padding,
221
324
                            unsigned char* encrypt, const unsigned char* aad, uint32_t aad_length) {
222
324
    const EVP_CIPHER* cipher = get_evp_type(mode);
223
    /* The encrypt key to be used for encryption */
224
324
    unsigned char encrypt_key[ENCRYPTION_MAX_KEY_LENGTH / 8];
225
324
    create_key(key, key_length, encrypt_key, mode);
226
227
324
    int iv_length = EVP_CIPHER_iv_length(cipher);
228
324
    if (cipher == nullptr || (iv_length > 0 && !iv_str)) {
229
0
        return AES_BAD_DATA;
230
0
    }
231
324
    char* init_vec = nullptr;
232
324
    std::string iv_default("DORISDORISDORIS_");
233
234
324
    if (iv_str) {
235
270
        init_vec = &iv_default[0];
236
270
        memcpy(init_vec, iv_str, std::min(iv_input_length, EVP_MAX_IV_LENGTH));
237
270
        init_vec[iv_length] = '\0';
238
270
    }
239
324
    EVP_CIPHER_CTX* cipher_ctx = EVP_CIPHER_CTX_new();
240
324
    EVP_CIPHER_CTX_reset(cipher_ctx);
241
324
    int length = 0;
242
324
    int ret = 0;
243
324
    if (is_gcm_mode(mode)) {
244
0
        ret = do_gcm_encrypt(cipher_ctx, cipher, source, source_length, encrypt_key,
245
0
                             reinterpret_cast<unsigned char*>(init_vec), iv_length, encrypt,
246
0
                             &length, aad, aad_length);
247
324
    } else {
248
324
        ret = do_encrypt(cipher_ctx, cipher, source, source_length, encrypt_key,
249
324
                         reinterpret_cast<unsigned char*>(init_vec), padding, encrypt, &length);
250
324
    }
251
252
324
    EVP_CIPHER_CTX_free(cipher_ctx);
253
324
    if (ret == 0) {
254
0
        ERR_clear_error();
255
0
        return AES_BAD_DATA;
256
324
    } else {
257
324
        return length;
258
324
    }
259
324
}
260
261
static int do_decrypt(EVP_CIPHER_CTX* cipher_ctx, const EVP_CIPHER* cipher,
262
                      const unsigned char* encrypt, uint32_t encrypt_length,
263
                      const unsigned char* encrypt_key, const unsigned char* iv, bool padding,
264
296
                      unsigned char* decrypt_content, int* length_ptr) {
265
296
    int ret = EVP_DecryptInit(cipher_ctx, cipher, encrypt_key, iv);
266
296
    if (ret == 0) {
267
0
        return ret;
268
0
    }
269
296
    ret = EVP_CIPHER_CTX_set_padding(cipher_ctx, padding);
270
296
    if (ret == 0) {
271
0
        return ret;
272
0
    }
273
296
    int u_len = 0;
274
296
    ret = EVP_DecryptUpdate(cipher_ctx, decrypt_content, &u_len, encrypt, encrypt_length);
275
296
    if (ret == 0) {
276
0
        return ret;
277
0
    }
278
296
    int f_len = 0;
279
296
    ret = EVP_DecryptFinal_ex(cipher_ctx, decrypt_content + u_len, &f_len);
280
296
    *length_ptr = u_len + f_len;
281
296
    return ret;
282
296
}
283
284
static int do_gcm_decrypt(EVP_CIPHER_CTX* cipher_ctx, const EVP_CIPHER* cipher,
285
                          const unsigned char* encrypt, uint32_t encrypt_length,
286
                          const unsigned char* encrypt_key, int iv_length,
287
                          unsigned char* decrypt_content, int* length_ptr, const unsigned char* aad,
288
0
                          uint32_t aad_length) {
289
0
    if (encrypt_length < iv_length + EncryptionUtil::GCM_TAG_SIZE) {
290
0
        return -1;
291
0
    }
292
0
    int ret = EVP_DecryptInit_ex(cipher_ctx, cipher, nullptr, nullptr, nullptr);
293
0
    if (ret != 1) {
294
0
        return ret;
295
0
    }
296
0
    ret = EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, iv_length, nullptr);
297
0
    if (ret != 1) {
298
0
        return ret;
299
0
    }
300
0
    ret = EVP_DecryptInit_ex(cipher_ctx, nullptr, nullptr, encrypt_key, encrypt);
301
0
    if (ret != 1) {
302
0
        return ret;
303
0
    }
304
0
    encrypt += iv_length;
305
0
    if (aad) {
306
0
        int tmp_len = 0;
307
0
        ret = EVP_DecryptUpdate(cipher_ctx, nullptr, &tmp_len, aad, aad_length);
308
0
        if (ret != 1) {
309
0
            return ret;
310
0
        }
311
0
    }
312
313
0
    uint32_t real_encrypt_length = encrypt_length - iv_length - EncryptionUtil::GCM_TAG_SIZE;
314
0
    int u_len = 0;
315
0
    ret = EVP_DecryptUpdate(cipher_ctx, decrypt_content, &u_len, encrypt, real_encrypt_length);
316
0
    if (ret != 1) {
317
0
        return ret;
318
0
    }
319
0
    encrypt += real_encrypt_length;
320
0
    decrypt_content += u_len;
321
322
0
    void* tag = const_cast<void*>(reinterpret_cast<const void*>(encrypt));
323
0
    ret = EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_TAG, EncryptionUtil::GCM_TAG_SIZE, tag);
324
0
    if (ret != 1) {
325
0
        return ret;
326
0
    }
327
328
0
    int f_len = 0;
329
0
    ret = EVP_DecryptFinal_ex(cipher_ctx, decrypt_content, &f_len);
330
0
    *length_ptr = u_len + f_len;
331
0
    return ret;
332
0
}
333
334
int EncryptionUtil::decrypt(EncryptionMode mode, const unsigned char* encrypt,
335
                            uint32_t encrypt_length, const unsigned char* key, uint32_t key_length,
336
                            const char* iv_str, int iv_input_length, bool padding,
337
                            unsigned char* decrypt_content, const unsigned char* aad,
338
296
                            uint32_t aad_length) {
339
296
    const EVP_CIPHER* cipher = get_evp_type(mode);
340
341
    /* The encrypt key to be used for decryption */
342
296
    unsigned char encrypt_key[ENCRYPTION_MAX_KEY_LENGTH / 8];
343
296
    create_key(key, key_length, encrypt_key, mode);
344
345
296
    int iv_length = EVP_CIPHER_iv_length(cipher);
346
296
    if (cipher == nullptr || (iv_length > 0 && !iv_str)) {
347
0
        return AES_BAD_DATA;
348
0
    }
349
296
    char* init_vec = nullptr;
350
296
    std::string iv_default("DORISDORISDORIS_");
351
352
296
    if (iv_str) {
353
248
        init_vec = &iv_default[0];
354
248
        memcpy(init_vec, iv_str, std::min(iv_input_length, EVP_MAX_IV_LENGTH));
355
248
        init_vec[iv_length] = '\0';
356
248
    }
357
296
    EVP_CIPHER_CTX* cipher_ctx = EVP_CIPHER_CTX_new();
358
296
    EVP_CIPHER_CTX_reset(cipher_ctx);
359
296
    int length = 0;
360
296
    int ret = 0;
361
296
    if (is_gcm_mode(mode)) {
362
0
        ret = do_gcm_decrypt(cipher_ctx, cipher, encrypt, encrypt_length, encrypt_key, iv_length,
363
0
                             decrypt_content, &length, aad, aad_length);
364
296
    } else {
365
296
        ret = do_decrypt(cipher_ctx, cipher, encrypt, encrypt_length, encrypt_key,
366
296
                         reinterpret_cast<unsigned char*>(init_vec), padding, decrypt_content,
367
296
                         &length);
368
296
    }
369
296
    EVP_CIPHER_CTX_free(cipher_ctx);
370
296
    if (ret > 0) {
371
296
        return length;
372
296
    } else {
373
0
        ERR_clear_error();
374
0
        return AES_BAD_DATA;
375
0
    }
376
296
}
377
378
} // namespace doris