void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b) { char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE]; char init[128]; char counter[4]; int c, i; /* iteration 1 */ memset (counter, 0, 4); counter[3] = (char) b; memcpy (init, salt, salt_len); /* salt */ memcpy (&init[salt_len], counter, 4); /* big-endian block number */ hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE); memcpy (u, j, WHIRLPOOL_DIGESTSIZE); /* remaining iterations */ for (c = 1; c < iterations; c++) { hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE); for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++) { u[i] ^= k[i]; j[i] = k[i]; } } /* Prevent possible leaks. */ burn (j, sizeof(j)); burn (k, sizeof(k)); }
static vector<u8> H2(const vector<u8>& s, const vector<u8>& rc, const vector<u8>& rs) { vector<u8> message; message.insert(message.end(), rc.begin(), rc.end()); message.insert(message.end(), rs.begin(), rs.end()); message.insert(message.end(), kPad2.begin(), kPad2.end()); vector<u8> ret; vector<u8> a = hmac_md5(s, message); ret.insert(ret.end(), a.begin(), a.end()); vector<u8> b = hmac_sha1(s, message); ret.insert(ret.end(), b.begin(), b.end()); vector<u8> c = hmac_whirlpool(s, message); ret.insert(ret.end(), c.begin(), c.end()); return ret; }