static int activate_luks_headers(struct reenc_ctx *rc) { struct crypt_device *cd = NULL, *cd_new = NULL; const char *pwd_old, *pwd_new, pwd_empty[] = ""; size_t pwd_old_len, pwd_new_len; int r; log_dbg("Activating LUKS devices from headers."); /* Never use real password for empty header processing */ if (rc->reencrypt_mode == REENCRYPT) { pwd_old = rc->p[rc->keyslot].password; pwd_old_len = rc->p[rc->keyslot].passwordLen; pwd_new = pwd_old; pwd_new_len = pwd_old_len; } else if (rc->reencrypt_mode == DECRYPT) { pwd_old = rc->p[rc->keyslot].password; pwd_old_len = rc->p[rc->keyslot].passwordLen; pwd_new = pwd_empty; pwd_new_len = 0; } else if (rc->reencrypt_mode == ENCRYPT) { pwd_old = pwd_empty; pwd_old_len = 0; pwd_new = rc->p[rc->keyslot].password; pwd_new_len = rc->p[rc->keyslot].passwordLen; } else return -EINVAL; if ((r = crypt_init(&cd, rc->header_file_org)) || (r = crypt_load(cd, CRYPT_LUKS1, NULL)) || (r = crypt_set_data_device(cd, rc->device))) goto out; log_verbose(_("Activating temporary device using old LUKS header.\n")); if ((r = crypt_activate_by_passphrase(cd, rc->header_file_org, opt_key_slot, pwd_old, pwd_old_len, CRYPT_ACTIVATE_READONLY|CRYPT_ACTIVATE_PRIVATE)) < 0) goto out; if ((r = crypt_init(&cd_new, rc->header_file_new)) || (r = crypt_load(cd_new, CRYPT_LUKS1, NULL)) || (r = crypt_set_data_device(cd_new, rc->device))) goto out; log_verbose(_("Activating temporary device using new LUKS header.\n")); if ((r = crypt_activate_by_passphrase(cd_new, rc->header_file_new, opt_key_slot, pwd_new, pwd_new_len, CRYPT_ACTIVATE_SHARED|CRYPT_ACTIVATE_PRIVATE)) < 0) goto out; r = 0; out: crypt_free(cd); crypt_free(cd_new); if (r < 0) log_err(_("Activation of temporary devices failed.\n")); return r; }
/* * 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 ) ; } }