|
1 /* |
|
2 * Copyright (c) 2002-2008 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: OMA DRM 2.x Crypto Algorithms |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <e32std.h> |
|
22 #include <asymmetric.h> |
|
23 #include <symmetric.h> |
|
24 #include <hash.h> |
|
25 #include "OmaCrypto.h" |
|
26 #include "DrmKeyStorage.h" |
|
27 |
|
28 #ifdef _DEBUG |
|
29 #define LOGGING |
|
30 #endif |
|
31 |
|
32 #ifdef LOGGING |
|
33 _LIT(KLogDir, "DRM"); |
|
34 _LIT(KLogName, "Crypto.log"); |
|
35 #include "flogger.h" |
|
36 #define LOG(string) \ |
|
37 RFileLogger::Write(KLogDir, KLogName, \ |
|
38 EFileLoggingModeAppend, string); |
|
39 #define LOGHEX(buffer) \ |
|
40 RFileLogger::HexDump(KLogDir, KLogName, \ |
|
41 EFileLoggingModeAppend, _S(""), _S(""), \ |
|
42 buffer.Ptr(), buffer.Length()); |
|
43 #define LOGFMT(string, value) \ |
|
44 RFileLogger::WriteFormat(KLogDir, KLogName, \ |
|
45 EFileLoggingModeAppend, string, value); |
|
46 #else |
|
47 #define LOG |
|
48 #define LOGHEX |
|
49 #define LOGFMT |
|
50 #endif |
|
51 |
|
52 // LOCAL CONSTANTS AND MACROS |
|
53 |
|
54 _LIT8(KWrapIv, "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6"); |
|
55 |
|
56 // LOCAL FUNCTION PROTOTYPES |
|
57 LOCAL_C void DeleteObject( TAny* aObject ); |
|
58 |
|
59 // FORWARD DECLARATIONS |
|
60 |
|
61 // ============================= LOCAL FUNCTIONS =============================== |
|
62 |
|
63 // ---------------------------------------------------------------------------- |
|
64 // DeleteObject |
|
65 // Deletes the file by TFileName presented by aHandle |
|
66 // ---------------------------------------------------------------------------- |
|
67 // |
|
68 LOCAL_C void DeleteObject( TAny* aObject ) |
|
69 { |
|
70 __ASSERT_DEBUG( aObject, User::Panic( _L( "DeleteObject" ), KErrArgument ) ); |
|
71 MDrmKeyStorage* object = reinterpret_cast< MDrmKeyStorage* >( aObject ); |
|
72 delete object; |
|
73 object = NULL; |
|
74 } |
|
75 |
|
76 |
|
77 // ============================ MEMBER FUNCTIONS =============================== |
|
78 |
|
79 // ----------------------------------------------------------------------------- |
|
80 // OmaCrypto:: |
|
81 // |
|
82 // ----------------------------------------------------------------------------- |
|
83 // |
|
84 EXPORT_C void OmaCrypto::WriteUint32ToBlock( |
|
85 TUint32 aInt, |
|
86 TDes8& aBlock, |
|
87 TInt aOffset) |
|
88 { |
|
89 aBlock[aOffset] = (aInt & 0xff000000) >> 24; |
|
90 aBlock[aOffset + 1] = (aInt & 0x00ff0000) >> 16; |
|
91 aBlock[aOffset + 2] = (aInt & 0x0000ff00) >> 8; |
|
92 aBlock[aOffset + 3] = (aInt & 0x000000ff); |
|
93 } |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // OmaCrypto:: |
|
97 // |
|
98 // ----------------------------------------------------------------------------- |
|
99 // |
|
100 EXPORT_C HBufC8* OmaCrypto::RsaDecryptL( |
|
101 MDrmKeyStorage* aKeyStorage, |
|
102 const TDesC8& aInput) |
|
103 { |
|
104 return aKeyStorage->RsaDecryptL(aInput); |
|
105 } |
|
106 |
|
107 // ----------------------------------------------------------------------------- |
|
108 // OmaCrypto:: |
|
109 // |
|
110 // ----------------------------------------------------------------------------- |
|
111 // |
|
112 EXPORT_C HBufC8* OmaCrypto::RsaEncryptL( |
|
113 CRSAPublicKey* aKey, |
|
114 const TDesC8& aInput) |
|
115 { |
|
116 RInteger result; |
|
117 RInteger input; |
|
118 HBufC8* output; |
|
119 |
|
120 input = OS2IPL(aInput); |
|
121 CleanupClosePushL(input); |
|
122 result = TInteger::ModularExponentiateL(input, aKey->E(), aKey->N()); |
|
123 CleanupClosePushL(result); |
|
124 output = I2OSPL(result); |
|
125 |
|
126 #ifdef LOGGING |
|
127 HBufC8* buffer = NULL; |
|
128 LOG(_L8("RsaEncryptL")); |
|
129 LOG(_L8("Input")); |
|
130 LOGHEX(aInput); |
|
131 buffer = aKey->E().BufferLC(); |
|
132 LOG(_L8("E")); |
|
133 LOGHEX((*buffer)); |
|
134 CleanupStack::PopAndDestroy(buffer); |
|
135 buffer = aKey->N().BufferLC(); |
|
136 LOG(_L8("N")); |
|
137 LOGHEX((*buffer)); |
|
138 CleanupStack::PopAndDestroy(buffer); |
|
139 LOG(_L8("Result")); |
|
140 LOGHEX((*output)); |
|
141 #endif |
|
142 |
|
143 CleanupStack::PopAndDestroy(2); // result, input |
|
144 return output; |
|
145 } |
|
146 |
|
147 // ----------------------------------------------------------------------------- |
|
148 // OmaCrypto:: |
|
149 // |
|
150 // ----------------------------------------------------------------------------- |
|
151 // |
|
152 EXPORT_C HBufC8* OmaCrypto::RsaVerifyL( |
|
153 CRSAPublicKey* aKey, |
|
154 const TDesC8& aInput) |
|
155 { |
|
156 RInteger result; |
|
157 RInteger input; |
|
158 HBufC8* output; |
|
159 |
|
160 input = OS2IPL(aInput); |
|
161 CleanupClosePushL(input); |
|
162 result = TInteger::ModularExponentiateL(input, aKey->E(), aKey->N()); |
|
163 CleanupClosePushL(result); |
|
164 output = I2OSPL(result); |
|
165 CleanupStack::PopAndDestroy(2); // result, input |
|
166 return output; |
|
167 } |
|
168 |
|
169 // ----------------------------------------------------------------------------- |
|
170 // OmaCrypto:: |
|
171 // |
|
172 // ----------------------------------------------------------------------------- |
|
173 // |
|
174 EXPORT_C HBufC8* OmaCrypto::RsaKemKwsEncryptL( |
|
175 CRSAPublicKey* aKey, |
|
176 const TDesC8& aRek, |
|
177 const TDesC8& aMac) |
|
178 { |
|
179 HBufC8* C1 = NULL; |
|
180 HBufC8* C2 = NULL; |
|
181 HBufC8* C; |
|
182 TPtr8 c(0, 0); |
|
183 TBuf8<128> Z; |
|
184 TBuf8<KKeySize + KMacSize> keyAndMac; |
|
185 HBufC8* kek = NULL; |
|
186 const TUint8 KFirstBitMask( 0x7f ); |
|
187 |
|
188 Z.SetLength(128); |
|
189 MDrmKeyStorage* storage = DrmKeyStorageNewL(); |
|
190 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
191 CleanupStack::PushL(storageCleanup); |
|
192 storage->RandomDataGetL(Z,Z.Size()); |
|
193 CleanupStack::PopAndDestroy( storage ); |
|
194 |
|
195 Z[0] &= KFirstBitMask; |
|
196 |
|
197 #ifdef LOGGING |
|
198 LOG(_L("RsaKemKwsEncryptL")); |
|
199 LOG(_L("random Z")); |
|
200 LOGHEX(Z); |
|
201 #endif |
|
202 C1 = RsaEncryptL(aKey, Z); |
|
203 CleanupStack::PushL(C1); |
|
204 kek = KdfL(Z, KNullDesC8, KKeySize); |
|
205 CleanupStack::PushL(kek); |
|
206 keyAndMac.Copy(aMac); |
|
207 keyAndMac.Append(aRek); |
|
208 C2 = AesWrapL(*kek, keyAndMac); |
|
209 CleanupStack::PushL(C2); |
|
210 C = HBufC8::NewL(C1->Length() + C2->Length()); |
|
211 c.Set(C->Des()); |
|
212 c.Copy(*C1); |
|
213 c.Append(*C2); |
|
214 |
|
215 #ifdef LOGGING |
|
216 LOG(_L("RsaKemKwsEncryptL")); |
|
217 LOG(_L("Z")); |
|
218 LOGHEX(Z); |
|
219 LOG(_L("C1")); |
|
220 LOGHEX((*C1)); |
|
221 LOG(_L("C2")); |
|
222 LOGHEX((*C2)); |
|
223 #endif |
|
224 |
|
225 CleanupStack::PopAndDestroy(3); // C2, kek, C1 |
|
226 return C; |
|
227 } |
|
228 |
|
229 // ----------------------------------------------------------------------------- |
|
230 // OmaCrypto:: |
|
231 // |
|
232 // ----------------------------------------------------------------------------- |
|
233 // |
|
234 EXPORT_C void OmaCrypto::RsaKemKwsDecryptL( |
|
235 MDrmKeyStorage* aKeyStorage, |
|
236 const TDesC8& aInput, |
|
237 TDes8& aRek, |
|
238 TDes8& aMac) |
|
239 { |
|
240 HBufC8* C1 = NULL; |
|
241 HBufC8* C2 = NULL; |
|
242 HBufC8* Z = NULL; |
|
243 HBufC8* keyAndMac = NULL; |
|
244 HBufC8* kek = NULL; |
|
245 |
|
246 C1 = aInput.Left(aInput.Length() - KWrappedKeySize).AllocL(); |
|
247 CleanupStack::PushL(C1); |
|
248 C2 = aInput.Right(KWrappedKeySize).AllocL(); |
|
249 CleanupStack::PushL(C2); |
|
250 Z = aKeyStorage->RsaDecryptL(*C1); |
|
251 CleanupStack::PushL(Z); |
|
252 kek = KdfL(*Z, KNullDesC8, KKeySize); |
|
253 CleanupStack::PushL(kek); |
|
254 keyAndMac = AesUnwrapL(*kek, *C2); |
|
255 aMac.Copy(keyAndMac->Left(KKeySize)); |
|
256 aRek.Copy(keyAndMac->Right(KMacSize)); |
|
257 |
|
258 #ifdef LOGGING |
|
259 LOG(_L("RsaKemKwsDecryptL")); |
|
260 LOG(_L("Z")); |
|
261 LOGHEX((*Z)); |
|
262 LOG(_L("C1")); |
|
263 LOGHEX((*C1)); |
|
264 LOG(_L("C2")); |
|
265 LOGHEX((*C2)); |
|
266 LOG(_L("REK + MAC")); |
|
267 LOGHEX((*keyAndMac)); |
|
268 LOG(_L("KEK")); |
|
269 LOGHEX((*kek)); |
|
270 #endif |
|
271 |
|
272 delete keyAndMac; |
|
273 CleanupStack::PopAndDestroy(4); // kek, Z, C2, C1 |
|
274 } |
|
275 |
|
276 // ----------------------------------------------------------------------------- |
|
277 // OmaCrypto:: |
|
278 // |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 EXPORT_C HBufC8* OmaCrypto::KdfL( |
|
282 const TDesC8& aInput, |
|
283 const TDesC8& aOtherData, |
|
284 TInt aKLen) |
|
285 { |
|
286 TUint32 d; |
|
287 CSHA1* h = NULL; |
|
288 TBuf8<sizeof(d)> c; |
|
289 HBufC8* t = NULL; |
|
290 HBufC8* r = NULL; |
|
291 TPtr8 T(0, 0); |
|
292 |
|
293 h = CSHA1::NewL(); |
|
294 CleanupStack::PushL(h); |
|
295 t = HBufC8::NewL(aKLen + SHA1_HASH); |
|
296 CleanupStack::PushL(t); |
|
297 T.Set(t->Des()); |
|
298 c.SetLength(sizeof(d)); |
|
299 d = 1; |
|
300 do |
|
301 { |
|
302 WriteUint32ToBlock(d, c, 0); |
|
303 h->Hash(aInput); |
|
304 h->Hash(c); |
|
305 if (aOtherData.Length() > 0) |
|
306 { |
|
307 h->Hash(aOtherData); |
|
308 } |
|
309 T.Append(h->Final()); |
|
310 d++; |
|
311 } |
|
312 while (d < SHA1_HASH / aKLen); |
|
313 r = t->Left(aKLen).AllocL(); |
|
314 CleanupStack::PopAndDestroy(2); // Tbuf, h |
|
315 return r; |
|
316 } |
|
317 |
|
318 // ----------------------------------------------------------------------------- |
|
319 // OmaCrypto:: |
|
320 // |
|
321 // ----------------------------------------------------------------------------- |
|
322 // |
|
323 EXPORT_C HBufC8* OmaCrypto::I2OSPL( |
|
324 RInteger& aInt) |
|
325 { |
|
326 HBufC8* r = aInt.BufferLC(); |
|
327 CleanupStack::Pop(r); |
|
328 return r; |
|
329 } |
|
330 |
|
331 // ----------------------------------------------------------------------------- |
|
332 // OmaCrypto:: |
|
333 // |
|
334 // ----------------------------------------------------------------------------- |
|
335 // |
|
336 EXPORT_C RInteger OmaCrypto::OS2IPL( |
|
337 const TDesC8& aOctetStream) |
|
338 { |
|
339 RInteger r; |
|
340 TInt i; |
|
341 |
|
342 r = RInteger::NewL(0); |
|
343 for (i = 0; i < aOctetStream.Length(); i++) |
|
344 { |
|
345 r *= 256; |
|
346 r += aOctetStream[i]; |
|
347 } |
|
348 return r; |
|
349 } |
|
350 |
|
351 // ----------------------------------------------------------------------------- |
|
352 // OmaCrypto:: |
|
353 // |
|
354 // ----------------------------------------------------------------------------- |
|
355 // |
|
356 EXPORT_C HBufC8* OmaCrypto::AesWrapL( |
|
357 const TDesC8& aKey, |
|
358 const TDesC8& aInput) |
|
359 { |
|
360 HBufC8* ret = NULL; |
|
361 TBuf8<KWrapBlockSize> A; |
|
362 TBuf8<2 * KWrapBlockSize> B; |
|
363 TInt i; |
|
364 TInt j; |
|
365 TPtr8 R(0, 0); |
|
366 TPtr8 Rn(0, 0); |
|
367 TInt t; |
|
368 TInt n; |
|
369 CAESEncryptor* e; |
|
370 |
|
371 e = CAESEncryptor::NewL(aKey); |
|
372 User::LeaveIfNull(e); |
|
373 CleanupStack::PushL(e); |
|
374 n = aInput.Length() / KWrapBlockSize; |
|
375 ret = HBufC8::NewMax((n + 1) * KWrapBlockSize); |
|
376 User::LeaveIfNull(ret); |
|
377 R.Set(ret->Des()); |
|
378 A.Copy(KWrapIv); |
|
379 R.Copy(A); |
|
380 R.Append(aInput); |
|
381 for (j = 0; j <= 5; j++) |
|
382 { |
|
383 for (i = 1; i <= n; i++) |
|
384 { |
|
385 t = (n * j) + i; |
|
386 Rn.Set(const_cast<TUint8*>(R.Ptr()) + KWrapBlockSize * i, |
|
387 KWrapBlockSize, KWrapBlockSize); |
|
388 B.Copy(A); |
|
389 B.Append(Rn); |
|
390 e->Transform(B); |
|
391 A.Copy(B.Left(KWrapBlockSize)); |
|
392 A[KWrapBlockSize - 1] ^= t; |
|
393 Rn.Copy(B.Right(KWrapBlockSize)); |
|
394 } |
|
395 } |
|
396 Rn.Set(const_cast<TUint8*>(R.Ptr()), KWrapBlockSize, KWrapBlockSize); |
|
397 Rn.Copy(A); |
|
398 CleanupStack::PopAndDestroy(); // e |
|
399 return ret; |
|
400 } |
|
401 |
|
402 // ----------------------------------------------------------------------------- |
|
403 // OmaCrypto:: |
|
404 // |
|
405 // ----------------------------------------------------------------------------- |
|
406 // |
|
407 EXPORT_C HBufC8* OmaCrypto::AesUnwrapL( |
|
408 const TDesC8& aKey, |
|
409 const TDesC8& aInput) |
|
410 { |
|
411 HBufC8* ret = NULL; |
|
412 TBuf8<KWrapBlockSize> A; |
|
413 TBuf8<2 * KWrapBlockSize> B; |
|
414 TInt i; |
|
415 TInt j; |
|
416 TPtr8 R(0, 0); |
|
417 TPtr8 Rn(0, 0); |
|
418 TInt t; |
|
419 TInt n; |
|
420 CAESDecryptor* d; |
|
421 |
|
422 d = CAESDecryptor::NewL(aKey); |
|
423 User::LeaveIfNull(d); |
|
424 CleanupStack::PushL(d); |
|
425 n = (aInput.Length() / KWrapBlockSize) - 1; |
|
426 ret = HBufC8::NewMax((n + 1) * KWrapBlockSize); |
|
427 User::LeaveIfNull(ret); |
|
428 R.Set(ret->Des()); |
|
429 A.Copy(aInput.Left(KWrapBlockSize)); |
|
430 R.Copy(aInput); |
|
431 for (j = 5; j >= 0; j--) |
|
432 { |
|
433 for (i = n; i >= 1; i--) |
|
434 { |
|
435 t = (n * j) + i; |
|
436 Rn.Set(const_cast<TUint8*>(R.Ptr()) + KWrapBlockSize * i, |
|
437 KWrapBlockSize, KWrapBlockSize); |
|
438 A[KWrapBlockSize - 1] ^= t; |
|
439 B.Copy(A); |
|
440 B.Append(Rn); |
|
441 d->Transform(B); |
|
442 A.Copy(B.Left(KWrapBlockSize)); |
|
443 Rn.Copy(B.Right(KWrapBlockSize)); |
|
444 } |
|
445 } |
|
446 R.Delete(0, KWrapBlockSize); |
|
447 CleanupStack::PopAndDestroy(); // e |
|
448 |
|
449 #ifdef LOGGING |
|
450 LOG(_L("OmaCrypto::AesUnwrapL")); |
|
451 LOG(_L("Key:")); |
|
452 LOGHEX(aKey); |
|
453 LOG(_L("Input:")); |
|
454 LOGHEX(aInput); |
|
455 LOG(_L("Ret:")); |
|
456 LOGHEX((*ret)); |
|
457 #endif |
|
458 |
|
459 return ret; |
|
460 } |
|
461 |
|
462 // ----------------------------------------------------------------------------- |
|
463 // OmaCrypto:: |
|
464 // |
|
465 // ----------------------------------------------------------------------------- |
|
466 // |
|
467 EXPORT_C HBufC8* OmaCrypto::Mgf1L( |
|
468 const TDesC8& aMfgSeed, |
|
469 TInt aMaskLen) |
|
470 { |
|
471 TUint32 c; |
|
472 CSHA1* h = NULL; |
|
473 TBuf8<4> counter; |
|
474 HBufC8* t = NULL; |
|
475 TPtr8 T(0, 0); |
|
476 TInt n; |
|
477 |
|
478 n = aMaskLen / SHA1_HASH + (aMaskLen % SHA1_HASH ? 1 : 0); |
|
479 h = CSHA1::NewL(); |
|
480 CleanupStack::PushL(h); |
|
481 t = HBufC8::NewL(aMaskLen + 2 * SHA1_HASH + 1); |
|
482 CleanupStack::PushL(t); |
|
483 T.Set(t->Des()); |
|
484 counter.SetLength(4); |
|
485 c = 0; |
|
486 do |
|
487 { |
|
488 WriteUint32ToBlock(c, counter, 0); |
|
489 h->Hash(aMfgSeed); |
|
490 h->Hash(counter); |
|
491 T.Append(h->Final()); |
|
492 c++; |
|
493 } |
|
494 while (c < n); |
|
495 T.SetLength(aMaskLen); |
|
496 CleanupStack::Pop(); // t |
|
497 CleanupStack::PopAndDestroy(); // h |
|
498 return t; |
|
499 } |
|
500 |
|
501 // ----------------------------------------------------------------------------- |
|
502 // OmaCrypto::RsaPssSignHashL |
|
503 // Sign a hash (not a message!) using RSASSA-PSS. |
|
504 // NOTE: The implementation is only correct for a private key modulus divisible |
|
505 // by eight! |
|
506 // ----------------------------------------------------------------------------- |
|
507 // |
|
508 EXPORT_C HBufC8* OmaCrypto::RsaPssSignHashL( |
|
509 MDrmKeyStorage* aKeyStorage, |
|
510 const TDesC8& aMHash) |
|
511 { |
|
512 CSHA1* hasher = NULL; |
|
513 HBufC8* em = NULL; |
|
514 HBufC8* S = NULL; |
|
515 TPtr8 EM(0, 0); |
|
516 TInt modBits; |
|
517 TInt emLen; |
|
518 TBuf8<KPssSaltLength> salt; |
|
519 TBuf8<SHA1_HASH> H; |
|
520 _LIT8(KMNullVector, "\0\0\0\0\0\0\0\0"); |
|
521 HBufC8* db = NULL; |
|
522 TPtr8 DB(0, 0); |
|
523 HBufC8* dbMask = NULL; |
|
524 TInt i; |
|
525 |
|
526 modBits = aKeyStorage->ModulusSize(); |
|
527 |
|
528 if( modBits < 0) |
|
529 { |
|
530 User::LeaveIfError( modBits ); |
|
531 } |
|
532 emLen = modBits / 8; |
|
533 hasher = CSHA1::NewL(); |
|
534 CleanupStack::PushL(hasher); |
|
535 |
|
536 salt.SetLength(KPssSaltLength); |
|
537 |
|
538 aKeyStorage->RandomDataGetL(salt,salt.Size()); |
|
539 |
|
540 #ifdef LOGGING |
|
541 LOG(_L("RsaKemKwsEncryptL")); |
|
542 LOG(_L("salt")); |
|
543 LOGHEX(salt); |
|
544 #endif |
|
545 |
|
546 hasher->Hash(KMNullVector); |
|
547 hasher->Hash(aMHash); |
|
548 hasher->Hash(salt); |
|
549 H.Copy(hasher->Final()); |
|
550 |
|
551 db = HBufC8::NewL(emLen - SHA1_HASH - 1); |
|
552 CleanupStack::PushL(db); |
|
553 DB.Set(db->Des()); |
|
554 DB.FillZ(emLen - KPssSaltLength - SHA1_HASH - 2); |
|
555 DB.Append(0x01); |
|
556 DB.Append(salt); |
|
557 |
|
558 dbMask = Mgf1L(H, emLen - SHA1_HASH - 1); |
|
559 CleanupStack::PushL(dbMask); |
|
560 |
|
561 for (i = 0; i < emLen - SHA1_HASH - 1; i++) |
|
562 { |
|
563 DB[i] = DB[i] ^ (*dbMask)[i]; |
|
564 } |
|
565 |
|
566 em = HBufC8::NewL(emLen); |
|
567 CleanupStack::PushL(em); |
|
568 EM.Set(em->Des()); |
|
569 EM.Copy(DB); |
|
570 EM[0] &= 0x7f; |
|
571 EM.Append(H); |
|
572 EM.Append(0xbc); |
|
573 S = aKeyStorage->RsaSignL(EM); |
|
574 |
|
575 CleanupStack::PopAndDestroy(4); // em, dbMask, db, hasher |
|
576 return S; |
|
577 } |
|
578 |
|
579 // ----------------------------------------------------------------------------- |
|
580 // OmaCrypto:: |
|
581 // |
|
582 // ----------------------------------------------------------------------------- |
|
583 // |
|
584 EXPORT_C TBool OmaCrypto::RsaPssVerifyHashL( |
|
585 CRSAPublicKey* aKey, |
|
586 const TDesC8& aSignature, |
|
587 const TDesC8& aMHash) |
|
588 { |
|
589 TBool r = EFalse; |
|
590 CSHA1* hasher = NULL; |
|
591 HBufC8* EM = NULL; |
|
592 TInt emLen; |
|
593 TBuf8<KPssSaltLength> salt; |
|
594 TBuf8<SHA1_HASH> H; |
|
595 _LIT8(KMNullVector, "\0\0\0\0\0\0\0\0"); |
|
596 HBufC8* db = NULL; |
|
597 TPtr8 DB(0, 0); |
|
598 HBufC8* dbMask = NULL; |
|
599 TInt i; |
|
600 |
|
601 EM = RsaVerifyL(aKey, aSignature); |
|
602 CleanupStack::PushL(EM); |
|
603 emLen = EM->Size(); |
|
604 |
|
605 hasher = CSHA1::NewL(); |
|
606 CleanupStack::PushL(hasher); |
|
607 |
|
608 db = EM->Left(emLen - SHA1_HASH - 1).AllocL(); |
|
609 CleanupStack::PushL(db); |
|
610 DB.Set(db->Des()); |
|
611 H.Copy(EM->Mid(emLen - SHA1_HASH - 1, SHA1_HASH)); |
|
612 |
|
613 dbMask = Mgf1L(H, emLen - SHA1_HASH - 1); |
|
614 CleanupStack::PushL(dbMask); |
|
615 |
|
616 for (i = 0; i < emLen - SHA1_HASH - 1; i++) |
|
617 { |
|
618 DB[i] = DB[i] ^ (*dbMask)[i]; |
|
619 } |
|
620 |
|
621 salt.Copy(DB.Right(KPssSaltLength)); |
|
622 |
|
623 hasher->Hash(KMNullVector); |
|
624 hasher->Hash(aMHash); |
|
625 hasher->Hash(salt); |
|
626 if (hasher->Final().Compare(H) == 0) |
|
627 { |
|
628 r = ETrue; |
|
629 } |
|
630 |
|
631 CleanupStack::PopAndDestroy(4); // dbMask, db, hasher, EM |
|
632 return r; |
|
633 } |
|
634 |
|
635 // End of File |