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; }
int main(int argc, char *argv[]) { uint8_t data[sizeof(UUID)] = {}; struct crypt_device *cd = NULL; luksmeta_uuid_t uuid = {}; uint32_t offset = 0; uint32_t length = 0; int r; crypt_free(test_format()); cd = test_init(); test_hole(cd, &offset, &length); r = luksmeta_save(cd, CRYPT_ANY_SLOT, UUID, UUID, sizeof(UUID)); if (r < 0) error(EXIT_FAILURE, -r, "%s:%d", __FILE__, __LINE__); /* Test the layout state. */ assert(test_layout((range_t[]) { { 0, 1024 }, /* LUKS header */ { 1024, 3072, true }, /* Keyslot Area */ { offset, 4096 }, /* luksmeta header */ { offset + 4096, 4096 }, /* luksmeta slot 0 */ END(offset + 8192), /* Rest of the file */ })); assert(luksmeta_load(cd, r, uuid, data, sizeof(data)) == sizeof(data)); assert(memcmp(uuid, UUID, sizeof(UUID)) == 0); assert(memcmp(data, UUID, sizeof(UUID)) == 0); assert(luksmeta_save(cd, r, UUID, UUID, sizeof(UUID)) == -EALREADY); assert(luksmeta_wipe(cd, r, (luksmeta_uuid_t) {}) == -EKEYREJECTED); assert(luksmeta_wipe(cd, r, (luksmeta_uuid_t) { 1 }) == -EKEYREJECTED); assert(luksmeta_wipe(cd, r, UUID) == 0); assert(luksmeta_wipe(cd, r, UUID) == -EALREADY); assert(luksmeta_wipe(cd, r, (luksmeta_uuid_t) {}) == -EALREADY); /* Test the layout state. */ assert(test_layout((range_t[]) { { 0, 1024 }, /* LUKS header */ { 1024, 3072, true }, /* Keyslot Area */ { offset, 4096 }, /* luksmeta header */ END(offset + 4096), /* Rest of the file */ })); crypt_free(cd); unlink(filename); return 0; }
static char * _volume_device_name( const char * mapper,char * ( *function )( const char * ) ) { struct crypt_device * cd ; const char * e = crypt_get_dir() ; char * f = NULL ; if( zuluCryptTrueCryptOrVeraCryptVolume( mapper ) ){ return _device_name( mapper,function ) ; }else{ if( crypt_init_by_name( &cd,mapper ) == 0 ){ e = crypt_get_device_name( cd ) ; if( e != NULL ){ f = function( e ) ; } crypt_free( cd ) ; } return f ; } }
static inline char * zuluExit( char * c,struct crypt_device * cd ) { if( cd != NULL ){ crypt_free( cd ); } return c ; }
void xs_ed_init(xsMachine *the) { ed_t *ed; mod_t *mod; /* mod_t* */ void *d; /* kcl_int_t* */ kcl_err_t err; if ((ed = crypt_malloc(sizeof(ed_t))) == NULL) kcl_throw_error(the, KCL_ERR_NOMEM); if ((err = kcl_ed_alloc(&ed->ctx)) != KCL_ERR_NONE) { crypt_free(ed); kcl_throw_error(the, err); } xsResult = xsGet(xsThis, xsID("mod")); mod = xsGetHostData(xsResult); xsResult = xsGet(xsThis, xsID("d")); d = xsGetHostData(xsResult); kcl_ed_init(ed->ctx, mod->ctx, d); ed->id_x = xsID("x"); ed->id_y = xsID("y"); ed->proto_int = xsGet(xsThis, xsID("_proto_int")); ed->proto_ecp = xsGet(xsThis, xsID("_proto_ecp")); xsSetHostData(xsThis, ed); }
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 ; }
void xs_ed_destructor(void *data) { if (data != NULL) { ed_t *ed = data; kcl_ed_dispose(ed->ctx); crypt_free(ed); } }
void xs_cipher_destructor(void *data) { if (data != NULL) { crypt_cipher_t *cipher = data; if (cipher->ctx != NULL) (*cipher->finish)(cipher->ctx); crypt_free(cipher); } }
void xs_stream_destructor(void *data) { if (data != NULL) { crypt_stream_t *stream = data; if (stream->ctx != NULL) (*stream->finish)(stream->ctx); crypt_free(stream); } }
void xs_z_destructor(void *data) { if (data) { z_t *z = data; if (z->ctx != NULL) kcl_z_dispose(z->ctx); crypt_free(z); } }
void xs_digest_destructor(void *data) { if (data != NULL) { crypt_digest_t *digest = data; if (digest->ctx != NULL) (*digest->finish)(digest->ctx); crypt_free(digest); } }
static int zuluExit_1( int r,struct crypt_device * cd,string_t st ) { crypt_free( cd ) ; /* * zuluCryptDeleteFile_1() is defined in open_path_security.c */ zuluCryptDeleteFile_1( st ) ; StringDelete( &st ) ; return r ; }
int initCryptDevice(struct crypt_device** cd, const char* filename) { int r; if ((r = crypt_init(cd, filename))) goto out; return r; out: crypt_free(*cd); return r; }
void xs_z_init(xsMachine *the) { z_t *z; kcl_err_t err; static kcl_error_callback_t cb; if ((z = crypt_malloc(sizeof(z_t))) == NULL) kcl_throw_error(the, KCL_ERR_NOMEM); if ((err = kcl_z_alloc(&z->ctx)) != KCL_ERR_NONE) { crypt_free(z); kcl_throw_error(the, err); } z->proto_int = xsGet(xsThis, xsID("_proto_int")); cb.f = kcl_z_error_callback; cb.closure = the; if ((err = kcl_z_init(z->ctx, &cb)) != KCL_ERR_NONE) { kcl_z_dispose(z->ctx); crypt_free(z); kcl_throw_error(the, err); } xsSetHostData(xsThis, z); }
static int handle_active_device(const char *device_name) { struct crypt_device *cd; int r; /* * crypt_init_by_name() initializes device context and loads LUKS header from backing device */ r = crypt_init_by_name(&cd, device_name); if (r < 0) { printf("crypt_init_by_name() failed for %s.\n", device_name); return r; } if (crypt_status(cd, device_name) == CRYPT_ACTIVE) printf("Device %s is still active.\n", device_name); else { printf("Something failed perhaps, device %s is not active.\n", device_name); crypt_free(cd); return -1; } /* * crypt_deactivate() is used to deactivate device */ r = crypt_deactivate(cd, device_name); if (r < 0) { printf("crypt_deactivate() failed.\n"); crypt_free(cd); return r; } printf("Device %s is now deactivated.\n", device_name); crypt_free(cd); return 0; }
static void remove_headers(struct reenc_ctx *rc) { struct crypt_device *cd = NULL; log_dbg("Removing headers."); if (crypt_init(&cd, NULL)) return; crypt_set_log_callback(cd, _quiet_log, NULL); if (*rc->header_file_org) (void)crypt_deactivate(cd, rc->header_file_org); if (*rc->header_file_new) (void)crypt_deactivate(cd, rc->header_file_new); crypt_free(cd); }
int crypt_lock(const char* name) { int ret = -1; struct crypt_device *cd = NULL; if ((ret = crypt_init_by_name(&cd, name)) < 0) fprintf(stderr, "pam_usermount: crypt_init_by_name() failed for '%s': %d\n", name, ret); else { if (crypt_status(cd, name) != CRYPT_ACTIVE) fprintf(stderr, "pam_usermount: Device %s isn't active\n", name); else ret = crypt_deactivate(cd, name); crypt_free(cd); } return ret; }
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 _save_luks_header( const struct_opts * opts,const char * temp_path,const char * path,uid_t uid ) { struct crypt_device * cd ; int st ; if( crypt_init( &cd,opts->device ) != 0 ){ st = 3 ; }else{ st = crypt_header_backup( cd,NULL,temp_path ) ; crypt_free( cd ) ; if( st == 0 ){ st = _secure_copy_file( temp_path,path,uid ) ; }else{ st = 4 ; } } return st ; }
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 ; }
char * zuluCryptGetUUIDFromMapper( const char * mapper ) { string_t uuid ; struct crypt_device * cd ; const char * id ; const char * e = " UUID: \t\"Nil\"" ; char * f ; if( crypt_init_by_name( &cd,mapper ) < 0 ){ uuid = String( e ) ; }else{ id = crypt_get_uuid( cd ) ; if( id == NULL ){ /* * Either not a LUKS volume or a LUKS volume but with a detached header. * consult udev to see if it can sort this volume out. */ f = _get_uuid_from_udev( mapper ) ; if( f == NULL ){ uuid = String( e ) ; }else{ uuid = String_1( " UUID: \t\"",f,"\"",NULL ) ; StringFree( f ) ; } }else{ uuid = String_1( " UUID: \t\"",id,"\"",NULL ) ; } crypt_free( cd ) ; } return StringDeleteHandle( &uuid ) ; }
static int restore_luks_header(struct reenc_ctx *rc) { struct crypt_device *cd = NULL; int r; log_dbg("Restoring header for %s from %s.", rc->device, rc->header_file_new); r = crypt_init(&cd, rc->device); if (r == 0) { crypt_set_confirm_callback(cd, NULL, NULL); r = crypt_header_restore(cd, CRYPT_LUKS1, rc->header_file_new); } crypt_free(cd); if (r) log_err(_("Cannot restore LUKS header on device %s.\n"), rc->device); else log_verbose(_("LUKS header on device %s restored.\n"), rc->device); return r; }
int main() { void *aesctx; char *s = "hello,world!"; char *r,*t; int len; aesctx = crypt_init(CRYPT_PWD_FILE,CRYPT_PWD_LEN16); if(!aesctx) { printf("call crypt_init() error.\n"); return 1; } r = crypt_encode(aesctx,s,strlen(s),&len); t = crypt_decode(aesctx,r,len,&len); printf("%s\n",t); xfree(r); xfree(t); crypt_free(aesctx); return 0; }
char * zuluCryptGetVolumeTypeFromMapperPath( const char * mapper ) { struct crypt_device * cd ; const char * type ; char * r ; string_t st ; if( StringPrefixNotEqual( mapper,crypt_get_dir() ) ){ return StringCopy_2( "Nil" ) ; } if( crypt_init_by_name( &cd,mapper ) < 0 ){ return StringCopy_2( "Nil" ) ; } type = crypt_get_type( cd ) ; if( type == NULL ){ if( StringHasComponent( mapper,"veracrypt" ) ){ r = StringCopy_2( "crypto_VCRYPT" ) ; }else if( StringHasComponent( mapper,"truecrypt" ) ){ r = StringCopy_2( "crypto_TCRYPT" ) ; }else{ r = _get_type_from_udev( mapper ) ; } }else{ st = String_1( "crypto_",type,NULL ) ; r = StringDeleteHandle( &st ) ; } crypt_free( cd ) ; return r ; }
static int create_new_header(struct reenc_ctx *rc, const char *cipher, const char *cipher_mode, const char *uuid, const char *key, int key_size, struct crypt_params_luks1 *params) { struct crypt_device *cd_new = NULL; int i, r; if ((r = crypt_init(&cd_new, rc->header_file_new))) goto out; if (opt_random) crypt_set_rng_type(cd_new, CRYPT_RNG_RANDOM); else if (opt_urandom) crypt_set_rng_type(cd_new, CRYPT_RNG_URANDOM); if (opt_iteration_time) crypt_set_iteration_time(cd_new, opt_iteration_time); if ((r = crypt_format(cd_new, CRYPT_LUKS1, cipher, cipher_mode, uuid, key, key_size, params))) goto out; log_verbose(_("New LUKS header for device %s created.\n"), rc->device); for (i = 0; i < MAX_SLOT; i++) { if (!rc->p[i].password) continue; if ((r = crypt_keyslot_add_by_volume_key(cd_new, i, NULL, 0, rc->p[i].password, rc->p[i].passwordLen)) < 0) goto out; log_verbose(_("Activated keyslot %i.\n"), r); r = 0; } out: crypt_free(cd_new); return r; }
void xs_z_toString(xsMachine *the) { z_t *z = xsGetHostData(xsThis); kcl_int_t *ai = arith_get_integer(z, xsArg(0)); unsigned int radix = xsToInteger(xsArg(1)); size_t usize, n; char *str; kcl_err_t err; #define NBITS(n) (n < 4 ? 1: n < 8 ? 2: n < 16 ? 3: n < 32 ? 4: 5) usize = kcl_int_sizeof(ai); n = (usize * 8) / NBITS(radix); /* quite inaccurate, but better than shortage */ n += 2; /* for "+-" sign + '\0' */ if ((str = crypt_malloc(n)) == NULL) kcl_throw_error(the, KCL_ERR_NOMEM); if ((err = kcl_z_i2str(z->ctx, ai, str, n, radix)) != KCL_ERR_NONE) goto bail; xsResult = xsString(str); bail: crypt_free(str); if (err != KCL_ERR_NONE) kcl_throw_error(the, err); }
static int zuluExit( int st,struct crypt_device * cd ) { crypt_free( cd ) ; return st ; }
static int format_and_add_keyslots(const char *path) { struct crypt_device *cd; struct crypt_params_luks1 params; int r; /* * crypt_init() call precedes most of operations of cryptsetup API. The call is used * to initialize crypt device context stored in structure referenced by _cd_ in * the example. Second parameter is used to pass underlaying device path. * * Note: * If path refers to a regular file it'll be attached to a first free loop device. * crypt_init() operation fails in case there's no more loop device available. * Also, loop device will have the AUTOCLEAR flag set, so the file loopback will * be detached automatically. */ r = crypt_init(&cd, path); if (r < 0 ) { printf("crypt_init() failed for %s.\n", path); return r; } printf("Context is attached to block device %s.\n", crypt_get_device_name(cd)); /* * So far no data were written on your device. This will change with call of * crypt_format() only if you specify CRYPT_LUKS1 as device type. */ printf("Device %s will be formatted to LUKS device after 5 seconds.\n" "Press CTRL+C now if you want to cancel this operation.\n", path); sleep(5); /* * Prepare LUKS format parameters * * hash parameter defines PBKDF2 hash algorithm used in LUKS header. * For compatibility reason we use SHA1 here. */ params.hash = "sha1"; /* * data_alignment parameter is relevant only in case of the luks header * and the payload are both stored on same device. * * if you set data_alignment = 0, cryptsetup will autodetect * data_alignment according to underlaying device topology. */ params.data_alignment = 0; /* * data_device parameter defines that no external device * for luks header will be used */ params.data_device = NULL; /* * NULLs for uuid and volume_key means that these attributes will be * generated during crypt_format(). Volume key is generated with respect * to key size parameter passed to function. * * crypt_format() checks device size (LUKS header must fit there). */ r = crypt_format(cd, /* crypt context */ CRYPT_LUKS1, /* LUKS1 is standard LUKS header */ "aes", /* used cipher */ "xts-plain64", /* used block mode and IV generator*/ NULL, /* generate UUID */ NULL, /* generate volume key from RNG */ 256 / 8, /* 256bit key - here AES-128 in XTS mode, size is in bytes */ ¶ms); /* parameters above */ if(r < 0) { printf("crypt_format() failed on device %s\n", crypt_get_device_name(cd)); crypt_free(cd); return r; } /* * The device now contains LUKS1 header, but there is * no active keyslot with encrypted volume key yet. */ /* * cryptt_kesylot_add_* call stores volume_key in encrypted form into keyslot. * Without keyslot you can't manipulate with LUKS device after the context will be freed. * * To create a new keyslot you need to supply the existing one (to get the volume key from) or * you need to supply the volume key. * * After format, we have volume key stored internally in context so add new keyslot * using this internal volume key. */ r = crypt_keyslot_add_by_volume_key(cd, /* crypt context */ CRYPT_ANY_SLOT, /* just use first free slot */ NULL, /* use internal volume key */ 0, /* unused (size of volume key) */ "foo", /* passphrase - NULL means query*/ 3); /* size of passphrase */ if (r < 0) { printf("Adding keyslot failed.\n"); crypt_free(cd); return r; } printf("The first keyslot is initialized.\n"); /* * Add another keyslot, now using the first keyslot. * It will decrypt volume key from the first keyslot and creates new one with another passphrase. */ r = crypt_keyslot_add_by_passphrase(cd, /* crypt context */ CRYPT_ANY_SLOT, /* just use first free slot */ "foo", 3, /* passphrase for the old keyslot */ "bar", 3); /* passphrase for the new kesylot */ if (r < 0) { printf("Adding keyslot failed.\n"); crypt_free(cd); return r; } printf("The second keyslot is initialized.\n"); crypt_free(cd); return 0; }
static string_t _get_crypto_info_from_cryptsetup( const char * mapper ) { char buff[ SIZE ] ; char * buffer = buff ; const char * z ; const char * type ; uint64_t e ; string_t q ; string_t p ; int k ; int i = 0 ; int j ; crypt_status_info info ; struct crypt_device * cd ; struct crypt_active_device cad ; if( crypt_init_by_name( &cd,mapper ) != 0 ){ return StringVoid ; } p = String( mapper ) ; info = crypt_status( cd,mapper ) ; switch( info ){ case CRYPT_INACTIVE : StringAppend( p," is inactive.\n" ) ; break ; case CRYPT_INVALID : StringAppend( p," is invalid.\n" ) ; break ; case CRYPT_ACTIVE : StringAppend( p," is active.\n" ) ; break ; case CRYPT_BUSY : StringAppend( p," is active and is in use.\n" ) ; break ; default : StringAppend( p," is invalid.\n" ) ; } if( info == CRYPT_ACTIVE || info == CRYPT_BUSY ){ StringAppend( p," type: \t" ) ; type = crypt_get_type( cd ) ; if( type != NULL ){ q = String( type ) ; StringAppend( p,StringToLowerCase( q ) ) ; StringDelete( &q ) ; }else{ q = _get_type_from_udev_1( mapper ) ; StringAppendString( p,q ) ; StringDelete( &q ) ; } z = crypt_get_cipher( cd ) ; if( z != NULL ){ StringMultipleAppend( p,"\n cipher:\t",z,"-",NULL ) ; }else{ StringAppend( p,"\n cipher:\tNil-" ) ; } z = crypt_get_cipher_mode( cd ) ; if( z != NULL ){ StringAppend( p,z ) ; }else{ StringAppend( p,"Nil" ) ; } z = StringIntToString_1( buffer,SIZE,8 * crypt_get_volume_key_size( cd ) ) ; StringMultipleAppend( p,"\n keysize:\t",z," bits",NULL ) ; e = crypt_get_data_offset( cd ) ; z = StringIntToString_1( buffer,SIZE,e ) ; StringMultipleAppend( p,"\n offset:\t",z," sectors",NULL ) ; zuluCryptFormatSize( e * 512,buffer,SIZE ) ; StringMultipleAppend( p," / ",buffer,NULL ) ; _device_info( p,crypt_get_device_name( cd ) ) ; crypt_get_active_device( NULL,mapper,&cad ) ; if( cad.flags == 1 ){ StringAppend( p,"\n mode: \tread only" ) ; }else{ StringAppend( p,"\n mode: \tread and write" ) ; } k = crypt_keyslot_max( crypt_get_type( cd ) ) ; if( k > 0 ){ i = 0 ; for( j = 0 ; j < k ; j++ ){ switch( crypt_keyslot_status( cd,j ) ){ case CRYPT_SLOT_ACTIVE_LAST : i++ ; break ; case CRYPT_SLOT_ACTIVE : i++ ; break ; default : ; } } StringMultipleAppend( p,"\n active slots:\t",StringIntToString_1( buffer,SIZE,i ),NULL ) ; StringMultipleAppend( p," / ",StringIntToString_1( buffer,SIZE,k ),NULL ) ; }else{ StringAppend( p,"\n active slots:\tNil" ) ; } } crypt_free( cd ) ; return p ; }
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; }