/* * crypt_sha_one() - * return: * thread_p(in): * src(in): * src_len(in): * dest_len_p(out): * Note: */ int crypt_sha_one (THREAD_ENTRY * thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p) { int hash_length; char *dest = NULL; char *dest_hex = NULL; int dest_len; int dest_hex_len; int error_status = NO_ERROR; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } hash_length = gcry_md_get_algo_dlen (GCRY_MD_SHA1); dest = (char *) db_private_alloc (thread_p, hash_length); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } dest_len = hash_length; gcry_md_hash_buffer (GCRY_MD_SHA1, dest, src, src_len); dest_hex = str_to_hex (thread_p, dest, dest_len, &dest_hex, &dest_hex_len); if (dest_hex == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } *dest_p = dest_hex; *dest_len_p = dest_hex_len; exit_and_free: if (dest != NULL) { db_private_free_and_init (thread_p, dest); } return error_status; }
/* * qst_free_class_list () - Frees the dynamic memory area used by the passed * linked list * return: void * class_id_list(in): list to be freed */ static void stats_free_class_list (CLASS_ID_LIST * class_id_list_p) { CLASS_ID_LIST *p, *next_p; if (class_id_list_p == NULL) { return; } for (p = class_id_list_p; p; p = next_p) { next_p = p->next; db_private_free_and_init (NULL, p); } class_id_list_p = NULL; }
/* * crypt_crc32() - * return: error code * thread_p(in): * src(in): original message * src_len(in): length of original message * dest(out): crc32 result * Note: */ int crypt_crc32 (THREAD_ENTRY * thread_p, const char *src, int src_len, int *dest) { int hash_length; char *hash_result; int error_status = NO_ERROR; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } hash_length = gcry_md_get_algo_dlen (GCRY_MD_CRC32); hash_result = (char *) db_private_alloc (thread_p, hash_length); if (hash_result == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } gcry_md_hash_buffer (GCRY_MD_CRC32, hash_result, src, src_len); *dest = htonl (*(UINT32 *) hash_result); exit_and_free: if (hash_result != NULL) { db_private_free_and_init (thread_p, hash_result); } return error_status; }
/* remote_execute_delete_query_by_host() - reorganize sub-XASL for specified host to execute * return: rc * * local_xasl(in): original XASL * db_vals_p(in): * dbval_count(in): * flag (in): * remote_host (in): specified host */ static int remote_execute_delete_query_by_host (THREAD_ENTRY * thread_p, XASL_NODE * local_xasl, const DB_VALUE * dbvals_p, int dbval_count, QUERY_FLAG flag, int remote_host, QFILE_LIST_ID ** list_id_p) { int rc = ER_FAILED; int no_classes = 0; int i, j, size, status = ER_FAILED; XASL_NODE *remote_xasl = NULL; ACCESS_SPEC_TYPE *remote_spec_list = NULL, *local_spec_list = NULL; ACCESS_SPEC_TYPE *remote_spec = NULL, *tmp_spec = NULL; OID *remote_oid = NULL; HFID *remote_hfid = NULL; int remote_spec_cnt = 0; int *remote_node_ids = NULL; char *remote_stream = NULL; int node_id; remote_xasl = (XASL_NODE *) db_private_alloc (thread_p, sizeof (XASL_NODE)); if (remote_xasl == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (XASL_NODE)); goto end; } memcpy (remote_xasl, local_xasl, sizeof (XASL_NODE)); remote_xasl->proc.delete_.no_classes = 0; /* save original XASL spec list */ local_spec_list = local_xasl->aptr_list->spec_list; no_classes = local_xasl->proc.delete_.no_classes; remote_oid = (OID *) db_private_alloc (thread_p, no_classes * sizeof (OID)); if (remote_oid == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (OID)); goto end; } remote_hfid = (HFID *) db_private_alloc (thread_p, no_classes * sizeof (HFID)); if (remote_hfid == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (HFID)); goto end; } remote_node_ids = (int *) db_private_alloc (thread_p, no_classes * sizeof (int)); if (remote_node_ids == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (int)); goto end; } memset (remote_node_ids, 0, no_classes * sizeof (int)); remote_xasl->proc.delete_.class_oid = remote_oid; remote_xasl->proc.delete_.class_hfid = remote_hfid; /* step1: find out spec and oid/hfid to reorgnize sub-XASL for specified host */ for (i = 0; i < no_classes; i++) { node_id = local_xasl->proc.delete_.node_ids[i]; if (node_id != remote_host) { continue; } /* for remote spec */ tmp_spec = local_spec_list; j = no_classes - i - 1; while (j--) { tmp_spec = tmp_spec->next; } remote_spec = (ACCESS_SPEC_TYPE *) db_private_alloc (thread_p, sizeof (ACCESS_SPEC_TYPE)); if (remote_spec == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (ACCESS_SPEC_TYPE)); goto end; } memcpy (remote_spec, tmp_spec, sizeof (ACCESS_SPEC_TYPE)); tmp_spec = remote_spec_list; if (remote_spec_list) { j = remote_spec_cnt - 1; while (j--) { tmp_spec = tmp_spec->next; } tmp_spec->next = remote_spec; } remote_spec->s.cls_node.node_id = 0; /* for remote delete proc */ remote_oid[remote_spec_cnt] = local_xasl->proc.delete_.class_oid[i]; remote_hfid[remote_spec_cnt] = local_xasl->proc.delete_.class_hfid[i]; remote_spec_cnt++; remote_xasl->proc.delete_.no_classes++; if (remote_spec_cnt == 1) { remote_spec_list = remote_spec; } } i = remote_spec_cnt - 1; tmp_spec = remote_spec_list; while (i--) { tmp_spec = tmp_spec->next; } tmp_spec->next = NULL; remote_xasl->proc.delete_.no_classes = remote_spec_cnt; remote_xasl->proc.delete_.no_logging = local_xasl->proc.delete_.no_logging; remote_xasl->proc.delete_.node_ids = remote_node_ids; remote_xasl->proc.delete_.release_lock = local_xasl->proc.delete_.release_lock; remote_xasl->proc.delete_.waitsecs = local_xasl->proc.delete_.waitsecs; remote_xasl->aptr_list->spec_list = remote_spec_list; /* step 2: send to remote host */ if (NO_ERROR != xts_map_xasl_to_stream (thread_p, remote_xasl, &remote_stream, &size)) { goto end; } if (NO_ERROR != remote_prepare_and_execute_query (thread_p, remote_host, remote_stream, size, dbvals_p, dbval_count, flag, list_id_p)) { goto end; } /* step3: end query for remote host */ remote_end_query (thread_p, remote_host, (*list_id_p)->query_id, &status); if (NO_ERROR != status) { rc = ER_FAILED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_END_FAIL, 1, node_id); goto end; } local_xasl->aptr_list->spec_list = local_spec_list; rc = NO_ERROR; end: db_private_free_and_init (thread_p, remote_stream); db_private_free_and_init (thread_p, remote_xasl); while (remote_spec_list) { remote_spec = remote_spec_list->next; db_private_free_and_init (thread_p, remote_spec_list); remote_spec_list = remote_spec; } db_private_free_and_init (thread_p, remote_oid); db_private_free_and_init (thread_p, remote_hfid); db_private_free_and_init (thread_p, remote_node_ids); return rc; }
/* remote_count_star_scan() : - * thread_p(in): * xasl(in/out): * spec(in): * direction(in): */ static SCAN_CODE remote_count_star_scan (THREAD_ENTRY * thread_p, XASL_NODE * xasl, ACCESS_SPEC_TYPE * spec, int direction, bool count_star_with_iscan_opt) { int size = 0, status, error; SCAN_CODE retval = S_ERROR; char *spec_stream = NULL; QUERY_EXEC_PARM *query_parm = QPARM_PTR (thread_p); XASL_NODE *remote_xasl = NULL; QFILE_LIST_ID *list_id = NULL; DB_VALUE *tmp_ptr = NULL; QUERY_FLAG remote_flag = QPARM_PTR (thread_p)->flag; /* stage 1: remote scan and open list can. */ if (!XASL_IS_FLAGED (spec, XASL_SPEC_VISITED)) { error = remote_generate_count_star_xasl (thread_p, &remote_xasl, xasl, spec); if (NO_ERROR != error) { goto end; } error = xts_map_xasl_to_stream (thread_p, remote_xasl, &spec_stream, &size); if (NO_ERROR != error) { goto end; } if (IS_ASYNC_EXEC_MODE (remote_flag)) { remote_flag &= ~ASYNC_EXEC; } error = remote_prepare_and_execute_query (thread_p, spec->s.cls_node. node_id, spec_stream, size, query_parm-> xasl_state->vd. dbval_ptr, query_parm-> xasl_state->vd. dbval_cnt, remote_flag, &list_id); if (error != NO_ERROR) { goto end; } list_id->remote_node_id = spec->s.cls_node.node_id; spec->s_id.scan_id = db_private_alloc (thread_p, sizeof (QFILE_LIST_SCAN_ID)); if (spec->s_id.scan_id == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (QFILE_LIST_SCAN_ID)); goto end; } if (qfile_open_list_scan (list_id, spec->s_id.scan_id) != NO_ERROR) { goto end; } XASL_SET_FLAG (spec, XASL_SPEC_VISITED); retval = qfile_to_val_list (thread_p, spec->s_id.scan_id, xasl->val_list); if (retval == S_ERROR) { goto end; } spec->s_id.scan_id->position = S_AFTER; spec->s_id.scan_id->curr_vpid.pageid = NULL_PAGEID; } if (db_get_int (xasl->val_list->valp->val) > 0) { if (count_star_with_iscan_opt) { (&xasl->curr_spec->s_id)->s.isid.oid_list.oid_cnt = db_get_int (xasl->val_list->valp->val); db_make_int (xasl->val_list->valp->val, 0); } else { db_make_int (xasl->val_list->valp->val, db_get_int (xasl->val_list->valp->val) - 1); } return S_SUCCESS; } else { retval = S_END; remote_end_query (thread_p, spec->s_id.scan_id->list_id.remote_node_id, spec->s_id.scan_id->list_id.query_id, &status); if (NO_ERROR != status) { retval = S_ERROR; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_END_FAIL, 1, spec->s.cls_node.node_id); } } end: if (spec->s_id.scan_id) { if (spec->s_id.scan_id->curr_pgptr) { free_and_init (spec->s_id.scan_id->curr_pgptr); } qfile_close_scan (thread_p, spec->s_id.scan_id); db_private_free_and_init (thread_p, spec->s_id.scan_id); } if (remote_xasl) { db_private_free_and_init (thread_p, remote_xasl->list_id); db_private_free_and_init (thread_p, remote_xasl->spec_list); } db_private_free_and_init (thread_p, remote_xasl); db_private_free_and_init (thread_p, spec_stream); if (list_id) { qfile_free_list_id (list_id); list_id = NULL; } return retval; }
/* remote_scan_next_scan() : - * thread_p(in): * xasl(in/out): * spec(in): * direction(in): */ static SCAN_CODE remote_scan_next_scan (THREAD_ENTRY * thread_p, XASL_NODE * xasl, ACCESS_SPEC_TYPE * spec, int direction) { int size = 0, status, error; SCAN_CODE retval = S_ERROR; char *spec_stream = NULL; QUERY_EXEC_PARM *query_parm = QPARM_PTR (thread_p); XASL_NODE *remote_xasl = NULL; QFILE_LIST_ID *list_id = NULL; DB_VALUE *tmp_ptr = NULL; QUERY_FLAG remote_flag = QPARM_PTR (thread_p)->flag; ACCESS_SPEC_TYPE *tmp_spec = NULL; /* stage 1: remote scan and open list can. */ if (spec->s_id.scan_id == NULL) { if (XASL_IS_FLAGED (spec, XASL_SPEC_VISITED)) { return S_END; } error = remote_generate_remote_xasl_by_host (thread_p, &remote_xasl, xasl, spec->s.cls_node.node_id); if (NO_ERROR != error) { goto end; } if (xasl->type == BUILDVALUE_PROC && xasl->val_list->valp == NULL) { remote_xasl->val_list->valp = db_private_alloc (thread_p, sizeof (QPROC_DB_VALUE_LIST)); remote_xasl->val_list->valp->val = remote_xasl->outptr_list->valptrp->value.value.dbvalptr; remote_xasl->val_list->valp->next = NULL; remote_xasl->val_list->val_cnt = 1; } QEXEC_REMOTE_OUTPTR_LIST (remote_xasl, &tmp_ptr); error = xts_map_xasl_to_stream (thread_p, remote_xasl, &spec_stream, &size); if (NO_ERROR != error) { goto end; } QEXEC_LOCAL_OUTPTR_LIST (remote_xasl, tmp_ptr); if (IS_ASYNC_EXEC_MODE (remote_flag)) { remote_flag &= ~ASYNC_EXEC; } error = remote_prepare_and_execute_query (thread_p, spec->s.cls_node. node_id, spec_stream, size, query_parm-> xasl_state->vd. dbval_ptr, query_parm-> xasl_state->vd. dbval_cnt, remote_flag, &list_id); if (error != NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_SCAN_FAIL, 1, spec->s.cls_node.node_id); qmgr_set_query_error (thread_p, query_parm->xasl_state->query_id); goto end; } list_id->remote_node_id = spec->s.cls_node.node_id; spec->s_id.scan_id = db_private_alloc (thread_p, sizeof (QFILE_LIST_SCAN_ID)); if (spec->s_id.scan_id == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (QFILE_LIST_SCAN_ID)); goto end; } if (qfile_open_list_scan (list_id, spec->s_id.scan_id) != NO_ERROR) { goto end; } XASL_SET_FLAG (spec, XASL_SPEC_VISITED); } /* stage 2 : do next scan */ retval = qfile_to_val_list (thread_p, spec->s_id.scan_id, xasl->val_list); /* stage 3 : close scan and send NET_SERVER_QM_QUERY_END to service node */ if (retval == S_SUCCESS) { return retval; } else if (retval == S_END) { remote_end_query (thread_p, spec->s_id.scan_id->list_id.remote_node_id, spec->s_id.scan_id->list_id.query_id, &status); if (NO_ERROR != status) { retval = S_ERROR; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_END_FAIL, 1, spec->s.cls_node.node_id); } } end: if (spec->s_id.scan_id) { qfile_close_scan (thread_p, spec->s_id.scan_id); db_private_free_and_init (thread_p, spec->s_id.scan_id); } if (remote_xasl) { db_private_free_and_init (thread_p, remote_xasl->list_id); while (remote_xasl->spec_list) { tmp_spec = remote_xasl->spec_list->next; db_private_free_and_init (thread_p, remote_xasl->spec_list); remote_xasl->spec_list = tmp_spec; } } db_private_free_and_init (thread_p, remote_xasl); db_private_free_and_init (thread_p, spec_stream); if (list_id) { qfile_free_list_id (list_id); list_id = NULL; } return retval; }
/* * xlogwr_get_log_pages - * * return: * * thread_p(in): * first_pageid(in): * mode(in): * * Note: */ int xlogwr_get_log_pages (THREAD_ENTRY * thread_p, PAGEID first_pageid, int mode) { LOGWR_ENTRY *entry; char *logpg_area; int logpg_used_size; PAGEID next_fpageid; LOGWR_MODE next_mode; int status; int rv; int error_code; bool check_cs_own = false; LOGWR_INFO *writer_info = &log_Gl.writer_info; logpg_used_size = 0; logpg_area = db_private_alloc (thread_p, PRM_LOG_NBUFFERS * LOG_PAGESIZE); if (logpg_area == NULL) { error_code = ER_OUT_OF_VIRTUAL_MEMORY; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, PRM_LOG_NBUFFERS * LOG_PAGESIZE); return ER_OUT_OF_VIRTUAL_MEMORY; } if (thread_p->conn_entry) { thread_p->conn_entry->stop_phase = THREAD_WORKER_STOP_PHASE_1; } while (true) { er_log_debug (ARG_FILE_LINE, "[tid:%ld] xlogwr_get_log_pages, fpageid(%d), mode(%s)\n", thread_p->tid, first_pageid, (mode == LOGWR_MODE_SYNC ? "sync" : (mode == LOGWR_MODE_ASYNC ? "async" : "semisync"))); /* Register the writer at the list and wait until LFT start to work */ LOG_MUTEX_LOCK (rv, writer_info->flush_start_mutex); error_code = logwr_register_writer_entry (&entry, thread_p, first_pageid, mode); if (error_code != NO_ERROR) { LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex); status = LOGWR_STATUS_ERROR; goto error; } if (entry->status == LOGWR_STATUS_WAIT) { bool continue_checking = true; thread_suspend_with_other_mutex (thread_p, &writer_info->flush_start_mutex, INF_WAIT, NULL, THREAD_LOGWR_SUSPENDED); LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex); if (logtb_is_interrupted (thread_p, false, &continue_checking) || thread_p->resume_status == THREAD_RESUME_DUE_TO_INTERRUPT) { /* interrupted, shutdown or connection has gone. */ error_code = ER_INTERRUPTED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0); status = LOGWR_STATUS_ERROR; goto error; } else if (thread_p->resume_status != THREAD_LOGWR_RESUMED) { error_code = ER_FAILED; status = LOGWR_STATUS_ERROR; goto error; } } else { assert (entry->status == LOGWR_STATUS_DELAY); LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex); LOG_CS_ENTER (thread_p); check_cs_own = true; } /* Send the log pages to be flushed until now */ error_code = logwr_pack_log_pages (thread_p, logpg_area, &logpg_used_size, &status, entry); if (error_code != NO_ERROR) { status = LOGWR_STATUS_ERROR; goto error; } error_code = xlog_send_log_pages_to_client (thread_p, logpg_area, logpg_used_size, mode); if (error_code != NO_ERROR) { status = LOGWR_STATUS_ERROR; goto error; } /* In case of async mode, unregister the writer and wakeup LFT to finish */ /* The result mode is the following. transition \ req mode | req_sync req_async ----------------------------------------- delay -> delay | n/a ASYNC delay -> done | n/a SYNC wait -> delay | SYNC ASYNC wait -> done | SYNC ASYNC */ if (mode == LOGWR_MODE_ASYNC && (entry->status != LOGWR_STATUS_DELAY || (entry->status == LOGWR_STATUS_DELAY && status != LOGWR_STATUS_DONE))) { if (check_cs_own) { check_cs_own = false; LOG_CS_EXIT (); } LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex); if (logwr_unregister_writer_entry (entry, status)) { COND_SIGNAL (writer_info->flush_end_cond); } LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex); } /* Get the next request from the client and reset the arguments */ error_code = xlog_get_page_request_with_reply (thread_p, &next_fpageid, &next_mode); if (error_code != NO_ERROR) { status = LOGWR_STATUS_ERROR; goto error; } /* In case of sync mode, unregister the writer and wakeup LFT to finish */ if (mode != LOGWR_MODE_ASYNC || (entry->status == LOGWR_STATUS_DELAY && status == LOGWR_STATUS_DONE)) { if (check_cs_own) { check_cs_own = false; LOG_CS_EXIT (); } LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex); if (logwr_unregister_writer_entry (entry, status)) { COND_SIGNAL (writer_info->flush_end_cond); } LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex); } /* Reset the arguments for the next request */ first_pageid = next_fpageid; mode = next_mode; } db_private_free_and_init (thread_p, logpg_area); return NO_ERROR; error: er_log_debug (ARG_FILE_LINE, "[tid:%ld] xlogwr_get_log_pages, error(%d)\n", thread_p->tid, error_code); if (check_cs_own) { LOG_CS_EXIT (); } LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex); if (entry != NULL && logwr_unregister_writer_entry (entry, status)) { COND_SIGNAL (writer_info->flush_end_cond); } LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex); db_private_free_and_init (thread_p, logpg_area); return error_code; }
/* * crypt_sha_two() - * return: * thread_p(in): * src(in): * src_len(in): * need_hash_len(in): * dest_p(out) * dest_len_p(out): * Note: */ 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) { int hash_length; int algo; char *dest = NULL; int dest_len; char *dest_hex = NULL; int dest_hex_len; int error_status = NO_ERROR; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; switch (need_hash_len) { case 0: case 256: algo = GCRY_MD_SHA256; break; case 224: algo = GCRY_MD_SHA224; break; case 384: algo = GCRY_MD_SHA384; break; case 512: algo = GCRY_MD_SHA512; break; default: return NO_ERROR; } if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } hash_length = gcry_md_get_algo_dlen (algo); dest_len = hash_length; dest = (char *) db_private_alloc (thread_p, hash_length); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } gcry_md_hash_buffer (algo, dest, src, src_len); dest_hex = str_to_hex (thread_p, dest, dest_len, &dest_hex, &dest_hex_len); if (dest_hex == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } *dest_p = dest_hex; *dest_len_p = dest_hex_len; exit_and_free: if (dest != NULL) { db_private_free_and_init (thread_p, dest); } return error_status; }
/* * crypt_aes_default_decrypt() - like mysql's aes_decrypt. Use AES-128/ECB/PKCS7 method. * return: * thread_p(in): * src(in): source string * src_len(in): the length of source string * key(in): the encrypt key * key_len(in): the length of the key * dest_p(out): the encrypted data. The pointer has to be free by db_private_free * dest_len_p(out): * Note: */ int crypt_aes_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) { gcry_error_t i_gcrypt_err; gcry_cipher_hd_t aes_ctx; char *dest = NULL; int dest_len = 0; char new_key[AES128_KEY_LEN]; int pad, pad_len; int i; int error_status = NO_ERROR; assert (src != NULL); assert (key != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; *dest_len_p = 0; /* src is not a string encrypted by aes_default_encrypt, return NULL */ if (src_len % AES128_BLOCK_LEN) { return NO_ERROR; } if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } i_gcrypt_err = gcry_cipher_open (&aes_ctx, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_OPEN_CIPHER_ERR]); return ER_ENCRYPTION_LIB_FAILED; } dest = (char *) db_private_alloc (thread_p, src_len * sizeof (char)); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto error_and_free; } aes_default_gen_key (key, key_len, new_key, AES128_KEY_LEN); i_gcrypt_err = gcry_cipher_setkey (aes_ctx, new_key, AES128_KEY_LEN); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_SET_KEY_ERR]); error_status = ER_ENCRYPTION_LIB_FAILED; goto error_and_free; } i_gcrypt_err = gcry_cipher_decrypt (aes_ctx, dest, src_len, src, src_len); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { error_status = ER_ENCRYPTION_LIB_FAILED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_CRYPT_ERR]); goto error_and_free; } /* PKCS7 */ if (src_len != 0) { pad = dest[src_len - 1]; if (pad > AES128_BLOCK_LEN) { /* src is not a string encrypted by aes_default_encrypt, return NULL */ if (dest != NULL) { db_private_free_and_init (thread_p, dest); } goto error_and_free; } i = src_len - 2; pad_len = 1; while ((i >= 0) && (dest[i] == pad)) { pad_len++; i--; } if ((pad_len >= pad)) { pad_len = pad; dest_len = src_len - pad_len; } else { /* src is not a string encrypted by aes_default_encrypt, return NULL */ if (dest != NULL) { db_private_free_and_init (thread_p, dest); } goto error_and_free; } } *dest_p = dest; *dest_len_p = dest_len; error_and_free: if ((dest != NULL) && (error_status != NO_ERROR)) { db_private_free_and_init (thread_p, dest); } gcry_cipher_close (aes_ctx); return error_status; }
/* * crypt_aes_default_encrypt() - like mysql's aes_encrypt. Use AES-128/ECB/PKCS7 method. * return: * thread_p(in): * src(in): source string * src_len(in): the length of source string * key(in): the encrypt key * key_len(in): the length of the key * dest_p(out): the encrypted data. The pointer has to be free by db_private_free * dest_len_p(out): * Note: */ int crypt_aes_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) { gcry_error_t i_gcrypt_err; gcry_cipher_hd_t aes_ctx; char new_key[AES128_KEY_LEN]; int pad; int padding_src_len; char *padding_src = NULL; char *dest = NULL; int error_status = NO_ERROR; assert (src != NULL); assert (key != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; *dest_len_p = 0; if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } i_gcrypt_err = gcry_cipher_open (&aes_ctx, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_OPEN_CIPHER_ERR]); return ER_ENCRYPTION_LIB_FAILED; } /* PKCS7 */ if ((src_len % AES128_BLOCK_LEN) == 0) { pad = AES128_BLOCK_LEN; padding_src_len = src_len + pad; } else { padding_src_len = ceil ((double) src_len / AES128_BLOCK_LEN) * AES128_BLOCK_LEN; pad = padding_src_len - src_len; } padding_src = (char *) db_private_alloc (thread_p, padding_src_len); if (padding_src == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } memcpy (padding_src, src, src_len); memset (padding_src + src_len, pad, pad); aes_default_gen_key (key, key_len, new_key, AES128_KEY_LEN); i_gcrypt_err = gcry_cipher_setkey (aes_ctx, new_key, AES128_KEY_LEN); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { error_status = ER_ENCRYPTION_LIB_FAILED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_SET_KEY_ERR]); goto exit_and_free; } dest = (char *) db_private_alloc (thread_p, padding_src_len); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } i_gcrypt_err = gcry_cipher_encrypt (aes_ctx, dest, padding_src_len, padding_src, padding_src_len); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_CRYPT_ERR]); error_status = ER_ENCRYPTION_LIB_FAILED; goto exit_and_free; } *dest_len_p = padding_src_len; *dest_p = dest; exit_and_free: if (padding_src != NULL) { db_private_free_and_init (thread_p, padding_src); } if ((dest != NULL) && (error_status != NO_ERROR)) { db_private_free_and_init (thread_p, dest); } gcry_cipher_close (aes_ctx); return error_status; }