-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgtmcrypt_sym_ref.c
184 lines (173 loc) · 5.71 KB
/
gtmcrypt_sym_ref.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/****************************************************************
* *
* Copyright (c) 2013-2016 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2019 YottaDB LLC and/or its subsidiaries. *
* All rights reserved. *
* *
* 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. *
* *
****************************************************************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <ctype.h>
#include <assert.h>
#include <errno.h>
#include <gpgme.h> /* gpgme functions */
#include <gpg-error.h> /* gcry*_err_t */
#include <libconfig.h>
#include "gtmxc_types.h"
#include "gtmcrypt_util.h"
#include "ydbcrypt_interface.h" /* Function prototypes for gtmcrypt*.* functions */
#include "gtmcrypt_ref.h"
#include "gtmcrypt_dbk_ref.h"
#include "gtmcrypt_sym_ref.h"
#include "gtmcrypt_pk_ref.h"
#ifndef USE_OPENSSL
/*
* Initialize encryption state if libgcrypt is used.
*
* Returns: 0 if the initialization succeeded; -1 otherwise.
*/
int gc_sym_init(void)
{
gcry_error_t rv;
if (!gcry_check_version(GCRYPT_VERSION))
{
UPDATE_ERROR_STRING("libgcrypt version mismatch. %s or higher is required", GCRYPT_VERSION);
return -1;
}
if (0 != (rv = gcry_control(GCRYCTL_DISABLE_SECMEM, 0)))
{
GC_APPEND_GCRY_ERROR(rv, "Failed to disable secure memory.");
return -1;
}
if (0 != (rv = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0)))
{
GC_APPEND_GCRY_ERROR(rv, "Failed to finish encryption initialization.")
return -1;
}
return 0;
}
#endif
/*
* Destroy the specified encryption / decryption state object.
*
* Arguments: handle Encryption / decryption state object to destroy.
*
* Returns: N/A neither OpenSSL nor GCrypt destructors return a status.
*/
void gc_sym_destroy_cipher_handle(crypt_key_t handle)
{
if (NULL != handle)
#ifdef USE_OPENSSL
EVP_CIPHER_CTX_free(handle);
#elif defined(USE_GCRYPT)
gcry_cipher_close(handle);
#else
error Encryption library not defined, please use either -DUSE_OPENSSL or -DUSE_GCRYPT
#endif
}
/*
* Create an encryption / decryption state object based on the specified key and IV and assign it to the passed pointer. If the
* reuse flag is TRUE, then the passed cipher state is not recreated but reinitialized with the specified IV. Note that for a
* successful reuse of the state object with OpenSSL the *same* raw key needs to be provided as during its creation.
*
* Arguments: raw_key Raw contents of the symmetric key to use.
* iv Initialization vector to use.
* handle Pointer to assign the newly created encryption / decryption state object to.
* direction Indicator of whether encryption or decryption state object is to be constructed.
* reuse Indicator of whether the state object should be reused or recreated.
*
* Returns: 0 if the state object was successfully constructed; -1 otherwise.
*/
int gc_sym_create_cipher_handle(unsigned char *raw_key, unsigned char *iv, crypt_key_t *handle, int direction, int reuse)
{
int rv, plain_text_length;
# ifdef USE_OPENSSL
if (NULL == *handle)
*handle = EVP_CIPHER_CTX_new();
else if (!reuse)
{
EVP_CIPHER_CTX_init(*handle);
}
if (!EVP_CipherInit_ex(*handle, ALGO, NULL, raw_key, iv, direction))
{
GC_APPEND_OPENSSL_ERROR("Failed to initialize encryption key handle.");
return -1;
}
# else
if (!reuse)
{
if (0 != (rv = gcry_cipher_open(handle, ALGO, MODE, 0)))
{
GC_APPEND_GCRY_ERROR(rv, "Failed to initialize encryption key handle ('gcry_cipher_open').");
return -1;
}
if (0 != (rv = gcry_cipher_setkey(*handle, raw_key, SYMMETRIC_KEY_MAX)))
{
GC_APPEND_GCRY_ERROR(rv, "Failed to initialize encryption key handle ('gcry_cipher_setkey').");
return -1;
}
}
gcry_cipher_setiv(*handle, iv, GTMCRYPT_IV_LEN);
# endif
return 0;
}
/*
* Perform an encryption or decryption operation using the specified state object and buffers (or buffer, if in-place).
*
* Arguments: key Pointer to the encryption / decryption state object.
* in_block Block from which to take the input data for the operation.
* in_block_len Length of the block from which to take the input data for the operation; it should match the length
* of the block for the output data, if not NULL.
* out_block Block where to place the output data from the operation.
* flag Indicator of whether encryption or decryption is to be performed.
*
* Returns: 0 if the operation went successfully; -1 otherwise.
*/
int gc_sym_encrypt_decrypt(crypt_key_t *key, unsigned char *in_block, int in_block_len, unsigned char *out_block, int flag)
{
int rv, tmp_len, out_block_len;
assert(in_block);
assert(0 < in_block_len);
if (NULL == out_block)
out_block = in_block;
out_block_len = in_block_len;
# ifdef USE_GCRYPT
if (out_block == in_block)
{
in_block = NULL;
in_block_len = 0;
}
rv = (GTMCRYPT_OP_ENCRYPT == flag)
? gcry_cipher_encrypt(*key, out_block, out_block_len, in_block, in_block_len)
: gcry_cipher_decrypt(*key, out_block, out_block_len, in_block, in_block_len);
if (0 != rv)
{
GC_APPEND_GCRY_ERROR(rv, "Libgcrypt function 'gcry_cipher_encrypt' or 'gcry_cipher_decrypt' failed.");
return -1;
}
# endif
# ifdef USE_OPENSSL
if (!EVP_CipherUpdate(*key, out_block, &out_block_len, in_block, in_block_len))
{
GC_APPEND_OPENSSL_ERROR("OpenSSL function 'EVP_CipherUpdate' failed.")
return -1;
}
if (!EVP_CipherFinal_ex(*key, out_block + out_block_len, &tmp_len))
{
GC_APPEND_OPENSSL_ERROR("OpenSSL function 'EVP_CipherFinal_ex' failed.")
return -1;
}
# endif
return 0;
}