|
1 /* |
|
2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Contains implementation for encryption/decryption. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #define EMULATOR ((defined(__WINS__) || defined(__WINSCW__))) |
|
22 |
|
23 #include <e32def.h> |
|
24 //#include <des.h> |
|
25 #include <hash.h> |
|
26 #include <errno.h> |
|
27 #include <string.h> |
|
28 |
|
29 // EXTERNAL FUNCTION PROTOTYPES |
|
30 extern "C" char *crypt_des(const char *key, const char *setting); |
|
31 extern "C" char *crypt_md5(const char *pw, const char *salt); |
|
32 |
|
33 // LOCAL CONSTANTS AND MACROS |
|
34 #define BYTE_SIZE 8 |
|
35 #define ENCRYPTION 0 |
|
36 #define DECRYPTION 1 |
|
37 |
|
38 // STATIC DATA |
|
39 #if !EMULATOR |
|
40 TBuf8<BYTE_SIZE> desKey; // For persistence between calls |
|
41 // to setkey() and encrypt() |
|
42 static TInt bSetkeyInvoked = 0; |
|
43 #else |
|
44 #include <sys/types.h> |
|
45 #include "wsd_solution.h" |
|
46 #define bSetkeyInvoked (GetGlobals()->bSetkeyInvoked) |
|
47 #endif |
|
48 |
|
49 // LOCAL FUNCTION PROTOTYPES |
|
50 static unsigned char GetByte(const char *bitVector); |
|
51 static void DesEncryptionL(const TDes8& aKey, TDes8& aInputBlock); |
|
52 static void DesDecryptionL(const TDes8& aKey, TDes8& aInputBlock); |
|
53 |
|
54 // LOCAL class declaration |
|
55 class CEncDecHack : public CBase |
|
56 { |
|
57 public: |
|
58 virtual void Transform(TDes8& aBlock){} |
|
59 }; |
|
60 |
|
61 typedef CEncDecHack* (*LookupFuncEncDecObjCreator)(const TDesC8& aKey, TBool aCheckWeakKey); |
|
62 |
|
63 _LIT(KCryptoDll,"cryptography.dll"); |
|
64 |
|
65 // ----------------------------------------------------------------------------- |
|
66 // function_name: _setkey |
|
67 // |
|
68 // Prepares a byte array for the key from the contents of the incoming bit vector. |
|
69 // Key thus constructed is statically stored for use during encryption/decryption. |
|
70 // |
|
71 // Returns: void |
|
72 // ----------------------------------------------------------------------------- |
|
73 // |
|
74 extern "C" |
|
75 void _setkey (const char *key) |
|
76 { |
|
77 #if !EMULATOR |
|
78 // Reset the contents of the 'key' descriptor |
|
79 desKey.Delete(0,desKey.Length()); |
|
80 #endif |
|
81 |
|
82 #if !EMULATOR |
|
83 // Pack the contents of the bit vector into a TDes derived object |
|
84 for( int i = 0 ; i < BYTE_SIZE ; ++i) |
|
85 { |
|
86 desKey.Append( GetByte( &key[i * BYTE_SIZE] ) ); |
|
87 } |
|
88 #else |
|
89 for(int i=0 ; i<64 ; ++i) |
|
90 { |
|
91 (GetGlobals()->desKey)[i] = key[i]; |
|
92 } |
|
93 #endif |
|
94 |
|
95 bSetkeyInvoked = 1; |
|
96 } |
|
97 |
|
98 // ----------------------------------------------------------------------------- |
|
99 // function_name: _encrypt |
|
100 // |
|
101 // Performs either encryption or decryption of the data block. Prior to invoking |
|
102 // Symbian OS cryptography APIs for encryptions/decryption, this function |
|
103 // packs the contents of the bit vector into a byte array of size eight. The byte |
|
104 // array obtained after encryption/decryption is unpacked to present the output |
|
105 // in the form of a bit vector. The incoming data block is modified in place |
|
106 // during the process. |
|
107 // |
|
108 // Assumption: User of the libcrypt library is expected the create a cleanupstack |
|
109 // |
|
110 // Returns: void |
|
111 // ----------------------------------------------------------------------------- |
|
112 // |
|
113 extern "C" |
|
114 void _encrypt (char block[], int edflag) |
|
115 { |
|
116 #if EMULATOR |
|
117 TBuf8<BYTE_SIZE> desKey; |
|
118 #endif |
|
119 |
|
120 // Determine if setkey() is invoked by the user |
|
121 if(!bSetkeyInvoked) |
|
122 { |
|
123 // Initialize the key with default values |
|
124 for(int i = 0 ; i < BYTE_SIZE ; ++i) |
|
125 { |
|
126 desKey.Append((unsigned char)0); |
|
127 } |
|
128 bSetkeyInvoked = 1; |
|
129 } |
|
130 #if EMULATOR |
|
131 else |
|
132 { |
|
133 for(int i=0 ; i<BYTE_SIZE ; ++i) |
|
134 { |
|
135 desKey.Append( GetByte( (const char*)&(GetGlobals()->desKey)[i * BYTE_SIZE] )); |
|
136 } |
|
137 } |
|
138 #endif |
|
139 |
|
140 // Determine whether encryption or decryption is requested |
|
141 if(edflag != ENCRYPTION) |
|
142 { |
|
143 if(edflag != DECRYPTION) |
|
144 { |
|
145 // Unrecognized flag parameter |
|
146 errno = EPERM; |
|
147 return; |
|
148 } |
|
149 } |
|
150 |
|
151 // Pack the contents of the input bit vector into a "byte" array |
|
152 TBuf8<BYTE_SIZE> inputBlock; |
|
153 TInt nIterator; |
|
154 for(nIterator = 0 ; nIterator < BYTE_SIZE ; ++nIterator) |
|
155 { |
|
156 inputBlock.Append( GetByte( &block[nIterator * BYTE_SIZE] ) ); |
|
157 } |
|
158 |
|
159 TInt error = KErrNone; |
|
160 typedef void (*DesOperation)(const TDes8&, TDes8&); |
|
161 DesOperation funcOperationL = NULL; |
|
162 |
|
163 switch(edflag) |
|
164 { |
|
165 case ENCRYPTION: // Encryption |
|
166 funcOperationL = DesEncryptionL; |
|
167 break; |
|
168 |
|
169 case DECRYPTION: // Decryption |
|
170 funcOperationL = DesDecryptionL; |
|
171 break; |
|
172 } |
|
173 |
|
174 TRAP(error, (*funcOperationL)(desKey, inputBlock)); |
|
175 |
|
176 if(error == KErrNone) |
|
177 { |
|
178 unsigned char chTemp; |
|
179 int k = 0; |
|
180 |
|
181 // Create the bit vector from the "byte" array (unpack) |
|
182 for(int i = 0 ; i < BYTE_SIZE ; ++i) |
|
183 { |
|
184 chTemp = inputBlock[i]; |
|
185 for(int j = 0 ; j < BYTE_SIZE ; ++j) |
|
186 { |
|
187 block[k++] = ((chTemp & 0x80) >> 7); |
|
188 chTemp <<= 1; |
|
189 } |
|
190 } |
|
191 } |
|
192 else |
|
193 { |
|
194 // Set the errno flag to indicate failure |
|
195 errno = EPERM; |
|
196 } |
|
197 } |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // function_name: _crypt |
|
201 // |
|
202 // Uses MD5-based algorithm or DES encryption mechanism to encode a constant |
|
203 // string using "key" as the key. Salt determines the algorithm to be used. |
|
204 // |
|
205 // Returns: pointer to a static data buffer containing the encoded "string" |
|
206 // ----------------------------------------------------------------------------- |
|
207 // |
|
208 extern "C" |
|
209 char* _crypt (const char *key, const char *salt) |
|
210 { |
|
211 // Identify the algorithm to be used as part of crypt |
|
212 if(strstr(salt, "$1$")) |
|
213 { |
|
214 // MD5-based algorithm |
|
215 return crypt_md5(key, salt); |
|
216 } |
|
217 else |
|
218 { |
|
219 return crypt_des(key, salt); |
|
220 } |
|
221 } |
|
222 |
|
223 // ----------------------------------------------------------------------------- |
|
224 // function_name: GetByte |
|
225 // |
|
226 // Packs the "bits" in the bit vector into a byte |
|
227 // |
|
228 // Returns: Byte composed of the bits from the bit vector |
|
229 // ----------------------------------------------------------------------------- |
|
230 // |
|
231 LOCAL_C unsigned char GetByte(const char *bitVector) |
|
232 { |
|
233 unsigned char chTemp = 0; |
|
234 |
|
235 for(int nIterator = 0 ; nIterator < BYTE_SIZE ; ++nIterator) |
|
236 { |
|
237 chTemp |= ( bitVector[nIterator] << (BYTE_SIZE - nIterator - 1) ); |
|
238 } |
|
239 return chTemp; |
|
240 } |
|
241 |
|
242 // ----------------------------------------------------------------------------- |
|
243 // function_name: DesEncryptionL |
|
244 // |
|
245 // Function to encrypt the input data bytes by invoking Symbian OS API for |
|
246 // DES algorithm for encryption |
|
247 // |
|
248 // Assumption: 1. BLOCKSIZE within the cryptography library is 8 for |
|
249 // DES encryption |
|
250 // 2. The input key is not checked against a set of known |
|
251 // weak key values |
|
252 // |
|
253 // Returns: void, however, this function leaves if there is insufficient |
|
254 // memory |
|
255 // ----------------------------------------------------------------------------- |
|
256 // |
|
257 LOCAL_C void DesEncryptionL(const TDes8& aKey, TDes8& aInputBlock) |
|
258 { |
|
259 // Construct the encryptor object |
|
260 /* CDESEncryptor *pEncryptor = CDESEncryptor::NewL(aKey, EFalse); |
|
261 |
|
262 if(!pEncryptor) |
|
263 { |
|
264 User::Leave(KErrNoMemory); |
|
265 } |
|
266 |
|
267 // Invoke DES trasnformation to encrypt the input data |
|
268 pEncryptor->Transform(aInputBlock); |
|
269 |
|
270 delete pEncryptor; |
|
271 */ |
|
272 RLibrary library; |
|
273 User::LeaveIfError(library.Load(KCryptoDll)); |
|
274 |
|
275 #ifdef __WINSCW__ |
|
276 TLibraryFunction func = library.Lookup(102); // CDESEncryptor::NewL |
|
277 #else |
|
278 TLibraryFunction func = library.Lookup(59); //CDESEncryptor::NewL |
|
279 #endif // ifdef __WINSCW__ |
|
280 |
|
281 if (func == NULL) |
|
282 { |
|
283 library.Close(); |
|
284 User::Leave(KErrNotFound); |
|
285 } |
|
286 LookupFuncEncDecObjCreator objCreatorFuncion = reinterpret_cast<LookupFuncEncDecObjCreator> (func); |
|
287 CEncDecHack* pEncryptor = reinterpret_cast<CEncDecHack*>(objCreatorFuncion(aKey, EFalse)); |
|
288 pEncryptor->Transform(aInputBlock); |
|
289 delete pEncryptor; |
|
290 library.Close(); |
|
291 } |
|
292 |
|
293 // ----------------------------------------------------------------------------- |
|
294 // function_name: DesDecryptionL |
|
295 // |
|
296 // Function to encrypt the input data bytes by invoking Symbian OS API for |
|
297 // DES algorithm for decryption |
|
298 // |
|
299 // Assumption: 1. BLOCKSIZE within the cryptography library is 8 for |
|
300 // DES decryption |
|
301 // 2. The input key is not checked against a set of known |
|
302 // weak key values |
|
303 // |
|
304 // Returns: void, however, this function leaves if there is insufficient |
|
305 // memory |
|
306 // ----------------------------------------------------------------------------- |
|
307 // |
|
308 LOCAL_C void DesDecryptionL(const TDes8& aKey, TDes8& aInputBlock) |
|
309 { |
|
310 // Construct the decryptor object |
|
311 /* CDESDecryptor *pDecryptor = CDESDecryptor::NewL(aKey, EFalse); |
|
312 |
|
313 if(!pDecryptor) |
|
314 { |
|
315 User::Leave(KErrNoMemory); |
|
316 } |
|
317 |
|
318 // Invoke DES decryption on the cipher text |
|
319 pDecryptor->Transform(aInputBlock); |
|
320 |
|
321 delete pDecryptor; |
|
322 */ |
|
323 RLibrary library; |
|
324 User::LeaveIfError(library.Load(KCryptoDll)); |
|
325 |
|
326 #ifdef __WINSCW__ |
|
327 TLibraryFunction func = library.Lookup(101); // CDESDecryptor::NewL |
|
328 #else |
|
329 TLibraryFunction func = library.Lookup(57); //CDESDecryptor::NewL |
|
330 #endif // ifdef __WINSCW |
|
331 |
|
332 if (func == NULL) |
|
333 { |
|
334 library.Close(); |
|
335 return; |
|
336 } |
|
337 LookupFuncEncDecObjCreator objCreatorFuncion = reinterpret_cast<LookupFuncEncDecObjCreator> (func); |
|
338 CEncDecHack* pDecryptor = reinterpret_cast<CEncDecHack*>(objCreatorFuncion(aKey, EFalse)); |
|
339 pDecryptor->Transform(aInputBlock); |
|
340 delete pDecryptor; |
|
341 library.Close(); |
|
342 } |
|
343 |
|
344 extern "C" { |
|
345 |
|
346 // ----------------------------------------------------------------------------- |
|
347 // function_name: Deallocate2DimensionalUchar |
|
348 // |
|
349 // To deallocate storage alloted for the two dimensional array |
|
350 // |
|
351 // Returns: void |
|
352 // ----------------------------------------------------------------------------- |
|
353 // |
|
354 void Deallocate2DimensionalUchar(unsigned char **buffer, int row) |
|
355 { |
|
356 int m; |
|
357 for(m=0 ; m<row ; ++m) |
|
358 { |
|
359 User::Free((TAny *)buffer[m]); |
|
360 } |
|
361 User::Free((TAny *)buffer); |
|
362 } |
|
363 |
|
364 // ----------------------------------------------------------------------------- |
|
365 // function_name: Deallocate2DimensionalUint |
|
366 // |
|
367 // To deallocate storage alloted for the two dimensional array |
|
368 // |
|
369 // Returns: void |
|
370 // ----------------------------------------------------------------------------- |
|
371 // |
|
372 void Deallocate2DimensionalUint(__uint32_t **buffer, int row) |
|
373 { |
|
374 int m; |
|
375 for(m=0 ; m<row ; ++m) |
|
376 { |
|
377 User::Free((TAny *)buffer[m]); |
|
378 } |
|
379 User::Free((TAny *)buffer); |
|
380 } |
|
381 |
|
382 // ----------------------------------------------------------------------------- |
|
383 // function_name: Allocate2DimensionalUchar |
|
384 // |
|
385 // Function to allocate storage for a two dimensional array from the heap. |
|
386 // If heap exhaustion occurs during the course of allocating memory to the array, |
|
387 // the previously allocated storage will be deleted prior to returning to the |
|
388 // caller. |
|
389 // |
|
390 // Returns: non-zero if allocation is successful, 0 if it fails |
|
391 // ----------------------------------------------------------------------------- |
|
392 // |
|
393 int Allocate2DimensionalUchar(unsigned char ***buffer, int row, int column) |
|
394 { |
|
395 *buffer = (unsigned char **)User::Alloc(row * sizeof(unsigned char *)); |
|
396 if(NULL == *buffer) |
|
397 { |
|
398 return 0; |
|
399 } |
|
400 for(int m=0 ; m<row ; ++m) |
|
401 { |
|
402 (*buffer)[m] = (unsigned char *)User::Alloc(column * sizeof(unsigned char)); |
|
403 if(NULL == (*buffer)[m]) |
|
404 { |
|
405 // Insufficient heap memory |
|
406 if(m) |
|
407 { |
|
408 // Deallocate the previously allocated storage |
|
409 Deallocate2DimensionalUchar(*buffer, m); |
|
410 } |
|
411 return 0; |
|
412 } |
|
413 } |
|
414 |
|
415 return 1; |
|
416 } |
|
417 |
|
418 // ----------------------------------------------------------------------------- |
|
419 // function_name: Allocate2DimensionalUint |
|
420 // |
|
421 // Function to allocate storage for a two dimensional array of type unsigned int |
|
422 // from the heap. If heap exhaustion occurs while allocating memory to the array, |
|
423 // the previously allocated storage will be deleted prior to returning to the |
|
424 // caller. |
|
425 // |
|
426 // Returns: non-zero if allocation is successful, 0 if it fails |
|
427 // ----------------------------------------------------------------------------- |
|
428 // |
|
429 int Allocate2DimensionalUint(__uint32_t ***buffer, int row, int column) |
|
430 { |
|
431 *buffer = (__uint32_t **)User::Alloc(row * sizeof(__uint32_t *)); |
|
432 if(NULL == *buffer) |
|
433 { |
|
434 return 0; |
|
435 } |
|
436 for(int m=0 ; m<row ; ++m) |
|
437 { |
|
438 (*buffer)[m] = (__uint32_t *)User::Alloc(column * sizeof(__uint32_t)); |
|
439 if(NULL == (*buffer)[m]) |
|
440 { |
|
441 // Insufficient heap memory |
|
442 if(m) |
|
443 { |
|
444 // Deallocate the previously allocated storage |
|
445 Deallocate2DimensionalUint(*buffer, m); |
|
446 } |
|
447 return 0; |
|
448 } |
|
449 } |
|
450 |
|
451 return 1; |
|
452 } |
|
453 |
|
454 } // <<end extern "C">> |