int LUKS1_activate(struct crypt_device *cd, const char *name, struct volume_key *vk, uint32_t flags) { int r; char *dm_cipher = NULL; enum devcheck device_check; struct crypt_dm_active_device dmd = { .target = DM_CRYPT, .uuid = crypt_get_uuid(cd), .flags = flags, .size = 0, .data_device = crypt_data_device(cd), .u.crypt = { .cipher = NULL, .vk = vk, .offset = crypt_get_data_offset(cd), .iv_offset = 0, .sector_size = crypt_get_sector_size(cd), } }; if (dmd.flags & CRYPT_ACTIVATE_SHARED) device_check = DEV_SHARED; else device_check = DEV_EXCL; r = device_block_adjust(cd, dmd.data_device, device_check, dmd.u.crypt.offset, &dmd.size, &dmd.flags); if (r) return r; r = asprintf(&dm_cipher, "%s-%s", crypt_get_cipher(cd), crypt_get_cipher_mode(cd)); if (r < 0) return -ENOMEM; dmd.u.crypt.cipher = dm_cipher; r = dm_create_device(cd, name, CRYPT_LUKS1, &dmd, 0); free(dm_cipher); return r; }
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 ; }
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; }
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; }
void genFDEStatusForBlockDevice(const std::string& name, const std::string& uuid, const std::string& parent_name, std::map<std::string, Row>& encrypted_rows, QueryData& results) { Row r; r["name"] = name; r["uuid"] = uuid; struct crypt_device* cd = nullptr; auto ci = crypt_status(cd, name.c_str()); switch (ci) { case CRYPT_ACTIVE: case CRYPT_BUSY: { r["encrypted"] = "1"; auto crypt_init = crypt_init_by_name_and_header(&cd, name.c_str(), nullptr); if (crypt_init < 0) { VLOG(1) << "Unable to initialize crypt device for " << name; break; } struct crypt_active_device cad; if (crypt_get_active_device(cd, name.c_str(), &cad) < 0) { VLOG(1) << "Unable to get active device for " << name; break; } // Construct the "type" with the cipher and mode too. std::vector<std::string> items; auto ctype = crypt_get_type(cd); if (ctype != nullptr) { items.push_back(ctype); } auto ccipher = crypt_get_cipher(cd); if (ccipher != nullptr) { items.push_back(ccipher); } auto ccipher_mode = crypt_get_cipher_mode(cd); if (ccipher_mode != nullptr) { items.push_back(ccipher_mode); } r["type"] = osquery::join(items, "-"); encrypted_rows[name] = r; break; } default: if (encrypted_rows.count(parent_name)) { auto parent_row = encrypted_rows[parent_name]; r["encrypted"] = "1"; r["type"] = parent_row["type"]; } else { r["encrypted"] = "0"; } } if (cd != nullptr) { crypt_free(cd); } results.push_back(r); }