MCPcopy Create free account
hub / github.com/assaultcube/AC / passphrase2key

Function passphrase2key

source/src/crypto.cpp:468–523  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

466// * last line of defense against "evil little brothers"
467
468void passphrase2key(const char *pass, const uchar *salt, int saltlen, uchar *key, int keylen, int *iterations, int maxtime, int memusage)
469{
470 memset(key, 0, keylen);
471 if(!*pass) return; // password "" ->
472 memusage = clamp(memusage, 2, 1024); // keep memory usage between 2MB and 1GB
473 int memsize = (1<<20) * memusage, passlen = strlen(pass), tmpbuflen = 2 * SHA512SIZE, pplen = 2 * (saltlen + passlen);
474
475 // prepare the passphrase (including salt)
476 uchar *pp = new uchar[pplen];
477 memcpy(pp, salt, saltlen);
478 memcpy(pp + saltlen, pass, passlen);
479 memcpy(pp + saltlen + passlen, pass, passlen);
480 memcpy(pp + saltlen + 2 * passlen, salt, saltlen);
481 if((memusage & 1) && passlen + saltlen >= 8) identhash((uint64_t *)(pp + saltlen + passlen));
482
483 // mix up the passphrase a bit
484 uchar *tmpbuf = new uchar[tmpbuflen + sizeof(uint)];
485 memset(tmpbuf, 0, tmpbuflen + sizeof(uint));
486 sha512(tmpbuf, pp, pplen);
487 xor_block(pp, tmpbuf, min(pplen, tmpbuflen));
488 sha512(tmpbuf + SHA512SIZE, pp, pplen);
489 tiger::hash(pp, pplen, *((tiger::hashval *)tmpbuf));
490
491 // initialise the huge buffer
492 uchar *hugebuf = new uchar[memsize];
493 memset(hugebuf, 0, memsize);
494 int memchunk = memsize / tmpbuflen;
495 loopi(tmpbuflen) seedMT_do(*((uint*)(tmpbuf + i)), (uint*)(hugebuf + memchunk * i), memchunk / sizeof(uint)); // spread the passphrase all over the huge buffer
496
497 // start mixing
498 #define mixit(x, y) (((((uint*)tmpbuf)[(roundsdone ^ (x)) % (tmpbuflen / sizeof(uint))]) % ((y) / 8 - (x) % 11)) * 8)
499 stopwatch watch;
500 watch.start();
501 int roundsdone = 0;
502 uint shortseed = 0;
503 do
504 {
505 loopirev(memsize / 127) shortseed = ((uint*)hugebuf)[shortseed % (memsize / sizeof(uint))];
506 seedMT_do(shortseed, (uint*)tmpbuf, tmpbuflen / sizeof(uint));
507 loopi(2999) sha512_compress((uint64_t*)(hugebuf + mixit(i * 5, memsize - SHA512SIZE)), hugebuf + mixit(i * 17, memsize - 128));
508 roundsdone++;
509 }
510 while((!*iterations && watch.elapsed() < maxtime) || (*iterations && *iterations > roundsdone)); // *iterations == 0: time-limited, otherwise rounds-limited
511
512 // extract the key
513 if(keylen * 8 > 192) sha512(tmpbuf, hugebuf, memsize);
514 else tiger::hash(hugebuf, memsize, *((tiger::hashval *)tmpbuf));
515 loopi(SHA512SIZE) sha512_compress(((uint64_t*)tmpbuf) + (i / 8), hugebuf + (((tmpbuf[i] * 68111) % (memsize - 128)) & ~7));
516 memcpy(key, tmpbuf, min(keylen, tmpbuflen)); // max keylen is 2 * SHA512SIZE
517 DEBUG("passphrase2key: " << watch.elapsed() << " ms, " << roundsdone << " rounds, " << memsize << " bytes used");
518 *iterations = roundsdone;
519 delete[] hugebuf;
520 delete[] tmpbuf;
521 delete[] pp;
522 #undef mixit
523}
524#endif
525

Callers 2

passdeferredFunction · 0.85
authsetupFunction · 0.85

Calls 11

identhashFunction · 0.85
sha512Function · 0.85
xor_blockFunction · 0.85
minFunction · 0.85
hashFunction · 0.85
seedMT_doFunction · 0.85
sha512_compressFunction · 0.85
elapsedMethod · 0.80
loopiFunction · 0.70
loopirevFunction · 0.70
startMethod · 0.45

Tested by

no test coverage detected