📄 kblock.cpp
字号:
/******************************************************************* * * Copyright (c) 1994-1999 Jetico, Inc., Finland * All rights reserved. * * File: kblock.cc * Revision: $Id: kblock.cpp,v 1.1 2005/05/12 09:51:39 crypt Rel-1.6-3 $ * Created: * Description: implementation of procedures to work with * Data Block that stores encryption keys * *******************************************************************/#include <stdlib.h>#include <malloc.h>#include <string.h>#include <bc_types.h>#include "kg_defs.h"#include "kg_misc.h"#include "kblock.h"#include "random.h"#include "sha256.h"#include "alg.h"char kblock_cpp[]="$Id: kblock.cpp,v 1.1 2005/05/12 09:51:39 crypt Rel-1.6-3 $";/* Forward declarations of local procedures */BOOL CalculateDigest( BYTE *Data, DWORD Length, BYTE *Digest );BOOL DataBlockVerifyDigest( DATA_BLOCK *DataBlock );BOOL DataBlockUpdateDigest( DATA_BLOCK *DataBlock );BOOL GetStorageKeyFromPassword( char *Password, BYTE *StorageKey );void setAttribute( DWORD *AttBuffer, DWORD Attribute );DWORD getAttribute( DWORD AttBuffer );BOOL createAlternativeKeyBlock( DATA_BLOCK *DataBlock, ALG_SERV Alg, DWORD AlgKeyLength, BYTE *Key, BYTE *PoolBuffer );/********************************************************************** * * DataBlockAllocate() - allocates memory for DATA_BLOCK structure * and initializes the structure. * * The procedure which calls DataBlockAllocate() is responsible for * releasing the memory with the DataBlockFree() function. * **********************************************************************/extern BOOL DataBlockAllocate(DATA_BLOCK **DataBlock, DWORD *DataSize, DWORD AlgId){ DATA_BLOCK *db; KEY_BLOCK *kb; int i; *DataSize = 0; *DataBlock = (DATA_BLOCK *)malloc(sizeof(DATA_BLOCK)); if ( !(*DataBlock) ) return FALSE; db = *DataBlock; *DataSize = sizeof(DATA_BLOCK); ShredData( (BYTE *)db, sizeof(DATA_BLOCK) ); /* fill DataBlock by random garbage */ strcpy( db->header.signature, SIGNATURE03 );// strcpy( db->header.signature, SIGNATURE04 ); db->header.formatVersion = FORMAT_VERSION; db->header.encrAlgorithmId = AlgId; db->header.hashAlgorithmId = SHA256_ID; db->header.dataBlockSize = sizeof(DATA_BLOCK); db->header.keyBlockSize = sizeof(KEY_BLOCK); db->header.keyBlockNumber = MAXIMUM_NUMBER_OF_KEYS; setAttribute( &(db->header.state), STATE_POOL_NOT_INITIALIZED); kb = db->keys; for ( i=0; i<MAXIMUM_NUMBER_OF_KEYS; i++, kb++ ) { setAttribute( &(kb->keyAttribute), KATTRIBUTE_KEY_EMPTY ); } if ( DataBlockUpdateDigest( *DataBlock ) ) return TRUE; DataBlockFree( DataBlock ); *DataSize = 0; return FALSE;}/********************************************************************** * * DataBlockFree() - wipes and frees DATA_BLOCK structure * * The procedure which calls DataBlockAllocate() is responsible for * releasing the memory with the DataBlockFree() function. * **********************************************************************/extern BOOL DataBlockFree( DATA_BLOCK **DataBlock ){ ShredData( (BYTE *)*DataBlock, sizeof(DATA_BLOCK) ); if ( *DataBlock ) free( *DataBlock); *DataBlock = NULL; return TRUE;}/********************************************************************** * * DataBlockCheck() - verifies that DATA_BLOCK structure is not damaged * and checks that DATA_BLOCK stores at least * KeysCount keys. * **********************************************************************/extern DWORD DataBlockCheck( DATA_BLOCK *DataBlock, DWORD DataSize, DWORD AlgId ){ if ( !DataBlock ) return ERROR_DAMAGED_DATA_BLOCK; if ( DataBlock->header.formatVersion != FORMAT_VERSION ) return ERROR_INCORRECT_FORMAT_VERSION; if ( (DataBlock->header.dataBlockSize != sizeof(DATA_BLOCK)) || (DataSize != sizeof(DATA_BLOCK)) ) return ERROR_INCORRECT_DATA_BLOCK_SIZE; if (strcmp(DataBlock->header.signature, SIGNATURE98) && strcmp(DataBlock->header.signature, SIGNATURE03) && strcmp(DataBlock->header.signature, SIGNATURE04)) return ERROR_INCORRECT_BLOCK_SIGNATURE; if ( DataBlock->header.encrAlgorithmId != AlgId ) return ERROR_INCORRECT_ENCR_ALGORITHM; if ( DataBlock->header.hashAlgorithmId != SHA256_ID ) return ERROR_INCORRECT_HASH_ALGORITHM; if ( !DataBlockVerifyDigest( DataBlock ) ) return ERROR_DAMAGED_DATA_BLOCK; return ERROR_NO;}/********************************************************************** * * DataBlockWriteKey() - fills a free KEY_BLOCK in the DataBlock. * **********************************************************************/extern DWORD DataBlockWriteKey( DATA_BLOCK *DataBlock, ALG_SERV Alg, DWORD AlgKeyLength, char * Password, BYTE *Key, DWORD KeyAttribute, BYTE *PoolBuffer ){ BYTE storageKey[ MAXIMUM_KEY_SIZE_BYTES ]; DWORD keyHandle; KEY_BLOCK *kb, *kbFound; BYTE iVector[ IVECTOR_LENGTH ]; /* find empty KEY_BLOCK inside DataBlock*/ kb = DataBlock->keys; kbFound = NULL; for ( int i=0; i<MAXIMUM_NUMBER_OF_KEYS; i++, kb++ ) { if ( getAttribute(kb->keyAttribute) == KATTRIBUTE_KEY_EMPTY ) { kbFound = kb; break; } } if ( !kbFound ) return ERROR_NOT_ENOUGH_SPACE_FOR_KEY; /* copy encryption key to the KEY_BLOCK memory */ memcpy( kbFound->key, Key, MAXIMUM_KEY_SIZE_BYTES ); /* calculate digest of the key and save it in KEY_BLOCK */ if ( !CalculateDigest( kbFound->key, MAXIMUM_KEY_SIZE_BYTES, kbFound->digest ) ) { ShredData( kbFound->key, MAXIMUM_KEY_SIZE_BYTES ); return ERROR_INVALID_ALGORITHM; } memcpy( iVector, kbFound->digest, IVECTOR_LENGTH ); /* Encrypt pool in the data block with the Key */ if ( getAttribute(DataBlock->header.state) == STATE_POOL_NOT_INITIALIZED ) { /* we must fill the PoolBuffer with zeros, because the pool in the DataBlock we are going to encrypt already contain random data */ memset( PoolBuffer, 0, POOL_SIZE_BYTES ); /* Load the Key to encryption algorithm module */ if ( alg_make_key (Alg, Key, AlgKeyLength, PoolBuffer, &keyHandle ) ) { ShredData( iVector, IVECTOR_LENGTH); return ERROR_INVALID_ALGORITHM; } /* Encrypt pool */ if ( alg_encrypt( Alg, keyHandle, iVector, DataBlock->pool, 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 */ alg_free_key( Alg, keyHandle ); setAttribute(&(DataBlock->header.state),STATE_POOL_INITIALIZED); } /* We begin to 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) */ 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); setAttribute( &(kbFound->keyAttribute), KeyAttribute ); /* Check if Alternative Key Block is initialized. If no, initialize it */ createAlternativeKeyBlock( DataBlock, Alg, AlgKeyLength,Key, PoolBuffer ); if ( !DataBlockUpdateDigest( DataBlock ) ) { setAttribute( &(kbFound->keyAttribute), KATTRIBUTE_KEY_EMPTY ); return ERROR_INTERNAL_PROBLEM; } return ERROR_NO;}DWORD DataBlockVerifyPasswordAndGetKey( DATA_BLOCK *DataBlock, ALG_SERV Alg, DWORD AlgKeyLength, char * Password, BYTE *Key, BYTE *PoolBuffer ){ KEY_BLOCK *kb, *kbFound; BYTE storageKey[ MAXIMUM_KEY_SIZE_BYTES ]; BYTE keyAndDigest[ MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES ]; BYTE calculatedDigest[ MAXIMUM_DIGEST_SIZE_BYTES ]; DWORD keyHandle, i; BYTE iVector[ IVECTOR_LENGTH ]; kb = DataBlock->keys; kbFound = NULL; /* we fill the PoolBuffer with zeros, because the buffers in the DataBlock we are going to decrypt contain random data */ /* in the first part of the procedure we use the PoolBuffer to initialize encryption algorithm module with zeroed pools. In the second part we will place a correct decrypted pool data to the PoolBuffer */ memset( PoolBuffer, 0, POOL_SIZE_BYTES ); for ( i=0; i<MAXIMUM_NUMBER_OF_KEYS; i++, kb++ ) { if ( getAttribute(kb->keyAttribute) == KATTRIBUTE_KEY_EMPTY ) continue; /* 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 copied to the Algorithm Driver */ ShredData( storageKey, MAXIMUM_KEY_SIZE_BYTES ); /* decrypt the key and its digest copied to the KEY_BLOCK */ memcpy( keyAndDigest, kb->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 */ memcpy( iVector, &(keyAndDigest[MAXIMUM_KEY_SIZE_BYTES]), IVECTOR_LENGTH ); /* second decryption with exact Initial Vector */ memcpy( keyAndDigest, kb->key, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES ); if ( alg_decrypt( Alg, keyHandle, iVector, keyAndDigest, MAXIMUM_KEY_SIZE_BYTES + MAXIMUM_DIGEST_SIZE_BYTES) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -