📄 bcreencrypt.c
字号:
/********************************************************************* Copyright (c) 1994-1999 Jetico, Inc., Finland* All rights reserved.** File: bccreate.c* Revision: $Id: bcreencrypt.c,v 1.17 2005/05/14 07:58:33 crypt Rel-1.6-3 $* Created:* Description: implementation of container reencryption routine********************************************************************/#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <strings.h>#include <string.h>#include <stdlib.h>#include <bc_types.h>#include <bc_ioctl.h>#include "keygen.h"#include <kg_defs.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <time.h>#include "header.h"#include <kblock.h>#include "alg.h"#include "config.h"#include "bctool.h"#include "misc.h"#include "error.h"#include "version.h"char bcreencrypt_c[]="$Id: bcreencrypt.c,v 1.17 2005/05/14 07:58:33 crypt Rel-1.6-3 $";#define BUFF_SIZE 1024*1024 // 1 Mbchar *fnbuff,*fnstat1,*fnstat2,*fnheader1,*fnheader2;ALG_SERV AlgOld,AlgNew;DWORD KeyHandleOld,KeyHandleNew;struct _state{ unsigned int step; //1:buffer empty(redy to fill bufer) //2:buffer full (redy to write data in container) //3: reencryption done(ready to write header) //4: all done int dir; // 1: begin to end; -1: end to begin; 0: read done unsigned int BuffSize; unsigned int OldDataOffset; // also = old header size unsigned int NewDataOffset; // also = new header size long long int ReadPos; long long int WritePos; long long int OldContSize; long long int NewContSize; int OldContVersion; int NewContVersion;}__attribute__ ((packed)) state;void ReencryptSignalHandler(int sig){ if ( ask_y_n("Do you really want to terminate process? (y/n) [n]:")==FALSE ) return; FreeKeyHandle(AlgNew,KeyHandleNew); FreeKeyHandle(AlgOld,KeyHandleOld); exit(-1);}int WriteStatFile(char *fileName, void *buffer, ssize_t size){ int fd; fd = open(fileName,O_WRONLY|O_CREAT|O_SYNC,S_IRUSR|S_IWUSR); if ( fd==-1 ) return FALSE; if ( write(fd,buffer,size) != size ) return FALSE; if ( close( fd )==-1 ) return FALSE; return TRUE;};int ReadStatFile(char *fileName, void *buffer, ssize_t size ){ struct stat buf; int fd; if ( lstat(fileName,&buf)==-1 ) return FALSE; if ( buf.st_size != size ) return FALSE; fd = open(fileName,O_RDONLY); if ( fd == -1 ) return FALSE; if ( read(fd,buffer,size)!=size ) { close(fd); return FALSE; } close(fd); return TRUE;}int PrepareFileNames(char *ContName){ fnbuff=(char*)malloc(strlen(ContName)+7); fnstat1=(char*)malloc(strlen(ContName)+7); fnstat2=(char*)malloc(strlen(ContName)+7); fnheader1=(char*)malloc(strlen(ContName)+7); fnheader2=(char*)malloc(strlen(ContName)+7); if ( fnbuff==NULL||fnstat1==NULL||fnstat2==NULL||fnheader1==NULL||fnheader2==NULL ) return FALSE; sprintf(fnbuff,"%s.bfr",ContName); sprintf(fnstat1,"%s.st1",ContName); sprintf(fnstat2,"%s.st2",ContName); sprintf(fnheader1,"%s.hr1",ContName); sprintf(fnheader2,"%s.hr2",ContName); return TRUE;}void FreeFileNames(){ free(fnbuff); free(fnstat1); free(fnstat2); free(fnheader1); free(fnheader2);}int UnlinkStatFiles(){ if ( unlink(fnbuff)==0&&unlink(fnstat1)==0&&unlink(fnstat2)==0&&unlink(fnheader1)==0&&unlink(fnheader2)==0 ) return 0; return errno;}/********************************************************* * init * * **********************************************************/int init(char *ContName,char *DB,int DB_size,unsigned int KgId, unsigned int AlgId){ int fd; struct HiddenSector hs; void *buff; if ( DB==NULL||ContName==NULL )return FALSE; if ( (fd = open(ContName, O_RDONLY|O_LARGEFILE)) < 0 ) return FALSE; if ( read(fd, &hs, sizeof(hs))!=sizeof(hs) ) return FALSE; state.OldDataOffset=hs.dwDataOffset; state.OldContSize=((long long int)hs.br.bpb.totalSectorsLong)*512L + hs.dwDataOffset; state.NewDataOffset=(sizeof(hs)+DB_size +511 ) & ~511; state.NewContSize=((long long int)hs.br.bpb.totalSectorsLong)*512L + state.NewDataOffset ; state.step=1; state.BuffSize=BUFF_SIZE; state.dir=state.OldDataOffset>= state.NewDataOffset ? 1 : -1; state.ReadPos = state.dir>0 ? state.OldDataOffset : state.OldContSize-state.BuffSize; state.WritePos = state.dir>0 ? state.NewDataOffset : state.NewContSize; state.OldContVersion = hs.version; state.NewContVersion = CONTAINER_VERSION; lseek(fd,0,SEEK_SET); buff=malloc(hs.dwDataOffset); if ( buff==NULL )return FALSE; if ( read(fd,buff,hs.dwDataOffset)!=(ssize_t)hs.dwDataOffset ) return FALSE; close(fd); if ( WriteStatFile(fnheader1,buff,hs.dwDataOffset)==FALSE )return FALSE; free(buff); // mark reencrypted strncpy(hs.br.volumeLabel,"REENCRYPTED",11); if ( WriteStatFile(ContName,&hs,sizeof(hs))==FALSE )return FALSE; // preparing new HiddenSector hs.dwKeySize = DB_size; strncpy(hs.br.volumeLabel,"CRYPTED_DSK",11); hs.algorithmId=AlgId; hs.keyGenId=KgId; hs.version = CONTAINER_VERSION; hs.dwDataOffset=state.NewDataOffset; buff=malloc(state.NewDataOffset); if ( buff==NULL )return FALSE; memset(buff,0,state.NewDataOffset); memcpy(buff,&hs,sizeof(hs)); memcpy(buff+sizeof(hs),DB,DB_size); if ( WriteStatFile(fnheader2,buff,state.NewDataOffset)==FALSE )return FALSE; free(buff); return WriteStatFile(fnstat1,&state,sizeof(state))&&WriteStatFile(fnstat2,&state,sizeof(state));}int WasInterrupted(char *ContName){ struct stat s; return (lstat(fnheader1,&s)!=-1 && lstat(fnheader1,&s)!=-1 && (lstat(fnstat1,&s)!=-1 || lstat(fnstat2,&s)!=-1)) ? TRUE : FALSE;}int WriteStatFiles(){ return (WriteStatFile(fnstat1,&state,sizeof(state)) && WriteStatFile(fnstat2,&state,sizeof(state)));}int ReadStatFiles(){ return ReadStatFile(fnstat1,&state,sizeof(state)) || ReadStatFile(fnstat2,&state,sizeof(state));}int WriteContFile(int fd, void *buff){ int size; if ( state.BuffSize==0 )return 0; if ( lseek(fd,state.WritePos,SEEK_SET)==-1 )return -1; if ( (size=write(fd,buff,state.BuffSize))==-1 )return -1; return size;}int ReadContFile(int fd, void *buff){ int size; if ( lseek(fd,state.ReadPos,SEEK_SET)==-1 )return -1; if ( (size=read(fd,buff,state.BuffSize))==-1 )return -1; return size;}int reencrypt(void *buff){ BYTE *IV; short old_iv[4]; long long int new_iv; unsigned int i; if ( state.BuffSize==0 )return TRUE; IV = (BYTE *)&new_iv; for ( i=0;i<state.BuffSize;i+=512 ) { new_iv = (state.ReadPos-state.OldDataOffset+i)>>9; old_iv[0] = old_iv[1]=old_iv[2]=old_iv[3]=new_iv & 0xFFFF; new_iv++; // first sector in new version is 1 not 0 if (state.OldContVersion == 0 ) IV = (BYTE *)old_iv; else IV = (BYTE *)&new_iv; if ( alg_decrypt(AlgOld,KeyHandleOld,IV,buff+i,512)!=0 ) return FALSE; if (state.NewContVersion == 0 ) IV = (BYTE *)old_iv; else IV = (BYTE *)&new_iv; if ( alg_encrypt(AlgNew,KeyHandleNew,IV,buff+i,512)!=0 ) return FALSE; } return TRUE;}int MoveData(char *ContName){ int fd; void *buff; int opr=0; int pr=0; time_t t,ot; if ( (buff=malloc(BUFF_SIZE))==NULL ) { msg(stderr,"Can not allocate memory for buffer\n"); return FALSE; } if ( (fd = open(ContName, O_RDWR|O_SYNC|O_LARGEFILE)) < 0 ) { msg(stderr,"Can not open container for Read/Write\n"); return FALSE; } if ( ReadStatFiles()==FALSE ) { msg(stderr,"Can not read stat files\n"); return FALSE; } if ( state.step==2 ) { if ( ReadStatFile(fnbuff,buff,state.BuffSize)==FALSE ) { msg(stderr,"Can not read data from buffer file\n"); close(fd); return FALSE; } } if ( o_verbose ) msg(stdout,"Reencrypting container %s\n",ContName); ot=t=time(NULL); do { switch ( state.step ) { case 1: if ( state.dir==-1 && state.ReadPos-state.OldDataOffset <= 0 ) { state.BuffSize=state.ReadPos+state.BuffSize-state.OldDataOffset; state.ReadPos=state.OldDataOffset; state.WritePos=state.NewDataOffset; } if ( (int)(state.BuffSize=ReadContFile(fd,buff))==-1 ) { msg(stderr,"Can not read data from container\n"); close(fd); free(buff); return FALSE; } if ( reencrypt(buff)==FALSE ) { msg(stderr,"Buffer reencryption error\n"); close(fd); free(buff); return FALSE; } if ( WriteStatFile(fnbuff,buff,state.BuffSize)==FALSE ) { msg(stderr,"Can not write data to buffer file\n"); close(fd); free(buff); return FALSE; } if ( state.BuffSize < BUFF_SIZE ) state.dir=0; if ( state.dir == 1 )state.ReadPos+=state.BuffSize; if ( state.dir == -1 )state.ReadPos-=state.BuffSize; state.step=2; if ( WriteStatFiles()==FALSE ) { msg(stderr,"Can not write stat files\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -