summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/libgcryptif.cpp2
-rw-r--r--pwmanager/pwmanager/libgcryptif.h2
2 files changed, 2 insertions, 2 deletions
diff --git a/pwmanager/pwmanager/libgcryptif.cpp b/pwmanager/pwmanager/libgcryptif.cpp
index 8175510..eafd318 100644
--- a/pwmanager/pwmanager/libgcryptif.cpp
+++ b/pwmanager/pwmanager/libgcryptif.cpp
@@ -1,449 +1,449 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2004 by Michael Buesch * 3 * copyright (C) 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * hashPassphrase() is derived from GnuPG and is * 6 * hashPassphrase() is derived from GnuPG and is *
7 * Copyright (C) 1998, 1999, 2000, 2001, 2003 * 7 * Copyright (C) 1998, 1999, 2000, 2001, 2003 *
8 * Free Software Foundation, Inc. * 8 * Free Software Foundation, Inc. *
9 * * 9 * *
10 * This program is free software; you can redistribute it and/or modify * 10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License version 2 * 11 * it under the terms of the GNU General Public License version 2 *
12 * as published by the Free Software Foundation. * 12 * as published by the Free Software Foundation. *
13 * * 13 * *
14 ***************************************************************************/ 14 ***************************************************************************/
15 15
16/*************************************************************************** 16/***************************************************************************
17 * copyright (C) 2004 by Ulf Schenk 17 * copyright (C) 2004 by Ulf Schenk
18 * This file is originaly based on version 2.0 of pwmanager 18 * This file is originaly based on version 1.1 of pwmanager
19 * and was modified to run on embedded devices that run microkde 19 * and was modified to run on embedded devices that run microkde
20 * 20 *
21 * $Id$ 21 * $Id$
22 **************************************************************************/ 22 **************************************************************************/
23 23
24#include "libgcryptif.h" 24#include "libgcryptif.h"
25 25
26#ifdef CONFIG_PWMANAGER_GCRY 26#ifdef CONFIG_PWMANAGER_GCRY
27 27
28#include "pwmdoc.h" 28#include "pwmdoc.h"
29#include "randomizer.h" 29#include "randomizer.h"
30 30
31#include <gcrypt.h> 31#include <gcrypt.h>
32 32
33#ifdef PWM_EMBEDDED 33#ifdef PWM_EMBEDDED
34#include <pwmprefs.h> 34#include <pwmprefs.h>
35#endif 35#endif
36 36
37 37
38PwMerror LibGCryptIf::encrypt(unsigned char **outBuf, 38PwMerror LibGCryptIf::encrypt(unsigned char **outBuf,
39 size_t *outBufLen, 39 size_t *outBufLen,
40 unsigned char *inBuf, 40 unsigned char *inBuf,
41 size_t inBufLen, 41 size_t inBufLen,
42 const unsigned char *key, 42 const unsigned char *key,
43 size_t keylen, 43 size_t keylen,
44 char _algo) 44 char _algo)
45{ 45{
46 PwMerror ret = e_success; 46 PwMerror ret = e_success;
47 gcry_error_t err; 47 gcry_error_t err;
48 gcry_cipher_hd_t handle; 48 gcry_cipher_hd_t handle;
49 size_t blklen; 49 size_t blklen;
50 size_t unpaddedLen = inBufLen; 50 size_t unpaddedLen = inBufLen;
51 size_t cipherKeylen; 51 size_t cipherKeylen;
52 unsigned char *hashedKey; 52 unsigned char *hashedKey;
53 unsigned char salt[STRING2KEY_SALTLEN]; 53 unsigned char salt[STRING2KEY_SALTLEN];
54 int algo = mapCipherId(_algo); 54 int algo = mapCipherId(_algo);
55 55
56 if (!inBufLen || !keylen) 56 if (!inBufLen || !keylen)
57 return e_invalidArg; 57 return e_invalidArg;
58 58
59 // test if algo is ready for encryption 59 // test if algo is ready for encryption
60 err = gcry_cipher_algo_info(algo, 60 err = gcry_cipher_algo_info(algo,
61 GCRYCTL_TEST_ALGO, 61 GCRYCTL_TEST_ALGO,
62 0, 0); 62 0, 0);
63 if (err != GPG_ERR_NO_ERROR) { 63 if (err != GPG_ERR_NO_ERROR) {
64 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ") 64 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ")
65 + gcry_strerror(err)); 65 + gcry_strerror(err));
66 ret = e_cryptNotImpl; 66 ret = e_cryptNotImpl;
67 goto out; 67 goto out;
68 } 68 }
69 // get the algo block length 69 // get the algo block length
70 err = gcry_cipher_algo_info(algo, 70 err = gcry_cipher_algo_info(algo,
71 GCRYCTL_GET_BLKLEN, 71 GCRYCTL_GET_BLKLEN,
72 0, 72 0,
73 &blklen); 73 &blklen);
74 if (err != GPG_ERR_NO_ERROR) { 74 if (err != GPG_ERR_NO_ERROR) {
75 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ") 75 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ")
76 + gcry_strerror(err)); 76 + gcry_strerror(err));
77 ret = e_cryptNotImpl; 77 ret = e_cryptNotImpl;
78 goto out; 78 goto out;
79 } 79 }
80 /* double check if we have enough space. 80 /* double check if we have enough space.
81 * We have only 1024 extra bytes for padding and salt. 81 * We have only 1024 extra bytes for padding and salt.
82 */ 82 */
83 BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN); 83 BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN);
84 // get the algo key length 84 // get the algo key length
85 err = gcry_cipher_algo_info(algo, 85 err = gcry_cipher_algo_info(algo,
86 GCRYCTL_GET_KEYLEN, 86 GCRYCTL_GET_KEYLEN,
87 0, 87 0,
88 &cipherKeylen); 88 &cipherKeylen);
89 if (err != GPG_ERR_NO_ERROR) { 89 if (err != GPG_ERR_NO_ERROR) {
90 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ") 90 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ")
91 + gcry_strerror(err)); 91 + gcry_strerror(err));
92 ret = e_cryptNotImpl; 92 ret = e_cryptNotImpl;
93 goto out; 93 goto out;
94 } 94 }
95 // now open the algo and get a handle 95 // now open the algo and get a handle
96 err = gcry_cipher_open(&handle, 96 err = gcry_cipher_open(&handle,
97 algo, 97 algo,
98 GCRY_CIPHER_MODE_CBC, 98 GCRY_CIPHER_MODE_CBC,
99 0); 99 0);
100 if (err != GPG_ERR_NO_ERROR) { 100 if (err != GPG_ERR_NO_ERROR) {
101 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ") 101 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ")
102 + gcry_strerror(err)); 102 + gcry_strerror(err));
103 ret = e_cryptNotImpl; 103 ret = e_cryptNotImpl;
104 goto out; 104 goto out;
105 } 105 }
106 // hash the "key" to a fixed size hash matching "cipherKeylen" 106 // hash the "key" to a fixed size hash matching "cipherKeylen"
107 hashedKey = new unsigned char[cipherKeylen]; 107 hashedKey = new unsigned char[cipherKeylen];
108 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true); 108 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true);
109 // so now set the hashed key 109 // so now set the hashed key
110 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen); 110 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
111 if (err != GPG_ERR_NO_ERROR) { 111 if (err != GPG_ERR_NO_ERROR) {
112 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ") 112 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ")
113 + gcry_strerror(err)); 113 + gcry_strerror(err));
114 ret = e_cryptNotImpl; 114 ret = e_cryptNotImpl;
115 delete [] hashedKey; 115 delete [] hashedKey;
116 goto out_close; 116 goto out_close;
117 } 117 }
118 delete [] hashedKey; 118 delete [] hashedKey;
119 /* allocate a buffer for the encrypted data. 119 /* allocate a buffer for the encrypted data.
120 * The size of the buffer is the inBuf length, but blklen 120 * The size of the buffer is the inBuf length, but blklen
121 * aligned and plus the length of the salt, that is appended. 121 * aligned and plus the length of the salt, that is appended.
122 */ 122 */
123 *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN; 123 *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN;
124 *outBuf = new unsigned char[*outBufLen]; 124 *outBuf = new unsigned char[*outBufLen];
125 padData(inBuf, unpaddedLen, blklen); 125 padData(inBuf, unpaddedLen, blklen);
126 // encrypt the padded data 126 // encrypt the padded data
127 err = gcry_cipher_encrypt(handle, 127 err = gcry_cipher_encrypt(handle,
128 *outBuf, 128 *outBuf,
129 *outBufLen - STRING2KEY_SALTLEN, 129 *outBufLen - STRING2KEY_SALTLEN,
130 inBuf, 130 inBuf,
131 *outBufLen - STRING2KEY_SALTLEN); 131 *outBufLen - STRING2KEY_SALTLEN);
132 if (err != GPG_ERR_NO_ERROR) { 132 if (err != GPG_ERR_NO_ERROR) {
133 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ") 133 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
134 + gcry_strerror(err)); 134 + gcry_strerror(err));
135 ret = e_cryptNotImpl; 135 ret = e_cryptNotImpl;
136 goto out_delete; 136 goto out_delete;
137 } 137 }
138 // append the salt to the encrypted data 138 // append the salt to the encrypted data
139 memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN); 139 memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN);
140 goto out_close; 140 goto out_close;
141out_delete: 141out_delete:
142 delete [] *outBuf; 142 delete [] *outBuf;
143out_close: 143out_close:
144 gcry_cipher_close(handle); 144 gcry_cipher_close(handle);
145out: 145out:
146 return ret; 146 return ret;
147} 147}
148 148
149PwMerror LibGCryptIf::decrypt(unsigned char **outBuf, 149PwMerror LibGCryptIf::decrypt(unsigned char **outBuf,
150 size_t *outBufLen, 150 size_t *outBufLen,
151 const unsigned char *inBuf, 151 const unsigned char *inBuf,
152 size_t inBufLen, 152 size_t inBufLen,
153 const unsigned char *key, 153 const unsigned char *key,
154 size_t keylen, 154 size_t keylen,
155 char _algo) 155 char _algo)
156{ 156{
157 PwMerror ret = e_success; 157 PwMerror ret = e_success;
158 gcry_error_t err; 158 gcry_error_t err;
159 gcry_cipher_hd_t handle; 159 gcry_cipher_hd_t handle;
160 size_t cipherKeylen; 160 size_t cipherKeylen;
161 unsigned char *hashedKey; 161 unsigned char *hashedKey;
162 unsigned char salt[STRING2KEY_SALTLEN]; 162 unsigned char salt[STRING2KEY_SALTLEN];
163 int algo = mapCipherId(_algo); 163 int algo = mapCipherId(_algo);
164 164
165 if (!inBufLen || !keylen) 165 if (!inBufLen || !keylen)
166 return e_invalidArg; 166 return e_invalidArg;
167 167
168 // test if algo is ready for encryption 168 // test if algo is ready for encryption
169 err = gcry_cipher_algo_info(algo, 169 err = gcry_cipher_algo_info(algo,
170 GCRYCTL_TEST_ALGO, 170 GCRYCTL_TEST_ALGO,
171 0, 0); 171 0, 0);
172 if (err != GPG_ERR_NO_ERROR) { 172 if (err != GPG_ERR_NO_ERROR) {
173 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ") 173 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ")
174 + gcry_strerror(err)); 174 + gcry_strerror(err));
175 ret = e_cryptNotImpl; 175 ret = e_cryptNotImpl;
176 goto out; 176 goto out;
177 } 177 }
178 // get algo key length 178 // get algo key length
179 err = gcry_cipher_algo_info(algo, 179 err = gcry_cipher_algo_info(algo,
180 GCRYCTL_GET_KEYLEN, 180 GCRYCTL_GET_KEYLEN,
181 0, 181 0,
182 &cipherKeylen); 182 &cipherKeylen);
183 if (err != GPG_ERR_NO_ERROR) { 183 if (err != GPG_ERR_NO_ERROR) {
184 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ") 184 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ")
185 + gcry_strerror(err)); 185 + gcry_strerror(err));
186 ret = e_cryptNotImpl; 186 ret = e_cryptNotImpl;
187 goto out; 187 goto out;
188 } 188 }
189 // extract the salt of the encrypted data buffer 189 // extract the salt of the encrypted data buffer
190 memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN); 190 memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN);
191 // open the algo and get a handle 191 // open the algo and get a handle
192 err = gcry_cipher_open(&handle, 192 err = gcry_cipher_open(&handle,
193 algo, 193 algo,
194 GCRY_CIPHER_MODE_CBC, 194 GCRY_CIPHER_MODE_CBC,
195 0); 195 0);
196 if (err != GPG_ERR_NO_ERROR) { 196 if (err != GPG_ERR_NO_ERROR) {
197 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ") 197 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ")
198 + gcry_strerror(err)); 198 + gcry_strerror(err));
199 ret = e_cryptNotImpl; 199 ret = e_cryptNotImpl;
200 goto out; 200 goto out;
201 } 201 }
202 // hash the "key" to a fixed size hash matching "cipherKeylen" 202 // hash the "key" to a fixed size hash matching "cipherKeylen"
203 hashedKey = new unsigned char[cipherKeylen]; 203 hashedKey = new unsigned char[cipherKeylen];
204 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false); 204 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false);
205 // so now set the hashed key 205 // so now set the hashed key
206 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen); 206 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
207 if (err != GPG_ERR_NO_ERROR) { 207 if (err != GPG_ERR_NO_ERROR) {
208 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ") 208 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ")
209 + gcry_strerror(err)); 209 + gcry_strerror(err));
210 ret = e_cryptNotImpl; 210 ret = e_cryptNotImpl;
211 delete [] hashedKey; 211 delete [] hashedKey;
212 goto out_close; 212 goto out_close;
213 } 213 }
214 delete [] hashedKey; 214 delete [] hashedKey;
215 *outBufLen = inBufLen - STRING2KEY_SALTLEN; 215 *outBufLen = inBufLen - STRING2KEY_SALTLEN;
216 *outBuf = new unsigned char[*outBufLen]; 216 *outBuf = new unsigned char[*outBufLen];
217 // decrypt the data 217 // decrypt the data
218 err = gcry_cipher_decrypt(handle, 218 err = gcry_cipher_decrypt(handle,
219 *outBuf, 219 *outBuf,
220 *outBufLen, 220 *outBufLen,
221 inBuf, 221 inBuf,
222 *outBufLen); 222 *outBufLen);
223 if (err != GPG_ERR_NO_ERROR) { 223 if (err != GPG_ERR_NO_ERROR) {
224 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ") 224 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
225 + gcry_strerror(err)); 225 + gcry_strerror(err));
226 ret = e_cryptNotImpl; 226 ret = e_cryptNotImpl;
227 goto out_delete; 227 goto out_delete;
228 } 228 }
229 // remove all random padding 229 // remove all random padding
230 unpadData(*outBuf, outBufLen); 230 unpadData(*outBuf, outBufLen);
231 goto out_close; 231 goto out_close;
232out_delete: 232out_delete:
233 delete [] *outBuf; 233 delete [] *outBuf;
234out_close: 234out_close:
235 gcry_cipher_close(handle); 235 gcry_cipher_close(handle);
236out: 236out:
237 return ret; 237 return ret;
238} 238}
239 239
240PwMerror LibGCryptIf::hash(unsigned char **outBuf, 240PwMerror LibGCryptIf::hash(unsigned char **outBuf,
241 size_t *outBufLen, 241 size_t *outBufLen,
242 const unsigned char *inBuf, 242 const unsigned char *inBuf,
243 size_t inBufLen, 243 size_t inBufLen,
244 char _algo) 244 char _algo)
245{ 245{
246 PwMerror ret = e_success; 246 PwMerror ret = e_success;
247 unsigned int hashLen; 247 unsigned int hashLen;
248 int algo = mapHashId(_algo); 248 int algo = mapHashId(_algo);
249 249
250 hashLen = gcry_md_get_algo_dlen(algo); 250 hashLen = gcry_md_get_algo_dlen(algo);
251 *outBufLen = hashLen; 251 *outBufLen = hashLen;
252 *outBuf = new unsigned char[*outBufLen]; 252 *outBuf = new unsigned char[*outBufLen];
253 gcry_md_hash_buffer(algo, 253 gcry_md_hash_buffer(algo,
254 *outBuf, 254 *outBuf,
255 inBuf, 255 inBuf,
256 inBufLen); 256 inBufLen);
257 return ret; 257 return ret;
258} 258}
259 259
260unsigned int LibGCryptIf::hashLength(char _algo) 260unsigned int LibGCryptIf::hashLength(char _algo)
261{ 261{
262 unsigned int ret; 262 unsigned int ret;
263 int algo = mapHashId(_algo); 263 int algo = mapHashId(_algo);
264 ret = gcry_md_get_algo_dlen(algo); 264 ret = gcry_md_get_algo_dlen(algo);
265 return ret; 265 return ret;
266} 266}
267 267
268int LibGCryptIf::mapCipherId(char algo) 268int LibGCryptIf::mapCipherId(char algo)
269{ 269{
270 switch (algo) { 270 switch (algo) {
271 case PWM_CRYPT_AES128: 271 case PWM_CRYPT_AES128:
272 return GCRY_CIPHER_AES; 272 return GCRY_CIPHER_AES;
273 case PWM_CRYPT_AES192: 273 case PWM_CRYPT_AES192:
274 return GCRY_CIPHER_AES192; 274 return GCRY_CIPHER_AES192;
275 case PWM_CRYPT_AES256: 275 case PWM_CRYPT_AES256:
276 return GCRY_CIPHER_AES256; 276 return GCRY_CIPHER_AES256;
277 case PWM_CRYPT_3DES: 277 case PWM_CRYPT_3DES:
278 return GCRY_CIPHER_3DES; 278 return GCRY_CIPHER_3DES;
279 case PWM_CRYPT_TWOFISH: 279 case PWM_CRYPT_TWOFISH:
280 return GCRY_CIPHER_TWOFISH; 280 return GCRY_CIPHER_TWOFISH;
281 case PWM_CRYPT_TWOFISH128: 281 case PWM_CRYPT_TWOFISH128:
282 return GCRY_CIPHER_TWOFISH128; 282 return GCRY_CIPHER_TWOFISH128;
283 default: 283 default:
284 BUG(); 284 BUG();
285 } 285 }
286 return GCRY_CIPHER_NONE; 286 return GCRY_CIPHER_NONE;
287} 287}
288 288
289int LibGCryptIf::mapHashId(char algo) 289int LibGCryptIf::mapHashId(char algo)
290{ 290{
291 switch (algo) { 291 switch (algo) {
292 case PWM_HASH_SHA1: 292 case PWM_HASH_SHA1:
293 return GCRY_MD_SHA1; 293 return GCRY_MD_SHA1;
294 case PWM_HASH_SHA256: 294 case PWM_HASH_SHA256:
295 return GCRY_MD_SHA256; 295 return GCRY_MD_SHA256;
296 case PWM_HASH_SHA384: 296 case PWM_HASH_SHA384:
297 return GCRY_MD_SHA384; 297 return GCRY_MD_SHA384;
298 case PWM_HASH_SHA512: 298 case PWM_HASH_SHA512:
299 return GCRY_MD_SHA512; 299 return GCRY_MD_SHA512;
300 case PWM_HASH_MD5: 300 case PWM_HASH_MD5:
301 return GCRY_MD_MD5; 301 return GCRY_MD_MD5;
302 case PWM_HASH_RMD160: 302 case PWM_HASH_RMD160:
303 return GCRY_MD_RMD160; 303 return GCRY_MD_RMD160;
304 case PWM_HASH_TIGER: 304 case PWM_HASH_TIGER:
305 return GCRY_MD_TIGER; 305 return GCRY_MD_TIGER;
306 default: 306 default:
307 BUG(); 307 BUG();
308 } 308 }
309 return GCRY_MD_NONE; 309 return GCRY_MD_NONE;
310} 310}
311 311
312bool LibGCryptIf::hashPassphrase(const unsigned char *pw, 312bool LibGCryptIf::hashPassphrase(const unsigned char *pw,
313 size_t pwlen, 313 size_t pwlen,
314 unsigned char *salt, 314 unsigned char *salt,
315 unsigned char *key, 315 unsigned char *key,
316 size_t keylen, 316 size_t keylen,
317 bool create) 317 bool create)
318{ 318{
319 DEK dek; 319 DEK dek;
320 STRING2KEY s2k; 320 STRING2KEY s2k;
321 bool ret; 321 bool ret;
322 322
323 dek.keylen = keylen; 323 dek.keylen = keylen;
324 s2k.mode = 1; 324 s2k.mode = 1;
325 s2k.hash_algo = mapHashId(conf()->confGlobHashAlgo()); 325 s2k.hash_algo = mapHashId(conf()->confGlobHashAlgo());
326 s2k.count = 0; 326 s2k.count = 0;
327 if (!create) 327 if (!create)
328 memcpy(s2k.salt, salt, STRING2KEY_SALTLEN); 328 memcpy(s2k.salt, salt, STRING2KEY_SALTLEN);
329 ret = doHashPassphrase(&dek, 329 ret = doHashPassphrase(&dek,
330 pw, 330 pw,
331 pwlen, 331 pwlen,
332 &s2k, 332 &s2k,
333 create); 333 create);
334 if (!ret) 334 if (!ret)
335 goto out; 335 goto out;
336 memcpy(key, dek.key, dek.keylen); 336 memcpy(key, dek.key, dek.keylen);
337 if (create) 337 if (create)
338 memcpy(salt, s2k.salt, STRING2KEY_SALTLEN); 338 memcpy(salt, s2k.salt, STRING2KEY_SALTLEN);
339out: 339out:
340 return ret; 340 return ret;
341} 341}
342 342
343 343
344bool LibGCryptIf::doHashPassphrase(DEK *dek, 344bool LibGCryptIf::doHashPassphrase(DEK *dek,
345 const unsigned char *pw, 345 const unsigned char *pw,
346 size_t pwlen, 346 size_t pwlen,
347 STRING2KEY *s2k, 347 STRING2KEY *s2k,
348 bool create) 348 bool create)
349{ 349{
350 // This function is derived from GnuPG-1.2.5-rc2 350 // This function is derived from GnuPG-1.2.5-rc2
351 gcry_md_hd_t md; 351 gcry_md_hd_t md;
352 gcry_error_t err; 352 gcry_error_t err;
353 bool ret = true; 353 bool ret = true;
354 size_t pass, i; 354 size_t pass, i;
355 size_t used = 0; 355 size_t used = 0;
356 356
357 PWM_ASSERT(s2k->hash_algo); 357 PWM_ASSERT(s2k->hash_algo);
358 BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key))); 358 BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key)));
359 359
360 err = gcry_md_open(&md, s2k->hash_algo, 0); 360 err = gcry_md_open(&md, s2k->hash_algo, 0);
361 if (err != GPG_ERR_NO_ERROR) { 361 if (err != GPG_ERR_NO_ERROR) {
362 ret = false; 362 ret = false;
363 goto out; 363 goto out;
364 } 364 }
365 for (pass = 0; used < dek->keylen; pass++) { 365 for (pass = 0; used < dek->keylen; pass++) {
366 if (pass) { 366 if (pass) {
367 gcry_md_reset(md); 367 gcry_md_reset(md);
368 for (i = 0; i < pass; i++) // preset the hash context 368 for (i = 0; i < pass; i++) // preset the hash context
369 gcry_md_putc(md, 0); 369 gcry_md_putc(md, 0);
370 } 370 }
371 if (s2k->mode == 1 || s2k->mode == 3) { 371 if (s2k->mode == 1 || s2k->mode == 3) {
372 size_t len2 = pwlen + 8; 372 size_t len2 = pwlen + 8;
373 size_t count = len2; 373 size_t count = len2;
374 374
375 if (create && !pass) { 375 if (create && !pass) {
376 Randomizer *rnd = Randomizer::obj(); 376 Randomizer *rnd = Randomizer::obj();
377 const unsigned int salt_len = 8; 377 const unsigned int salt_len = 8;
378 string rndBuf(rnd->genRndBuf(salt_len)); 378 string rndBuf(rnd->genRndBuf(salt_len));
379 memcpy(s2k->salt, rndBuf.c_str(), salt_len); 379 memcpy(s2k->salt, rndBuf.c_str(), salt_len);
380 if (s2k->mode == 3) 380 if (s2k->mode == 3)
381 s2k->count = 96; // 65536 iterations 381 s2k->count = 96; // 65536 iterations
382 } 382 }
383 if (s2k->mode == 3) { 383 if (s2k->mode == 3) {
384 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); 384 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
385 if (count < len2) 385 if (count < len2)
386 count = len2; 386 count = len2;
387 } 387 }
388 // a little bit complicated because we need a ulong for count 388 // a little bit complicated because we need a ulong for count
389 while (count > len2) { // maybe iterated+salted 389 while (count > len2) { // maybe iterated+salted
390 gcry_md_write(md, s2k->salt, 8); 390 gcry_md_write(md, s2k->salt, 8);
391 gcry_md_write(md, pw, pwlen); 391 gcry_md_write(md, pw, pwlen);
392 count -= len2; 392 count -= len2;
393 } 393 }
394 if (count < 8) { 394 if (count < 8) {
395 gcry_md_write(md, s2k->salt, count); 395 gcry_md_write(md, s2k->salt, count);
396 } else { 396 } else {
397 gcry_md_write(md, s2k->salt, 8); 397 gcry_md_write(md, s2k->salt, 8);
398 count -= 8; 398 count -= 8;
399 gcry_md_write(md, pw, count); 399 gcry_md_write(md, pw, count);
400 } 400 }
401 } else 401 } else
402 gcry_md_write(md, pw, pwlen); 402 gcry_md_write(md, pw, pwlen);
403 gcry_md_final(md); 403 gcry_md_final(md);
404 i = gcry_md_get_algo_dlen(s2k->hash_algo); 404 i = gcry_md_get_algo_dlen(s2k->hash_algo);
405 if (i > dek->keylen - used) 405 if (i > dek->keylen - used)
406 i = dek->keylen - used; 406 i = dek->keylen - used;
407 memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i); 407 memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i);
408 used += i; 408 used += i;
409 } 409 }
410 gcry_md_close(md); 410 gcry_md_close(md);
411out: 411out:
412 return ret; 412 return ret;
413} 413}
414 414
415void LibGCryptIf::padData(unsigned char *buf, 415void LibGCryptIf::padData(unsigned char *buf,
416 size_t bufLen, 416 size_t bufLen,
417 size_t boundary) 417 size_t boundary)
418{ 418{
419 size_t numPadBytes = boundary - ((bufLen + 1) % boundary); 419 size_t numPadBytes = boundary - ((bufLen + 1) % boundary);
420 buf[bufLen] = static_cast<char>(0x01); 420 buf[bufLen] = static_cast<char>(0x01);
421 size_t i = 0; 421 size_t i = 0;
422 Randomizer *rnd = Randomizer::obj(); 422 Randomizer *rnd = Randomizer::obj();
423 char c; 423 char c;
424 unsigned char *b; 424 unsigned char *b;
425 while (i < numPadBytes) { 425 while (i < numPadBytes) {
426 c = rnd->genRndChar(); 426 c = rnd->genRndChar();
427 if (c == static_cast<char>(0x01)) 427 if (c == static_cast<char>(0x01))
428 continue; 428 continue;
429 b = buf + bufLen + 1 + i; 429 b = buf + bufLen + 1 + i;
430 *b = c; 430 *b = c;
431 ++i; 431 ++i;
432 } 432 }
433} 433}
434 434
435void LibGCryptIf::unpadData(const unsigned char *buf, 435void LibGCryptIf::unpadData(const unsigned char *buf,
436 size_t *bufLen) 436 size_t *bufLen)
437{ 437{
438 size_t pos; 438 size_t pos;
439 BUG_ON(*bufLen % 8); 439 BUG_ON(*bufLen % 8);
440 pos = *bufLen - 1; 440 pos = *bufLen - 1;
441 while (buf[pos] != static_cast<char>(0x01)) { 441 while (buf[pos] != static_cast<char>(0x01)) {
442 BUG_ON(!pos); 442 BUG_ON(!pos);
443 --pos; 443 --pos;
444 } 444 }
445 *bufLen = pos; 445 *bufLen = pos;
446} 446}
447 447
448#endif // CONFIG_PWMANAGER_GCRY 448#endif // CONFIG_PWMANAGER_GCRY
449 449
diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h
index ce76675..dffd55b 100644
--- a/pwmanager/pwmanager/libgcryptif.h
+++ b/pwmanager/pwmanager/libgcryptif.h
@@ -1,166 +1,166 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2004 by Michael Buesch * 3 * copyright (C) 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * hashPassphrase() is derived from GnuPG and is * 6 * hashPassphrase() is derived from GnuPG and is *
7 * Copyright (C) 1998, 1999, 2000, 2001, 2003 * 7 * Copyright (C) 1998, 1999, 2000, 2001, 2003 *
8 * Free Software Foundation, Inc. * 8 * Free Software Foundation, Inc. *
9 * * 9 * *
10 * This program is free software; you can redistribute it and/or modify * 10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License version 2 * 11 * it under the terms of the GNU General Public License version 2 *
12 * as published by the Free Software Foundation. * 12 * as published by the Free Software Foundation. *
13 * * 13 * *
14 ***************************************************************************/ 14 ***************************************************************************/
15 15
16/*************************************************************************** 16/***************************************************************************
17 * copyright (C) 2004 by Ulf Schenk 17 * copyright (C) 2004 by Ulf Schenk
18 * This file is originaly based on version 2.0 of pwmanager 18 * This file is originaly based on version 1.1 of pwmanager
19 * and was modified to run on embedded devices that run microkde 19 * and was modified to run on embedded devices that run microkde
20 * 20 *
21 * $Id$ 21 * $Id$
22 **************************************************************************/ 22 **************************************************************************/
23 23
24#ifndef __LIBGCRYPTIF_H 24#ifndef __LIBGCRYPTIF_H
25#define __LIBGCRYPTIF_H 25#define __LIBGCRYPTIF_H
26 26
27#include "pwmexception.h" 27#include "pwmexception.h"
28 28
29//#undef CONFIG_PWMANAGER_GCRY // for debugging only. 29//#undef CONFIG_PWMANAGER_GCRY // for debugging only.
30#ifdef CONFIG_PWMANAGER_GCRY 30#ifdef CONFIG_PWMANAGER_GCRY
31 31
32#include <stddef.h> 32#include <stddef.h>
33#include <sys/types.h> 33#include <sys/types.h>
34#include <stdint.h> 34#include <stdint.h>
35 35
36 #define STRING2KEY_SALTLEN8 36 #define STRING2KEY_SALTLEN8
37 37
38/** interface class for the libgcrypt cipher and hash algorithms 38/** interface class for the libgcrypt cipher and hash algorithms
39 * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding) 39 * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding)
40 */ 40 */
41class LibGCryptIf 41class LibGCryptIf
42{ 42{
43protected: 43protected:
44 struct STRING2KEY 44 struct STRING2KEY
45 { 45 {
46 int mode; 46 int mode;
47 int hash_algo; 47 int hash_algo;
48 uint8_t salt[STRING2KEY_SALTLEN]; 48 uint8_t salt[STRING2KEY_SALTLEN];
49 uint32_t count; 49 uint32_t count;
50 }; 50 };
51 struct DEK 51 struct DEK
52 { 52 {
53 size_t keylen; 53 size_t keylen;
54 uint8_t key[32]; // this is the largest used keylen (256 bit) 54 uint8_t key[32]; // this is the largest used keylen (256 bit)
55 }; 55 };
56 56
57public: 57public:
58 LibGCryptIf() { } 58 LibGCryptIf() { }
59 /** is libgcrypt available? */ 59 /** is libgcrypt available? */
60 static bool available() 60 static bool available()
61 { return true; } 61 { return true; }
62 /** encrypt data. _algo is the PWM_CRYPT_* ID 62 /** encrypt data. _algo is the PWM_CRYPT_* ID
63 * of the algorithm. 63 * of the algorithm.
64 */ 64 */
65 PwMerror encrypt(unsigned char **outBuf, 65 PwMerror encrypt(unsigned char **outBuf,
66 size_t *outBufLen, 66 size_t *outBufLen,
67 unsigned char *inBuf, 67 unsigned char *inBuf,
68 size_t inBufLen, 68 size_t inBufLen,
69 const unsigned char *key, 69 const unsigned char *key,
70 size_t keylen, 70 size_t keylen,
71 char _algo); 71 char _algo);
72 /** decrypt data. _algo is the PWM_CRYPT_* ID 72 /** decrypt data. _algo is the PWM_CRYPT_* ID
73 * of the algorithm. 73 * of the algorithm.
74 */ 74 */
75 PwMerror decrypt(unsigned char **outBuf, 75 PwMerror decrypt(unsigned char **outBuf,
76 size_t *outBufLen, 76 size_t *outBufLen,
77 const unsigned char *inBuf, 77 const unsigned char *inBuf,
78 size_t inBufLen, 78 size_t inBufLen,
79 const unsigned char *key, 79 const unsigned char *key,
80 size_t keylen, 80 size_t keylen,
81 char _algo); 81 char _algo);
82 /** hash data. _algo is the PWM_HASH_* ID of the hash */ 82 /** hash data. _algo is the PWM_HASH_* ID of the hash */
83 PwMerror hash(unsigned char **outBuf, 83 PwMerror hash(unsigned char **outBuf,
84 size_t *outBufLen, 84 size_t *outBufLen,
85 const unsigned char *inBuf, 85 const unsigned char *inBuf,
86 size_t inBufLen, 86 size_t inBufLen,
87 char _algo); 87 char _algo);
88 /** returns the length of the hash. _algo is the PWM_HASH_* 88 /** returns the length of the hash. _algo is the PWM_HASH_*
89 * id of the hash. returns 0 on error. 89 * id of the hash. returns 0 on error.
90 */ 90 */
91 unsigned int hashLength(char _algo); 91 unsigned int hashLength(char _algo);
92 92
93protected: 93protected:
94 /** returns the total buffer length */ 94 /** returns the total buffer length */
95 size_t getBufLen(size_t inBufLen, size_t boundary) 95 size_t getBufLen(size_t inBufLen, size_t boundary)
96 { 96 {
97 return ((boundary - (inBufLen % boundary)) + inBufLen); 97 return ((boundary - (inBufLen % boundary)) + inBufLen);
98 } 98 }
99 /** pad the data up to the given boundary. 99 /** pad the data up to the given boundary.
100 * "buf" has to be big enough! 100 * "buf" has to be big enough!
101 */ 101 */
102 void padData(unsigned char *buf, 102 void padData(unsigned char *buf,
103 size_t bufLen, 103 size_t bufLen,
104 size_t boundary); 104 size_t boundary);
105 /** unpad the data */ 105 /** unpad the data */
106 void unpadData(const unsigned char *buf, 106 void unpadData(const unsigned char *buf,
107 size_t *bufLen); 107 size_t *bufLen);
108 /** maps the PWM_CRYPT_* ID of an algorithm 108 /** maps the PWM_CRYPT_* ID of an algorithm
109 * to the libgcrypt GCRY_CIPHER_* ID 109 * to the libgcrypt GCRY_CIPHER_* ID
110 */ 110 */
111 int mapCipherId(char algo); 111 int mapCipherId(char algo);
112 /** maps the PWM_HASH_* ID of an algorithm 112 /** maps the PWM_HASH_* ID of an algorithm
113 * to the libgcrypt GCRY_MD_* ID 113 * to the libgcrypt GCRY_MD_* ID
114 */ 114 */
115 int mapHashId(char algo); 115 int mapHashId(char algo);
116 /** hash a passphrase to a cipher key */ 116 /** hash a passphrase to a cipher key */
117 bool hashPassphrase(const unsigned char *pw, 117 bool hashPassphrase(const unsigned char *pw,
118 size_t pwlen, 118 size_t pwlen,
119 unsigned char *salt, 119 unsigned char *salt,
120 unsigned char *key, 120 unsigned char *key,
121 size_t keylen, 121 size_t keylen,
122 bool create); 122 bool create);
123 /** hash a passphrase to a cipher key */ 123 /** hash a passphrase to a cipher key */
124 bool doHashPassphrase(DEK *dek, 124 bool doHashPassphrase(DEK *dek,
125 const unsigned char *pw, 125 const unsigned char *pw,
126 size_t pwlen, 126 size_t pwlen,
127 STRING2KEY *s2k, 127 STRING2KEY *s2k,
128 bool create); 128 bool create);
129}; 129};
130 130
131 131
132#else // CONFIG_PWMANAGER_GCRY 132#else // CONFIG_PWMANAGER_GCRY
133/** libgcrypt is not installed. This is a NOP wrapper. */ 133/** libgcrypt is not installed. This is a NOP wrapper. */
134class LibGCryptIf 134class LibGCryptIf
135{ 135{
136public: 136public:
137 LibGCryptIf() { } 137 LibGCryptIf() { }
138 static bool available() 138 static bool available()
139 { return false; } 139 { return false; }
140 PwMerror encrypt(unsigned char **, 140 PwMerror encrypt(unsigned char **,
141 size_t *, 141 size_t *,
142 unsigned char *, 142 unsigned char *,
143 size_t, 143 size_t,
144 const unsigned char *, 144 const unsigned char *,
145 size_t, 145 size_t,
146 char) 146 char)
147 { return e_cryptNotImpl; } 147 { return e_cryptNotImpl; }
148 PwMerror decrypt(unsigned char **, 148 PwMerror decrypt(unsigned char **,
149 size_t *, 149 size_t *,
150 const unsigned char *, 150 const unsigned char *,
151 size_t, 151 size_t,
152 const unsigned char *, 152 const unsigned char *,
153 size_t, 153 size_t,
154 char) 154 char)
155 { return e_cryptNotImpl; } 155 { return e_cryptNotImpl; }
156 PwMerror hash(unsigned char **, 156 PwMerror hash(unsigned char **,
157 size_t *, 157 size_t *,
158 const unsigned char *, 158 const unsigned char *,
159 size_t, 159 size_t,
160 char) 160 char)
161 { return e_hashNotImpl; } 161 { return e_hashNotImpl; }
162 unsigned int hashLength(char) 162 unsigned int hashLength(char)
163 { return 0; } 163 { return 0; }
164}; 164};
165#endif // CONFIG_PWMANAGER_GCRY 165#endif // CONFIG_PWMANAGER_GCRY
166#endif // __LIBGCRYPTIF_H 166#endif // __LIBGCRYPTIF_H