2
* Copyright © 2012 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3, as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License along
14
* with this program. If not, see <http://www.gnu.org/licenses/>.
25
static gcry_cipher_hd_t
26
setup_cipher (const gchar * password)
28
gcry_error_t gcryError;
29
gcry_cipher_hd_t gcryHandle;
31
const size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES);
32
const size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES);
34
// We are assuming keyLength and blkLength are the same, check it
35
if (keyLength != blkLength)
38
char * aesSymKey = malloc(blkLength);
39
const size_t passwordLength = strlen(password);
40
strncpy(aesSymKey, password, blkLength);
42
for (i = passwordLength; i < blkLength; ++i)
45
gcryError = gcry_cipher_open(&gcryHandle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
47
g_warning("gcry_cipher_open failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));
51
gcryError = gcry_cipher_setkey(gcryHandle, aesSymKey, keyLength);
53
g_warning("gcry_cipher_setkey failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));
54
gcry_cipher_close(gcryHandle);
58
// Use the key as IV too
59
gcryError = gcry_cipher_setiv(gcryHandle, aesSymKey, blkLength);
61
g_warning("gcry_cipher_setiv failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));
62
gcry_cipher_close(gcryHandle);
71
* @origBuffer: text to encrypt. Needs to be null terminated
72
* @password: password to use. Will be cut/padded with 0 if it exceeds/does not reach the needed length
73
* @outBufferLength: (out) On success contains the length of the returned buffer
75
* Returns the AES encrypted version of the text. It is responsability of the caller to free it
78
do_aes_encrypt(const gchar *origBuffer, const gchar * password, size_t *outBufferLength)
80
gcry_error_t gcryError;
81
gcry_cipher_hd_t gcryHandle;
83
gcryHandle = setup_cipher (password);
84
if (gcryHandle == NULL) {
88
const size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES);
89
const size_t origBufferLength = strlen(origBuffer);
90
const size_t bufferLength = ceil((double)origBufferLength / blkLength) * blkLength;
91
gchar *buffer = malloc(bufferLength);
92
memcpy(buffer, origBuffer, origBufferLength);
94
for (i = origBufferLength; i < bufferLength; ++i)
97
char * encBuffer = malloc(bufferLength);
98
size_t lengthDone = 0;
99
while (lengthDone < bufferLength) {
100
gcryError = gcry_cipher_encrypt(gcryHandle, &encBuffer[lengthDone], blkLength, &buffer[lengthDone], blkLength);
102
g_warning("gcry_cipher_encrypt failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));
103
gcry_cipher_close(gcryHandle);
107
lengthDone += blkLength;
110
gcry_cipher_close(gcryHandle);
112
*outBufferLength = bufferLength;
118
* @encBuffer: encrypted data
119
* @password: password to use. Will be cut/padded with 0 if it exceeds/does not reach the needed length
120
* @encBufferLength: Length of encBuffer
122
* Returns the AES decrypted version of the data. It is null terminated. It is responsability of the caller to free it
125
do_aes_decrypt(const gchar *encBuffer, const gchar * password, const size_t encBufferLength)
127
gcry_error_t gcryError;
128
gcry_cipher_hd_t gcryHandle;
130
gcryHandle = setup_cipher (password);
131
if (gcryHandle == NULL) {
135
const size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES128);
136
const size_t bufferLength = encBufferLength;
137
char * outBuffer = malloc(bufferLength);
138
size_t lengthDone = 0;
139
while (lengthDone < bufferLength) {
140
gcryError = gcry_cipher_decrypt(gcryHandle, &outBuffer[lengthDone], 16, &encBuffer[lengthDone], 16);
143
g_warning("gcry_cipher_decrypt failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));
146
lengthDone += blkLength;
149
gcry_cipher_close(gcryHandle);
150
char *result = g_strndup(outBuffer, bufferLength);