175 lines
5.8 KiB
C
175 lines
5.8 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2009, 2010 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_SYM_REF_H
|
|
#define GTMCRYPT_SYM_REF_H
|
|
/* ==================================================================================== */
|
|
/* Macros and functions for symmetric encryption tasks */
|
|
/* ==================================================================================== */
|
|
|
|
#ifdef USE_OPENSSL
|
|
#define GC_SYM_CREATE_HANDLES(cur_entry) \
|
|
{ \
|
|
int ecode; \
|
|
unsigned char *key = (unsigned char *)(cur_entry->key_string.address); \
|
|
\
|
|
EVP_CIPHER_CTX_init(&(cur_entry->encr_key_handle)); \
|
|
ecode = EVP_CipherInit(&(cur_entry->encr_key_handle), ALGO, key, NULL, GC_ENCRYPT); \
|
|
GC_SYM_ERROR(ecode, GC_FAILURE); \
|
|
\
|
|
EVP_CIPHER_CTX_init(&(cur_entry->decr_key_handle)); \
|
|
ecode = EVP_CipherInit(&(cur_entry->decr_key_handle), ALGO, key, NULL, GC_DECRYPT); \
|
|
GC_SYM_ERROR(ecode, GC_FAILURE); \
|
|
}
|
|
|
|
#define GC_SYM_ERROR(err, return_value) \
|
|
{ \
|
|
if (!err) \
|
|
{ \
|
|
ERR_error_string_n(err, err_string, ERR_STRLEN); \
|
|
return return_value; \
|
|
} \
|
|
}
|
|
#else
|
|
#define GC_SYM_CREATE_HANDLES(cur_entry) \
|
|
{ \
|
|
gcry_error_t err; \
|
|
char *key = cur_entry->key_string.address; \
|
|
size_t keylen = cur_entry->key_string.length; \
|
|
\
|
|
GC_SYM_INIT; \
|
|
err = gcry_cipher_open(&(cur_entry->encr_key_handle), ALGO, MODE, FLAGS); \
|
|
if (!err) \
|
|
err = gcry_cipher_setkey(cur_entry->encr_key_handle, key, keylen); \
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
err = gcry_cipher_open(&(cur_entry->decr_key_handle), ALGO, MODE, FLAGS); \
|
|
if (!err) \
|
|
err = gcry_cipher_setkey(cur_entry->decr_key_handle, key, keylen); \
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
}
|
|
#define GC_SYM_ERROR(err, return_value) \
|
|
{ \
|
|
if (GPG_ERR_NO_ERROR != err) \
|
|
{ \
|
|
snprintf(err_string, ERR_STRLEN, "%s", gcry_strerror(err)); \
|
|
return return_value; \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
#ifdef USE_GCRYPT
|
|
/* Initialization and error handling functions defined only for libgcrypt.
|
|
* OpenSSL doesn't neeed them. */
|
|
#define GC_SYM_INIT \
|
|
{ \
|
|
gcry_error_t err; \
|
|
char *ver; \
|
|
\
|
|
if (!gcry_already_inited) \
|
|
{ \
|
|
memset(iv, 0, IV_LEN); \
|
|
if (!gcry_check_version(GCRYPT_VERSION)) \
|
|
{ \
|
|
snprintf(err_string, \
|
|
ERR_STRLEN, \
|
|
"libgcrypt version mismatch. %s or higher is required", \
|
|
GCRYPT_VERSION); \
|
|
return GC_FAILURE; \
|
|
} \
|
|
if (!(err = gcry_control(GCRYCTL_DISABLE_SECMEM, 0))) \
|
|
if (!(err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0))) \
|
|
gcry_already_inited = TRUE; \
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
} \
|
|
}
|
|
#endif
|
|
#ifdef USE_OPENSSL
|
|
#define GC_SYM_COMMON(key_handle, in_block, out_block, flag) \
|
|
{ \
|
|
int block_len, is_inplace, ecode, tmp_len; \
|
|
int out_len; \
|
|
char *static_out_blk; \
|
|
unsigned char *in = NULL, *out = NULL; \
|
|
\
|
|
assert(in_block->address); \
|
|
assert(0 != in_block->length); \
|
|
in = (unsigned char *)in_block->address; \
|
|
block_len = in_block->length; \
|
|
out = (unsigned char *)out_block->address; \
|
|
if (NULL == out_block->address) \
|
|
{ \
|
|
GC_GET_STATIC_BLOCK(static_out_blk, block_len); \
|
|
out = (unsigned char *)static_out_blk; \
|
|
is_inplace = TRUE; \
|
|
} else \
|
|
is_inplace = FALSE; \
|
|
ecode = EVP_CipherUpdate(&key_handle, out, &out_len, in, block_len); \
|
|
if (ecode) \
|
|
ecode = EVP_CipherFinal(&key_handle, out + out_len, &tmp_len); \
|
|
GC_SYM_ERROR(ecode, GC_FAILURE); \
|
|
if (is_inplace) \
|
|
memcpy(in, out, block_len); \
|
|
}
|
|
#else /* USE_GCRYPT */
|
|
#define GC_SYM_COMMON(key_handle, in_block, out_block, flag) \
|
|
{ \
|
|
int is_inplace = 0; \
|
|
size_t blen; \
|
|
gcry_error_t err; \
|
|
\
|
|
assert(in_block->address); \
|
|
assert(0 != in_block->length); \
|
|
blen = in_block->length; \
|
|
if (NULL == out_block->address) \
|
|
is_inplace = TRUE; \
|
|
\
|
|
GC_SYM_INIT; \
|
|
gcry_cipher_setiv(key_handle, iv, IV_LEN); \
|
|
if (is_inplace) \
|
|
{ \
|
|
if (flag == GC_ENCRYPT) \
|
|
{ \
|
|
err = gcry_cipher_encrypt(key_handle, in_block->address, blen, NULL, 0);\
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
} else \
|
|
{ \
|
|
err = gcry_cipher_decrypt(key_handle, in_block->address, blen, NULL, 0);\
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
} \
|
|
} else \
|
|
{ \
|
|
if (flag == GC_ENCRYPT) \
|
|
{ \
|
|
err = gcry_cipher_encrypt(key_handle, \
|
|
out_block->address, \
|
|
blen, \
|
|
in_block->address, \
|
|
blen); \
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
} else \
|
|
{ \
|
|
err = gcry_cipher_decrypt(key_handle, \
|
|
out_block->address, \
|
|
blen, \
|
|
in_block->address, \
|
|
blen); \
|
|
GC_SYM_ERROR(err, GC_FAILURE); \
|
|
} \
|
|
} \
|
|
}
|
|
#endif
|
|
#define GC_SYM_DECODE(key_handle, encrypted_block, unencrypted_block) \
|
|
GC_SYM_COMMON(key_handle, encrypted_block, unencrypted_block, GC_DECRYPT)
|
|
|
|
#define GC_SYM_ENCODE(key_handle, unencrypted_block, encrypted_block) \
|
|
GC_SYM_COMMON(key_handle, unencrypted_block, encrypted_block, GC_ENCRYPT)
|
|
#endif /* GTMCRYPT_SYM_REF_H */
|