PBKDF2 for 32 byte key length. We generate the key for specified number of iteration count also as two supplementary values (key for checksums and password verification) for iterations+16 and iterations+32.
| 83 | // of iteration count also as two supplementary values (key for checksums |
| 84 | // and password verification) for iterations+16 and iterations+32. |
| 85 | void pbkdf2(const byte *Pwd, size_t PwdLength, |
| 86 | const byte *Salt, size_t SaltLength, |
| 87 | byte *Key, byte *V1, byte *V2, uint Count) |
| 88 | { |
| 89 | const size_t MaxSalt=64; |
| 90 | byte SaltData[MaxSalt+4]; |
| 91 | memcpy(SaltData, Salt, Min(SaltLength,MaxSalt)); |
| 92 | |
| 93 | SaltData[SaltLength + 0] = 0; // Salt concatenated to 1. |
| 94 | SaltData[SaltLength + 1] = 0; |
| 95 | SaltData[SaltLength + 2] = 0; |
| 96 | SaltData[SaltLength + 3] = 1; |
| 97 | |
| 98 | // First iteration: HMAC of password, salt and block index (1). |
| 99 | byte U1[SHA256_DIGEST_SIZE]; |
| 100 | hmac_sha256(Pwd, PwdLength, SaltData, SaltLength + 4, U1, NULL, NULL, NULL, NULL); |
| 101 | byte Fn[SHA256_DIGEST_SIZE]; // Current function value. |
| 102 | memcpy(Fn, U1, sizeof(Fn)); // Function at first iteration. |
| 103 | |
| 104 | uint CurCount[] = { Count-1, 16, 16 }; |
| 105 | byte *CurValue[] = { Key , V1, V2 }; |
| 106 | |
| 107 | sha256_context ICtxOpt,RCtxOpt; |
| 108 | bool SetIOpt=false,SetROpt=false; |
| 109 | |
| 110 | byte U2[SHA256_DIGEST_SIZE]; |
| 111 | for (uint I = 0; I < 3; I++) // For output key and 2 supplementary values. |
| 112 | { |
| 113 | for (uint J = 0; J < CurCount[I]; J++) |
| 114 | { |
| 115 | // U2 = PRF (P, U1). |
| 116 | hmac_sha256(Pwd, PwdLength, U1, sizeof(U1), U2, &ICtxOpt, &SetIOpt, &RCtxOpt, &SetROpt); |
| 117 | memcpy(U1, U2, sizeof(U1)); |
| 118 | for (uint K = 0; K < sizeof(Fn); K++) // Function ^= U. |
| 119 | Fn[K] ^= U1[K]; |
| 120 | } |
| 121 | memcpy(CurValue[I], Fn, SHA256_DIGEST_SIZE); |
| 122 | } |
| 123 | |
| 124 | cleandata(SaltData, sizeof(SaltData)); |
| 125 | cleandata(Fn, sizeof(Fn)); |
| 126 | cleandata(U1, sizeof(U1)); |
| 127 | cleandata(U2, sizeof(U2)); |
| 128 | } |
| 129 | |
| 130 | |
| 131 | void CryptData::SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW, |