1
0

crypt5.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. static void hmac_sha256(const byte *Key,size_t KeyLength,const byte *Data,
  2. size_t DataLength,byte *ResDigest,
  3. sha256_context *ICtxOpt,bool *SetIOpt,
  4. sha256_context *RCtxOpt,bool *SetROpt)
  5. {
  6. const size_t Sha256BlockSize=64; // As defined in RFC 4868.
  7. byte KeyHash[SHA256_DIGEST_SIZE];
  8. if (KeyLength > Sha256BlockSize) // Convert longer keys to key hash.
  9. {
  10. sha256_context KCtx;
  11. sha256_init(&KCtx);
  12. sha256_process(&KCtx, Key, KeyLength);
  13. sha256_done(&KCtx, KeyHash);
  14. Key = KeyHash;
  15. KeyLength = SHA256_DIGEST_SIZE;
  16. }
  17. byte KeyBuf[Sha256BlockSize]; // Store the padded key here.
  18. sha256_context ICtx;
  19. if (ICtxOpt!=NULL && *SetIOpt)
  20. ICtx=*ICtxOpt; // Use already calculated first block context.
  21. else
  22. {
  23. // This calculation is the same for all iterations with same password.
  24. // So for PBKDF2 we can calculate it only for first block and then reuse
  25. // to improve performance.
  26. for (size_t I = 0; I < KeyLength; I++) // Use 0x36 padding for inner digest.
  27. KeyBuf[I] = Key[I] ^ 0x36;
  28. for (size_t I = KeyLength; I < Sha256BlockSize; I++)
  29. KeyBuf[I] = 0x36;
  30. sha256_init(&ICtx);
  31. sha256_process(&ICtx, KeyBuf, Sha256BlockSize); // Hash padded key.
  32. }
  33. if (ICtxOpt!=NULL && !*SetIOpt) // Store constant context for further reuse.
  34. {
  35. *ICtxOpt=ICtx;
  36. *SetIOpt=true;
  37. }
  38. sha256_process(&ICtx, Data, DataLength); // Hash data.
  39. byte IDig[SHA256_DIGEST_SIZE]; // Internal digest for padded key and data.
  40. sha256_done(&ICtx, IDig);
  41. sha256_context RCtx;
  42. if (RCtxOpt!=NULL && *SetROpt)
  43. RCtx=*RCtxOpt; // Use already calculated first block context.
  44. else
  45. {
  46. // This calculation is the same for all iterations with same password.
  47. // So for PBKDF2 we can calculate it only for first block and then reuse
  48. // to improve performance.
  49. for (size_t I = 0; I < KeyLength; I++) // Use 0x5c for outer key padding.
  50. KeyBuf[I] = Key[I] ^ 0x5c;
  51. for (size_t I = KeyLength; I < Sha256BlockSize; I++)
  52. KeyBuf[I] = 0x5c;
  53. sha256_init(&RCtx);
  54. sha256_process(&RCtx, KeyBuf, Sha256BlockSize); // Hash padded key.
  55. }
  56. if (RCtxOpt!=NULL && !*SetROpt) // Store constant context for further reuse.
  57. {
  58. *RCtxOpt=RCtx;
  59. *SetROpt=true;
  60. }
  61. sha256_process(&RCtx, IDig, SHA256_DIGEST_SIZE); // Hash internal digest.
  62. sha256_done(&RCtx, ResDigest);
  63. }
  64. // PBKDF2 for 32 byte key length. We generate the key for specified number
  65. // of iteration count also as two supplementary values (key for checksums
  66. // and password verification) for iterations+16 and iterations+32.
  67. void pbkdf2(const byte *Pwd, size_t PwdLength,
  68. const byte *Salt, size_t SaltLength,
  69. byte *Key, byte *V1, byte *V2, uint Count)
  70. {
  71. const size_t MaxSalt=64;
  72. byte SaltData[MaxSalt+4];
  73. memcpy(SaltData, Salt, Min(SaltLength,MaxSalt));
  74. SaltData[SaltLength + 0] = 0; // Salt concatenated to 1.
  75. SaltData[SaltLength + 1] = 0;
  76. SaltData[SaltLength + 2] = 0;
  77. SaltData[SaltLength + 3] = 1;
  78. // First iteration: HMAC of password, salt and block index (1).
  79. byte U1[SHA256_DIGEST_SIZE];
  80. hmac_sha256(Pwd, PwdLength, SaltData, SaltLength + 4, U1, NULL, NULL, NULL, NULL);
  81. byte Fn[SHA256_DIGEST_SIZE]; // Current function value.
  82. memcpy(Fn, U1, sizeof(Fn)); // Function at first iteration.
  83. uint CurCount[] = { Count-1, 16, 16 };
  84. byte *CurValue[] = { Key , V1, V2 };
  85. sha256_context ICtxOpt,RCtxOpt;
  86. bool SetIOpt=false,SetROpt=false;
  87. byte U2[SHA256_DIGEST_SIZE];
  88. for (uint I = 0; I < 3; I++) // For output key and 2 supplementary values.
  89. {
  90. for (uint J = 0; J < CurCount[I]; J++)
  91. {
  92. // U2 = PRF (P, U1).
  93. hmac_sha256(Pwd, PwdLength, U1, sizeof(U1), U2, &ICtxOpt, &SetIOpt, &RCtxOpt, &SetROpt);
  94. memcpy(U1, U2, sizeof(U1));
  95. for (uint K = 0; K < sizeof(Fn); K++) // Function ^= U.
  96. Fn[K] ^= U1[K];
  97. }
  98. memcpy(CurValue[I], Fn, SHA256_DIGEST_SIZE);
  99. }
  100. cleandata(SaltData, sizeof(SaltData));
  101. cleandata(Fn, sizeof(Fn));
  102. cleandata(U1, sizeof(U1));
  103. cleandata(U2, sizeof(U2));
  104. }
  105. void CryptData::SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW,
  106. const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey,
  107. byte *PswCheck)
  108. {
  109. if (Lg2Cnt>CRYPT5_KDF_LG2_COUNT_MAX)
  110. return;
  111. byte Key[32],PswCheckValue[SHA256_DIGEST_SIZE],HashKeyValue[SHA256_DIGEST_SIZE];
  112. bool Found=false;
  113. for (uint I=0;I<ASIZE(KDF5Cache);I++)
  114. {
  115. KDF5CacheItem *Item=KDF5Cache+I;
  116. if (Item->Lg2Count==Lg2Cnt && Item->Pwd==*Password &&
  117. memcmp(Item->Salt,Salt,SIZE_SALT50)==0)
  118. {
  119. memcpy(Key,Item->Key,sizeof(Key));
  120. SecHideData(Key,sizeof(Key),false,false);
  121. memcpy(PswCheckValue,Item->PswCheckValue,sizeof(PswCheckValue));
  122. memcpy(HashKeyValue,Item->HashKeyValue,sizeof(HashKeyValue));
  123. Found=true;
  124. break;
  125. }
  126. }
  127. if (!Found)
  128. {
  129. char PwdUtf[MAXPASSWORD*4];
  130. WideToUtf(PwdW,PwdUtf,ASIZE(PwdUtf));
  131. pbkdf2((byte *)PwdUtf,strlen(PwdUtf),Salt,SIZE_SALT50,Key,HashKeyValue,PswCheckValue,(1<<Lg2Cnt));
  132. cleandata(PwdUtf,sizeof(PwdUtf));
  133. KDF5CacheItem *Item=KDF5Cache+(KDF5CachePos++ % ASIZE(KDF5Cache));
  134. Item->Lg2Count=Lg2Cnt;
  135. Item->Pwd=*Password;
  136. memcpy(Item->Salt,Salt,SIZE_SALT50);
  137. memcpy(Item->Key,Key,sizeof(Item->Key));
  138. memcpy(Item->PswCheckValue,PswCheckValue,sizeof(PswCheckValue));
  139. memcpy(Item->HashKeyValue,HashKeyValue,sizeof(HashKeyValue));
  140. SecHideData(Item->Key,sizeof(Item->Key),true,false);
  141. }
  142. if (HashKey!=NULL)
  143. memcpy(HashKey,HashKeyValue,SHA256_DIGEST_SIZE);
  144. if (PswCheck!=NULL)
  145. {
  146. memset(PswCheck,0,SIZE_PSWCHECK);
  147. for (uint I=0;I<SHA256_DIGEST_SIZE;I++)
  148. PswCheck[I%SIZE_PSWCHECK]^=PswCheckValue[I];
  149. cleandata(PswCheckValue,sizeof(PswCheckValue));
  150. }
  151. // NULL initialization vector is possible if we only need the password
  152. // check value for archive encryption header.
  153. if (InitV!=NULL)
  154. rin.Init(Encrypt, Key, 256, InitV);
  155. cleandata(Key,sizeof(Key));
  156. }
  157. void ConvertHashToMAC(HashValue *Value,byte *Key)
  158. {
  159. if (Value->Type==HASH_CRC32)
  160. {
  161. byte RawCRC[4];
  162. RawPut4(Value->CRC32,RawCRC);
  163. byte Digest[SHA256_DIGEST_SIZE];
  164. hmac_sha256(Key,SHA256_DIGEST_SIZE,RawCRC,sizeof(RawCRC),Digest,NULL,NULL,NULL,NULL);
  165. Value->CRC32=0;
  166. for (uint I=0;I<ASIZE(Digest);I++)
  167. Value->CRC32^=Digest[I] << ((I & 3) * 8);
  168. }
  169. if (Value->Type==HASH_BLAKE2)
  170. {
  171. byte Digest[BLAKE2_DIGEST_SIZE];
  172. hmac_sha256(Key,BLAKE2_DIGEST_SIZE,Value->Digest,sizeof(Value->Digest),Digest,NULL,NULL,NULL,NULL);
  173. memcpy(Value->Digest,Digest,sizeof(Value->Digest));
  174. }
  175. }
  176. #if 0
  177. static void TestPBKDF2();
  178. struct TestKDF {TestKDF() {TestPBKDF2();exit(0);}} GlobalTestKDF;
  179. void TestPBKDF2() // Test PBKDF2 HMAC-SHA256
  180. {
  181. byte Key[32],V1[32],V2[32];
  182. pbkdf2((byte *)"password", 8, (byte *)"salt", 4, Key, V1, V2, 1);
  183. byte Res1[32]={0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, 0xa8, 0x65, 0x48, 0xc9, 0x2c, 0xcc, 0x35, 0x48, 0x08, 0x05, 0x98, 0x7c, 0xb7, 0x0b, 0xe1, 0x7b };
  184. mprintf(L"\nPBKDF2 test1: %s", memcmp(Key,Res1,32)==0 ? L"OK":L"Failed");
  185. pbkdf2((byte *)"password", 8, (byte *)"salt", 4, Key, V1, V2, 4096);
  186. byte Res2[32]={0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, 0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11, 0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a };
  187. mprintf(L"\nPBKDF2 test2: %s", memcmp(Key,Res2,32)==0 ? L"OK":L"Failed");
  188. pbkdf2((byte *)"just some long string pretending to be a password", 49, (byte *)"salt, salt, salt, a lot of salt", 31, Key, V1, V2, 65536);
  189. byte Res3[32]={0x08, 0x0f, 0xa3, 0x1d, 0x42, 0x2d, 0xb0, 0x47, 0x83, 0x9b, 0xce, 0x3a, 0x3b, 0xce, 0x49, 0x51, 0xe2, 0x62, 0xb9, 0xff, 0x76, 0x2f, 0x57, 0xe9, 0xc4, 0x71, 0x96, 0xce, 0x4b, 0x6b, 0x6e, 0xbf};
  190. mprintf(L"\nPBKDF2 test3: %s", memcmp(Key,Res3,32)==0 ? L"OK":L"Failed");
  191. }
  192. #endif