Annotation of truecrypt/volume/encryptionmodecbc.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
        !             3: 
        !             4:  Governed by the TrueCrypt License 2.4 the full text of which is contained
        !             5:  in the file License.txt included in TrueCrypt binary and source code
        !             6:  distribution packages.
        !             7: */
        !             8: 
        !             9: #include "Platform/Memory.h"
        !            10: #include "Common/Crc.h"
        !            11: #include "Common/Endian.h"
        !            12: #include "EncryptionModeCBC.h"
        !            13: 
        !            14: namespace TrueCrypt
        !            15: {
        !            16:        void EncryptionModeCBC::Decrypt (byte *data, uint64 length) const
        !            17:        {
        !            18:                if_debug (ValidateState ());
        !            19:                if_debug (ValidateParameters (data, length));
        !            20: 
        !            21:                if (IsOuterCBC (Ciphers))
        !            22:                {
        !            23:                        DecryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
        !            24:                }
        !            25:                else
        !            26:                {
        !            27:                        for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
        !            28:                                iCipherList != Ciphers.rend();
        !            29:                                ++iCipherList)
        !            30:                        {
        !            31:                                CipherList cl;
        !            32:                                cl.push_back (*iCipherList);
        !            33: 
        !            34:                                DecryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
        !            35:                        }
        !            36:                }
        !            37:        }
        !            38: 
        !            39:        void EncryptionModeCBC::DecryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const
        !            40:        {
        !            41:                size_t blockSize = ciphers.front()->GetBlockSize();
        !            42:                if (blockSize != 8 && blockSize != 16)
        !            43:                        throw ParameterIncorrect (SRC_POS);
        !            44: 
        !            45:                uint32 *data32 = (uint32 *) data;
        !            46:                uint32 bufIV[4];
        !            47:                uint32 ct[4];
        !            48:                uint64 i;
        !            49: 
        !            50:                bufIV[0] = iv[0];
        !            51:                bufIV[1] = iv[1];
        !            52:                if (blockSize == 16)
        !            53:                {
        !            54:                        bufIV[2] = iv[2];
        !            55:                        bufIV[3] = iv[3];
        !            56:                }
        !            57: 
        !            58:                for (i = 0; i < length / blockSize; i++)
        !            59:                {
        !            60:                        // Dewhitening
        !            61:                        data32[0] ^= whitening[0];
        !            62:                        data32[1] ^= whitening[1];
        !            63:                        if (blockSize == 16)
        !            64:                        {
        !            65:                                data32[2] ^= whitening[0];
        !            66:                                data32[3] ^= whitening[1];
        !            67:                        }
        !            68: 
        !            69:                        // CBC
        !            70:                        ct[0] = data32[0];
        !            71:                        ct[1] = data32[1];
        !            72:                        if (blockSize == 16)
        !            73:                        {
        !            74:                                ct[2] = data32[2];
        !            75:                                ct[3] = data32[3];
        !            76:                        }
        !            77: 
        !            78:                        for (CipherList::const_reverse_iterator iCipherList = ciphers.rbegin();
        !            79:                                iCipherList != ciphers.rend();
        !            80:                                ++iCipherList)
        !            81:                        {
        !            82:                                const Cipher &c = **iCipherList;
        !            83: 
        !            84:                                if (c.GetBlockSize () != blockSize)
        !            85:                                        throw ParameterIncorrect (SRC_POS);
        !            86: 
        !            87:                                c.DecryptBlock ((byte *) data32);
        !            88:                        }
        !            89: 
        !            90:                        // CBC
        !            91:                        data32[0] ^= bufIV[0];
        !            92:                        data32[1] ^= bufIV[1];
        !            93:                        bufIV[0] = ct[0];
        !            94:                        bufIV[1] = ct[1];
        !            95:                        if (blockSize == 16)
        !            96:                        {
        !            97:                                data32[2] ^= bufIV[2];
        !            98:                                data32[3] ^= bufIV[3];
        !            99:                                bufIV[2] = ct[2];
        !           100:                                bufIV[3] = ct[3];
        !           101:                        }
        !           102: 
        !           103:                        data32 += blockSize / sizeof(*data32);
        !           104:                }
        !           105: 
        !           106:                Memory::Erase (bufIV, sizeof (bufIV));
        !           107:                Memory::Erase (ct, sizeof (ct));
        !           108:        }
        !           109: 
        !           110:        void EncryptionModeCBC::DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
        !           111:        {
        !           112:                if_debug (ValidateState ());
        !           113:                if_debug (ValidateParameters (data, sectorCount, sectorSize));
        !           114: 
        !           115:                uint32 sectorIV[4];
        !           116:                uint32 sectorWhitening[2];
        !           117: 
        !           118:                while (sectorCount--)
        !           119:                {
        !           120:                        if (IsOuterCBC (Ciphers))
        !           121:                        {
        !           122:                                InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
        !           123:                                DecryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening);
        !           124:                        }
        !           125:                        else
        !           126:                        {
        !           127:                                for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
        !           128:                                        iCipherList != Ciphers.rend();
        !           129:                                        ++iCipherList)
        !           130:                                {
        !           131:                                        const Cipher &c = **iCipherList;
        !           132:                                        CipherList cl;
        !           133:                                        cl.push_back (*iCipherList);
        !           134: 
        !           135:                                        InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
        !           136:                                        DecryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening);
        !           137:                                }
        !           138:                        }
        !           139: 
        !           140:                        data += sectorSize;
        !           141:                        sectorIndex++;
        !           142:                }
        !           143: 
        !           144:                Memory::Erase (sectorIV, sizeof (sectorIV));
        !           145:                Memory::Erase (sectorWhitening, sizeof (sectorWhitening));
        !           146:        }
        !           147: 
        !           148:        void EncryptionModeCBC::Encrypt (byte *data, uint64 length) const
        !           149:        {
        !           150:                if_debug (ValidateState ());
        !           151:                if_debug (ValidateParameters (data, length));
        !           152: 
        !           153:                if (IsOuterCBC (Ciphers))
        !           154:                {
        !           155:                        EncryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
        !           156:                }
        !           157:                else
        !           158:                {
        !           159:                        for (CipherList::const_iterator iCipherList = Ciphers.begin();
        !           160:                                iCipherList != Ciphers.end();
        !           161:                                ++iCipherList)
        !           162:                        {
        !           163:                                CipherList cl;
        !           164:                                cl.push_back (*iCipherList);
        !           165: 
        !           166:                                EncryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
        !           167:                        }
        !           168:                }
        !           169:        }
        !           170: 
        !           171:        void EncryptionModeCBC::EncryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const
        !           172:        {
        !           173:                size_t blockSize = ciphers.front()->GetBlockSize();
        !           174:                if (blockSize != 8 && blockSize != 16)
        !           175:                        throw ParameterIncorrect (SRC_POS);
        !           176: 
        !           177:                uint32 *data32 = (uint32 *) data;
        !           178:                uint32 bufIV[4];
        !           179:                uint64 i;
        !           180: 
        !           181:                bufIV[0] = iv[0];
        !           182:                bufIV[1] = iv[1];
        !           183:                if (blockSize == 16)
        !           184:                {
        !           185:                        bufIV[2] = iv[2];
        !           186:                        bufIV[3] = iv[3];
        !           187:                }
        !           188: 
        !           189:                for (i = 0; i < length / blockSize; i++)
        !           190:                {
        !           191:                        data32[0] ^= bufIV[0];
        !           192:                        data32[1] ^= bufIV[1];
        !           193:                        if (blockSize == 16)
        !           194:                        {
        !           195:                                data32[2] ^= bufIV[2];
        !           196:                                data32[3] ^= bufIV[3];
        !           197:                        }
        !           198: 
        !           199:                        for (CipherList::const_iterator iCipherList = ciphers.begin();
        !           200:                                iCipherList != ciphers.end();
        !           201:                                ++iCipherList)
        !           202:                        {
        !           203:                                const Cipher &c = **iCipherList;
        !           204: 
        !           205:                                if (c.GetBlockSize () != blockSize)
        !           206:                                        throw ParameterIncorrect (SRC_POS);
        !           207: 
        !           208:                                c.EncryptBlock ((byte *) data32);
        !           209:                        }
        !           210: 
        !           211:                        bufIV[0] = data32[0];
        !           212:                        bufIV[1] = data32[1];
        !           213:                        if (blockSize == 16)
        !           214:                        {
        !           215:                                bufIV[2] = data32[2];
        !           216:                                bufIV[3] = data32[3];
        !           217:                        }
        !           218: 
        !           219:                        data32[0] ^= whitening[0];
        !           220:                        data32[1] ^= whitening[1];
        !           221:                        if (blockSize == 16)
        !           222:                        {
        !           223:                                data32[2] ^= whitening[0];
        !           224:                                data32[3] ^= whitening[1];
        !           225:                        }
        !           226: 
        !           227:                        data32 += blockSize / sizeof(*data32);
        !           228:                }
        !           229: 
        !           230:                Memory::Erase (bufIV, sizeof (bufIV));
        !           231:        }
        !           232: 
        !           233:        void EncryptionModeCBC::EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
        !           234:        {
        !           235:                if_debug (ValidateState ());
        !           236:                if_debug (ValidateParameters (data, sectorCount, sectorSize));
        !           237: 
        !           238:                uint32 sectorIV[4];
        !           239:                uint32 sectorWhitening[2];
        !           240: 
        !           241:                while (sectorCount--)
        !           242:                {
        !           243:                        if (IsOuterCBC (Ciphers))
        !           244:                        {
        !           245:                                InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
        !           246:                                EncryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening);
        !           247:                        }
        !           248:                        else
        !           249:                        {
        !           250:                                for (CipherList::const_iterator iCipherList = Ciphers.begin();
        !           251:                                        iCipherList != Ciphers.end();
        !           252:                                        ++iCipherList)
        !           253:                                {
        !           254:                                        const Cipher &c = **iCipherList;
        !           255:                                        CipherList cl;
        !           256:                                        cl.push_back (*iCipherList);
        !           257: 
        !           258:                                        InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
        !           259:                                        EncryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening);
        !           260:                                }
        !           261:                        }
        !           262: 
        !           263:                        data += sectorSize;
        !           264:                        sectorIndex++;
        !           265:                }
        !           266: 
        !           267:                Memory::Erase (sectorIV, sizeof (sectorIV));
        !           268:                Memory::Erase (sectorWhitening, sizeof (sectorWhitening));
        !           269:        }
        !           270: 
        !           271:        void EncryptionModeCBC::InitSectorIVAndWhitening (uint64 sectorIndex, size_t blockSize, const uint64 *ivSeed, uint32 *iv, uint32 *whitening) const
        !           272:        {
        !           273:                if (blockSize != 8 && blockSize != 16)
        !           274:                        throw ParameterIncorrect (SRC_POS);
        !           275: 
        !           276:                uint64 iv64[4];
        !           277:                uint32 *iv32 = (uint32 *) iv64;
        !           278: 
        !           279:                iv64[0] = ivSeed[0] ^ Endian::Little (sectorIndex);
        !           280:                iv64[1] = ivSeed[1] ^ Endian::Little (sectorIndex);
        !           281:                iv64[2] = ivSeed[2] ^ Endian::Little (sectorIndex);
        !           282:                if (blockSize == 16)
        !           283:                {
        !           284:                        iv64[3] = ivSeed[3] ^ Endian::Little (sectorIndex);
        !           285:                }
        !           286: 
        !           287:                iv[0] = iv32[0];
        !           288:                iv[1] = iv32[1];
        !           289: 
        !           290:                if (blockSize == 8)
        !           291:                {
        !           292:                        whitening[0] = Endian::Little ( crc32int ( &iv32[2] ) ^ crc32int ( &iv32[5] ) );
        !           293:                        whitening[1] = Endian::Little ( crc32int ( &iv32[3] ) ^ crc32int ( &iv32[4] ) );
        !           294:                }
        !           295:                else
        !           296:                {
        !           297:                        iv[2] = iv32[2];
        !           298:                        iv[3] = iv32[3];
        !           299: 
        !           300:                        whitening[0] = Endian::Little ( crc32int ( &iv32[4] ) ^ crc32int ( &iv32[7] ) );
        !           301:                        whitening[1] = Endian::Little ( crc32int ( &iv32[5] ) ^ crc32int ( &iv32[6] ) );
        !           302:                }
        !           303:        }
        !           304: 
        !           305:        bool EncryptionModeCBC::IsOuterCBC (const CipherList &ciphers) const
        !           306:        {
        !           307:                if (ciphers.size() < 2)
        !           308:                        return false;
        !           309: 
        !           310:                size_t blockSize = ciphers.front()->GetBlockSize();
        !           311: 
        !           312:                for (CipherList::const_iterator iCipherList = ciphers.begin();
        !           313:                        iCipherList != ciphers.end();
        !           314:                        ++iCipherList)
        !           315:                {
        !           316:                        const Cipher &c = **iCipherList;
        !           317:                        if (c.GetBlockSize() != blockSize)
        !           318:                                return false;
        !           319:                }
        !           320: 
        !           321:                return true;
        !           322:        }
        !           323: 
        !           324:        void EncryptionModeCBC::SetKey (const ConstBufferPtr &key)
        !           325:        {
        !           326:                if (key.Size() != GetKeySize ())
        !           327:                        throw ParameterIncorrect (SRC_POS);
        !           328: 
        !           329:                if (!KeySet)
        !           330:                        IV.Allocate (GetKeySize ());
        !           331:                
        !           332:                IV.CopyFrom (key);
        !           333:                KeySet = true;
        !           334:        }
        !           335: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.