CUBRID Engine  latest
tde.c
Go to the documentation of this file.
1 /*
2  *
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  * tde.c - Transparent Data Encryption (TDE) Module
21  */
22 
23 #ident "$Id$"
24 
25 #include <stdlib.h>
26 #include <assert.h>
27 
28 #include <openssl/conf.h>
29 #include <openssl/evp.h>
30 #include <openssl/err.h>
31 #include <openssl/sha.h>
32 #include <openssl/rand.h>
33 #include <signal.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 
38 #if defined(WINDOWS)
39 #include <io.h>
40 #endif /* WINDOWS */
41 
42 #if !defined(CS_MODE)
43 #include "heap_file.h"
44 #include "btree.h"
45 #include "system_parameter.h"
46 #include "boot_sr.h"
47 #include "file_io.h"
48 #endif /* !CS_MODE */
49 
50 #include "error_manager.h"
51 #include "error_code.h"
52 #include "log_storage.hpp"
53 #include "log_volids.hpp"
54 #include "tde.h"
55 
56 #define off_signals(new_mask, old_mask) \
57  do { \
58  sigfillset (&(new_mask)); \
59  sigdelset (&(new_mask), SIGINT); \
60  sigdelset (&(new_mask), SIGQUIT); \
61  sigdelset (&(new_mask), SIGTERM); \
62  sigdelset (&(new_mask), SIGHUP); \
63  sigdelset (&(new_mask), SIGABRT); \
64  sigprocmask (SIG_SETMASK, &(new_mask), &(old_mask)); \
65  } while (0)
66 #define restore_signals(old_mask) sigprocmask(SIG_SETMASK, &(old_mask), NULL)
67 
68 #if !defined(CS_MODE)
69 TDE_CIPHER tde_Cipher; /* global var for TDE Module */
70 
71 static OID tde_Keyinfo_oid = OID_INITIALIZER; /* Location of keys */
73 
74 static int tde_generate_keyinfo (TDE_KEYINFO * keyinfo, int mk_index, const unsigned char *master_key,
75  const time_t created_time, const TDE_DATA_KEY_SET * dks);
76 static int tde_update_keyinfo (THREAD_ENTRY * thread_p, const TDE_KEYINFO * keyinfo);
77 
78 static int tde_create_keys_file (const char *keyfile_fullname);
79 static bool tde_validate_mk (const unsigned char *master_key, const unsigned char *mk_hash);
80 static void tde_make_mk_hash (const unsigned char *master_key, unsigned char *mk_hash);
81 static int tde_load_dks (const unsigned char *master_key, const TDE_KEYINFO * keyinfo);
82 static int tde_create_dk (unsigned char *data_key);
83 static int tde_encrypt_dk (const unsigned char *dk_plain, TDE_DATA_KEY_TYPE dk_type, const unsigned char *master_key,
84  unsigned char *dk_cipher);
85 static int tde_decrypt_dk (const unsigned char *dk_cipher, TDE_DATA_KEY_TYPE dk_type, const unsigned char *master_key,
86  unsigned char *dk_plain);
87 
88 static void tde_dk_nonce (TDE_DATA_KEY_TYPE dk_type, unsigned char *dk_nonce);
89 
90 /*
91  * TDE internal functions for encrpytion and decryption. All the en/decryption go through it.
92  */
93 static int tde_encrypt_internal (const unsigned char *plain_buffer, int length, TDE_ALGORITHM tde_algo,
94  const unsigned char *key, const unsigned char *nonce, unsigned char *cipher_buffer);
95 static int tde_decrypt_internal (const unsigned char *cipher_buffer, int length, TDE_ALGORITHM tde_algo,
96  const unsigned char *key, const unsigned char *nonce, unsigned char *plain_buffer);
97 
98 /*
99  * tde_initialize () - Initialize the tde module, which is called during initializing server.
100  *
101  * return : Error code
102  * thread_p (in) : Thread entry
103  * keyinfo_hfid (in) : HFID of the special heap file which stores TDE_KEY_INFO.
104  */
105 int
106 tde_initialize (THREAD_ENTRY * thread_p, HFID * keyinfo_hfid)
107 {
108  char mk_path[PATH_MAX] = { 0, };
109  unsigned char default_mk[TDE_MASTER_KEY_LENGTH] = { 0, };
110  int mk_index;
111  int err = NO_ERROR;
112  RECDES recdes;
113  HEAP_OPERATION_CONTEXT heapop_context;
114  TDE_DATA_KEY_SET dks;
115  time_t created_time;
116  int vdes = -1;
117  TDE_KEYINFO keyinfo;
118  char recdes_buffer[sizeof (int) + sizeof (TDE_KEYINFO)];
119  int repid_and_flag_bits = 0;
120 
121  tde_make_keys_file_fullname (mk_path, boot_db_full_name (), false);
122  err = tde_create_keys_file (mk_path);
123  if (err == NO_ERROR)
124  {
125  vdes = fileio_mount (thread_p, boot_db_full_name (), mk_path, LOG_DBTDE_KEYS_VOLID, false, false);
126  if (vdes == NULL_VOLDES)
127  {
128  ASSERT_ERROR ();
129  err = er_errid ();
130  goto exit;
131  }
132 
133  err = tde_create_mk (default_mk, &created_time);
134  if (err != NO_ERROR)
135  {
136  goto exit;
137  }
138 
139  err = tde_add_mk (vdes, default_mk, created_time, &mk_index);
140  if (err != NO_ERROR)
141  {
142  goto exit;
143  }
144  }
145  else if (err == ER_BO_VOLUME_EXISTS)
146  {
147  vdes = fileio_mount (thread_p, boot_db_full_name (), mk_path, LOG_DBTDE_KEYS_VOLID, false, false);
148  if (vdes == NULL_VOLDES)
149  {
150  ASSERT_ERROR ();
151  err = er_errid ();
152  goto exit;
153  }
154 
155  if (tde_validate_keys_file (vdes) == false)
156  {
159  goto exit;
160  }
161 
162  err = tde_find_first_mk (vdes, &mk_index, default_mk, &created_time);
163  if (err != NO_ERROR)
164  {
165  goto exit;
166  }
167  }
168  else
169  {
170  goto exit;
171  }
172 
173  err = tde_create_dk (dks.perm_key);
174  if (err != NO_ERROR)
175  {
176  goto exit;
177  }
178  err = tde_create_dk (dks.temp_key);
179  if (err != NO_ERROR)
180  {
181  goto exit;
182  }
183  err = tde_create_dk (dks.log_key);
184  if (err != NO_ERROR)
185  {
186  goto exit;
187  }
188 
189  err = tde_generate_keyinfo (&keyinfo, mk_index, default_mk, created_time, &dks);
190  if (err != NO_ERROR)
191  {
192  goto exit;
193  }
194 
195  /* HACK: to prevent the record from adjuestment in vacuum_rv_check_at_undo() while UNDOing */
196  memcpy (recdes_buffer, &repid_and_flag_bits, sizeof (int));
197  memcpy (recdes_buffer + sizeof (int), &keyinfo, sizeof (TDE_KEYINFO));
198 
199  recdes.length = recdes.area_size = sizeof (recdes_buffer);
200  recdes.type = REC_HOME;
201  recdes.data = (char *) recdes_buffer;
202 
203  /* Prepare context */
204  heap_create_insert_context (&heapop_context, keyinfo_hfid, NULL, &recdes, NULL);
205 
206  /* Insert and fetch location */
207  err = heap_insert_logical (thread_p, &heapop_context, NULL);
208  if (err != NO_ERROR)
209  {
210  goto exit;
211  }
212 
213  HFID_COPY (&tde_Keyinfo_hfid, keyinfo_hfid);
214  COPY_OID (&tde_Keyinfo_oid, &heapop_context.res_oid);
215 
216 exit:
217  fileio_dismount (thread_p, vdes);
218 
219  return err;
220 }
221 
222 /*
223  * tde_cipher_initialize () - Load the tde module, which is called during restarting server.
224  * It prepares the tde_Cipher to encrpyt and decrypt.
225  *
226  * return : Error code
227  * thread_p (in) : Thread entry
228  * keyinfo_hfid (in) : HFID of the special heap file which stores TDE_KEY_INFO.
229  * mk_path_given (in) : The path of the master key file. It has higher priority than the default path or that from the system parameter.
230  */
231 int
232 tde_cipher_initialize (THREAD_ENTRY * thread_p, const HFID * keyinfo_hfid, const char *mk_path_given)
233 {
234  char mk_path_buffer[PATH_MAX] = { 0, };
235  const char *mk_path = NULL;
236  unsigned char master_key[TDE_MASTER_KEY_LENGTH];
237  TDE_KEYINFO keyinfo;
238  int err = NO_ERROR;
239  int vdes = NULL_VOLDES;
240 
241  if (mk_path_given != NULL)
242  {
243  mk_path = mk_path_given;
244  vdes = fileio_mount (thread_p, boot_db_full_name (), mk_path, LOG_DBTDE_KEYS_VOLID, 1, false);
245  /*
246  * When restoredb, backup _keys file is given.
247  * if it is fail to mount, try to use normal key file ([db]_keys) below
248  */
249  }
250 
251  if (mk_path == NULL || vdes == NULL_VOLDES)
252  {
253  tde_make_keys_file_fullname (mk_path_buffer, boot_db_full_name (), false);
254  mk_path = mk_path_buffer;
255  vdes = fileio_mount (thread_p, boot_db_full_name (), mk_path, LOG_DBTDE_KEYS_VOLID, 1, false);
256  if (vdes == NULL_VOLDES)
257  {
258  ASSERT_ERROR ();
259  return er_errid ();
260  }
261  }
262 
263  if (tde_validate_keys_file (vdes) == false)
264  {
267  goto exit;
268  }
269 
270  HFID_COPY (&tde_Keyinfo_hfid, keyinfo_hfid);
271 
272  err = tde_get_keyinfo (thread_p, &keyinfo);
273  if (err != NO_ERROR)
274  {
275  goto exit;
276  }
277 
278  assert (keyinfo.mk_index >= 0);
279 
280  err = tde_load_mk (vdes, &keyinfo, master_key);
281  if (err != NO_ERROR)
282  {
283  goto exit;
284  }
285 
286  err = tde_load_dks (master_key, &keyinfo);
287  if (err != NO_ERROR)
288  {
289  goto exit;
290  }
291 
292  tde_Cipher.temp_write_counter = 0;
293 
294  tde_Cipher.is_loaded = true;
295 
296 exit:
297  fileio_dismount (thread_p, vdes);
298 
299  return err;
300 }
301 
302 /*
303  * tde_create_keys_file () - Create TDE master key file
304  *
305  * return : Error code
306  * keyfile_fullname (in) : Full name of the key file.
307  */
308 static int
309 tde_create_keys_file (const char *keyfile_fullname)
310 {
311  int vdes = NULL_VOLDES;
312  int err = NO_ERROR;
313  char magic[CUBRID_MAGIC_MAX_LENGTH] = { 0, };
314 #if !defined(WINDOWS)
315  sigset_t new_mask, old_mask;
316  off_signals (new_mask, old_mask);
317 #endif /* !WINDOWS */
318 
319  if (fileio_is_volume_exist (keyfile_fullname))
320  {
322  err = ER_BO_VOLUME_EXISTS;
323  goto exit;
324  }
325 
326  if ((vdes = fileio_open (keyfile_fullname, O_CREAT | O_RDWR, 0600)) == NULL_VOLDES)
327  {
331  goto exit;
332  }
333 
334  memcpy (magic, CUBRID_MAGIC_KEYS, sizeof (CUBRID_MAGIC_KEYS));
335  write (vdes, magic, CUBRID_MAGIC_MAX_LENGTH);
336 
337  fsync (vdes);
338 
339 exit:
340  if (vdes != NULL_VOLDES)
341  {
342  fileio_close (vdes);
343  }
344 #if !defined(WINDOWS)
345  restore_signals (old_mask);
346 #endif /* !WINDOWS */
347 
348  return err;
349 }
350 
351 /*
352  * tde_validate_keys_file () - Validate the master key file
353  *
354  * return : Whether or not it is valid
355  * vdes (in) : Key file descriptor
356  */
357 bool
359 {
360  char magic[CUBRID_MAGIC_MAX_LENGTH] = { 0, };
361  bool valid = true;
362 #if !defined(WINDOWS)
363  sigset_t new_mask, old_mask;
364  off_signals (new_mask, old_mask);
365 #endif /* !WINDOWS */
366 
367  if (lseek (vdes, 0L, SEEK_SET) != 0L)
368  {
369  valid = false;
370  goto exit;
371  }
372 
373  read (vdes, magic, CUBRID_MAGIC_MAX_LENGTH);
374  if (memcmp (magic, CUBRID_MAGIC_KEYS, sizeof (CUBRID_MAGIC_MAX_LENGTH)) != 0)
375  {
376  valid = false;
377  goto exit;
378  }
379 
380 exit:
381 #if !defined(WINDOWS)
382  restore_signals (old_mask);
383 #endif /* !WINDOWS */
384  return valid;
385 }
386 
387 /*
388  * tde_copy_keys_file () - Copy the master key file
389  *
390  * return : Error code
391  * thread_p (in) : Thread entry
392  * dest_fullname (in) : Copy to
393  * src_fullname (in) : Copy from
394  * keep_dest_mount (in) : Whether to keep the destination file mount after this function finishes
395  * keep_src_mount (in) : Whether to keep the source file mount after this function finishes
396  */
397 int
398 tde_copy_keys_file (THREAD_ENTRY * thread_p, const char *dest_fullname, const char *src_fullname, bool keep_dest_mount,
399  bool keep_src_mount)
400 {
401  char buffer[4096];
402  int from_vdes = -1;
403  int to_vdes = -1;
404  int err = NO_ERROR;
405  int nread = -1;
406 
407  from_vdes = fileio_mount (thread_p, boot_db_full_name (), src_fullname, LOG_DBTDE_KEYS_VOLID, 1, false);
408  if (from_vdes == NULL_VOLDES)
409  {
410  ASSERT_ERROR ();
411  return er_errid ();
412  }
413 
414  if (tde_validate_keys_file (from_vdes) == false)
415  {
416  fileio_dismount (thread_p, from_vdes);
419  }
420 
421  if (fileio_is_volume_exist (dest_fullname))
422  {
423  fileio_unformat_and_rename (thread_p, dest_fullname, NULL);
424  }
425 
426  err = tde_create_keys_file (dest_fullname);
427  if (err != NO_ERROR)
428  {
429  fileio_dismount (thread_p, from_vdes);
430  return err;
431  }
432 
433  to_vdes = fileio_mount (thread_p, boot_db_full_name (), dest_fullname, LOG_DBCOPY_VOLID, 1, false);
434  if (to_vdes == NULL_VOLDES)
435  {
436  ASSERT_ERROR_AND_SET (err);
437  fileio_dismount (thread_p, from_vdes);
438  return err;
439  }
440 
441  if (lseek (from_vdes, 0L, SEEK_SET) != 0L)
442  {
443  fileio_dismount (thread_p, from_vdes);
444  fileio_unformat_and_rename (thread_p, dest_fullname, NULL);
445  return ER_FAILED;
446  }
447 
448  while ((nread = read (from_vdes, buffer, 4096)) > 0)
449  {
450  char *out_ptr = buffer;
451  ssize_t nwritten = -1;
452 
453  do
454  {
455  nwritten = write (to_vdes, out_ptr, nread);
456 
457  if (nwritten >= 0)
458  {
459  nread -= nwritten;
460  out_ptr += nwritten;
461  }
462  else if (errno != EINTR)
463  {
464  fileio_dismount (thread_p, from_vdes);
465  fileio_unformat_and_rename (thread_p, dest_fullname, NULL);
467  return ER_IO_WRITE;
468  }
469  }
470  while (nread > 0);
471  }
472 
473  if (!keep_src_mount)
474  {
475  fileio_dismount (thread_p, from_vdes);
476  }
477  if (!keep_dest_mount)
478  {
479  fileio_dismount (thread_p, to_vdes);
480  }
481  return err;
482 }
483 
484 /*
485  * tde_make_keys_file_fullname () - Make the full name of TDE master key file. I can be set by a system parameter
486  *
487  * keys_vol_fullname (out) : Full path of the key file
488  * db_full_name (in) : Full paht of the data volume
489  * ignore_parm (in) : Wwhether to ignore the system parameter or not
490  */
491 void
492 tde_make_keys_file_fullname (char *keys_vol_fullname, const char *db_full_name, bool ignore_parm)
493 {
494  char *mk_path = NULL;
495  const char *base_name = NULL;
496 
497  mk_path = (char *) prm_get_string_value (PRM_ID_TDE_KEYS_FILE_PATH);
498  if (ignore_parm || mk_path == NULL || mk_path[0] == '\0')
499  {
500  fileio_make_keys_name (keys_vol_fullname, db_full_name);
501  }
502  else
503  {
504  base_name = fileio_get_base_file_name (db_full_name);
505  fileio_make_keys_name_given_path (keys_vol_fullname, mk_path, base_name);
506  }
507 }
508 
509 /*
510  * tde_generate_keyinfo () - Generate a keyinfo with a master key and data keys information
511  *
512  * return : Error code
513  * keyinfo (out) : keyinfo
514  * mk_index (in) : Index in the master key file
515  * master_key (in) : Master key
516  * created_time (in) : Creation time of the master key
517  * dks (in) : Data key set
518  */
519 static int
520 tde_generate_keyinfo (TDE_KEYINFO * keyinfo, int mk_index, const unsigned char *master_key,
521  const time_t created_time, const TDE_DATA_KEY_SET * dks)
522 {
523  int err = NO_ERROR;
524 
525  keyinfo->mk_index = mk_index;
526  tde_make_mk_hash (master_key, keyinfo->mk_hash);
527 
528  err = tde_encrypt_dk (dks->perm_key, TDE_DATA_KEY_TYPE_PERM, master_key, keyinfo->dk_perm);
529  if (err != NO_ERROR)
530  {
531  return err;
532  }
533  err = tde_encrypt_dk (dks->temp_key, TDE_DATA_KEY_TYPE_TEMP, master_key, keyinfo->dk_temp);
534  if (err != NO_ERROR)
535  {
536  return err;
537  }
538  err = tde_encrypt_dk (dks->log_key, TDE_DATA_KEY_TYPE_LOG, master_key, keyinfo->dk_log);
539  if (err != NO_ERROR)
540  {
541  return err;
542  }
543 
544  keyinfo->created_time = created_time;
545  keyinfo->set_time = time (NULL);
546  return err;
547 }
548 
549 /*
550  * tde_get_keyinfo () - Get keyinfo from key info heap file
551  *
552  * return : Error code
553  * thread_p (in) : Thread entry
554  * keyinfo (out) : keyinfo from the keyinfo heap
555  */
556 int
557 tde_get_keyinfo (THREAD_ENTRY * thread_p, TDE_KEYINFO * keyinfo)
558 {
559  RECDES recdes;
560  HEAP_SCANCACHE scan_cache;
561  SCAN_CODE scan = S_SUCCESS;
562  char recdes_buffer[sizeof (int) + sizeof (TDE_KEYINFO)];
563  int error_code = NO_ERROR;
564 
565  assert (!HFID_IS_NULL (&tde_Keyinfo_hfid));
566 
567  recdes.length = recdes.area_size = sizeof (recdes_buffer);
568  recdes.data = (char *) recdes_buffer;
569 
570  heap_scancache_quick_start_with_class_hfid (thread_p, &scan_cache, &tde_Keyinfo_hfid);
571  scan = heap_first (thread_p, &tde_Keyinfo_hfid, NULL, &tde_Keyinfo_oid, &recdes, &scan_cache, COPY);
572  heap_scancache_end (thread_p, &scan_cache);
573 
574  if (scan != S_SUCCESS)
575  {
576  assert (false);
577  return ER_FAILED;
578  }
579 
580  /* HACK: the front of the record if dummy int to prevent the record from adjuestment
581  * in vacuum_rv_check_at_undo() while UNDOing, refer to tde_insert_keyinfo() */
582  memcpy (keyinfo, recdes_buffer + sizeof (int), sizeof (TDE_KEYINFO));
583 
584  return NO_ERROR;
585 }
586 
587 /*
588  * tde_get_keyinfo () - Get keyinfo from key info heap file
589  *
590  * return : Error code
591  * thread_p (in) : Thread entry
592  * keyinfo (in) : keyinfo to update that in the keyinfo heap
593  */
594 static int
595 tde_update_keyinfo (THREAD_ENTRY * thread_p, const TDE_KEYINFO * keyinfo)
596 {
597  HEAP_SCANCACHE scan_cache;
598  HEAP_OPERATION_CONTEXT update_context;
599  RECDES recdes;
600  char recdes_buffer[sizeof (int) + sizeof (TDE_KEYINFO)];
601  int repid_and_flag_bits = 0;
602  int error_code = NO_ERROR;
603 
604  assert (!HFID_IS_NULL (&tde_Keyinfo_hfid));
605  assert (!OID_ISNULL (&tde_Keyinfo_oid));
606 
607  /* HACK: to prevent the record from adjuestment in vacuum_rv_check_at_undo() while UNDOing */
608  memcpy (recdes_buffer, &repid_and_flag_bits, sizeof (int));
609  memcpy (recdes_buffer + sizeof (int), keyinfo, sizeof (TDE_KEYINFO));
610 
611  recdes.length = recdes.area_size = sizeof (recdes_buffer);
612  recdes.data = (char *) recdes_buffer;
613 
614  /* note that we start a scan cache with NULL class_oid. That's because ketinfo_oid doesn't really have a class!
615  * we have to start the scan cache this way so it can cache also cache file type for heap_update_logical.
616  * otherwise it will try to read it from cache using root class OID. which actually has its own heap file and its own
617  * heap file type.
618  */
619  error_code = heap_scancache_start_modify (thread_p, &scan_cache, &tde_Keyinfo_hfid, NULL, SINGLE_ROW_UPDATE, NULL);
620  if (error_code != NO_ERROR)
621  {
622  ASSERT_ERROR ();
623  return error_code;
624  }
625 
626  /* hack the class to avoid heap_scancache_check_with_hfid. */
627  scan_cache.node.class_oid = *oid_Root_class_oid;
628  heap_create_update_context (&update_context, &tde_Keyinfo_hfid, &tde_Keyinfo_oid, oid_Root_class_oid, &recdes,
629  &scan_cache, UPDATE_INPLACE_CURRENT_MVCCID);
630  error_code = heap_update_logical (thread_p, &update_context);
631  if (error_code != NO_ERROR)
632  {
633  ASSERT_ERROR ();
634  }
635  heap_scancache_end (thread_p, &scan_cache);
636  return error_code;
637 }
638 
639 /*
640  * tde_chnage_mk () - Change the master key set on the database
641  *
642  * return : Error code
643  * thread_p (in) : Thread entry
644  * mk_index (in) : The index in the master key file
645  * master_key (in) : The master key
646  * created_time (in) : The creation time of the master key
647  */
648 int
649 tde_change_mk (THREAD_ENTRY * thread_p, const int mk_index, const unsigned char *master_key, const time_t created_time)
650 {
651  TDE_KEYINFO keyinfo;
652  TDE_DATA_KEY_SET dks;
653  int err = NO_ERROR;
654 
655  if (!tde_Cipher.is_loaded)
656  {
659  return err;
660  }
661 
662  /* generate keyinfo from tde_Cipher and update heap (on Disk) */
663  err = tde_generate_keyinfo (&keyinfo, mk_index, master_key, created_time, &tde_Cipher.data_keys);
664  if (err != NO_ERROR)
665  {
666  return err;
667  }
668 
669  err = tde_update_keyinfo (thread_p, &keyinfo);
670  if (err != NO_ERROR)
671  {
672  return err;
673  }
674 
675  /* heap_flush() is mandatory. Without this, it cannot be guaranteed
676  * that the master key corresponding key info in heap exists in _keys file.
677  * By calling heap_flush at end of changing key, DBA can remove the previous key after it.
678  */
679  heap_flush (thread_p, &tde_Keyinfo_oid);
680 
681  return err;
682 }
683 
684 /*
685  * tde_load_mk () - Read a master key specified by keyinfo from the master key file and validate it
686  *
687  * return : Error code
688  * vdes (in) : Key file descriptor
689  * keyinfo (in) : Key info which contains the master key information to load
690  * master_key (out) : Master key
691  */
692 int
693 tde_load_mk (int vdes, const TDE_KEYINFO * keyinfo, unsigned char *master_key)
694 {
695  int err = NO_ERROR;
696  unsigned char mk[TDE_MASTER_KEY_LENGTH];
697  time_t created_time;
698 
699  assert (keyinfo->mk_index >= 0);
700 
701  err = tde_find_mk (vdes, keyinfo->mk_index, mk, &created_time);
702  if (err != NO_ERROR)
703  {
704  return err;
705  }
706 
707  /* MK has found */
708 
709  if (!(tde_validate_mk (mk, keyinfo->mk_hash) && created_time == keyinfo->created_time))
710  {
713  return err;
714  }
715  /* MK has validated */
716 
717  memcpy (master_key, mk, TDE_MASTER_KEY_LENGTH);
718 
719  return err;
720 }
721 
722 /*
723  * tde_load_dks () - Load data keys from keyinfo onto tde_Cipher
724  *
725  * return : Error code
726  * master_key (in) : Master key
727  * keyinfo (in) : Keyinfo which contains encrypted data keys
728  */
729 static int
730 tde_load_dks (const unsigned char *master_key, const TDE_KEYINFO * keyinfo)
731 {
732  int err = NO_ERROR;
733 
734  err = tde_decrypt_dk (keyinfo->dk_perm, TDE_DATA_KEY_TYPE_PERM, master_key, tde_Cipher.data_keys.perm_key);
735  if (err != NO_ERROR)
736  {
737  return err;
738  }
739  err = tde_decrypt_dk (keyinfo->dk_temp, TDE_DATA_KEY_TYPE_TEMP, master_key, tde_Cipher.data_keys.temp_key);
740  if (err != NO_ERROR)
741  {
742  return err;
743  }
744  err = tde_decrypt_dk (keyinfo->dk_log, TDE_DATA_KEY_TYPE_LOG, master_key, tde_Cipher.data_keys.log_key);
745  if (err != NO_ERROR)
746  {
747  return err;
748  }
749 
750  return err;
751 }
752 
753 /*
754  * tde_validate_mk () - Validate a master key by comparing with the hash value,
755  * usually with the hash value stored in tde key info heap
756  *
757  * return : Valid or not
758  * master_key (in) : Master key
759  * mk_hash (in) : Hash to be compared with the master key
760  */
761 static bool
762 tde_validate_mk (const unsigned char *master_key, const unsigned char *mk_hash)
763 {
764  unsigned char hash[SHA256_DIGEST_LENGTH];
765 
766  tde_make_mk_hash (master_key, hash);
767 
768  if (memcmp (mk_hash, hash, TDE_MASTER_KEY_LENGTH) != 0)
769  {
770  return false;
771  }
772  return true;
773 }
774 
775 /*
776  * tde_make_mk_hash () - Make a hash value to validate master key later
777  *
778  * master_key (in) : Master key
779  * mk_hash (out) : Hash value created with the master key
780  */
781 static void
782 tde_make_mk_hash (const unsigned char *master_key, unsigned char *mk_hash)
783 {
784  SHA256_CTX sha_ctx;
785 
786  assert (SHA256_DIGEST_LENGTH == TDE_MASTER_KEY_LENGTH);
787  assert (master_key != NULL);
788  assert (mk_hash != NULL);
789 
790  SHA256_Init (&sha_ctx);
791  SHA256_Update (&sha_ctx, master_key, TDE_MASTER_KEY_LENGTH);
792  SHA256_Final (mk_hash, &sha_ctx);
793 }
794 
795 /*
796  * tde_create_dk () - Create a data key
797  *
798  * return : Error code
799  * data_key (out) : Data key created
800  */
801 static int
802 tde_create_dk (unsigned char *data_key)
803 {
804  assert (data_key != NULL);
805 
806  if (RAND_bytes (data_key, TDE_DATA_KEY_LENGTH) != 1)
807  {
810  }
811 
812  return NO_ERROR;
813 }
814 
815 /*
816  * tde_encrypt_dk () - encrypt a data key to store a data key in stable storage,
817  * it has to be encrypted.
818  *
819  * return : error code
820  * dk_plain (in) : data key to encrypt
821  * dk_type (in) : data key type
822  * master_key (in) : a master key to encrypt the data key
823  * dk_cipher (out) : encrypted data key
824  */
825 static int
826 tde_encrypt_dk (const unsigned char *dk_plain, TDE_DATA_KEY_TYPE dk_type, const unsigned char *master_key,
827  unsigned char *dk_cipher)
828 {
829  unsigned char dk_nonce[TDE_DK_NONCE_LENGTH] = { 0, };
830 
831  tde_dk_nonce (dk_type, dk_nonce);
832 
833  return tde_encrypt_internal (dk_plain, TDE_DATA_KEY_LENGTH, TDE_DK_ALGORITHM, master_key, dk_nonce, dk_cipher);
834 }
835 
836 /*
837  * tde_decrypt_dk () - Decrypt a data key
838  *
839  * return : Error code
840  * dk_cipher (in) : Data key to decrypt
841  * dk_type (in) : Data key type
842  * master_key (in) : A master key to encrypt the data key
843  * dk_plain (out) : Decrypted data key
844  */
845 static int
846 tde_decrypt_dk (const unsigned char *dk_cipher, TDE_DATA_KEY_TYPE dk_type, const unsigned char *master_key,
847  unsigned char *dk_plain)
848 {
849  unsigned char dk_nonce[TDE_DK_NONCE_LENGTH] = { 0, };
850 
851  tde_dk_nonce (dk_type, dk_nonce);
852 
853  return tde_decrypt_internal (dk_cipher, TDE_DATA_KEY_LENGTH, TDE_DK_ALGORITHM, master_key, dk_nonce, dk_plain);
854 }
855 
856 /*
857  * tde_dk_nonce () - Get a data key nonce according to dk_type
858  *
859  * dk_type (in) : Data key type
860  * dk_nonce (out) : A nonce for dk_type
861  */
862 static inline void
863 tde_dk_nonce (TDE_DATA_KEY_TYPE dk_type, unsigned char *dk_nonce)
864 {
865  assert (dk_nonce != NULL);
866 
867  switch (dk_type)
868  {
870  memset (dk_nonce, 0, TDE_DK_NONCE_LENGTH);
871  break;
873  memset (dk_nonce, 1, TDE_DK_NONCE_LENGTH);
874  break;
876  memset (dk_nonce, 2, TDE_DK_NONCE_LENGTH);
877  break;
878  default:
879  assert (false);
880  break;
881  }
882 }
883 
884 /*
885  * tde_encrypt_data_page () - Encrypt a data page.
886  *
887  * return : Error code
888  * iopage_plain (in) : Data page to encrypt
889  * tde_algo (in) : Encryption algorithm
890  * is_temp (in) : Whether the page is for temp file
891  * iopage_cipher (out) : Encrpyted data page
892  *
893  * Nonce value for temporary file and permanent file are different.
894  */
895 int
896 tde_encrypt_data_page (const FILEIO_PAGE * iopage_plain, TDE_ALGORITHM tde_algo, bool is_temp,
897  FILEIO_PAGE * iopage_cipher)
898 {
899  int err = NO_ERROR;
900  unsigned char nonce[TDE_DATA_PAGE_NONCE_LENGTH] = { 0, };
901  const unsigned char *data_key;
902  int64_t tmp_nonce;
903 
904  if (tde_Cipher.is_loaded == false)
905  {
908  }
909 
910  if (is_temp)
911  {
912  // temporary file: atomic counter for nonce
913  data_key = tde_Cipher.data_keys.temp_key;
914  tmp_nonce = ATOMIC_INC_64 (&tde_Cipher.temp_write_counter, 1);
915  memcpy (nonce, &tmp_nonce, sizeof (tmp_nonce));
916  }
917  else
918  {
919  // permanent file: page lsa as nonce
920  data_key = tde_Cipher.data_keys.perm_key;
921  memcpy (nonce, &iopage_plain->prv.lsa, sizeof (iopage_plain->prv.lsa));
922  }
923 
924  /* copy FILEIO_PAGE_RESERVED */
925  memcpy (iopage_cipher, iopage_plain, TDE_DATA_PAGE_ENC_OFFSET);
926  /* copy FILEIO_PAGE_WATERMARK */
927  memcpy ((char *) iopage_cipher + TDE_DATA_PAGE_ENC_OFFSET + TDE_DATA_PAGE_ENC_LENGTH,
928  (char *) iopage_plain + TDE_DATA_PAGE_ENC_OFFSET + TDE_DATA_PAGE_ENC_LENGTH, sizeof (FILEIO_PAGE_WATERMARK));
929 
930  memcpy (&iopage_cipher->prv.tde_nonce, nonce, sizeof (iopage_cipher->prv.tde_nonce));
931 
932  err = tde_encrypt_internal (((const unsigned char *) iopage_plain) + TDE_DATA_PAGE_ENC_OFFSET,
933  TDE_DATA_PAGE_ENC_LENGTH, tde_algo, data_key, nonce,
934  ((unsigned char *) iopage_cipher) + TDE_DATA_PAGE_ENC_OFFSET);
935 
936  return err;
937 }
938 
939 /*
940  * tde_decrypt_data_page () - Decrypt a data page.
941  *
942  * return : Error code
943  * iopage_cipher (in) : Data page to decrypt
944  * tde_algo (in) : Encryption algorithm
945  * is_temp (in) : Whether the page is for temp file
946  * iopage_plain (out) : Decrypted data page
947  */
948 int
949 tde_decrypt_data_page (const FILEIO_PAGE * iopage_cipher, TDE_ALGORITHM tde_algo, bool is_temp,
950  FILEIO_PAGE * iopage_plain)
951 {
952  int err = NO_ERROR;
953  unsigned char nonce[TDE_DATA_PAGE_NONCE_LENGTH] = { 0, };
954  const unsigned char *data_key;
955 
956  if (tde_Cipher.is_loaded == false)
957  {
960  }
961 
962  if (is_temp)
963  {
964  // temporary file: atomic counter for nonce
965  data_key = tde_Cipher.data_keys.temp_key;
966  }
967  else
968  {
969  // permanent file: page lsa for nonce
970  data_key = tde_Cipher.data_keys.perm_key;
971  }
972 
973  /* copy FILEIO_PAGE_RESERVED */
974  memcpy (iopage_plain, iopage_cipher, TDE_DATA_PAGE_ENC_OFFSET);
975  /* copy FILEIO_PAGE_WATERMARK */
976  memcpy ((char *) iopage_plain + TDE_DATA_PAGE_ENC_OFFSET + TDE_DATA_PAGE_ENC_LENGTH,
977  (char *) iopage_cipher + TDE_DATA_PAGE_ENC_OFFSET + TDE_DATA_PAGE_ENC_LENGTH, sizeof (FILEIO_PAGE_WATERMARK));
978 
979  memcpy (nonce, &iopage_cipher->prv.tde_nonce, sizeof (iopage_cipher->prv.tde_nonce));
980 
981  err = tde_decrypt_internal (((const unsigned char *) iopage_cipher) + TDE_DATA_PAGE_ENC_OFFSET,
982  TDE_DATA_PAGE_ENC_LENGTH, tde_algo, data_key, nonce,
983  ((unsigned char *) iopage_plain) + TDE_DATA_PAGE_ENC_OFFSET);
984 
985  return err;
986 }
987 
988 /*
989  * tde_encrypt_log_page () - Encrypt a log page.
990  *
991  * return : Error code
992  * iopage_plain (in) : Log page to encrypt
993  * tde_algo (in) : Encryption algorithm
994  * iopage_cipher (out) : Encrpyted log page
995  */
996 int
997 tde_encrypt_log_page (const LOG_PAGE * logpage_plain, TDE_ALGORITHM tde_algo, LOG_PAGE * logpage_cipher)
998 {
999  unsigned char nonce[TDE_LOG_PAGE_NONCE_LENGTH] = { 0, };
1000  const unsigned char *data_key;
1001 
1002  if (tde_Cipher.is_loaded == false)
1003  {
1006  }
1007 
1008  data_key = tde_Cipher.data_keys.log_key;
1009 
1010  memcpy (nonce, &logpage_plain->hdr.logical_pageid, sizeof (logpage_plain->hdr.logical_pageid));
1011  memcpy (logpage_cipher, logpage_plain, TDE_LOG_PAGE_ENC_OFFSET);
1012 
1013  return tde_encrypt_internal (((const unsigned char *) logpage_plain) + TDE_LOG_PAGE_ENC_OFFSET,
1014  TDE_LOG_PAGE_ENC_LENGTH, tde_algo, data_key, nonce,
1015  ((unsigned char *) logpage_cipher) + TDE_LOG_PAGE_ENC_OFFSET);
1016 }
1017 
1018 /*
1019  * tde_decrypt_log_page () - Decrypt a log page.
1020  *
1021  * return : Error code
1022  * iopage_cipher (in) : Log page to decrypt
1023  * tde_algo (in) : Encryption algorithm
1024  * iopage_plain (out) : Decrpyted log page
1025  */
1026 int
1027 tde_decrypt_log_page (const LOG_PAGE * logpage_cipher, TDE_ALGORITHM tde_algo, LOG_PAGE * logpage_plain)
1028 {
1029  unsigned char nonce[TDE_LOG_PAGE_NONCE_LENGTH] = { 0, };
1030  const unsigned char *data_key;
1031 
1032  if (tde_Cipher.is_loaded == false)
1033  {
1036  }
1037 
1038  data_key = tde_Cipher.data_keys.log_key;
1039 
1040  memcpy (nonce, &logpage_cipher->hdr.logical_pageid, sizeof (logpage_cipher->hdr.logical_pageid));
1041  memcpy (logpage_plain, logpage_cipher, TDE_LOG_PAGE_ENC_OFFSET);
1042 
1043  return tde_decrypt_internal (((const unsigned char *) logpage_cipher) + TDE_LOG_PAGE_ENC_OFFSET,
1044  TDE_LOG_PAGE_ENC_LENGTH, tde_algo, data_key, nonce,
1045  ((unsigned char *) logpage_plain) + TDE_LOG_PAGE_ENC_OFFSET);
1046 }
1047 
1048 /*
1049  * tde_encrypt_internal () - Gerneral encryption function
1050  *
1051  * return : Error code
1052  * plain_buffer (in) : Data to encrypt
1053  * length (in) : The length of data
1054  * tde_algo (in) : Encryption algorithm
1055  * key (in) : key
1056  * nonce (in) : nonce, which has to be unique in time and space
1057  * cipher_buffer (out) : Encrypted data
1058  *
1059  * plain_buffer and cipher_buffer has more space than length
1060  */
1061 static int
1062 tde_encrypt_internal (const unsigned char *plain_buffer, int length, TDE_ALGORITHM tde_algo, const unsigned char *key,
1063  const unsigned char *nonce, unsigned char *cipher_buffer)
1064 {
1065  EVP_CIPHER_CTX *ctx;
1066  const EVP_CIPHER *cipher_type;
1067  int len;
1068  int cipher_len;
1070 
1071  if ((ctx = EVP_CIPHER_CTX_new ()) == NULL)
1072  {
1073  goto exit;
1074  }
1075 
1076  switch (tde_algo)
1077  {
1078  case TDE_ALGORITHM_AES:
1079  cipher_type = EVP_aes_256_ctr ();
1080  break;
1081  case TDE_ALGORITHM_ARIA:
1082  cipher_type = EVP_aria_256_ctr ();
1083  break;
1084  case TDE_ALGORITHM_NONE:
1085  default:
1086  assert (false);
1087  goto cleanup;
1088  }
1089 
1090  if (EVP_EncryptInit_ex (ctx, cipher_type, NULL, key, nonce) != 1)
1091  {
1092  goto cleanup;
1093  }
1094 
1095  if (EVP_EncryptUpdate (ctx, cipher_buffer, &len, plain_buffer, length) != 1)
1096  {
1097  goto cleanup;
1098  }
1099  cipher_len = len;
1100 
1101  // Further ciphertext bytes may be written at finalizing (Partial block).
1102 
1103  if (EVP_EncryptFinal_ex (ctx, cipher_buffer + len, &len) != 1)
1104  {
1105  goto cleanup;
1106  }
1107 
1108  cipher_len += len;
1109 
1110  // CTR_MODE is stream mode so that there is no need to check,
1111  // but check it for safe.
1112  assert (cipher_len == length);
1113 
1114  err = NO_ERROR;
1115 
1116 cleanup:
1117  EVP_CIPHER_CTX_free (ctx);
1118 
1119 exit:
1120  if (err != NO_ERROR)
1121  {
1123  }
1124  return err;
1125 }
1126 
1127 /*
1128  * tde_decrypt_internal () - Gerneral decryption function
1129  *
1130  * return : Error code
1131  * cipher_buffer (in) : Data to decrypt
1132  * length (in) : The length of data
1133  * tde_algo (in) : Encryption algorithm
1134  * key (in) : key
1135  * nonce (in) : nonce used during encryption
1136  * plain_buffer (out) : Decrypted data
1137  *
1138  * plain_buffer and cipher_buffer has more space than length
1139  */
1140 static int
1141 tde_decrypt_internal (const unsigned char *cipher_buffer, int length, TDE_ALGORITHM tde_algo, const unsigned char *key,
1142  const unsigned char *nonce, unsigned char *plain_buffer)
1143 {
1144  EVP_CIPHER_CTX *ctx;
1145  const EVP_CIPHER *cipher_type;
1146  int len;
1147  int plain_len;
1149 
1150  if ((ctx = EVP_CIPHER_CTX_new ()) == NULL)
1151  {
1152  goto exit;
1153  }
1154 
1155  switch (tde_algo)
1156  {
1157  case TDE_ALGORITHM_AES:
1158  cipher_type = EVP_aes_256_ctr ();
1159  break;
1160  case TDE_ALGORITHM_ARIA:
1161  cipher_type = EVP_aria_256_ctr ();
1162  break;
1163  case TDE_ALGORITHM_NONE:
1164  default:
1165  assert (false);
1166  goto cleanup;
1167  }
1168 
1169  if (EVP_DecryptInit_ex (ctx, cipher_type, NULL, key, nonce) != 1)
1170  {
1171  goto cleanup;
1172  }
1173 
1174  if (EVP_DecryptUpdate (ctx, plain_buffer, &len, cipher_buffer, length) != 1)
1175  {
1176  goto cleanup;
1177  }
1178  plain_len = len;
1179 
1180  // Further plaintext bytes may be written at finalizing (Partial block).
1181  if (EVP_DecryptFinal_ex (ctx, plain_buffer + len, &len) != 1)
1182  {
1183  goto cleanup;
1184  }
1185  plain_len += len;
1186 
1187  // CTR_MODE is stream mode so that there is no need to check,
1188  // but check it for safe.
1189  assert (plain_len == length);
1190 
1191  err = NO_ERROR;
1192 
1193 cleanup:
1194  EVP_CIPHER_CTX_free (ctx);
1195 
1196 exit:
1197  if (err != NO_ERROR)
1198  {
1200  }
1201  return err;
1202 }
1203 
1204 /*
1205  * xtde_get_mk_info () - Get some information of the master key set on the database
1206  *
1207  * return : Error code
1208  * thread_p (in) : Thread entry
1209  * mk_index (out) : Index of the master key in the master key file
1210  * created_time (out) : Creation time of the master key
1211  * set_time (out) : Set time of the master key
1212  */
1213 int
1214 xtde_get_mk_info (THREAD_ENTRY * thread_p, int *mk_index, time_t * created_time, time_t * set_time)
1215 {
1216  TDE_KEYINFO keyinfo;
1217  int err = NO_ERROR;
1218 
1219  if (!tde_Cipher.is_loaded)
1220  {
1223  }
1224 
1225  err = tde_get_keyinfo (thread_p, &keyinfo);
1226  if (err != NO_ERROR)
1227  {
1228  return err;
1229  }
1230  *mk_index = keyinfo.mk_index;
1231  *created_time = keyinfo.created_time;
1232  *set_time = keyinfo.set_time;
1233 
1234  return err;
1235 }
1236 
1237 /*
1238  * xtde_change_mk_without_flock () - Change the master key on the database.
1239  * While changing, it mounts the key file without file lock.
1240  *
1241  * return : Error code
1242  * thread_p (in) : Thread entry
1243  * mk_index (in) : Index of the master key to set
1244  */
1245 int
1246 xtde_change_mk_without_flock (THREAD_ENTRY * thread_p, const int mk_index)
1247 {
1248  char mk_path[PATH_MAX] = { 0, };
1249  TDE_KEYINFO keyinfo;
1250  unsigned char master_key[TDE_MASTER_KEY_LENGTH] = { 0, };
1251  time_t created_time;
1252  int vdes;
1253  int err = NO_ERROR;
1254 
1255  tde_make_keys_file_fullname (mk_path, boot_db_full_name (), false);
1256 
1257  /* Without file lock: It is because it must've already been locked in client-side: tde() */
1258  vdes = fileio_open (mk_path, O_RDONLY, 0);
1259  if (vdes == NULL_VOLDES)
1260  {
1262  return ER_IO_MOUNT_FAIL;
1263  }
1264 
1265  err = tde_find_mk (vdes, mk_index, master_key, &created_time);
1266  if (err != NO_ERROR)
1267  {
1268  goto exit;
1269  }
1270 
1271  err = tde_get_keyinfo (thread_p, &keyinfo);
1272  if (err != NO_ERROR)
1273  {
1274  goto exit;
1275  }
1276 
1277  /* if the same key with the key set on the database */
1278  if (mk_index == keyinfo.mk_index && tde_validate_mk (master_key, keyinfo.mk_hash))
1279  {
1280  goto exit;
1281  }
1282 
1283  /* The previous key has to exist */
1284  err = tde_find_mk (vdes, keyinfo.mk_index, NULL, NULL);
1285  if (err != NO_ERROR)
1286  {
1287  goto exit;
1288  }
1289 
1290  err = tde_change_mk (thread_p, mk_index, master_key, created_time);
1291  if (err != NO_ERROR)
1292  {
1293  goto exit;
1294  }
1295 
1296 exit:
1297  fileio_close (vdes);
1298  return err;
1299 }
1300 
1301 #endif /* !CS_MODE */
1302 
1303 /*
1304  * tde_create_mk () - Create a master key
1305  *
1306  * return : Error code
1307  * master_key (out) : Created master key
1308  * created_time (out) : The time the key created
1309  */
1310 int
1311 tde_create_mk (unsigned char *master_key, time_t * created_time)
1312 {
1313  assert (master_key != NULL);
1314 
1315  if (RAND_bytes (master_key, TDE_MASTER_KEY_LENGTH) != 1)
1316  {
1318  return ER_TDE_KEY_CREATION_FAIL;
1319  }
1320 
1321  *created_time = time (NULL);
1322 
1323  return NO_ERROR;
1324 }
1325 
1326 /*
1327  * tde_print_mk () - Print a master key value
1328  *
1329  * master_key (out) : Master key to print
1330  */
1331 void
1332 tde_print_mk (const unsigned char *master_key)
1333 {
1334  int i;
1335  for (i = 0; i < TDE_MASTER_KEY_LENGTH; i++)
1336  {
1337  printf ("%02x", master_key[i]);
1338  }
1339 }
1340 
1341 /*
1342  * tde_add_mk () - Add a master key to the master key file
1343  *
1344  * return : Error code
1345  * vdes (in) : Key file descriptor
1346  * master_key (in) : A master key to add
1347  * created_time (in) : When the master key was created
1348  * mk_index (out) : The assigend index for the master key to add
1349  */
1350 int
1351 tde_add_mk (int vdes, const unsigned char *master_key, time_t created_time, int *mk_index)
1352 {
1353  TDE_MK_FILE_ITEM adding_item;
1354  TDE_MK_FILE_ITEM reading_item;
1355  int location = 0;
1356  int err = NO_ERROR;
1357  int ret;
1358 #if !defined(WINDOWS)
1359  sigset_t new_mask, old_mask;
1360  off_signals (new_mask, old_mask);
1361 #endif /* !WINDOWS */
1362 
1363  if (lseek (vdes, TDE_MK_FILE_CONTENTS_START, SEEK_SET) != TDE_MK_FILE_CONTENTS_START)
1364  {
1365  err = ER_FAILED;
1366  goto exit;
1367  }
1368 
1369  adding_item.created_time = created_time;
1370  memcpy (adding_item.master_key, master_key, TDE_MASTER_KEY_LENGTH);
1371 
1372  while (true)
1373  {
1374  ret = read (vdes, &reading_item, TDE_MK_FILE_ITEM_SIZE);
1375  if (ret < 0)
1376  {
1377  err = ER_IO_READ;
1379  fileio_get_volume_label_by_fd (vdes, PEEK), -1);
1380  goto exit;
1381  }
1382  else if (ret == 0)
1383  {
1384  break; /* EOF */
1385  }
1386  else if (ret != TDE_MK_FILE_ITEM_SIZE)
1387  {
1391  goto exit;
1392  }
1393 
1394  if (reading_item.created_time == -1)
1395  {
1396  /* invalid item, which means available space */
1397  lseek (vdes, -TDE_MK_FILE_ITEM_SIZE, SEEK_CUR);
1398  break;
1399  }
1400  }
1401 
1402  location = lseek (vdes, 0, SEEK_CUR);
1403 
1405  {
1406  err = ER_TDE_MAX_KEY_FILE;
1408  goto exit;
1409  }
1410  else
1411  {
1412  *mk_index = TDE_MK_FILE_ITEM_INDEX (location);
1413  }
1414 
1415  /* add key */
1416  write (vdes, &adding_item, TDE_MK_FILE_ITEM_SIZE);
1417 
1418  fsync (vdes);
1419 exit:
1420 #if !defined(WINDOWS)
1421  restore_signals (old_mask);
1422 #endif /* !WINDOWS */
1423 
1424  return err;
1425 }
1426 
1427 /*
1428  * tde_find_mk () - Find a master key in the master key file
1429  *
1430  * return : Error code
1431  * vdes (in) : Key file descriptor
1432  * mk_index (in) : Index of the master key to find
1433  * master_key (out) : The master key to add
1434  * created_time (out) : When the master key was created
1435  */
1436 int
1437 tde_find_mk (int vdes, int mk_index, unsigned char *master_key, time_t * created_time)
1438 {
1439  bool found;
1440  int location;
1441  TDE_MK_FILE_ITEM item;
1442 
1443 #if !defined(WINDOWS)
1444  sigset_t new_mask, old_mask;
1445  off_signals (new_mask, old_mask);
1446 #endif /* !WINDOWS */
1447 
1448  location = TDE_MK_FILE_ITEM_OFFSET (mk_index);
1449 
1450  if (lseek (vdes, location, SEEK_SET) != location)
1451  {
1452  found = false;
1453  goto exit; /* not found */
1454  }
1455 
1456  if (read (vdes, &item, TDE_MK_FILE_ITEM_SIZE) != TDE_MK_FILE_ITEM_SIZE)
1457  {
1458  found = false;
1459  goto exit;
1460  }
1461 
1462  if (item.created_time == -1)
1463  {
1464  found = false;
1465  goto exit;
1466  }
1467 
1468  if (master_key != NULL)
1469  {
1470  memcpy (master_key, item.master_key, TDE_MASTER_KEY_LENGTH);
1471  }
1472 
1473  if (created_time != NULL)
1474  {
1475  *created_time = item.created_time;
1476  }
1477 
1478  found = true;
1479 
1480 exit:
1481 #if !defined(WINDOWS)
1482  restore_signals (old_mask);
1483 #endif /* !WINDOWS */
1484 
1485  if (!found)
1486  {
1489  }
1490 
1491  return NO_ERROR;
1492 }
1493 
1494 /*
1495  * tde_find_first_mk () - Find the first master key in the master key file
1496  *
1497  * return : Error code
1498  * vdes (in) : Key file descriptor
1499  * mk_index (out) : Index of the master key first met
1500  * master_key (out) : The master key to be found
1501  * created_time (out) : When the master key was created
1502  */
1503 int
1504 tde_find_first_mk (int vdes, int *mk_index, unsigned char *master_key, time_t * created_time)
1505 {
1506  TDE_MK_FILE_ITEM item;
1507  int location;
1508  int index = 0;
1509  int err = NO_ERROR;
1510  int ret;
1511 
1512 #if !defined(WINDOWS)
1513  sigset_t new_mask, old_mask;
1514  off_signals (new_mask, old_mask);
1515 #endif /* !WINDOWS */
1516 
1517  location = TDE_MK_FILE_ITEM_OFFSET (0);
1518 
1519  if (lseek (vdes, location, SEEK_SET) != location)
1520  {
1521  err = ER_FAILED;
1522  goto exit; /* not found */
1523  }
1524 
1525  while (true)
1526  {
1527  ret = read (vdes, &item, TDE_MK_FILE_ITEM_SIZE);
1528  if (ret < 0)
1529  {
1530  err = ER_IO_READ;
1532  fileio_get_volume_label_by_fd (vdes, PEEK), -1);
1533  goto exit;
1534  }
1535  else if (ret != TDE_MK_FILE_ITEM_SIZE)
1536  {
1537  /* The file has been crashed, or the key is not found and EOF. */
1541  goto exit;
1542  }
1543 
1544  if (item.created_time != -1)
1545  {
1546  *mk_index = index;
1547  *created_time = item.created_time;
1548  memcpy (master_key, item.master_key, TDE_MASTER_KEY_LENGTH);
1549  break;
1550  }
1551  index++;
1552  }
1553 
1554 exit:
1555 #if !defined(WINDOWS)
1556  restore_signals (old_mask);
1557 #endif /* !WINDOWS */
1558  return err;
1559 }
1560 
1561 /*
1562  * tde_delete_mk () - Delete a master key in the master key file
1563  *
1564  * return : Error code
1565  * vdes (in) : Key file descriptor
1566  * mk_index (in) : Index of the master key to delete
1567  */
1568 int
1569 tde_delete_mk (int vdes, int mk_index)
1570 {
1571  bool found;
1572  int location;
1573  TDE_MK_FILE_ITEM item;
1574 
1575 #if !defined(WINDOWS)
1576  sigset_t new_mask, old_mask;
1577  off_signals (new_mask, old_mask);
1578 #endif /* !WINDOWS */
1579 
1580  location = TDE_MK_FILE_ITEM_OFFSET (mk_index);
1581 
1582  if (lseek (vdes, location, SEEK_SET) != location)
1583  {
1584  found = false;
1585  goto exit; /* not found */
1586  }
1587 
1588  if (read (vdes, &item, TDE_MK_FILE_ITEM_SIZE) != TDE_MK_FILE_ITEM_SIZE)
1589  {
1590  found = false;
1591  goto exit;
1592  }
1593 
1594  if (item.created_time == -1)
1595  {
1596  found = false;
1597  goto exit;
1598  }
1599 
1600  item.created_time = -1; /* mark it invalid */
1601 
1602  lseek (vdes, -TDE_MK_FILE_ITEM_SIZE, SEEK_CUR);
1603  write (vdes, &item, TDE_MK_FILE_ITEM_SIZE);
1604  fsync (vdes);
1605  found = true;
1606 
1607 exit:
1608 #if !defined(WINDOWS)
1609  restore_signals (old_mask);
1610 #endif /* !WINDOWS */
1611 
1612  if (!found)
1613  {
1616  }
1617 
1618  return NO_ERROR;
1619 }
1620 
1621 /*
1622  * tde_find_mk () - Dump master keys in a master key file
1623  *
1624  * return : Error code
1625  * vdes (in) : Key file descriptor
1626  * print_value (in) : Wheter to print key value
1627  */
1628 int
1629 tde_dump_mks (int vdes, bool print_value)
1630 {
1631  TDE_MK_FILE_ITEM item;
1632  int cnt_valid = 0;
1633  int cnt_invalid = 0;
1634  int location;
1635  int i;
1636  char ctime_buf[CTIME_MAX] = { 0, };
1637 #if !defined(WINDOWS)
1638  sigset_t new_mask, old_mask;
1639  off_signals (new_mask, old_mask);
1640 #endif /* !WINDOWS */
1641 
1642  if ((location = lseek (vdes, TDE_MK_FILE_CONTENTS_START, SEEK_SET)) != TDE_MK_FILE_CONTENTS_START)
1643  {
1644  return ER_FAILED;
1645  }
1646 
1647  printf ("Keys Information: \n");
1648 
1649  while (true)
1650  {
1651  if (read (vdes, &item, TDE_MK_FILE_ITEM_SIZE) != TDE_MK_FILE_ITEM_SIZE)
1652  {
1653  break; /* EOF */
1654  }
1655 
1656  if (item.created_time == -1)
1657  {
1658  cnt_invalid++;
1659  }
1660  else
1661  {
1662  cnt_valid++;
1663  ctime_r (&item.created_time, ctime_buf);
1664  printf ("Key Index: %lu ", TDE_MK_FILE_ITEM_INDEX (location));
1665  printf ("created on %s", ctime_buf);
1666  if (print_value)
1667  {
1668  printf ("Key: ");
1669  tde_print_mk (item.master_key);
1670  printf ("\n");
1671  }
1672  }
1673  location += TDE_MK_FILE_ITEM_SIZE;
1674  }
1675  printf ("\n");
1676 
1677 exit:
1678  printf ("The number of keys: %d\n", cnt_valid);
1679 
1680 #if !defined(WINDOWS)
1681  restore_signals (old_mask);
1682 #endif /* !WINDOWS */
1683  return NO_ERROR;
1684 }
1685 
1686 /*
1687  * tde_get_algorithm_name () - Convert TDE_ALGORITHM to corresponding string
1688  *
1689  * return : String version of tde_algo. NULL means it is not valid
1690  * tde_algo (in) : Encryption algorithm
1691  *
1692  */
1693 const char *
1695 {
1696  switch (tde_algo)
1697  {
1698  case TDE_ALGORITHM_NONE:
1699  return "NONE";
1700  case TDE_ALGORITHM_AES:
1701  return "AES";
1702  case TDE_ALGORITHM_ARIA:
1703  return "ARIA";
1704  default:
1705  return NULL;
1706  }
1707 }
#define OID_INITIALIZER
Definition: oid.h:36
time_t set_time
Definition: tde.h:162
int xtde_get_mk_info(THREAD_ENTRY *thread_p, int *mk_index, time_t *created_time, time_t *set_time)
Definition: tde.c:1214
OID * oid_Root_class_oid
Definition: oid.c:73
int mk_index
Definition: tde.h:160
#define NO_ERROR
Definition: error_code.h:46
static int tde_update_keyinfo(THREAD_ENTRY *thread_p, const TDE_KEYINFO *keyinfo)
Definition: tde.c:595
int area_size
void fileio_unformat_and_rename(THREAD_ENTRY *thread_p, const char *vol_label_p, const char *new_label_p)
Definition: file_io.c:2736
#define TDE_MK_FILE_ITEM_OFFSET(index)
Definition: tde.h:60
#define ASSERT_ERROR()
SCAN_CODE
#define HFID_INITIALIZER
#define ER_TDE_INVALID_MASTER_KEY
Definition: error_code.h:1610
int heap_scancache_start_modify(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache, const HFID *hfid, const OID *class_oid, int op_type, MVCC_SNAPSHOT *mvcc_snapshot)
Definition: heap_file.c:6867
#define TDE_MK_FILE_ITEM_INDEX(offset)
Definition: tde.h:62
#define TDE_DATA_PAGE_ENC_LENGTH
Definition: tde.h:44
#define ER_FAILED
Definition: error_code.h:47
void fileio_make_keys_name_given_path(char *keys_name_p, const char *keys_path_p, const char *db_name_p)
Definition: file_io.c:5914
static int tde_create_dk(unsigned char *data_key)
Definition: tde.c:802
LOG_HDRPAGE hdr
Definition: log_storage.hpp:84
#define TDE_DATA_PAGE_NONCE_LENGTH
Definition: tde.h:49
#define ER_TDE_MAX_KEY_FILE
Definition: error_code.h:1622
#define ASSERT_ERROR_AND_SET(error_code)
int xtde_change_mk_without_flock(THREAD_ENTRY *thread_p, const int mk_index)
Definition: tde.c:1246
static bool tde_validate_mk(const unsigned char *master_key, const unsigned char *mk_hash)
Definition: tde.c:762
int tde_initialize(THREAD_ENTRY *thread_p, HFID *keyinfo_hfid)
Definition: tde.c:106
#define TDE_LOG_PAGE_ENC_OFFSET
Definition: tde.h:45
char * data
#define off_signals(new_mask, old_mask)
Definition: tde.c:56
bool fileio_is_volume_exist(const char *vol_label_p)
Definition: file_io.c:5094
int er_errid(void)
int64_t temp_write_counter
Definition: tde.h:150
static int tde_load_dks(const unsigned char *master_key, const TDE_KEYINFO *keyinfo)
Definition: tde.c:730
time_t created_time
Definition: tde.h:161
const VOLID LOG_DBCOPY_VOLID
Definition: log_volids.hpp:55
int heap_scancache_end(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache)
Definition: heap_file.c:7195
char * fileio_get_volume_label_by_fd(int vol_fd, bool is_peek)
Definition: file_io.c:6254
#define NULL_VOLDES
Definition: file_io.h:44
#define COPY_OID(dest_oid_ptr, src_oid_ptr)
Definition: oid.h:63
int fileio_mount(THREAD_ENTRY *thread_p, const char *db_full_name_p, const char *vol_label_p, VOLID vol_id, int lock_wait, bool is_do_sync)
Definition: file_io.c:2957
#define ER_TDE_ENCRYPTION_ERROR
Definition: error_code.h:1611
static int tde_encrypt_internal(const unsigned char *plain_buffer, int length, TDE_ALGORITHM tde_algo, const unsigned char *key, const unsigned char *nonce, unsigned char *cipher_buffer)
Definition: tde.c:1062
const char * er_get_msglog_filename(void)
int tde_delete_mk(int vdes, int mk_index)
Definition: tde.c:1569
void THREAD_ENTRY
#define ER_BO_CANNOT_CREATE_VOL
Definition: error_code.h:184
HEAP_SCANCACHE_NODE node
Definition: heap_file.h:144
#define ER_BO_VOLUME_EXISTS
Definition: error_code.h:185
#define ER_IO_READ
Definition: error_code.h:62
#define TDE_DATA_PAGE_ENC_OFFSET
Definition: tde.h:43
const char * tde_get_algorithm_name(TDE_ALGORITHM tde_algo)
Definition: tde.c:1694
const char * boot_db_full_name()
Definition: boot_sr.c:470
#define TDE_LOG_PAGE_ENC_LENGTH
Definition: tde.h:46
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
const char * fileio_get_base_file_name(const char *full_name_p)
Definition: file_io.c:5533
#define assert(x)
TDE_ALGORITHM
Definition: tde.h:71
static void tde_dk_nonce(TDE_DATA_KEY_TYPE dk_type, unsigned char *dk_nonce)
Definition: tde.c:863
#define TDE_DK_ALGORITHM
Definition: tde.h:40
void fileio_close(int vol_fd)
Definition: file_io.c:2078
#define TDE_DATA_KEY_LENGTH
Definition: tde.h:55
#define CUBRID_MAGIC_MAX_LENGTH
int tde_add_mk(int vdes, const unsigned char *master_key, time_t created_time, int *mk_index)
Definition: tde.c:1351
TDE_CIPHER tde_Cipher
Definition: tde.c:69
static int tde_encrypt_dk(const unsigned char *dk_plain, TDE_DATA_KEY_TYPE dk_type, const unsigned char *master_key, unsigned char *dk_cipher)
Definition: tde.c:826
#define SINGLE_ROW_UPDATE
Definition: btree.h:54
#define restore_signals(old_mask)
Definition: tde.c:66
void tde_print_mk(const unsigned char *master_key)
Definition: tde.c:1332
int heap_update_logical(THREAD_ENTRY *thread_p, HEAP_OPERATION_CONTEXT *context)
Definition: heap_file.c:22771
void tde_make_keys_file_fullname(char *keys_vol_fullname, const char *db_full_name, bool ignore_parm)
Definition: tde.c:492
void heap_create_update_context(HEAP_OPERATION_CONTEXT *context, HFID *hfid_p, OID *oid_p, OID *class_oid_p, RECDES *recdes_p, HEAP_SCANCACHE *scancache_p, UPDATE_INPLACE_STYLE in_place)
Definition: heap_file.c:22378
LOG_PAGEID logical_pageid
Definition: log_storage.hpp:65
void heap_create_insert_context(HEAP_OPERATION_CONTEXT *context, HFID *hfid_p, OID *class_oid_p, RECDES *recdes_p, HEAP_SCANCACHE *scancache_p)
Definition: heap_file.c:22324
unsigned char perm_key[TDE_DATA_KEY_LENGTH]
Definition: tde.h:87
int tde_get_keyinfo(THREAD_ENTRY *thread_p, TDE_KEYINFO *keyinfo)
Definition: tde.c:557
void fileio_dismount(THREAD_ENTRY *thread_p, int vol_fd)
Definition: file_io.c:3134
time_t created_time
Definition: tde.h:94
int heap_insert_logical(THREAD_ENTRY *thread_p, HEAP_OPERATION_CONTEXT *context, PGBUF_WATCHER *home_hint_p)
Definition: heap_file.c:22426
int tde_create_mk(unsigned char *master_key, time_t *created_time)
Definition: tde.c:1311
static OID tde_Keyinfo_oid
Definition: tde.c:71
static void cleanup(int signo)
Definition: broker.c:717
#define NULL
Definition: freelistheap.h:34
#define CTIME_MAX
Definition: porting.h:72
static int tde_decrypt_internal(const unsigned char *cipher_buffer, int length, TDE_ALGORITHM tde_algo, const unsigned char *key, const unsigned char *nonce, unsigned char *plain_buffer)
Definition: tde.c:1141
static int tde_decrypt_dk(const unsigned char *dk_cipher, TDE_DATA_KEY_TYPE dk_type, const unsigned char *master_key, unsigned char *dk_plain)
Definition: tde.c:846
#define ER_IO_MOUNT_FAIL
Definition: error_code.h:59
#define err(fd,...)
Definition: porting.h:431
int tde_find_mk(int vdes, int mk_index, unsigned char *master_key, time_t *created_time)
Definition: tde.c:1437
int tde_find_first_mk(int vdes, int *mk_index, unsigned char *master_key, time_t *created_time)
Definition: tde.c:1504
int tde_change_mk(THREAD_ENTRY *thread_p, const int mk_index, const unsigned char *master_key, const time_t created_time)
Definition: tde.c:649
unsigned char mk_hash[TDE_MASTER_KEY_LENGTH]
Definition: tde.h:163
#define TDE_MK_FILE_CONTENTS_START
Definition: tde.h:58
void er_set_with_oserror(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
void fileio_make_keys_name(char *keys_name_p, const char *db_full_name_p)
Definition: file_io.c:5897
int tde_load_mk(int vdes, const TDE_KEYINFO *keyinfo, unsigned char *master_key)
Definition: tde.c:693
#define ER_IO_WRITE
Definition: error_code.h:63
SCAN_CODE heap_first(THREAD_ENTRY *thread_p, const HFID *hfid, OID *class_oid, OID *oid, RECDES *recdes, HEAP_SCANCACHE *scan_cache, int ispeeking)
Definition: heap_file.c:8097
static HFID tde_Keyinfo_hfid
Definition: tde.c:72
unsigned char dk_perm[TDE_DATA_KEY_LENGTH]
Definition: tde.h:164
#define TDE_MK_FILE_ITEM_SIZE
Definition: tde.h:59
#define HFID_IS_NULL(hfid)
static void tde_make_mk_hash(const unsigned char *master_key, unsigned char *mk_hash)
Definition: tde.c:782
#define ARG_FILE_LINE
Definition: error_manager.h:44
const VOLID LOG_DBTDE_KEYS_VOLID
Definition: log_volids.hpp:41
static const bool COPY
bool tde_validate_keys_file(int vdes)
Definition: tde.c:358
unsigned char temp_key[TDE_DATA_KEY_LENGTH]
Definition: tde.h:88
int tde_cipher_initialize(THREAD_ENTRY *thread_p, const HFID *keyinfo_hfid, const char *mk_path_given)
Definition: tde.c:232
#define ER_TDE_KEY_CREATION_FAIL
Definition: error_code.h:1614
int heap_scancache_quick_start_with_class_hfid(THREAD_ENTRY *thread_p, HEAP_SCANCACHE *scan_cache, const HFID *hfid)
Definition: heap_file.c:19308
int tde_decrypt_data_page(const FILEIO_PAGE *iopage_cipher, TDE_ALGORITHM tde_algo, bool is_temp, FILEIO_PAGE *iopage_plain)
Definition: tde.c:949
static void print_value(FIELD_NAME name, const void *value, FIELD_TYPE type)
char * prm_get_string_value(PARAM_ID prm_id)
int tde_copy_keys_file(THREAD_ENTRY *thread_p, const char *dest_fullname, const char *src_fullname, bool keep_dest_mount, bool keep_src_mount)
Definition: tde.c:398
unsigned char dk_temp[TDE_DATA_KEY_LENGTH]
Definition: tde.h:165
#define TDE_DK_NONCE_LENGTH
Definition: tde.h:51
bool is_loaded
Definition: tde.h:148
enum tde_data_key_type TDE_DATA_KEY_TYPE
void heap_flush(THREAD_ENTRY *thread_p, const OID *oid)
Definition: heap_file.c:5974
int i
Definition: dynamic_load.c:954
TDE_DATA_KEY_SET data_keys
Definition: tde.h:149
#define ER_TDE_DECRYPTION_ERROR
Definition: error_code.h:1612
INT16 type
#define ER_TDE_MASTER_KEY_NOT_FOUND
Definition: error_code.h:1609
unsigned char log_key[TDE_DATA_KEY_LENGTH]
Definition: tde.h:89
#define TDE_LOG_PAGE_NONCE_LENGTH
Definition: tde.h:50
#define ER_TDE_INVALID_KEYS_FILE
Definition: error_code.h:1608
static int tde_create_keys_file(const char *keyfile_fullname)
Definition: tde.c:309
#define OID_ISNULL(oidp)
Definition: oid.h:81
#define TDE_MK_FILE_ITEM_COUNT_MAX
Definition: tde.h:65
#define CUBRID_MAGIC_KEYS
int tde_encrypt_data_page(const FILEIO_PAGE *iopage_plain, TDE_ALGORITHM tde_algo, bool is_temp, FILEIO_PAGE *iopage_cipher)
Definition: tde.c:896
FILEIO_PAGE_RESERVED prv
Definition: file_io.h:194
unsigned char master_key[TDE_MASTER_KEY_LENGTH]
Definition: tde.h:95
#define ER_TDE_CIPHER_IS_NOT_LOADED
Definition: error_code.h:1613
#define PEEK
Definition: file_io.h:74
int tde_decrypt_log_page(const LOG_PAGE *logpage_cipher, TDE_ALGORITHM tde_algo, LOG_PAGE *logpage_plain)
Definition: tde.c:1027
int tde_dump_mks(int vdes, bool print_value)
Definition: tde.c:1629
int fileio_open(const char *vol_label_p, int flags, int mode)
Definition: file_io.c:1957
#define HFID_COPY(hfid_ptr1, hfid_ptr2)
unsigned char dk_log[TDE_DATA_KEY_LENGTH]
Definition: tde.h:166
#define TDE_MASTER_KEY_LENGTH
Definition: tde.h:54
static int tde_generate_keyinfo(TDE_KEYINFO *keyinfo, int mk_index, const unsigned char *master_key, const time_t created_time, const TDE_DATA_KEY_SET *dks)
Definition: tde.c:520
int tde_encrypt_log_page(const LOG_PAGE *logpage_plain, TDE_ALGORITHM tde_algo, LOG_PAGE *logpage_cipher)
Definition: tde.c:997