CUBRID Engine  latest
crypt_opfunc.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * Crypt_opfunc.c
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <memory>
30 #include <memory.h>
31 #include <string.h>
32 #include <math.h>
33 #include <assert.h>
34 #include <errno.h>
35 #if defined (WINDOWS)
36 #include <winsock2.h>
37 #else
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #endif
41 
42 #include "CRC.h"
43 #include "thread_compat.hpp"
44 #include "porting.h"
45 #include "error_code.h"
46 #include "error_manager.h"
47 #include "memory_alloc.h"
48 #include "crypt_opfunc.h"
49 #if defined (SERVER_MODE)
50 #include "thread_manager.hpp" // for thread_get_thread_entry_info
51 #endif // SERVER_MODE
52 
53 #include <openssl/evp.h>
54 #include <openssl/sha.h>
55 #include <openssl/rand.h>
56 
57 #define AES128_BLOCK_LEN (128/8)
58 #define AES128_KEY_LEN (128/8)
59 #define DES_BLOCK_LEN (8)
60 #define MD5_CHECKSUM_LEN 16
61 #define MD5_CHECKSUM_HEX_LEN (32 + 1)
62 
63 typedef enum
64 {
71 
72 typedef enum
73 {
79 } SHA_FUNCTION;
80 
81 // *INDENT-OFF*
82 template<typename T>
83 using deleted_unique_ptr = std::unique_ptr<T, std::function<void (T *)>>;
84 // *INDENT-ON*
85 
86 static const char *const crypt_lib_fail_info[] = {
87  "Initialization failure!",
88  "Open cipher failure!",
89  "Set secret key failure!",
90  "Encrypt/decrypt failure!",
91  "Unknown error!"
92 };
93 
94 static const char lower_hextable[] = "0123456789abcdef";
95 static const char upper_hextable[] = "0123456789ABCDEF";
96 
97 static int crypt_sha_functions (THREAD_ENTRY * thread_p, const char *src, int src_len, SHA_FUNCTION sha_func,
98  char **dest_p, int *dest_len_p);
99 static int crypt_md5_buffer_binary (const char *buffer, size_t len, char *resblock);
100 static void aes_default_gen_key (const char *key, int key_len, char *dest_key, int dest_key_len);
101 
102 void
103 str_to_hex_prealloced (const char *src, int src_len, char *dest, int dest_len, HEX_LETTERCASE lettercase)
104 {
105  int i = src_len;
106  unsigned char item_num = 0;
107  const char *hextable;
108 
109  assert (src != NULL && dest != NULL);
110  assert (dest_len >= (src_len * 2 + 1));
111 
112  if (lettercase == HEX_UPPERCASE)
113  {
114  hextable = upper_hextable;
115  }
116  else
117  {
118  hextable = lower_hextable;
119  }
120  while (i > 0)
121  {
122  --i;
123  item_num = (unsigned char) src[i];
124  dest[2 * i] = hextable[item_num / 16];
125  dest[2 * i + 1] = hextable[item_num % 16];
126  }
127  dest[src_len * 2] = '\0';
128 }
129 
130 /*
131  * str_to_hex() - convert a string to its hexadecimal expreesion string
132  * return:
133  * thread_p(in):
134  * src(in):
135  * src_len(in):
136  * dest_p(out):
137  * dest_len_p(out):
138  * Note:
139  */
140 char *
141 str_to_hex (THREAD_ENTRY * thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p,
142  HEX_LETTERCASE lettercase)
143 {
144  int dest_len = 2 * src_len + 1;
145  int i = 0;
146  unsigned char item_num = 0;
147  char *dest;
148 
149  assert (src != NULL);
150 
151 #if defined (SERVER_MODE)
152  if (thread_p == NULL)
153  {
154  thread_p = thread_get_thread_entry_info ();
155  }
156 #endif // SERVER_MODE
157 
158  dest = (char *) db_private_alloc (thread_p, dest_len * sizeof (char));
159  if (dest == NULL)
160  {
161  return NULL;
162  }
163 
164  str_to_hex_prealloced (src, src_len, dest, dest_len, lettercase);
165  *dest_p = dest;
166  *dest_len_p = dest_len - 1;
167  return dest;
168 }
169 
170 
171 /*
172  * aes_default_gen_key() - if aes's key is not equal to 128, the function generate the 128 length key. like mysql.
173  * return:
174  * key(in):
175  * key_len(in):
176  * dest_key(out):
177  * dest_key_len(in):
178  * Note:
179  */
180 static void
181 aes_default_gen_key (const char *key, int key_len, char *dest_key, int dest_key_len)
182 {
183  int i, j;
184 
185  assert (key != NULL);
186  assert (dest_key != NULL);
187 
188  memset (dest_key, 0, dest_key_len);
189  for (i = 0, j = 0; j < key_len; ++i, ++j)
190  {
191  if (i == dest_key_len)
192  {
193  i = 0;
194  }
195  dest_key[i] = ((unsigned char) dest_key[i]) ^ ((unsigned char) key[j]);
196  }
197 }
198 
199 /*
200  * crypt_default_encrypt() - like mysql's aes_encrypt. Use (AES-128/DES)/ECB/PKCS7 method.
201  * return:
202  * thread_p(in):
203  * src(in): source string
204  * src_len(in): the length of source string
205  * key(in): the encrypt key
206  * key_len(in): the length of the key
207  * dest_p(out): the encrypted data. The pointer has to be free by db_private_free
208  * dest_len_p(out):
209  * Note:
210  */
211 int
212 crypt_default_encrypt (THREAD_ENTRY * thread_p, const char *src, int src_len, const char *key, int key_len,
213  char **dest_p, int *dest_len_p, CIPHER_ENCRYPTION_TYPE enc_type)
214 {
215  int pad;
216  int padding_src_len;
217  int ciphertext_len = 0;
218  char *padding_src = NULL;
219  char *dest = NULL;
220  int error_status = NO_ERROR;
221 
222  assert (src != NULL);
223  assert (key != NULL);
224  const EVP_CIPHER *cipher;
225  int block_len;
226  char new_key[AES128_KEY_LEN + 1];
227  const char *key_arg = NULL;
228  switch (enc_type)
229  {
230  case AES_128_ECB:
231  cipher = EVP_aes_128_ecb ();
232  block_len = AES128_BLOCK_LEN;
233  aes_default_gen_key (key, key_len, new_key, AES128_KEY_LEN);
234  new_key[AES128_KEY_LEN] = '\0';
235  key_arg = new_key;
236  break;
237  case DES_ECB:
238  cipher = EVP_des_ecb ();
239  block_len = DES_BLOCK_LEN;
240  key_arg = key;
241  break;
242  default:
243  return ER_FAILED;
244  }
245 
246 #if defined (SERVER_MODE)
247  if (thread_p == NULL)
248  {
249  thread_p = thread_get_thread_entry_info ();
250  }
251 #endif // SERVER_MODE
252 
253  *dest_p = NULL;
254  *dest_len_p = 0;
255 
256  // *INDENT-OFF*
257  deleted_unique_ptr<EVP_CIPHER_CTX> context (EVP_CIPHER_CTX_new (), [] (EVP_CIPHER_CTX *ctxt_ptr)
258  {
259  if (ctxt_ptr != NULL)
260  {
261  EVP_CIPHER_CTX_free (ctxt_ptr);
262  }
263  });
264  // *INDENT-ON*
265 
266  if (context == NULL)
267  {
270  }
271 
272  if (EVP_EncryptInit (context.get (), cipher, (const unsigned char *) key_arg, NULL) != 1)
273  {
276  }
277 
278  /* PKCS7 */
279  if ((src_len % block_len) == 0)
280  {
281  pad = block_len;
282  padding_src_len = src_len + pad;
283  }
284  else
285  {
286  padding_src_len = (int) ceil ((double) src_len / block_len) * block_len;
287  pad = padding_src_len - src_len;
288  }
289 
290  padding_src = (char *) db_private_alloc (thread_p, padding_src_len);
291  if (padding_src == NULL)
292  {
294  }
295  memcpy (padding_src, src, src_len);
296  memset (padding_src + src_len, pad, pad);
297 
298  dest = (char *) db_private_alloc (thread_p, padding_src_len);
299  if (dest == NULL)
300  {
301  db_private_free_and_init (thread_p, padding_src);
303  }
304 
305  if (EVP_EncryptUpdate (context.get (), (unsigned char *) dest, &ciphertext_len, (const unsigned char *) padding_src,
306  padding_src_len) != 1)
307  {
308  db_private_free_and_init (thread_p, padding_src);
309  db_private_free_and_init (thread_p, dest);
312  }
313 
314  *dest_len_p = ciphertext_len;
315  *dest_p = dest;
316 
317  db_private_free_and_init (thread_p, padding_src);
318  return NO_ERROR;
319 }
320 
321 /*
322  * crypt_default_decrypt() - like mysql's aes_decrypt. Use AES-128/ECB/PKCS7 method.
323  * return:
324  * thread_p(in):
325  * src(in): source string
326  * src_len(in): the length of source string
327  * key(in): the encrypt key
328  * key_len(in): the length of the key
329  * dest_p(out): the encrypted data. The pointer has to be free by db_private_free
330  * dest_len_p(out):
331  * Note:
332  */
333 int
334 crypt_default_decrypt (THREAD_ENTRY * thread_p, const char *src, int src_len, const char *key, int key_len,
335  char **dest_p, int *dest_len_p, CIPHER_ENCRYPTION_TYPE enc_type)
336 {
337  char *dest = NULL;
338  int dest_len;
339  int error_status = NO_ERROR;
340  int pad, pad_len;
341  int i;
342 
343  const EVP_CIPHER *cipher;
344  int block_len;
345  char new_key[AES128_KEY_LEN + 1];
346  const char *key_arg = NULL;
347  switch (enc_type)
348  {
349  case AES_128_ECB:
350  cipher = EVP_aes_128_ecb ();
351  block_len = AES128_BLOCK_LEN;
352  aes_default_gen_key (key, key_len, new_key, AES128_KEY_LEN);
353  new_key[AES128_KEY_LEN] = '\0';
354  key_arg = new_key;
355  break;
356  case DES_ECB:
357  cipher = EVP_des_ecb ();
358  block_len = DES_BLOCK_LEN;
359  key_arg = key;
360  break;
361  default:
362  return ER_FAILED;
363  }
364 
365 #if defined (SERVER_MODE)
366  if (thread_p == NULL)
367  {
368  thread_p = thread_get_thread_entry_info ();
369  }
370 #endif // SERVER_MODE
371 
372  assert (src != NULL);
373  assert (key != NULL);
374 
375  *dest_p = NULL;
376  *dest_len_p = 0;
377 
378  /* src is not a string encrypted by aes_default_encrypt, return NULL */
379  if (src_len % block_len)
380  {
381  return NO_ERROR;
382  }
383 
384  // *INDENT-OFF*
385  deleted_unique_ptr<EVP_CIPHER_CTX> context (EVP_CIPHER_CTX_new (), [] (EVP_CIPHER_CTX *ctxt_ptr)
386  {
387  if (ctxt_ptr != NULL)
388  {
389  EVP_CIPHER_CTX_free (ctxt_ptr);
390  }
391  });
392  // *INDENT-ON*
393 
394  if (context == NULL)
395  {
398  }
399 
400  if (EVP_DecryptInit (context.get (), cipher, (const unsigned char *) key_arg, NULL) != 1)
401  {
404  }
405 
406  dest = (char *) db_private_alloc (thread_p, src_len * sizeof (char));
407  if (dest == NULL)
408  {
409  error_status = ER_OUT_OF_VIRTUAL_MEMORY;
410  return error_status;
411  }
412 
413  int len;
414  if (EVP_DecryptUpdate (context.get (), (unsigned char *) dest, &len, (const unsigned char *) src, src_len) != 1)
415  {
416  db_private_free_and_init (thread_p, dest);
419  }
420 
421  if (EVP_DecryptFinal (context.get (), (unsigned char *) dest + len, &len) != 1)
422  {
423  db_private_free_and_init (thread_p, dest);
426  }
427 
428  /* PKCS7 */
429  if (src_len != 0)
430  {
431  pad = dest[src_len - 1];
432  if (pad > AES128_BLOCK_LEN)
433  {
434  /* src is not a string encrypted by aes_default_encrypt, return NULL */
435  db_private_free_and_init (thread_p, dest);
436  return ER_FAILED;
437  }
438  i = src_len - 2;
439  pad_len = 1;
440  while ((i >= 0) && (dest[i] == pad))
441  {
442  pad_len++;
443  i--;
444  }
445  if ((pad_len >= pad))
446  {
447  pad_len = pad;
448  dest_len = src_len - pad_len;
449  }
450  else
451  {
452  /* src is not a string encrypted by aes_default_encrypt, return NULL */
453  db_private_free_and_init (thread_p, dest);
454  return ER_FAILED;
455  }
456  }
457 
458  *dest_p = dest;
459  *dest_len_p = dest_len;
460  return NO_ERROR;
461 }
462 
463 /*
464  * crypt_sha_one() -
465  * return:
466  * thread_p(in):
467  * src(in):
468  * src_len(in):
469  * dest_len_p(out):
470  * Note:
471  */
472 int
473 crypt_sha_one (THREAD_ENTRY * thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p)
474 {
475  return crypt_sha_functions (thread_p, src, src_len, SHA_ONE, dest_p, dest_len_p);
476 }
477 
478 /*
479  * crypt_sha_two() -
480  * return:
481  * thread_p(in):
482  * src(in):
483  * src_len(in):
484  * need_hash_len(in):
485  * dest_p(out)
486  * dest_len_p(out):
487  * Note:
488  */
489 int
490 crypt_sha_two (THREAD_ENTRY * thread_p, const char *src, int src_len, int need_hash_len, char **dest_p, int *dest_len_p)
491 {
492  SHA_FUNCTION sha_func;
493 
494  switch (need_hash_len)
495  {
496  case 0:
497  case 256:
498  sha_func = SHA_TWO_256;
499  break;
500  case 224:
501  sha_func = SHA_TWO_224;
502  break;
503  case 384:
504  sha_func = SHA_TWO_384;
505  break;
506  case 512:
507  sha_func = SHA_TWO_512;
508  break;
509  default:
510  return NO_ERROR;
511  }
512  return crypt_sha_functions (thread_p, src, src_len, sha_func, dest_p, dest_len_p);
513 }
514 
515 static int
516 crypt_sha_functions (THREAD_ENTRY * thread_p, const char *src, int src_len, SHA_FUNCTION sha_func, char **dest_p,
517  int *dest_len_p)
518 {
519  char *dest_hex = NULL;
520  int dest_hex_len;
521  assert (src != NULL);
522 
523 #if defined (SERVER_MODE)
524  if (thread_p == NULL)
525  {
526  thread_p = thread_get_thread_entry_info ();
527  }
528 #endif // SERVER_MODE
529 
530  *dest_p = NULL;
531 
532  // *INDENT-OFF*
533  deleted_unique_ptr<EVP_MD_CTX> context (EVP_MD_CTX_new (), [] (EVP_MD_CTX * ctxt_ptr)
534  {
535  if (ctxt_ptr != NULL)
536  {
537  EVP_MD_CTX_free (ctxt_ptr);
538  }
539  });
540  // *INDENT-ON*
541 
542  if (context == NULL)
543  {
546  }
547 
548  int rc;
549  switch (sha_func)
550  {
551  case SHA_ONE:
552  rc = EVP_DigestInit (context.get (), EVP_sha1 ());
553  break;
554  case SHA_TWO_256:
555  rc = EVP_DigestInit (context.get (), EVP_sha256 ());
556  break;
557  case SHA_TWO_224:
558  rc = EVP_DigestInit (context.get (), EVP_sha224 ());
559  break;
560  case SHA_TWO_384:
561  rc = EVP_DigestInit (context.get (), EVP_sha384 ());
562  break;
563  case SHA_TWO_512:
564  rc = EVP_DigestInit (context.get (), EVP_sha512 ());
565  break;
566  default:
567  assert (false);
568  return ER_FAILED;
569  }
570  if (rc == 0)
571  {
574  }
575 
576  if (EVP_DigestUpdate (context.get (), src, src_len) == 0)
577  {
580  }
581 
582  unsigned char hash[EVP_MAX_MD_SIZE];
583  unsigned int lengthOfHash = 0;
584  if (EVP_DigestFinal (context.get (), hash, &lengthOfHash) == 0)
585  {
588  }
589 
590  dest_hex = str_to_hex (thread_p, (char *) hash, lengthOfHash, &dest_hex, &dest_hex_len, HEX_UPPERCASE);
591  if (dest_hex == NULL)
592  {
594  }
595 
596  *dest_p = dest_hex;
597  *dest_len_p = dest_hex_len;
598 
599  return NO_ERROR;
600 }
601 
602 static int
603 crypt_md5_buffer_binary (const char *buffer, size_t len, char *resblock)
604 {
605  if (buffer == NULL || resblock == NULL)
606  {
607  assert (false);
608  return ER_FAILED;
609  }
610  // *INDENT-OFF*
611  deleted_unique_ptr<EVP_MD_CTX> context (EVP_MD_CTX_new (), [] (EVP_MD_CTX *ctxt_ptr)
612  {
613  if (ctxt_ptr != NULL)
614  {
615  EVP_MD_CTX_free (ctxt_ptr);
616  }
617  });
618  // *INDENT-ON*
619 
620  if (context == NULL)
621  {
624  }
625 
626  if (EVP_DigestInit (context.get (), EVP_md5 ()) == 0)
627  {
630  }
631  if (EVP_DigestUpdate (context.get (), buffer, len) == 0)
632  {
635  }
636  if (EVP_DigestFinal (context.get (), (unsigned char *) resblock, NULL) == 0)
637  {
640  }
641 
642  return NO_ERROR;
643 }
644 
645 int
646 crypt_md5_buffer_hex (const char *buffer, size_t len, char *resblock)
647 {
648  int ec = NO_ERROR;
649  if (buffer == NULL || resblock == NULL)
650  {
651  assert (false);
652  return ER_FAILED;
653  }
654  ec = crypt_md5_buffer_binary (buffer, len, resblock);
655  if (ec != NO_ERROR)
656  {
657  return ec;
658  }
660  return NO_ERROR;
661 }
662 
663 /*
664  * crypt_crc32() -
665  * return:
666  * src(in): original message
667  * src_len(in): length of original message
668  * dest(out): crc32 result
669  * Note:
670  */
671 void
672 crypt_crc32 (const char *src, int src_len, int *dest)
673 {
674  assert (src != NULL && dest != NULL);
675 // *INDENT-OFF*
676  *dest = CRC::Calculate (src, src_len, CRC::CRC_32 ());
677 // *INDENT-ON*
678 }
679 
680 /*
681  * crypt_generate_random_bytes() - Generate random number bytes
682  * return: error code or NO_ERROR
683  * dest(out): the generated bytes
684  * length(in): the length of bytes to generate
685  * Note:
686  */
687 int
688 crypt_generate_random_bytes (char *dest, int length)
689 {
690  assert (dest != NULL && length > 0);
691 
692  if (RAND_bytes ((unsigned char *) dest, length) != 1)
693  {
696  }
697 
698  return NO_ERROR;
699 }
cubthread::entry * thread_get_thread_entry_info(void)
#define NO_ERROR
Definition: error_code.h:46
static const Parameters< crcpp_uint32, 32 > & CRC_32()
Returns a set of parameters for CRC-32 (aka CRC-32 ADCCP, CRC-32 PKZip).
Definition: CRC.h:1567
SHA_FUNCTION
Definition: crypt_opfunc.c:72
#define ER_FAILED
Definition: error_code.h:47
int crypt_sha_two(THREAD_ENTRY *thread_p, const char *src, int src_len, int need_hash_len, char **dest_p, int *dest_len_p)
Definition: crypt_opfunc.c:490
HEX_LETTERCASE
Definition: crypt_opfunc.h:30
#define ER_ENCRYPTION_LIB_FAILED
Definition: error_code.h:1445
void crypt_crc32(const char *src, int src_len, int *dest)
Definition: crypt_opfunc.c:672
void THREAD_ENTRY
int crypt_generate_random_bytes(char *dest, int length)
Definition: crypt_opfunc.c:688
void str_to_hex_prealloced(const char *src, int src_len, char *dest, int dest_len, HEX_LETTERCASE lettercase)
Definition: crypt_opfunc.c:103
CRYPT_LIB_ERROR
Definition: crypt_opfunc.c:63
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define assert(x)
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define DES_BLOCK_LEN
Definition: crypt_opfunc.c:59
#define MD5_CHECKSUM_LEN
Definition: crypt_opfunc.c:60
#define AES128_BLOCK_LEN
Definition: crypt_opfunc.c:57
#define NULL
Definition: freelistheap.h:34
#define MD5_CHECKSUM_HEX_LEN
Definition: crypt_opfunc.c:61
int crypt_md5_buffer_hex(const char *buffer, size_t len, char *resblock)
Definition: crypt_opfunc.c:646
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
CIPHER_ENCRYPTION_TYPE
Definition: crypt_opfunc.h:36
static int crypt_md5_buffer_binary(const char *buffer, size_t len, char *resblock)
Definition: crypt_opfunc.c:603
int crypt_default_encrypt(THREAD_ENTRY *thread_p, const char *src, int src_len, const char *key, int key_len, char **dest_p, int *dest_len_p, CIPHER_ENCRYPTION_TYPE enc_type)
Definition: crypt_opfunc.c:212
static int rc
Definition: serial.c:50
char * str_to_hex(THREAD_ENTRY *thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p, HEX_LETTERCASE lettercase)
Definition: crypt_opfunc.c:141
#define ARG_FILE_LINE
Definition: error_manager.h:44
int crypt_default_decrypt(THREAD_ENTRY *thread_p, const char *src, int src_len, const char *key, int key_len, char **dest_p, int *dest_len_p, CIPHER_ENCRYPTION_TYPE enc_type)
Definition: crypt_opfunc.c:334
static const char *const crypt_lib_fail_info[]
Definition: crypt_opfunc.c:86
static CRCType Calculate(const void *data, crcpp_size size, const Parameters< CRCType, CRCWidth > &parameters)
Computes a CRC.
Definition: CRC.h:436
static const char upper_hextable[]
Definition: crypt_opfunc.c:95
std::unique_ptr< T, std::function< void(T *)>> deleted_unique_ptr
Definition: crypt_opfunc.c:83
static const char lower_hextable[]
Definition: crypt_opfunc.c:94
int i
Definition: dynamic_load.c:954
#define AES128_KEY_LEN
Definition: crypt_opfunc.c:58
static int crypt_sha_functions(THREAD_ENTRY *thread_p, const char *src, int src_len, SHA_FUNCTION sha_func, char **dest_p, int *dest_len_p)
Definition: crypt_opfunc.c:516
static void aes_default_gen_key(const char *key, int key_len, char *dest_key, int dest_key_len)
Definition: crypt_opfunc.c:181
int crypt_sha_one(THREAD_ENTRY *thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p)
Definition: crypt_opfunc.c:473