📄 kblock.cpp
字号:
} if ( !kbFound ) return FALSE; // Empty key block is already filled in by random data. // We'll create digest for the data and encrypt it using the Key if ( !CalculateDigest( kbFound->verifyBytes, VERIFY_BYTES_LENGTH, kbFound->digest ) ) return FALSE; memset( PoolBuffer, 0, POOL_SIZE_BYTES ); memset( iVector, 0, IVECTOR_LENGTH ); /* Load the Key to encryption algorithm module */ if ( alg_make_key( Alg, Key, AlgKeyLength, PoolBuffer, &keyHandle ) ) return FALSE; /* Encrypt 'verify data' and 'digest' */ if ( alg_encrypt( Alg, keyHandle, iVector, kbFound->verifyBytes, VERIFY_BYTES_LENGTH + MAXIMUM_DIGEST_SIZE_BYTES ) ) { alg_free_key( Alg, keyHandle ); return FALSE; } /* Erase and free the Key data from the encryption algorithm module */ alg_free_key( Alg, keyHandle ); setAttribute( &(kbFound->keyAttribute), KATTRIBUTE_ALTERNATIVE_BLOCK ); return TRUE;}/**** Procedures for creating and opening Hidden part of container ****//********************************************************************** * * DataBlockWriteKey_Hidden() .B- * fills a LAST free KEY_BLOCK in the DataBlock without * changing the KATTRIBUTE_KEY_EMPTY attribute * **********************************************************************/#define OFFSET_IN_KEY_SPACE (MAXIMUM_KEY_SIZE_BYTES - sizeof(DWORD) - sizeof(DWORD))#define KEYMAP_IN_KEY_SPACE (MAXIMUM_KEY_SIZE_BYTES - sizeof(DWORD))static DWORD localDataBlockWriteKey_Hidden( DATA_BLOCK *DataBlock, KEY_BLOCK *kbFound, ALG_SERV Alg, DWORD AlgId, DWORD AlgKeyLength, char *Password, BYTE *Key, DWORD KeyAttribute, // in the current release we don't use the parameter BYTE *PoolBuffer, DWORD Offset, DWORD Mask ){ BYTE storageKey[ MAXIMUM_KEY_SIZE_BYTES ]; DWORD keyHandle, *offsetPlace; BYTE iVector[ IVECTOR_LENGTH ]; /* copy encryption key to the KEY_BLOCK memory */ memcpy( kbFound->key, Key, MAXIMUM_KEY_SIZE_BYTES ); /* save offset inside last 4 bytes of key space. we reserved 64 bytes for key space,o last 4 bytes are not busy by encryption key - usually up to 32 bytes, maximum one is Blowfish-448, hence in any case we have 64 bits in key space free. Will use the space for Offset and Mask) */ offsetPlace = (DWORD *)(&( kbFound->key[OFFSET_IN_KEY_SPACE] )); *offsetPlace = Offset; offsetPlace = (DWORD *)(&( kbFound->key[KEYMAP_IN_KEY_SPACE] )); *offsetPlace = Mask; /* calculate digest of the key and save it in KEY_BLOCK */ if ( !CalculateDigest( kbFound->key, MAXIMUM_KEY_SIZE_BYTES - sizeof(DWORD), kbFound->digest ) ) { ShredData( kbFound->key, MAXIMUM_KEY_SIZE_BYTES ); return ERROR_INVALID_ALGORITHM; } memcpy( iVector, kbFound->digest, IVECTOR_LENGTH ); /* We don't encrypt pool in the data block with the Key, because it's already encrypted. */ /* Encrypt file-container's encryption key and its digest using storageKey. First of all, calculate storageKey from the password */ if ( !GetStorageKeyFromPassword( Password, storageKey ) ) { ShredData( kbFound->key, MAXIMUM_KEY_SIZE_BYTES ); ShredData( kbFound->digest, MAXIMUM_DIGEST_SIZE_BYTES ); ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* Load storageKey into the Algorithm driver and again, the Pool must be filled by zeros, because we are going to encrypt random data (Key) */ memset( PoolBuffer, 0, POOL_SIZE_BYTES ); if ( alg_make_key( Alg, storageKey, AlgKeyLength, PoolBuffer, &keyHandle ) ) { ShredData( storageKey, MAXIMUM_KEY_SIZE_BYTES ); ShredData( kbFound->key, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES); ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* Now we don't need in storageKey, because it is copied to the Algorithm Driver */ ShredData( storageKey, MAXIMUM_KEY_SIZE_BYTES ); /* encrypt the key and its digest copied to the KEY_BLOCK */ if ( alg_encrypt( Alg, keyHandle, iVector, kbFound->key, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES) ) { alg_free_key( Alg, keyHandle ); ShredData( kbFound->key, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES); ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* erase storageKey from the Algorithm driver memory */ alg_free_key( Alg, keyHandle ); ShredData( iVector, IVECTOR_LENGTH); if ( !DataBlockUpdateDigest( DataBlock ) ) { return ERROR_INTERNAL_PROBLEM; } return ERROR_NO;}DWORD DataBlockWriteKey_Hidden( DATA_BLOCK *DataBlock, ALG_SERV Alg, DWORD AlgKeyLength, char *Password, BYTE *Key, DWORD KeyAttribute, // in the current release we don't use the parameter BYTE *PoolBuffer, DWORD Offset, DWORD *BusyMask, DWORD KeyBlockPositionMask ){ KEY_BLOCK *kbFound; int i; DWORD mask, dwRes, position; dwRes = ERROR_NOT_ENOUGH_SPACE_FOR_KEY; /* Check if Alternative Key Block is initialized. If no, initialize it */ createAlternativeKeyBlock( DataBlock, Alg, AlgKeyLength, Key, PoolBuffer ); if ( KeyBlockPositionMask == HIDDEN_POSITION_ANY ) { for ( i = MAXIMUM_NUMBER_OF_KEYS - 1; i>0; i-- ) { kbFound = &(DataBlock->keys[i]); if ( getAttribute(kbFound->keyAttribute) != KATTRIBUTE_KEY_EMPTY ) continue; if ( (*BusyMask) & (1 << i) ) continue; mask = (*BusyMask) | (1 << i); dwRes = localDataBlockWriteKey_Hidden( DataBlock, kbFound, Alg, Alg.alg_id, AlgKeyLength, Password, Key, KeyAttribute, PoolBuffer, Offset, mask ); if ( dwRes == ERROR_NO ) { *BusyMask = mask; return ERROR_NO; } } } else { position = KeyBlockPositionMask; for ( i = 0; (i<MAXIMUM_NUMBER_OF_KEYS) && (position != 1); i++ ) { position >>= 1; } if ( i==MAXIMUM_NUMBER_OF_KEYS ) return ERROR_INTERNAL_PROBLEM; kbFound = &(DataBlock->keys[i]); if ( getAttribute(kbFound->keyAttribute) != KATTRIBUTE_KEY_EMPTY ) return ERROR_INTERNAL_PROBLEM; mask = (*BusyMask) | (1 << i); dwRes = localDataBlockWriteKey_Hidden( DataBlock, kbFound, Alg, Alg.alg_id, AlgKeyLength, Password, Key, KeyAttribute, PoolBuffer, Offset, mask ); if ( dwRes == ERROR_NO ) { *BusyMask = mask; return ERROR_NO; } } return dwRes;}/******************************************************* * * DataBlockVerifyPasswordAndGetKey_Hidden() * *******************************************************/static DWORD localDataBlockVerifyPasswordAndGetKey_Hidden( DATA_BLOCK *DataBlock, KEY_BLOCK *kbFound, ALG_SERV Alg, DWORD AlgId, DWORD AlgKeyLength, char *Password, BYTE *Key, BYTE *PoolBuffer, DWORD *Offset, DWORD *BusyMask ){ BYTE storageKey[ MAXIMUM_KEY_SIZE_BYTES ]; BYTE keyAndDigest[ MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES ]; BYTE calculatedDigest[ MAXIMUM_DIGEST_SIZE_BYTES ]; DWORD keyHandle; BYTE iVector[ IVECTOR_LENGTH ]; memset( PoolBuffer, 0, POOL_SIZE_BYTES ); if ( getAttribute(kbFound->keyAttribute) != KATTRIBUTE_KEY_EMPTY ) return ERROR_INCORRECT_PASSWORD; /* Calculate encryption key for decrypting KEY_BLOCK */ if ( !GetStorageKeyFromPassword( Password, storageKey ) ) return ERROR_INVALID_ALGORITHM; /* Decrypt KEY_BLOCK kb */ /* First, load storageKey into the Algorithm driver */ if ( alg_make_key( Alg, storageKey, AlgKeyLength, PoolBuffer, &keyHandle ) ) return ERROR_INVALID_ALGORITHM; /* Now we don't need in storageKey, because it is saved in the Algorithm Driver */ ShredData( storageKey, MAXIMUM_KEY_SIZE_BYTES ); /* decrypt the key and its digest copied to the KEY_BLOCK */ memcpy( keyAndDigest, kbFound->key, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES ); /* initialize iVector with any value. After first decrypting we will define it exactly */ memset( iVector, 0, IVECTOR_LENGTH ); /* first decryption */ if ( alg_decrypt( Alg, keyHandle, iVector, keyAndDigest, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES) ) { alg_free_key( Alg, keyHandle ); ShredData( keyAndDigest, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES); return ERROR_INVALID_ALGORITHM; } /* define Initial Vector exactly */ memcpy( iVector, &(keyAndDigest[MAXIMUM_KEY_SIZE_BYTES]), IVECTOR_LENGTH ); /* second decryption with exact Initial Vector */ memcpy( keyAndDigest, kbFound->key, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES ); if ( alg_decrypt( Alg, keyHandle, iVector, keyAndDigest, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES) ) { alg_free_key( Alg, keyHandle ); ShredData( keyAndDigest, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES); ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* erase storageKey from the Algorithm driver memory */ alg_free_key( Alg, keyHandle ); /* calculate digest of the key and compare it with digest */ if ( !CalculateDigest( keyAndDigest, MAXIMUM_KEY_SIZE_BYTES - sizeof(DWORD), calculatedDigest ) ) { ShredData( keyAndDigest, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES); ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } if ( memcmp( calculatedDigest, &(keyAndDigest[MAXIMUM_KEY_SIZE_BYTES]), SHA256_DIGEST_SIZE) != 0 ) { ShredData( iVector, IVECTOR_LENGTH); return ERROR_INCORRECT_PASSWORD; } /* Get encryption key */ memcpy( Key, keyAndDigest, MAXIMUM_KEY_SIZE_BYTES ); /* Get offset of the hidden part inside container */ *Offset = *(DWORD*)(keyAndDigest + OFFSET_IN_KEY_SPACE ); *BusyMask = *(DWORD*)(keyAndDigest + KEYMAP_IN_KEY_SPACE ); /* In the following part we will decrypt and place a correct pool data to the PoolBuffer, Now everything is Ok, and we have correct IVector. */ if ( getAttribute(DataBlock->header.state) == STATE_POOL_NOT_INITIALIZED ) { ShredData( iVector, IVECTOR_LENGTH); return ERROR_INCORRECT_POOL; } /* Load the Key into the Algorithm driver and again, the Pool is filled by zeros, because we are going to decrypt random data (Pool stored in the DataBlock) */ /* Load the Key to encryption algorithm module */ if ( alg_make_key( Alg, Key, AlgKeyLength, PoolBuffer, &keyHandle ) ) { ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* copy encrypted pool from DataBlock to the PoolBuffer */ memcpy( PoolBuffer, DataBlock->pool, POOL_SIZE_BYTES ); /* Decrypt pool */ if ( alg_decrypt( Alg, keyHandle, iVector, PoolBuffer, POOL_SIZE_BYTES ) ) { alg_free_key( Alg, keyHandle ); ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* Erase and free the Key data from the encryption algorithm module */ ShredData( iVector, IVECTOR_LENGTH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -