|
1 /* |
|
2 * Copyright (c) 2000, 2004 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: This module contains the implementation of CCrAlgInfo class. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include "cralginfo.h" |
|
21 |
|
22 #include "random.h" // Random data. |
|
23 |
|
24 |
|
25 // ----------------------------------------------------------------------------- |
|
26 // CCrAlgInfo |
|
27 // Constructor. |
|
28 // This function constructs CCrAlgInfo object. |
|
29 // ----------------------------------------------------------------------------- |
|
30 CCrAlgInfo::CCrAlgInfo() |
|
31 { |
|
32 iType = ECrLAST_SYMM_CRYPTO; |
|
33 iAlgorithmObject = NULL; |
|
34 iLastPortion = NULL; |
|
35 iDigest = NULL; |
|
36 iKey = NULL; |
|
37 iIV = NULL; |
|
38 iEncrypt = ETrue; |
|
39 iSingleBlock = ETrue; |
|
40 iMode = ECrCBC; |
|
41 iPadding = NULL; |
|
42 } |
|
43 |
|
44 // ----------------------------------------------------------------------------- |
|
45 // ~CCrAlgInfo |
|
46 // Destructor. |
|
47 // This function destructs CCrAlgInfo object. |
|
48 // ----------------------------------------------------------------------------- |
|
49 CCrAlgInfo::~CCrAlgInfo() |
|
50 { |
|
51 delete iDigest; |
|
52 delete iLastPortion; |
|
53 delete iKey; |
|
54 delete iIV; |
|
55 |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // CCrAlgInfo::ConstructL |
|
60 // This function initializes this object's members. |
|
61 // Parameters: aType Type of the algorithm |
|
62 // aLen Length of the key or digest |
|
63 // aIVLen Length of the initialization vector |
|
64 // of this object. |
|
65 // aKey Key of this object. |
|
66 // aIV Initialization vector of this object. |
|
67 // aEncrypt = ETrue Encrypt if true, otherwise decrypt. |
|
68 // aSingleBlock = ETrue Single block mode if true. |
|
69 // aMode = ECrCBC Algorithm mode. |
|
70 // ----------------------------------------------------------------------------- |
|
71 void CCrAlgInfo::ConstructL( |
|
72 const TCrAlgorithm aType, |
|
73 const TInt aLen, |
|
74 const TInt aIVLen /* = 0 */, |
|
75 const TDesC8* aKey /* = NULL */, |
|
76 const TDesC8* aIV /* = NULL */, |
|
77 const TBool aEncrypt /* = ETrue */, |
|
78 const TBool aSingleBlock /* = ETrue */, |
|
79 const TCrSymmMode aMode /* = ECrCBC */) |
|
80 { |
|
81 iType = aType; |
|
82 |
|
83 if (iType < ECrLAST_DIGEST) |
|
84 { |
|
85 iDigest = HBufC8::NewL(aLen); |
|
86 } |
|
87 else |
|
88 { |
|
89 iEncrypt = aEncrypt; |
|
90 iSingleBlock = aSingleBlock; |
|
91 iMode = aMode; |
|
92 |
|
93 switch (iType) |
|
94 { |
|
95 case ECrDES3: |
|
96 case ECrDES: |
|
97 case ECrDES2: |
|
98 case ECrDESX: |
|
99 case ECrRC2: |
|
100 case ECrRC5: |
|
101 { |
|
102 iLastPortion = HBufC8::NewL(KCrPaddingLength); |
|
103 iKey = HBufC8::NewL(aLen); |
|
104 iIV = HBufC8::NewL(aIVLen); |
|
105 |
|
106 break; |
|
107 } |
|
108 case ECrRC4: |
|
109 { |
|
110 iLastPortion = HBufC8::NewL(KCrPaddingLength); |
|
111 iKey = HBufC8::NewL(aLen); |
|
112 |
|
113 break; |
|
114 } |
|
115 default: |
|
116 { |
|
117 break; |
|
118 } |
|
119 } |
|
120 |
|
121 // If given key isn't empty, |
|
122 if (aKey && aKey->Length()) |
|
123 { |
|
124 // use it, |
|
125 *iKey = *aKey; |
|
126 |
|
127 // Check if IV is needed. |
|
128 if (iIV != NULL) |
|
129 { |
|
130 // Use given iv, if any. |
|
131 if (aIV && aIV->Length()) |
|
132 { |
|
133 *iIV = *aIV; |
|
134 } |
|
135 else |
|
136 { |
|
137 // Otherwise null iv. |
|
138 TPtr8 ptrIV = iIV->Des(); |
|
139 |
|
140 ptrIV.AppendFill(0, aIVLen); |
|
141 } |
|
142 } |
|
143 } |
|
144 else |
|
145 { |
|
146 /* |
|
147 // otherwise create key. |
|
148 TPtr8 ptrKey = iKey->Des(); |
|
149 |
|
150 // aLen must have a reasonable value. |
|
151 if (aLen < 1 || aLen > ptrKey.MaxLength()) |
|
152 { |
|
153 return; |
|
154 } |
|
155 |
|
156 ptrKey.SetLength(aLen); |
|
157 |
|
158 GetRandom(ptrKey); |
|
159 |
|
160 switch (iType) |
|
161 { |
|
162 case ECrDES3: |
|
163 case ECrDES: |
|
164 case ECrDES2: |
|
165 case ECrDESX: |
|
166 { |
|
167 |
|
168 // Take care that weak keys are not used. |
|
169 // Set parity bits. Check that the key is not weak. |
|
170 // Recreate key until it is not weak. |
|
171 |
|
172 // Key is weak, when weakKey is 1. Then it has to |
|
173 // be recreated. |
|
174 // Key is acceptable, when weakKey is 0. |
|
175 |
|
176 if (aLen == 24) // 3des |
|
177 { |
|
178 TInt weakKey = 1; |
|
179 while (weakKey != 0) |
|
180 { |
|
181 // Put parity bits to DESkeys. |
|
182 SetParityBits(ptrKey); |
|
183 |
|
184 TPtrC8 firstKeyPtr = ptrKey.Left(8); |
|
185 NC_BYTE* tempKey = CONST_CAST(NC_BYTE*, firstKeyPtr.Ptr()); |
|
186 weakKey = des_weak_key(tempKey); |
|
187 |
|
188 if (weakKey == 0) |
|
189 { |
|
190 TPtrC8 secondKeyPtr = ptrKey.Mid(8,8); |
|
191 tempKey = CONST_CAST(NC_BYTE*, secondKeyPtr.Ptr()); |
|
192 weakKey = des_weak_key(tempKey); |
|
193 |
|
194 if (weakKey == 0) |
|
195 { |
|
196 TPtrC8 thirdKeyPtr = ptrKey.Right(8); |
|
197 tempKey = CONST_CAST(NC_BYTE*, thirdKeyPtr.Ptr()); |
|
198 weakKey = des_weak_key(tempKey); |
|
199 } |
|
200 } |
|
201 |
|
202 if (weakKey == 1) |
|
203 { |
|
204 GetRandom(ptrKey); |
|
205 } |
|
206 } |
|
207 } |
|
208 |
|
209 if (aLen == 8) |
|
210 { |
|
211 // Put parity bits to DESkeys. |
|
212 SetParityBits(ptrKey); |
|
213 |
|
214 NC_BYTE* tempKey = CONST_CAST(NC_BYTE*, iKey->Ptr()); |
|
215 TInt weakKey = des_weak_key(tempKey); |
|
216 while (weakKey != 0) |
|
217 { |
|
218 GetRandom(ptrKey); |
|
219 SetParityBits(ptrKey); |
|
220 weakKey = des_weak_key(tempKey ); |
|
221 } |
|
222 } |
|
223 |
|
224 break; |
|
225 } |
|
226 default: |
|
227 break; |
|
228 } |
|
229 |
|
230 // Check if IV is needed. |
|
231 if (iIV != NULL) |
|
232 { |
|
233 // create iv. |
|
234 TPtr8 ptrIV = iIV->Des(); |
|
235 |
|
236 ptrIV.SetLength(aIVLen); |
|
237 |
|
238 GetRandom(ptrIV); |
|
239 }*/ |
|
240 } |
|
241 } |
|
242 |
|
243 } |
|
244 |
|
245 // ----------------------------------------------------------------------------- |
|
246 // CCrAlgInfo::NewLC |
|
247 // This function implements the two-phase construction of this class. |
|
248 // The function uses standard constructor to reserve memory for |
|
249 // CCrAlgInfo object, stores a pointer to the object into clean up |
|
250 // stack, and returns the pointer to the object. |
|
251 // ----------------------------------------------------------------------------- |
|
252 CCrAlgInfo* CCrAlgInfo::NewLC( |
|
253 const TCrAlgorithm aType, |
|
254 const TDesC8& aKey, |
|
255 const TDesC8& aIV, |
|
256 const TBool aEncrypt /* = ETrue */, |
|
257 const TBool aSingleBlock /* = ETrue */, |
|
258 const TCrSymmMode aMode /* = ECrCBC */) |
|
259 { |
|
260 TInt keyLen = aKey.Length(); |
|
261 TInt ivLen = aIV.Length(); |
|
262 |
|
263 CCrAlgInfo* self = new (ELeave) CCrAlgInfo(); |
|
264 CleanupStack::PushL(self); |
|
265 |
|
266 // If given key is empty, assume that caller wants us to create key. |
|
267 if (keyLen == 0) |
|
268 { |
|
269 switch (aType) |
|
270 { |
|
271 case ECrDES3: |
|
272 { |
|
273 keyLen = 3 * KCrDESKeyLength; |
|
274 |
|
275 break; |
|
276 } |
|
277 case ECrDES: |
|
278 { |
|
279 keyLen = KCrDESKeyLength; |
|
280 |
|
281 break; |
|
282 } |
|
283 case ECrDES2: |
|
284 { |
|
285 keyLen = 2 * KCrDESKeyLength; |
|
286 |
|
287 break; |
|
288 } |
|
289 case ECrDESX: |
|
290 { |
|
291 keyLen = 3 * KCrDESKeyLength; |
|
292 |
|
293 break; |
|
294 } |
|
295 case ECrRC2: |
|
296 case ECrRC5: |
|
297 { |
|
298 keyLen = KCrRCLongKeyLength; |
|
299 |
|
300 break; |
|
301 } |
|
302 case ECrRC4: |
|
303 { |
|
304 keyLen = KCrRCLongKeyLength; |
|
305 |
|
306 break; |
|
307 } |
|
308 default: |
|
309 { |
|
310 break; |
|
311 } |
|
312 } |
|
313 } |
|
314 |
|
315 // If given iv is empty, assume that caller wants us to create iv. |
|
316 if (ivLen == 0) |
|
317 { |
|
318 switch (aType) |
|
319 { |
|
320 case ECrDES3: |
|
321 { |
|
322 ivLen = KCrDESIVLength; |
|
323 |
|
324 break; |
|
325 } |
|
326 case ECrDES: |
|
327 { |
|
328 ivLen = KCrDESIVLength; |
|
329 |
|
330 break; |
|
331 } |
|
332 case ECrDES2: |
|
333 { |
|
334 ivLen = KCrDESIVLength; |
|
335 |
|
336 break; |
|
337 } |
|
338 case ECrDESX: |
|
339 { |
|
340 ivLen = KCrDESIVLength; |
|
341 |
|
342 break; |
|
343 } |
|
344 case ECrRC2: |
|
345 case ECrRC5: |
|
346 { |
|
347 ivLen = KCrRCIVLength; |
|
348 |
|
349 break; |
|
350 } |
|
351 case ECrRC4: |
|
352 { |
|
353 break; |
|
354 } |
|
355 default: |
|
356 { |
|
357 break; |
|
358 } |
|
359 } |
|
360 } |
|
361 |
|
362 self->ConstructL( |
|
363 aType, |
|
364 keyLen, |
|
365 ivLen, |
|
366 &aKey, |
|
367 &aIV, |
|
368 aEncrypt, |
|
369 aSingleBlock, |
|
370 aMode); |
|
371 |
|
372 return self; |
|
373 } |
|
374 |
|
375 // ----------------------------------------------------------------------------- |
|
376 // CCrAlgInfo::NewLC |
|
377 // This function implements the two-phase construction of this class. |
|
378 // The function uses standard constructor to reserve memory for |
|
379 // CCrAlgInfo object, stores a pointer to the object into clean up |
|
380 // stack, and returns the pointer to the object. |
|
381 // ----------------------------------------------------------------------------- |
|
382 CCrAlgInfo* CCrAlgInfo::NewLC(const TCrAlgorithm aType) |
|
383 { |
|
384 TInt len = 0; |
|
385 |
|
386 CCrAlgInfo* self = new (ELeave) CCrAlgInfo(); |
|
387 CleanupStack::PushL(self); |
|
388 |
|
389 switch (aType) |
|
390 { |
|
391 case ECrSHA1: |
|
392 case ECrHMAC_SHA1: |
|
393 case ECrHMAC_RIPEMD: |
|
394 case ECrRIPEMD: |
|
395 case ECrSHA: |
|
396 { |
|
397 len = KCrLongDigestLength; |
|
398 break; |
|
399 } |
|
400 case ECrMD5: |
|
401 case ECrMD2: |
|
402 case ECrHMAC_MD5: |
|
403 { |
|
404 len = KCrMediumDigestLength; |
|
405 break; |
|
406 } |
|
407 default: |
|
408 { |
|
409 break; |
|
410 } |
|
411 } |
|
412 |
|
413 self->ConstructL(aType, len); |
|
414 |
|
415 return self; |
|
416 } |
|
417 |
|
418 // -------------------------------------------------------------------------------- |
|
419 // CCrAlgInfo::NewL |
|
420 // This function implements the two-phase construction of this class. |
|
421 // The function reserves memory for CCrAlgInfo object and returns |
|
422 // pointer to that object. This function uses NewLC to create the object |
|
423 // and store it to cleanup stack. Finally the object is popped from clean |
|
424 // up stack. |
|
425 // -------------------------------------------------------------------------------- |
|
426 CCrAlgInfo* CCrAlgInfo::NewL( |
|
427 const TCrAlgorithm aType, |
|
428 const TDesC8& aKey, |
|
429 const TDesC8& aIV, |
|
430 const TBool aEncrypt /* = ETrue */, |
|
431 const TBool aSingleBlock /* = ETrue */, |
|
432 const TCrSymmMode aMode /* = ECrCBC */) |
|
433 { |
|
434 CCrAlgInfo* self = NewLC( |
|
435 aType, |
|
436 aKey, |
|
437 aIV, |
|
438 aEncrypt, |
|
439 aSingleBlock, |
|
440 aMode); |
|
441 |
|
442 CleanupStack::Pop(); |
|
443 |
|
444 return self; |
|
445 } |
|
446 |
|
447 // -------------------------------------------------------------------------------- |
|
448 // CCrAlgInfo::NewL |
|
449 // This function implements the two-phase construction of this class. |
|
450 // The function reserves memory for CCrAlgInfo object and returns |
|
451 // pointer to that object. This function uses NewLC to create the object |
|
452 // and store it to cleanup stack. Finally the object is popped from clean |
|
453 // up stack. |
|
454 // -------------------------------------------------------------------------------- |
|
455 CCrAlgInfo* CCrAlgInfo::NewL(const TCrAlgorithm aType) |
|
456 { |
|
457 CCrAlgInfo* self = NewLC(aType); |
|
458 |
|
459 CleanupStack::Pop(); |
|
460 |
|
461 return self; |
|
462 } |
|
463 |
|
464 // -------------------------------------------------------------------------------- |
|
465 // CCrAlgInfo::SetParityBits |
|
466 // Sets parity bits to des keys. |
|
467 // -------------------------------------------------------------------------------- |
|
468 TCrStatus CCrAlgInfo::SetParityBits(TPtr8 aPtrKey) |
|
469 { |
|
470 TInt len = aPtrKey.Length(); |
|
471 if (len < 1 ) // len should be positive |
|
472 { |
|
473 return KCrNotInitialized; |
|
474 } |
|
475 |
|
476 for (TInt i = 0; i < len; i++) |
|
477 { |
|
478 TUint temp = aPtrKey[i]; |
|
479 TInt parity = 0; |
|
480 for (TInt j = 0; j < 7; j++) |
|
481 { |
|
482 temp >>= 1; |
|
483 if (temp & 0x01) |
|
484 { |
|
485 parity++; |
|
486 } |
|
487 } |
|
488 |
|
489 if ((parity % 2) == 0) |
|
490 { |
|
491 // even parity, change least significant bit to one. |
|
492 aPtrKey[i] |= 0x01; // or |
|
493 } |
|
494 else |
|
495 { |
|
496 // Change least significant bit to zero. |
|
497 aPtrKey[i] &= 0xfe; // and |
|
498 } |
|
499 } |
|
500 return KCrOK; |
|
501 } |
|
502 |
|
503 // End Of File |