Пример #1
0
/**
 * Opens the device with the specified flags.
 *
 * The length parameter is set to the amount of space in the gap between the
 * end of the last slot and the start of the encrypted data.
 *
 * The function returns either the file descriptor positioned to the start of
 * the hole or a negative errno.
 */
static int
open_hole(struct crypt_device *cd, int flags, uint32_t *length)
{
    const char *name = NULL;
    const char *type = NULL;
    uint64_t hole = 0;
    uint64_t data = 0;
    int fd = 0;
    int r = 0;

    type = crypt_get_type(cd);
    if (!type || strcmp(CRYPT_LUKS1, type) != 0)
        return -ENOTSUP;

    data = crypt_get_data_offset(cd) * 512;
    if (data < 4096)
        return -ENOSPC;

    for (int slot = 0; slot < LUKS_NSLOTS; slot++) {
        uint64_t off = 0;
        uint64_t len = 0;

        r = crypt_keyslot_area(cd, slot, &off, &len);
        if (r < 0)
            return r;

        if (hole < off + len)
            hole = ALIGN(off + len, true);
    }

    if (hole == 0)
        return -ENOTSUP;

    if (hole >= data)
        return -ENOSPC;

    name = crypt_get_device_name(cd);
    if (!name)
        return -ENOTSUP;

    fd = open(name, flags);
    if (fd < 0)
        return -errno;

    if (lseek(fd, hole, SEEK_SET) == -1) {
        close(fd);
        return -errno;
    }

    *length = ALIGN(data - hole, false);
    return fd;
}
Пример #2
0
int LUKS1_activate(struct crypt_device *cd,
		   const char *name,
		   struct volume_key *vk,
		   uint32_t flags)
{
	int r;
	struct crypt_dm_active_device dmd = {
		.flags = flags,
		.uuid = crypt_get_uuid(cd),
	};

	r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
			vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd),
			crypt_get_data_offset(cd), crypt_get_integrity(cd),
			crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd));
	if (!r)
		r = create_or_reload_device(cd, name, CRYPT_LUKS1, &dmd);

	dm_targets_free(cd, &dmd);

	return r;
}
Пример #3
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 ;
}
Пример #4
0
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),
		&params);
out:
	crypt_free(cd);
	crypt_safe_free(old_key);
	if (r)
		log_err(_("Creation of LUKS backup headers failed.\n"));
	return r;
}