// encryption: data must be NUL-padded to BLOCKSIZE // decryption: data must be padded to BLOCKSIZE // len must be < 2^31 void SymmCipher::ctr_crypt(byte* data, unsigned len, m_off_t pos, ctr_iv ctriv, byte* mac, bool encrypt, bool initmac) { assert(!(pos & (KEYLENGTH - 1))); byte ctr[BLOCKSIZE], tmp[BLOCKSIZE]; MemAccess::set<int64_t>(ctr,ctriv); setint64(pos / BLOCKSIZE, ctr + sizeof ctriv); if (mac && initmac) { memcpy(mac, ctr, sizeof ctriv); memcpy(mac + sizeof ctriv, ctr, sizeof ctriv); } while ((int)len > 0) { if (encrypt) { if(mac) { xorblock(data, mac); ecb_encrypt(mac); } ecb_encrypt(ctr, tmp); xorblock(tmp, data); } else { ecb_encrypt(ctr, tmp); xorblock(tmp, data); if (mac) { if (len >= (unsigned)BLOCKSIZE) { xorblock(data, mac); } else { xorblock(data, mac, len); } ecb_encrypt(mac); } } len -= BLOCKSIZE; data += BLOCKSIZE; incblock(ctr); } }
// encryption: data must be NUL-padded to BLOCKSIZE // decryption: data must be padded to BLOCKSIZE // len must be < 2^31 void SymmCipher::ctr_crypt(byte* data, unsigned len, m_off_t pos, ctr_iv ctriv, byte* mac, int encrypt) { assert(!(pos&(KEYLENGTH-1))); byte ctr[BLOCKSIZE], tmp[BLOCKSIZE]; *(uint64_t*)ctr = ctriv; setint64(pos/BLOCKSIZE,ctr+sizeof ctriv); memcpy(mac,ctr,sizeof ctriv); memcpy(mac+sizeof ctriv,ctr,sizeof ctriv); while ((int)len > 0) { if (encrypt) { xorblock(data,mac); ecb_encrypt(mac); ecb_encrypt(ctr,tmp); xorblock(tmp,data); } else { ecb_encrypt(ctr,tmp); xorblock(tmp,data); if (len >= (unsigned)BLOCKSIZE) xorblock(data,mac); else xorblock(data,mac,len); ecb_encrypt(mac); } len -= BLOCKSIZE; data += BLOCKSIZE; incblock(ctr); } }