int zuluCryptOpenTcrypt( const char * device,const char * mapper,const char * key,size_t key_len, int key_source,int volume_type,const char * m_point, uid_t uid,unsigned long m_flags,const char * fs_opts ) { open_struct_t opts ; string_t st ; int r ; const char * keyfile ; memset( &opts,'\0',sizeof( open_struct_t ) ) ; opts.device = device ; opts.mapper_name = mapper ; opts.volume_type = volume_type ; opts.m_point = m_point ; opts.uid = uid ; opts.m_flags = m_flags ; opts.fs_opts = fs_opts ; if( m_flags & MS_RDONLY ){ opts.m_opts = "ro" ; }else{ opts.m_opts = "rw" ; } if( key_source == TCRYPT_KEYFILE ){ st = zuluCryptCreateKeyFile( key,key_len,"open_tcrypt-" ) ; if( st != StringVoid ){ keyfile = StringContent( st ) ; opts.tcrypt_keyfiles_count = 1 ; opts.tcrypt_keyfiles = &keyfile ; r = zuluCryptOpenTcrypt_1( &opts ) ; /* * zuluCryptDeleteFile() is defined in open_path_security.c */ zuluCryptDeleteFile( keyfile ) ; StringDelete( &st ) ; }else{ r = 1 ; } }else if( key_source == TCRYPT_KEYFILE_FILE ){ opts.tcrypt_keyfiles_count = 1 ; opts.tcrypt_keyfiles = &key ; r = zuluCryptOpenTcrypt_1( &opts ) ; }else{ opts.key_len = key_len ; opts.key = key ; r = zuluCryptOpenTcrypt_1( &opts ) ; } return r ; }
static int _modify_tcrypt( info_t * info,const struct_opts * opts ) { int k = 4 ; int r ; string_t st = StringVoid ; string_t xt = StringVoid ; if( StringsAreEqual( opts->key_source,"-p" ) ){ info->header_key = opts->key ; info->header_key_source = "passphrase" ; info->header_new_key_source = "new_passphrase" ; }else if( opts->key == NULL && StringsAreNotEqual( opts->key_source,"-f" ) ){ st = info->getKey( &r ) ; if( r ){ info->key = StringContent( st ) ; info->header_key = info->key ; info->header_key_source = "passphrase" ; info->header_new_key_source = "new_passphrase" ; }else{ return zuluExit_1( k,st,xt ) ; } }else{ /* * function is defined at "path_access.c" */ zuluCryptGetPassFromFile( opts->key,info->uid,&st ) ; zuluCryptSecurityGainElevatedPrivileges() ; if( st == StringVoid ){ return zuluExit_1( k,st,xt ) ; }else{ if( StringHasComponent( opts->key,".zuluCrypt-socket" ) ){ info->key = StringContent( st ) ; info->header_key = info->key ; info->header_key_source = "passphrase" ; info->header_new_key_source = "new_passphrase" ; }else{ xt = zuluCryptCreateKeyFile( StringContent( st ),StringLength( st ),"tcrypt-bk-" ) ; if( xt == StringVoid ){ return zuluExit_1( k,st,xt ) ; }else{ info->key = StringContent( xt ) ; info->header_key = info->key ; info->header_key_source = "keyfiles" ; info->header_new_key_source = "new_keyfiles" ; } } } } /* * zuluCryptModifyTcryptHeader() is defined in ../lib/create_tcrypt.c */ k = zuluCryptModifyTcryptHeader( info ) ; if( xt != StringVoid ){ /* * zuluCryptDeleteFile() is defined in ../lib/file_path_security.c */ zuluCryptDeleteFile( StringContent( xt ) ) ; } return zuluExit_1( k,st,xt ) ; }
static int _replace_truecrypt_key( const tcrypt_opts * opts ) { info_t info ; string_t st = StringVoid ; string_t xt = StringVoid ; int r ; memset( &info,'\0',sizeof( info_t ) ) ; info.device = opts->device ; /* * zuluCryptCreateKeyFile() is defined in ../lib/open_tcrypt.c */ if( opts->existing_key_is_keyfile ){ info.header_key_source = "keyfiles" ; st = zuluCryptCreateKeyFile( opts->existing_key,opts->existing_key_size,"add-tcrypt-1" ) ; info.header_key = StringContent( st ) ; }else{ info.header_key_source = "passphrase" ; info.header_key = opts->existing_key ; } if( opts->new_key_is_keyfile ){ info.header_new_key_source = "new_keyfiles" ; st = zuluCryptCreateKeyFile( opts->new_key,opts->new_key_size,"add-tcrypt-2" ) ; info.header_new_key = StringContent( st ) ; }else{ info.header_new_key_source = "new_passphrase" ; info.header_new_key = opts->new_key ; } info.rng = "/dev/urandom" ; /* * zuluCryptModifyTcryptHeader() is defined in ../lib/create_tcrypt.c */ r = zuluCryptModifyTcryptHeader( &info ) ; /* * zuluCryptDeleteFile_1() is defined in ../lib/file_path_security.c */ if( st != StringVoid ){ zuluCryptDeleteFile_1( st ) ; StringDelete( &st ) ; } if( xt != StringVoid ){ zuluCryptDeleteFile_1( xt ) ; StringDelete( &xt ) ; } if( r == 0 ){ return 0 ; }else{ return 1 ; } }
static int _create_tcrypt_volume( const char * device,const char * file_system, const char * rng,const char * key,size_t key_len, int key_source,u_int64_t hidden_volume_size, const char * file_system_h,const char * key_h,size_t key_len_h,int key_source_h ) { string_t st = StringVoid ; string_t xt = StringVoid ; tcrypt_t info ; int r = 3 ; if( zuluCryptPathIsNotValid( device ) ){ return 1 ; } memset( &info,'\0',sizeof( tcrypt_t ) ) ; info.device = device ; info.key_source = key_source ; info.key_source_h = key_source_h ; info.hidden_volume_size = hidden_volume_size ; if( StringPrefixMatch( rng,"/dev/urandom",12 ) ){ info.weak_keys_and_salt = 1 ; } if( info.key_source == TCRYPT_PASSPHRASE ){ info.key = key ; info.key_source_1 = "passphrase" ; }else{ /* * zuluCryptCreateKeyFile() is defined in open_tcrypt.c */ st = zuluCryptCreateKeyFile( key,key_len,"create_tcrypt-1-" ) ; info.key = StringContent( st ) ; info.key_source = TCRYPT_KEYFILE_FILE ; info.key_source_1 = "keyfiles" ; } if( info.hidden_volume_size > 0 ){ if( info.key_source_h == TCRYPT_PASSPHRASE ){ info.key_h = key_h ; info.key_source_h_1 = "h_passphrase" ; }else{ xt = zuluCryptCreateKeyFile( key_h,key_len_h,"create_tcrypt-2-" ) ; info.key_h = StringContent( xt ) ; info.key_source_h = TCRYPT_KEYFILE_FILE ; info.key_source_h_1 = "h_keyfiles" ; } } if( _create_volume( &info ) == TC_OK ){ r = _create_file_system( device,file_system,info.key_source,info.key,key_len,TCRYPT_NORMAL ) ; if( info.hidden_volume_size > 0 && r == 0 ){ r = _create_file_system( device,file_system_h,info.key_source_h,info.key_h,key_len_h,TCRYPT_HIDDEN ) ; } } /* * zuluCryptDeleteFile() is defined in file_path_security.c */ if( st != StringVoid ){ zuluCryptDeleteFile( StringContent( st ) ) ; StringDelete( &st ) ; } if( xt != StringVoid ){ zuluCryptDeleteFile( StringContent( xt ) ) ; StringDelete( &xt ) ; } return r ; }
string_t zuluCryptCreateKeyFile_1( string_t st,const char * fileName ) { return zuluCryptCreateKeyFile( StringContent( st ),StringLength( st ),fileName ) ; }
/* * This functionality is enabled with cryptsetup >= 1.4.0 */ static int _open_luks_1( const char * device,const resolve_path_t * opt ) { u_int32_t key_len ; u_int32_t flags ; u_int32_t luks_header_file_size ; u_int32_t buffer_size ; string_t st ; struct crypt_device * cd = NULL ; /* * open_struct_t is defined in includes.h */ const open_struct_t * opts = opt->args ; int r ; const size_t e = sizeof( u_int32_t ) ; const char * key ; const char * luks_header_file ; const char * luks_header_file_contents ; buffer_size = opts->key_len ; if( buffer_size < 1048576 + 8 || buffer_size > 8192000 ){ /* * the structure is expected to be atleast 1MB + 8 bytes */ /* * cryptsetup has an 8MB limit somewhere i cant remember */ return 1 ; } /* * opts->key variable is expected to hold a structure made up of 4 components. * first component at offset 0 is a u_int32_t structure holding the size of the passphrase * Second component at offset 4 is a u_int32_t structure holding the size of the contents of luks header * third component at offset 8 is the passphrase to unlock the LUKS volume. * last component is at offset that marks the end of the third component.Where this offset will be depends on the length of the passphrase */ memcpy( &key_len,opts->key,e ) ; key = opts->key + e + e ; memcpy( &luks_header_file_size,opts->key + e,e ) ; luks_header_file_contents = opts->key + e + e + key_len ; if( key_len + luks_header_file_size + e + e != buffer_size ){ /* * malformed structure detected */ return 1 ; } if( luks_header_file_size < 1048576 || luks_header_file_size > 3145728 ){ /* * luks header backup or detached header is expected to be greater than 1MB but less than 2MB,we check * against 3MB to be generous. */ return 1 ; } /* * zuluCryptCreateKeyFile() is defined in open_tcrypt.c */ st = zuluCryptCreateKeyFile( luks_header_file_contents,luks_header_file_size,"luks_header_file-" ) ; luks_header_file = StringContent( st ) ; if( crypt_init( &cd,luks_header_file ) != 0 ){ return zuluExit_1( 1,cd,st ) ; } if( crypt_load( cd,NULL,NULL ) != 0 ){ return zuluExit_1( 1,cd,st ) ; } if( crypt_set_data_device( cd,device ) != 0 ){ return zuluExit_1( 1,cd,st ) ; } if( opt->open_mode == O_RDONLY ){ flags = CRYPT_ACTIVATE_READONLY ; }else{ flags = CRYPT_ACTIVATE_ALLOW_DISCARDS ; } r = crypt_activate_by_passphrase( cd,opts->mapper_name,CRYPT_ANY_SLOT,key,key_len,flags ) ; if( r == 0 ){ return zuluExit_1( 0,cd,st ) ; }else{ return zuluExit_1( 1,cd,st ) ; } }