Esempio n. 1
0
Blob PBKDF2(PseudoRandomFunction& prf, const ConstBuf& password, const ConstBuf& salt, uint32_t c, size_t dkLen) {
	size_t hlen = prf.HashSize();
	if (dkLen > uint64_t(hlen) * uint32_t(0xFFFFFFFF))
		Throw(ExtErr::DerivedKeyTooLong);
	uint32_t iBe = 0;
	Blob salt_i = salt + ConstBuf(&iBe, 4);
	Blob r(nullptr, dkLen);
	for (uint32_t i=1, n=uint32_t((dkLen + hlen - 1) / hlen); i<=n; ++i) {
		memcpy(salt_i.data()+salt.Size, &(iBe = htobe(i)), 4);
		hashval u = prf(password, salt_i), rh = u;
		for (uint32_t j=1; j<c; ++j)
			VectorXor(rh.data(), (u = prf(password, u)).data(), hlen);
		memcpy(r.data() + (i-1)*hlen, rh.data(), (min)(hlen, r.Size - (i-1)*hlen));
	}
	return r;
}
Esempio n. 2
0
bool CPU_ProbeAltivec()
{
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
    return false;
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)

    // longjmp and clobber warnings. Volatile is required.
    // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
    volatile int result = true;

    volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler);
    if (oldHandler == SIG_ERR)
        return false;

    volatile sigset_t oldMask;
    if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask))
        return false;

    if (setjmp(s_jmpSIGILL))
        result = false;
    else
    {
        const byte b1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        const byte b2[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
        byte b3[16];

        const uint8x16_p v1 = (uint8x16_p)VectorLoad(0, b1);
        const uint8x16_p v2 = (uint8x16_p)VectorLoad(0, b2);
        const uint8x16_p v3 = (uint8x16_p)VectorXor(v1, v2);
        VectorStore(v3, b3);

        result = (0 == std::memcmp(b2, b3, 16));
    }

    sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
    signal(SIGILL, oldHandler);
    return result;
# endif
#else
    return false;
#endif  // CRYPTOPP_ALTIVEC_AVAILABLE
}
Esempio n. 3
0
Blob Scrypt(const ConstBuf& password, const ConstBuf& salt, int n, int r, int p, size_t dkLen) {
	HmacPseudoRandomFunction<SHA256> prf;
	const size_t mfLen = r*128;
	Blob bb = PBKDF2(prf, password, salt, 1, p*mfLen);
	AlignedMem am((n+1)*r*128, 128);
	uint32_t *v = (uint32_t*)am.get();
	SalsaBlockPtr tmp = (SalsaBlockPtr)alloca(r*128);
	for (int i=0; i<p; ++i) {
		SalsaBlockPtr x = (SalsaBlockPtr)(bb.data()+i*mfLen);
		for (int i=0; i<n; ++i) {
			memcpy(&v[i * 32 * r], x, 2*r * sizeof(x[0]));
			VectorMix(Salsa20Core, x, tmp, r, 8);
		}
		for (int i=0; i<n; ++i) {
			int j = 32*r * (x[2 * r - 1][0] & (n - 1));
			VectorXor(x[0], &v[j], 2*r*16);
			VectorMix(Salsa20Core, x, tmp, r, 8);
		}
	}
	return PBKDF2(prf, password, bb, 1, dkLen);
}