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; }
static int _remove_key( const char * device ,const char * pass,size_t pass_size ) { int slot ; struct crypt_device * cd ; if( zuluCryptVolumeIsNotLuks( device ) ){ return 1 ; } if( crypt_init( &cd,device ) != 0 ){ return 3 ; } if( crypt_load( cd,NULL,NULL ) != 0 ){ return zuluExit( 3,cd ) ; } slot = crypt_activate_by_passphrase( cd,NULL,CRYPT_ANY_SLOT,pass,pass_size,0 ); if ( slot < 0 ){ return zuluExit( 2,cd ) ; } if( crypt_keyslot_destroy( cd,slot ) < 0 ){ return zuluExit( 2,cd ) ; }else{ return zuluExit( 0,cd ) ; } }
static int _remove_key( const char * device,const resolve_path_t * opts ) { int slot ; struct crypt_device * cd ; const arguments * args = opts->args ; if( zuluCryptVolumeIsNotLuks( device ) ){ return 1 ; } if( crypt_init( &cd,device ) != 0 ){ return 3 ; } if( crypt_load( cd,NULL,NULL ) != 0 ){ return zuluExit( 3,cd ) ; } slot = crypt_activate_by_passphrase( cd,NULL,CRYPT_ANY_SLOT,args->key,args->key_len,0 ) ; if( slot < 0 ){ return zuluExit( 2,cd ) ; } if( crypt_keyslot_destroy( cd,slot ) < 0 ){ return zuluExit( 2,cd ) ; }else{ return zuluExit( 0,cd ) ; } }
static int _restore_luks_header( const struct_opts * opts,const char * temp_path ) { int st ; struct crypt_device * cd ; if( crypt_init( &cd,opts->device ) != 0 ){ st = 7 ; }else{ if( crypt_load( cd,NULL,NULL ) != 0 ){ st = 2 ; }else{ if( crypt_header_restore( cd,NULL,temp_path ) == 0 ){ st = 1 ; }else{ st = 7 ; } } crypt_free( cd ) ; } return st ; }
int main(int argc, char **argv) { int32_t ch, index, excl_index; const char *name; bool load_default, exclusive; load_default = true; exclusive = false; index = 0; while (1) { if ((ch = getopt_long_only(argc, argv, "", opt_field, &index)) < 0) break; switch (ch) { case OPT_LOG: log_load(optarg); break; case OPT_CONFIG: config_load(optarg); load_default = false; break; case OPT_EXCL: if (exclusive) error("Cannot use --%s with --%s", opt_field[index].name, opt_field[excl_index].name); exclusive = true; excl_index = index; case OPT_NRML: name = opt_field[index].name; if (opt_field[index].has_arg) config_set(name, optarg); else config_set(name, "true"); break; case OPT_VERSION: version(); return 1; case OPT_HELP: default: usage(); return 1; } } if (load_default) config_default(); mt_init(); store_load(); bucket_load(); crypt_load(); volume_load(); return 0; }
int crypt_unlock(const char* path, const char* authtok, const char* name, int flags) { int ret = -1; struct crypt_device *cd = NULL; if ((ret = crypt_init(&cd, path)) < 0) fprintf(stderr, "pam_usermount: crypt_init() failed for '%s': %d\n", path, ret); else { if (crypt_status(cd, name) == CRYPT_ACTIVE) fprintf(stderr, "pam_usermount: Device %s is already active\n", name); else if ((ret = crypt_load(cd, CRYPT_LUKS1, NULL)) >= 0) ret = crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, authtok, strlen(authtok), flags); crypt_free(cd); } return ret; }
static int _is_luks( const char * dev,const resolve_path_t * opts ) { struct crypt_device * cd ; int st ; if( opts ){;} if( crypt_init( &cd,dev ) != 0 ){ return 0 ; } st = crypt_load( cd,NULL,NULL ) ; crypt_free( cd ) ; return st == 0 ; }
static char * _empty_slots( const char * device,const resolve_path_t * opts ) { struct crypt_device * cd; int j ; int k ; const char * type ; string_t p ; if( opts ){;} if( crypt_init( &cd,device ) != 0 ){ return zuluExit( NULL,NULL ) ; } if( crypt_load( cd,NULL,NULL ) != 0 ){ return zuluExit( NULL,cd ) ; } type = crypt_get_type( cd ) ; if( type == NULL ){ return zuluExit( NULL,cd ) ; } k = crypt_keyslot_max( type ) ; if( k < 0 ){ return zuluExit( NULL,cd ) ; } p = StringEmpty() ; for( j = 0 ; j < k ; j++ ){ switch( crypt_keyslot_status( cd,j ) ){ case CRYPT_SLOT_INACTIVE : StringAppend( p,"0" ) ; break ; case CRYPT_SLOT_ACTIVE : StringAppend( p,"1" ) ; break ; case CRYPT_SLOT_INVALID : StringAppend( p,"2" ) ; break ; case CRYPT_SLOT_ACTIVE_LAST: StringAppend( p,"3" ) ; break ; default : ; } } return zuluExit( StringDeleteHandle( &p ),cd ) ; }
static int _add_key( const char * device,const char * existingkey,size_t existingkey_size,const char * newkey,size_t newkey_size ) { struct crypt_device * cd ; if( zuluCryptVolumeIsNotLuks( device ) ){ return 3 ; } if( crypt_init( &cd,device ) != 0 ){ return 2 ; } if( crypt_load( cd,NULL,NULL ) != 0 ){ return zuluExit( 2,cd ) ; } if( crypt_keyslot_add_by_passphrase( cd,CRYPT_ANY_SLOT,existingkey,existingkey_size,newkey,newkey_size ) < 0 ){ return zuluExit( 1,cd ) ; }else{ return zuluExit( 0,cd ) ; } }
/* * 1 is returned if a volume is a truecrypt volume. * 0 is returned if a volume is not a truecrypt volume or functionality is not supported */ int zuluCryptVolumeIsTcrypt( const char * device,const char * key,int key_source ) { struct crypt_device * cd = NULL; struct crypt_params_tcrypt params ; memset( ¶ms,'\0',sizeof( struct crypt_params_tcrypt ) ) ; if( key_source ){;} if( crypt_init( &cd,device ) < 0 ){ return 0 ; }else{ params.passphrase = key ; params.passphrase_size = StringSize( key ) ; params.flags = CRYPT_TCRYPT_LEGACY_MODES ; if( crypt_load( cd,CRYPT_TCRYPT,¶ms ) == 0 ){ return zuluExit( 1,cd ) ; }else{ return zuluExit( 0,cd ) ; } } }
static int _open_luks_2( const char * device,const resolve_path_t * opt ) { struct crypt_device * cd ; uint32_t flags ; int st ; /* * open_struct_t is defined in includes.h */ const open_struct_t * opts = opt->args ; if( zuluCryptPathIsNotValid( device ) ){ return 3 ; } if( crypt_init( &cd,device ) != 0 ){ return 2 ; } if( crypt_load( cd,NULL,NULL ) != 0 ){ return zuluExit( 2,cd ) ; } if( opt->open_mode == O_RDONLY ){ flags = CRYPT_ACTIVATE_READONLY ; }else{ flags = CRYPT_ACTIVATE_ALLOW_DISCARDS ; } st = crypt_activate_by_passphrase( cd,opts->mapper_name,CRYPT_ANY_SLOT, opts->key,opts->key_len,flags ) ; if( st >= 0 ){ return zuluExit( 0,cd ) ; }else if( st == -1 ){ return zuluExit( 1,cd ) ; }else{ return zuluExit( 2,cd ) ; } }
int main(int argc, char *argv[]) { struct crypt_device *cd = NULL; struct options opts = {}; const char *type = NULL; int nerr = 0; if (argp_parse(&argp, argc, argv, 0, NULL, &opts) != 0) return EX_OSERR; if (strlen(opts.params.hostname) == 0) { for (int slot = 0; slot < LUKS_NUMKEYS; slot++) { TANG_LUKS *tl = NULL; sbuf_t *buf = NULL; buf = meta_read(opts.device, slot); if (!buf) continue; tl = TANG_LUKS_from_sbuf(buf); sbuf_free(buf); if (!tl) continue; fwrite(tl->hostname->data, tl->hostname->length, 1, stderr); fwrite(":", 1, 1, stderr); fwrite(tl->service->data, tl->service->length, 1, stderr); fwrite("\n", 1, 1, stderr); TANG_LUKS_free(tl); } return 0; } nerr = crypt_init(&cd, opts.device); if (nerr != 0) { fprintf(stderr, "Unable to open device (%s): %s\n", opts.device, strerror(-nerr)); goto error; } nerr = crypt_load(cd, NULL, NULL); if (nerr != 0) { fprintf(stderr, "Unable to load device (%s): %s\n", opts.device, strerror(-nerr)); goto error; } type = crypt_get_type(cd); if (type == NULL) { fprintf(stderr, "Unable to determine device type\n"); goto error; } if (strcmp(type, CRYPT_LUKS1) != 0) { fprintf(stderr, "%s (%s) is not a LUKS device\n", opts.device, type); goto error; } for (int slot = 0; slot < crypt_keyslot_max(CRYPT_LUKS1); slot++) { TANG_LUKS *tl = NULL; sbuf_t *buf = NULL; switch (crypt_keyslot_status(cd, slot)) { case CRYPT_SLOT_ACTIVE: case CRYPT_SLOT_ACTIVE_LAST: buf = meta_read(opts.device, slot); if (!buf) continue; tl = TANG_LUKS_from_sbuf(buf); sbuf_free(buf); if (!tl) continue; if (strncmp((char *) tl->hostname->data, opts.params.hostname, tl->hostname->length) != 0) { TANG_LUKS_free(tl); continue; } if (strncmp((char *) tl->service->data, opts.params.service, tl->service->length) != 0) { TANG_LUKS_free(tl); continue; } TANG_LUKS_free(tl); if (crypt_keyslot_destroy(cd, slot) == 0) meta_erase(opts.device, slot); break; default: break; } } crypt_free(cd); return 0; error: crypt_free(cd); return EX_IOERR; }
static int activate_and_check_status(const char *path, const char *device_name) { struct crypt_device *cd; struct crypt_active_device cad; int r; /* * LUKS device activation example. * It's sequence of sub-steps: device initialization, LUKS header load * and the device activation itself. */ r = crypt_init(&cd, path); if (r < 0 ) { printf("crypt_init() failed for %s.\n", path); return r; } /* * crypt_load() is used to load the LUKS header from block device * into crypt_device context. */ r = crypt_load(cd, /* crypt context */ CRYPT_LUKS1, /* requested type */ NULL); /* additional parameters (not used) */ if (r < 0) { printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd)); crypt_free(cd); return r; } /* * Device activation creates device-mapper devie mapping with name device_name. */ r = crypt_activate_by_passphrase(cd, /* crypt context */ device_name, /* device name to activate */ CRYPT_ANY_SLOT,/* which slot use (ANY - try all) */ "foo", 3, /* passphrase */ CRYPT_ACTIVATE_READONLY); /* flags */ if (r < 0) { printf("Device %s activation failed.\n", device_name); crypt_free(cd); return r; } printf("LUKS device %s/%s is active.\n", crypt_get_dir(), device_name); printf("\tcipher used: %s\n", crypt_get_cipher(cd)); printf("\tcipher mode: %s\n", crypt_get_cipher_mode(cd)); printf("\tdevice UUID: %s\n", crypt_get_uuid(cd)); /* * Get info about active device (query DM backend) */ r = crypt_get_active_device(cd, device_name, &cad); if (r < 0) { printf("Get info about active device %s failed.\n", device_name); crypt_deactivate(cd, device_name); crypt_free(cd); return r; } printf("Active device parameters for %s:\n" "\tDevice offset (in sectors): %" PRIu64 "\n" "\tIV offset (in sectors) : %" PRIu64 "\n" "\tdevice size (in sectors) : %" PRIu64 "\n" "\tread-only flag : %s\n", device_name, cad.offset, cad.iv_offset, cad.size, cad.flags & CRYPT_ACTIVATE_READONLY ? "1" : "0"); crypt_free(cd); return 0; }
static int action_format(int arg) { struct crypt_device *cd = NULL; struct crypt_params_integrity params = { .journal_size = opt_journal_size, .interleave_sectors = opt_interleave_sectors, /* in bitmap mode we have to overload these values... */ .journal_watermark = opt_integrity_bitmap ? opt_bitmap_sectors_per_bit : opt_journal_watermark, .journal_commit_time = opt_integrity_bitmap ? opt_bitmap_flush_time : opt_journal_commit_time, .buffer_sectors = opt_buffer_sectors, .tag_size = opt_tag_size, .sector_size = opt_sector_size ?: SECTOR_SIZE, }; char integrity[MAX_CIPHER_LEN], journal_integrity[MAX_CIPHER_LEN], journal_crypt[MAX_CIPHER_LEN]; char *integrity_key = NULL, *msg = NULL; int r; size_t signatures; if (opt_integrity) { r = crypt_parse_hash_integrity_mode(opt_integrity, integrity); if (r < 0) { log_err(_("No known integrity specification pattern detected.")); return r; } params.integrity = integrity; } if (opt_journal_integrity) { r = crypt_parse_hash_integrity_mode(opt_journal_integrity, journal_integrity); if (r < 0) { log_err(_("No known integrity specification pattern detected.")); return r; } params.journal_integrity = journal_integrity; } if (opt_journal_crypt) { r = crypt_parse_hash_integrity_mode(opt_journal_crypt, journal_crypt); if (r < 0) { log_err(_("No known integrity specification pattern detected.")); return r; } params.journal_crypt = journal_crypt; } r = _read_keys(&integrity_key, ¶ms); if (r) goto out; r = crypt_init_data_device(&cd, action_argv[0], opt_data_device); if (r < 0) goto out; r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]); if (r == -1) { r = -ENOMEM; goto out; } r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL; free(msg); if (r < 0) goto out; r = tools_detect_signatures(action_argv[0], 0, &signatures); if (r < 0) goto out; /* Signature candidates found */ if (signatures && ((r = tools_wipe_all_signatures(action_argv[0])) < 0)) goto out; r = crypt_format(cd, CRYPT_INTEGRITY, NULL, NULL, NULL, NULL, 0, ¶ms); if (r < 0) /* FIXME: call wipe signatures again */ goto out; if (!opt_batch_mode) log_std(_("Formatted with tag size %u, internal integrity %s.\n"), opt_tag_size, opt_integrity); if (!opt_no_wipe) r = _wipe_data_device(cd, integrity_key); out: crypt_safe_free(integrity_key); crypt_safe_free(CONST_CAST(void*)params.journal_integrity_key); crypt_safe_free(CONST_CAST(void*)params.journal_crypt_key); crypt_free(cd); return r; } static int action_open(int arg) { struct crypt_device *cd = NULL; struct crypt_params_integrity params = { /* in bitmap mode we have to overload these values... */ .journal_watermark = opt_integrity_bitmap ? opt_bitmap_sectors_per_bit : opt_journal_watermark, .journal_commit_time = opt_integrity_bitmap ? opt_bitmap_flush_time : opt_journal_commit_time, .buffer_sectors = opt_buffer_sectors, }; uint32_t activate_flags = 0; char integrity[MAX_CIPHER_LEN], journal_integrity[MAX_CIPHER_LEN], journal_crypt[MAX_CIPHER_LEN]; char *integrity_key = NULL; int r; if (opt_integrity) { r = crypt_parse_hash_integrity_mode(opt_integrity, integrity); if (r < 0) { log_err(_("No known integrity specification pattern detected.")); return r; } params.integrity = integrity; } if (opt_journal_integrity) { r = crypt_parse_hash_integrity_mode(opt_journal_integrity, journal_integrity); if (r < 0) { log_err(_("No known integrity specification pattern detected.")); return r; } params.journal_integrity = journal_integrity; } if (opt_journal_crypt) { r = crypt_parse_hash_integrity_mode(opt_journal_crypt, journal_crypt); if (r < 0) { log_err(_("No known integrity specification pattern detected.")); return r; } params.journal_crypt = journal_crypt; } if (opt_integrity_nojournal || opt_integrity_bitmap) activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL; if (opt_integrity_recovery) activate_flags |= CRYPT_ACTIVATE_RECOVERY; if (opt_integrity_bitmap) activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP; if (opt_integrity_recalculate) activate_flags |= CRYPT_ACTIVATE_RECALCULATE; r = _read_keys(&integrity_key, ¶ms); if (r) goto out; if ((r = crypt_init_data_device(&cd, action_argv[0], opt_data_device))) goto out; r = crypt_load(cd, CRYPT_INTEGRITY, ¶ms); if (r) goto out; r = crypt_activate_by_volume_key(cd, action_argv[1], integrity_key, opt_integrity_key_size, activate_flags); out: crypt_safe_free(integrity_key); crypt_safe_free(CONST_CAST(void*)params.journal_integrity_key); crypt_safe_free(CONST_CAST(void*)params.journal_crypt_key); crypt_free(cd); return r; } static int action_close(int arg) { struct crypt_device *cd = NULL; int r; r = crypt_init_by_name(&cd, action_argv[0]); if (r == 0) r = crypt_deactivate(cd, action_argv[0]); crypt_free(cd); return r; } static int action_status(int arg) { crypt_status_info ci; struct crypt_active_device cad; struct crypt_params_integrity ip = {}; struct crypt_device *cd = NULL; char *backing_file; const char *device, *metadata_device; int path = 0, r = 0; /* perhaps a path, not a dm device name */ if (strchr(action_argv[0], '/')) path = 1; ci = crypt_status(NULL, action_argv[0]); switch (ci) { case CRYPT_INVALID: r = -EINVAL; break; case CRYPT_INACTIVE: if (path) log_std("%s is inactive.\n", action_argv[0]); else log_std("%s/%s is inactive.\n", crypt_get_dir(), action_argv[0]); r = -ENODEV; break; case CRYPT_ACTIVE: case CRYPT_BUSY: if (path) log_std("%s is active%s.\n", action_argv[0], ci == CRYPT_BUSY ? " and is in use" : ""); else log_std("%s/%s is active%s.\n", crypt_get_dir(), action_argv[0], ci == CRYPT_BUSY ? " and is in use" : ""); r = crypt_init_by_name_and_header(&cd, action_argv[0], NULL); if (r < 0) goto out; log_std(" type: %s\n", crypt_get_type(cd) ?: "n/a"); r = crypt_get_active_device(cd, action_argv[0], &cad); if (r < 0) goto out; r = crypt_get_integrity_info(cd, &ip); if (r < 0) goto out; log_std(" tag size: %u\n", ip.tag_size); log_std(" integrity: %s\n", ip.integrity ?: "(none)"); device = crypt_get_device_name(cd); metadata_device = crypt_get_metadata_device_name(cd); log_std(" device: %s%s\n", device, metadata_device ? " (detached)" : ""); if (crypt_loop_device(device)) { backing_file = crypt_loop_backing_file(device); log_std(" loop: %s\n", backing_file); free(backing_file); } if (metadata_device) { log_std(" metadata device: %s\n", metadata_device); if (crypt_loop_device(metadata_device)) { backing_file = crypt_loop_backing_file(metadata_device); log_std(" loop: %s\n", backing_file); free(backing_file); } } log_std(" sector size: %u bytes\n", crypt_get_sector_size(cd)); log_std(" interleave sectors: %u\n", ip.interleave_sectors); log_std(" size: %" PRIu64 " sectors\n", cad.size); log_std(" mode: %s%s\n", cad.flags & CRYPT_ACTIVATE_READONLY ? "readonly" : "read/write", cad.flags & CRYPT_ACTIVATE_RECOVERY ? " recovery" : ""); log_std(" failures: %" PRIu64 "\n", crypt_get_active_integrity_failures(cd, action_argv[0])); if (cad.flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) { log_std(" bitmap 512-byte sectors per bit: %u\n", ip.journal_watermark); log_std(" bitmap flush interval: %u ms\n", ip.journal_commit_time); } if (cad.flags & CRYPT_ACTIVATE_NO_JOURNAL) { log_std(" journal: not active\n"); } else { log_std(" journal size: %" PRIu64 " bytes\n", ip.journal_size); log_std(" journal watermark: %u%%\n", ip.journal_watermark); log_std(" journal commit time: %u ms\n", ip.journal_commit_time); if (ip.journal_integrity) log_std(" journal integrity MAC: %s\n", ip.journal_integrity); if (ip.journal_crypt) log_std(" journal encryption: %s\n", ip.journal_crypt); } } out: crypt_free(cd); if (r == -ENOTSUP) r = 0; return r; return -EINVAL; } static int action_dump(int arg) { struct crypt_device *cd = NULL; struct crypt_params_integrity params = {}; int r; if ((r = crypt_init(&cd, action_argv[0]))) return r; r = crypt_load(cd, CRYPT_INTEGRITY, ¶ms); if (!r) crypt_dump(cd); crypt_free(cd); return r; } static struct action_type { const char *type; int (*handler)(int); int required_action_argc; const char *arg_desc; const char *desc; } action_types[] = { { "format", action_format, 1, N_("<integrity_device>"),N_("format device") }, { "open", action_open, 2, N_("<integrity_device> <name>"),N_("open device as <name>") }, { "close", action_close, 1, N_("<name>"),N_("close device (deactivate and remove mapping)") }, { "status", action_status, 1, N_("<name>"),N_("show active device status") }, { "dump", action_dump, 1, N_("<integrity_device>"),N_("show on-disk information") }, { NULL, NULL, 0, NULL, NULL } }; static void help(poptContext popt_context, enum poptCallbackReason reason __attribute__((unused)), struct poptOption *key, const char *arg __attribute__((unused)), void *data __attribute__((unused))) { struct action_type *action; if (key->shortName == '?') { log_std("%s %s\n", PACKAGE_INTEGRITY, PACKAGE_VERSION); poptPrintHelp(popt_context, stdout, 0); log_std(_("\n" "<action> is one of:\n")); for(action = action_types; action->type; action++) log_std("\t%s %s - %s\n", action->type, _(action->arg_desc), _(action->desc)); log_std(_("\n" "<name> is the device to create under %s\n" "<integrity_device> is the device containing data with integrity tags\n"), crypt_get_dir()); log_std(_("\nDefault compiled-in dm-integrity parameters:\n" "\tTag size: %u bytes, Checksum algorithm: %s\n"), DEFAULT_TAG_SIZE, DEFAULT_ALG_NAME); exit(EXIT_SUCCESS); } else usage(popt_context, EXIT_SUCCESS, NULL, NULL); } static int run_action(struct action_type *action) { int r; log_dbg("Running command %s.", action->type); r = action->handler(0); show_status(r); return translate_errno(r); }
static int backup_luks_headers(struct reenc_ctx *rc) { struct crypt_device *cd = NULL; struct crypt_params_luks1 params = {0}; char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN]; char *old_key = NULL; size_t old_key_size; int r; log_dbg("Creating LUKS header backup for device %s.", rc->device); if ((r = crypt_init(&cd, rc->device)) || (r = crypt_load(cd, CRYPT_LUKS1, NULL))) goto out; crypt_set_confirm_callback(cd, NULL, NULL); if ((r = crypt_header_backup(cd, CRYPT_LUKS1, rc->header_file_org))) goto out; log_verbose(_("LUKS header backup of device %s created.\n"), rc->device); /* For decrypt, new header will be fake one, so we are done here. */ if (rc->reencrypt_mode == DECRYPT) goto out; if ((r = create_empty_header(rc->header_file_new, rc->header_file_org, crypt_get_data_offset(cd)))) goto out; params.hash = opt_hash ?: DEFAULT_LUKS1_HASH; params.data_alignment = crypt_get_data_offset(cd); params.data_alignment += ROUND_SECTOR(opt_reduce_size); params.data_device = rc->device; if (opt_cipher) { r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode); if (r < 0) { log_err(_("No known cipher specification pattern detected.\n")); goto out; } } if (opt_keep_key) { log_dbg("Keeping key from old header."); old_key_size = crypt_get_volume_key_size(cd); old_key = crypt_safe_alloc(old_key_size); if (!old_key) { r = -ENOMEM; goto out; } r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, old_key, &old_key_size, rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen); if (r < 0) goto out; } r = create_new_header(rc, opt_cipher ? cipher : crypt_get_cipher(cd), opt_cipher ? cipher_mode : crypt_get_cipher_mode(cd), crypt_get_uuid(cd), old_key, opt_key_size ? opt_key_size / 8 : crypt_get_volume_key_size(cd), ¶ms); out: crypt_free(cd); crypt_safe_free(old_key); if (r) log_err(_("Creation of LUKS backup headers failed.\n")); return r; }
void benchmark::benchmarkCryptsetup() { #if CRYPTSETUP auto _benchmark = []( const char * key,const char * path ){ Task::await( [ & ](){ struct crypt_device * cd = nullptr ; struct crypt_params_tcrypt params ; if( crypt_init( &cd,path ) == 0 ){ memset( ¶ms,'\0',sizeof( struct crypt_params_tcrypt ) ) ; params.passphrase = key ; params.passphrase_size = strlen( key ) ; params.flags = CRYPT_TCRYPT_VERA_MODES ; if( crypt_load( cd,CRYPT_TCRYPT,¶ms ) == 0 ){ crypt_free( cd ) ; }else{ params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER ; if( crypt_load( cd,CRYPT_TCRYPT,¶ms ) == 0 ){ crypt_free( cd ) ; } } } } ) ; } ; puts( "\nbenchmarking cryptsetup" ) ; this->startTimer( "testing sha512(normal) " ) ; _benchmark( "xxx","sha512.img" ) ; this->stopTimer() ; this->startTimer( "testing sha512(hidden) " ) ; _benchmark( "qqq","sha512.img" ) ; this->stopTimer() ; this->startTimer( "testing whirlpool(normal)" ) ; _benchmark( "xxx","whirlpool.img" ) ; this->stopTimer() ; this->startTimer( "testing whirlpool(hidden)" ) ; _benchmark( "qqq","whirlpool.img" ) ; this->stopTimer() ; this->startTimer( "testing sha256(normal) " ) ; _benchmark( "xxx","sha256.img" ) ; this->stopTimer() ; this->startTimer( "testing sha256(hidden) " ) ; _benchmark( "qqq","sha256.img" ) ; this->stopTimer() ; this->startTimer( "testing ripemd160(normal)" ) ; _benchmark( "xxx","ripemd160.img" ) ; this->stopTimer() ; this->startTimer( "testing ripemdi60(hidden)" ) ; _benchmark( "qqq","ripemd160.img" ) ; this->stopTimer() ; this->startTimer( "testing wrong password " ) ; _benchmark( "zzz","ripemd160.img" ) ; this->stopTimer() ; #endif }
/* * 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 ) ; } }
/* Main */ int main(int argc, char **argv) { /* for option processing */ int c, r; char *device; /* for use of libcryptsetup */ struct crypt_device *cd; /* Other vars */ int f_luks; /* device file for the luks device */ FILE *out; /* temporary helper vars */ int res; /* getopt values */ char *s, *end; double tvalue; int svalue; /* global initializations */ out = stdout; /* get commandline parameters */ while ((c = getopt (argc, argv, "t:s:vd")) != -1) { switch (c) { case 't': s = optarg; tvalue = strtod(s, &end); if (s == end) { fprintf(stderr, "\nError: Parsing of argument to -t failed.\n"); exit(EXIT_FAILURE); } if (tvalue < 0.0 || tvalue > 1.0) { fprintf(stderr,"\nError: Argument to -t must be in 0.0 ... 1.0\n"); exit(EXIT_FAILURE); } threshold = tvalue; break; case 's': s = optarg; svalue = strtol(s, &end, 10); if (s == end) { fprintf(stderr, "\nError: Parsing of argument to -s failed.\n"); exit(EXIT_FAILURE); } if (svalue < 1) { fprintf(stderr,"\nError: Argument to -s must be >= 1 \n"); exit(EXIT_FAILURE); } sector_size = svalue; break; case 'v': verbose = 1; break; case 'd': print_decimal = 1; break; case '?': if (optopt == 't' || optopt == 's') fprintf (stderr,"\nError: Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) { fprintf(stderr,"\nError: Unknown option `-%c'.\n", optopt); fprintf(stderr,"\n\n%s", help); } else { fprintf (stderr, "\nError: Unknown option character `\\x%x'.\n", optopt); fprintf(stderr,"\n\n%s", help); } exit(EXIT_SUCCESS); default: exit(EXIT_FAILURE); } } /* parse non-option stuff. Should be exactly one, the device. */ if (optind+1 != argc) { fprintf(stderr,"\nError: exactly one non-option argument expected!\n"); fprintf(stderr,"\n\n%s", help); exit(EXIT_FAILURE); } device = argv[optind]; /* test whether we can open and read device */ /* This is neded as we are reading the actual data * in the keyslots dirtectly from the LUKS container. */ f_luks = open(device, O_RDONLY); if (f_luks == -1) { fprintf(stderr,"\nError: Opening of device %s failed:\n", device); perror(NULL); exit(EXIT_FAILURE); } /* now get the parameters we need via libcryptsetup */ /* Basically we need all active keyslots and their placement on disk */ /* first init. This does the following: * - gets us a crypt_device struct with some values filled in * Note: This does some init stuff we do not need, but that * should not cause trouble. */ res = crypt_init(&cd, device); if (res < 0) { fprintf(stderr, "crypt_init() failed. Maybe not running as root?\n"); close(f_luks); exit(EXIT_FAILURE); } /* now load LUKS header into the crypt_device * This should also make sure a valid LUKS1 header is on disk * and hence we should be able to skip magic and version checks. */ res = crypt_load(cd, CRYPT_LUKS1, NULL); if (res < 0) { fprintf(stderr, "crypt_load() failed. LUKS header too broken/absent?\n"); crypt_free(cd); close(f_luks); exit(EXIT_FAILURE); } fprintf(out, "\nparameters (commandline and LUKS header):\n"); fprintf(out, " sector size: %d\n", sector_size); fprintf(out, " threshold: %0f\n\n", threshold); r = check_keyslots(out, cd, f_luks); crypt_free(cd); close(f_luks); return r; }