/**************************************************************** * * * Copyright 2009, 2011 Fidelity Information Services, Inc * * * * This source code contains the intellectual property * * of its copyright holder(s), and is made available * * under a license. If you do not know the terms of * * the license, please stop and do not read further. * * * ****************************************************************/ #ifndef GTMCRYPT_REF_H #define GTMCRYPT_REF_H #ifdef USE_OPENSSL # include # include # include #elif defined USE_GCRYPT # include #else # error "Unsupported encryption library. Reference implementation currently supports openssl and gcrypt" #endif #ifndef DEBUG #undef assert #define assert(x) #endif /* Any change done to the below macro should be reflected in mdef.h and vice versa */ /* Note: sizeof returns a "unsigned long" type by default. In expressions involving 32-bit quantities, * using sizeof causes a compiler warning for every 64->32 bit auto cast (zOS compiler for now). * Hence typecasting the return to "int" on zOS (to avoid warning) in most common sizeof usages. * Whenever SIZEOF needs to be used in expressions involving 64-bit pointer quantities, use ((INTPTR_T)SIZEOF(...)). * Whenever SIZEOF needs to be used in expressions involving 64-bit integer quantities, use ((long)SIZEOF(...)). */ #if defined(__MVS__) # define SIZEOF(X) ((int)(sizeof(X))) /* BYPASSOK */ #else # define SIZEOF(X) ((long)sizeof(X)) /* BYPASSOK */ #endif typedef enum { ERROR_LINE_INFO = -1, DAT_LINE_INFO, KEY_LINE_INFO } dbkeyfile_line_type; typedef enum { LOOKING_FOR_DAT_ENTRY = 1, LOOKING_FOR_KEY_ENTRY, NUM_STATES } dbkeyfile_states; #ifdef USE_OPENSSL typedef EVP_CIPHER_CTX crypt_key_t; #else typedef gcry_cipher_hd_t crypt_key_t; #endif #define TAB_NAME_MAX 512 #define GTM_PASSPHRASE_MAX 512 #define GC_ENCRYPT 1 #define GC_DECRYPT 0 #define GC_FAILURE 1 #define GC_SUCCESS 0 #define TRUE 1 #define FALSE 0 #define GNUPGHOME "GNUPGHOME" #define DOT_GNUPG ".gnupg" #define GTM_PASSWD "gtm_passwd" #define GTM_DBKEYS "gtm_dbkeys" #define DOT_GTM_DBKEYS "."GTM_DBKEYS #define PASSWD_EMPTY "Environment variable gtm_passwd set to empty string. Password prompting not allowed for utilities" #define GTM_PATH_MAX 1024 #define GTM_KEY_MAX 32 #define GTMCRYPT_HASH_LEN 64 #define GTMCRYPT_HASH_HEX_LEN GTMCRYPT_HASH_LEN * 2 #define DAT_LINE_INDICATOR "dat " #define KEY_LINE_INDICATOR "key " #define DAT_LINE_INDICATOR_SIZE (SIZEOF(DAT_LINE_INDICATOR) - 1) #define KEY_LINE_INDICATOR_SIZE (SIZEOF(KEY_LINE_INDICATOR) - 1) #define INVALID_HANDLE -1 #define GTMCI "GTMCI" #define ERR_STRLEN 2048 #ifdef USE_GCRYPT #define IV_LEN 16 #define ALGO GCRY_CIPHER_AES256 #define MODE GCRY_CIPHER_MODE_CFB /* This string uniquely identifies the encryption algorithm and its parameters. * It will be appended to the encryption key and the combination will be hashed (with SHA512). * This hash will be used verify that the same algorithm (including parameters) and key are used to * open the database file as were used to create the database file. */ #define UNIQ_ENC_PARAM_STRING "AES256CFB" #define FLAGS 0 static char iv[IV_LEN]; static int gcry_already_inited = FALSE; #else #define ALGO EVP_bf_cfb64() #define UNIQ_ENC_PARAM_STRING "BLOWFISHCFB" #endif #define UNIQ_ENC_PARAM_LEN SIZEOF(UNIQ_ENC_PARAM_STRING) - 1 #define HASH_INPUT_BUFF_LEN UNIQ_ENC_PARAM_LEN + GTM_KEY_MAX /* ==================================================================================== */ /* Legend to namespaces used - * gc_XXXXX - All functions start with the gc_ namespace * gc_dbk_XXX - All functions related to db key mapping and internal book keeping * gc_sym_XXX - All functions related to usages of symmetric enc/dec activities, primarily using libgcrypt or libcrypto * gc_pk_XXX - All functions related to usages of public/private key enc/dec activities, primarily using libgpgme */ /* ==================================================================================== */ /* ==================================================================================== */ /* Generic macros and functions related to this plugin */ /* ==================================================================================== */ #define GC_MIN_STATIC_BLOCK_SIZE 4096 /* Have a good size block, so that we dont keep reallocating */ #define GC_ROUNDUP(x, y) ((x / y) * y) + ((x % y) ? y : 0) #define GC_FLAGS (RTLD_NOW | RTLD_GLOBAL) #define GTM_MALLOC_FUNC "gtm_malloc" #define GTM_FREE_FUNC "gtm_free" #define GTM_FILENAME_TO_ID_FUNC "gtm_filename_to_id" #define GTM_CI_FUNC "gtm_ci" #define GTM_ZSTATUS_FUNC "gtm_zstatus" #define GTM_IS_FILE_IDENTICAL_FUNC "gtm_is_file_identical" #define GTM_XCFILEID_FREE_FUNC "gtm_xcfileid_free" xc_status_t gc_init_interface(int prompt_passwd); typedef void * (*gtm_malloc_fptr_t)(size_t); typedef void (*gtm_free_fptr_t)(void *); typedef xc_status_t (*gtm_filename_to_id_fptr_t)(xc_string_t *, xc_fileid_ptr_t *); typedef xc_status_t (*gtm_ci_fptr_t)(const char *c_rtn_name, ...); typedef void (*gtm_zstatus_fptr_t)(char *msg, int len); typedef xc_status_t (*gtm_is_file_identical_fptr_t)(xc_fileid_ptr_t, xc_fileid_ptr_t); typedef void (*gtm_xcfileid_free_fptr_t)(xc_fileid_ptr_t); gtm_malloc_fptr_t gtm_malloc_fptr; gtm_free_fptr_t gtm_free_fptr; gtm_filename_to_id_fptr_t gtm_filename_to_id_fptr; gtm_ci_fptr_t gtm_ci_fptr; gtm_zstatus_fptr_t gtm_zstatus_fptr; gtm_is_file_identical_fptr_t gtm_is_file_identical_fptr; gtm_xcfileid_free_fptr_t gtm_xcfileid_free_fptr; #define DLSYM_ERR_AND_EXIT(fptr_type, fptr, func_name) \ { \ fptr = (fptr_type)dlsym(handle, func_name); \ if (NULL == fptr) \ { \ snprintf(err_string, ERR_STRLEN, "Enable to resolve %s ", func_name); /* BYPASSOK */ \ return GC_FAILURE; \ } \ } #define GC_MALLOC(blk, len, type) \ { \ blk = (type *)gtm_malloc_fptr(len); \ assert (blk); \ } #define GC_FREE(blk) gtm_free_fptr(blk) #define GC_COPY_TO_XC_STRING(X, STR, N) \ { \ memcpy((X)->address, STR, N); \ (X)->length = N; \ } /* Following makes sure that at no point we are in the encryption library without gtmcrypt_init getting called * prior to the current call */ #define GC_VERIFY_INITED \ { \ if (!gtmcrypt_inited) \ { \ snprintf(err_string, ERR_STRLEN, "%s", "Encryption library has not been initialized"); /* BYPASSOK */ \ return GC_FAILURE; \ } \ } #define GC_IF_INITED_RETURN \ { \ /* Check if init has happened already */ \ if (gtmcrypt_inited) \ return GC_SUCCESS; \ } #define GC_SET_INITED gtmcrypt_inited = TRUE; #define GC_CLEAR_INITED gtmcrypt_inited = FALSE; #define GC_INT(H) ((H >= 'A' && H <= 'F') ? ((H - 'A') + 10) : (H - '0')) #define GC_UNHEX(a, b, len) \ { \ int i; \ for (i = 0; i < len; i+=2) \ b[i/2] = (unsigned char)(GC_INT(a[i]) * 16 + GC_INT(a[i + 1])); \ } #define GC_HEX(a, b, len) \ { \ int i; \ for (i = 0; i < len; i+=2) \ sprintf(b + i, "%02X", (unsigned char)a[i/2]); /* BYPASSOK */ \ } #define GC_GETENV(ptr, key, RC) \ { \ RC = GC_SUCCESS; \ if (NULL == (ptr = (char *)getenv(key))) \ RC = GC_FAILURE; \ } #define GC_ENV_UNSET_ERROR(key) \ { \ snprintf(err_string, ERR_STRLEN, "Environment variable %s not set", key); /* BYPASSOK */ \ } /* Allocate a single block, and try reusing the same everytime this macro is called */ #ifdef USE_OPENSSL #define GC_GET_STATIC_BLOCK(out, block_len) \ { \ static char *blk = (char *)NULL; \ static int allocated_len = GC_MIN_STATIC_BLOCK_SIZE; \ if (blk == NULL || (block_len > allocated_len)) \ { \ if (blk) \ GC_FREE(blk); \ allocated_len = (block_len > allocated_len) ? \ GC_ROUNDUP(block_len, GC_MIN_STATIC_BLOCK_SIZE) : \ allocated_len; \ GC_MALLOC(blk, allocated_len, char); \ } \ out = blk; \ } #endif #endif /* GTMCRYPT_REF_H */