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;
}
Beispiel #2
0
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 ;
}
Beispiel #4
0
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 ) ;
	}
}
Beispiel #5
0
static int _open_plain( const char * device,const open_struct_t * opt )
{
	uint32_t flags ;

	struct crypt_device * cd ;
	struct crypt_params_plain params ;

	memset( &params,'\0',sizeof( struct crypt_params_plain ) ) ;

	params.hash = "ripemd160" ;

	if( zuluCryptPathIsNotValid( device ) ){
		return 3 ;
	}
	if( crypt_init( &cd,device ) != 0 ){
		return 2 ;
	}

	params.offset = _offset( opt->offset ) ;

	if( StringHasComponent( opt->m_opts,"ro" ) ){
		flags = CRYPT_ACTIVATE_READONLY ;
	}else{
		flags = CRYPT_ACTIVATE_ALLOW_DISCARDS ;
	}
	if( crypt_format( cd,CRYPT_PLAIN,"aes","cbc-essiv:sha256",NULL,NULL,32,&params ) != 0 ){
		return zuluExit( 2,cd ) ;
	}
	if( crypt_activate_by_passphrase( cd,opt->mapper_name,CRYPT_ANY_SLOT,
		opt->key,opt->key_len,flags ) < 0 ){
		return zuluExit( 2,cd ) ;
	}else{
		return zuluExit( 0,cd ) ;
	}
}
Beispiel #6
0
static int _open_plain( const char * device,const char * mapper,const char * mode,const char * pass,size_t pass_size )
{
	int flags ;
	
	struct crypt_device * cd ;
	struct crypt_params_plain params ;
	
	memset( &params,'\0',sizeof( struct crypt_params_plain ) ) ;
	
	params.hash = "ripemd160";
	params.skip = 0;
	params.offset = 0;
	
	if( zuluCryptPathIsNotValid( device ) ){
		return 3 ;
	}
	if( StringHasComponent( mode,"ro" ) ){
		flags = 1 ;
	}else{
		flags = 0 ;
	}
	if( crypt_init( &cd,device ) != 0 ){
		return 2 ;
	}
	if( crypt_format( cd,CRYPT_PLAIN,"aes","cbc-essiv:sha256",NULL,NULL,32,&params ) != 0 ){
		return zuluExit( 2,cd ) ;
	}
	if( crypt_activate_by_passphrase( cd,mapper,CRYPT_ANY_SLOT,pass,pass_size,flags ) < 0 ){
		return zuluExit( 2,cd ) ;
	}else{
		return zuluExit( 0,cd ) ;
	}
}
Beispiel #7
0
void lw_sha1 (char * output, const char * input, size_t length)
{
   HCRYPTPROV hash_prov;
   DWORD hash_length = 20;

   crypt_init ();

   CryptCreateHash (crypt_prov, CALG_SHA1, 0, 0, &hash_prov);
   CryptHashData (hash_prov, (BYTE *) input, (DWORD) length, 0);
   CryptGetHashParam (hash_prov, HP_HASHVAL, (BYTE *) output, &hash_length, 0);
   CryptDestroyHash (hash_prov);
}
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;
}
Beispiel #9
0
lw_bool lw_random (char * buffer, size_t size)
{
   if (!crypt_init ())
      return lw_false;

   if (size > 0xFFFFFFFF)
      return lw_false;

   if (!CryptGenRandom (crypt_prov, (DWORD) size, (PBYTE) buffer))
      return lw_false;

   return lw_true;
}
Beispiel #10
0
static int _open_plain( const char * device,const resolve_path_t * opts )
{
	uint32_t flags ;

	struct crypt_device * cd ;
	struct crypt_params_plain params ;

	size_t size ;
	/*
	 * open_struct_t is defined in includes.h
	 */
	const open_struct_t * opt = opts->args ;

	const args * e = opt->variables ;

	memset( &params,'\0',sizeof( struct crypt_params_plain ) ) ;

	params.hash = e->hash ;

	if( zuluCryptPathIsNotValid( device ) ){

		return 3 ;
	}
	if( crypt_init( &cd,device ) != 0 ){

		return 2 ;
	}

	params.offset = _offset( e->offset ) ;

	if( opts->open_mode == O_RDONLY ){

		flags = CRYPT_ACTIVATE_READONLY ;
	}else{
		flags = CRYPT_ACTIVATE_ALLOW_DISCARDS ;
	}

	size = ( size_t ) StringConvertToInt( e->keySize ) / 8 ;

	if( crypt_format( cd,CRYPT_PLAIN,e->algo,e->cipher,NULL,NULL,size,&params ) != 0 ){

		return zuluExit( 2,cd ) ;
	}
	if( crypt_activate_by_passphrase( cd,opt->mapper_name,CRYPT_ANY_SLOT,
		opt->key,opt->key_len,flags ) < 0 ){

		return zuluExit( 2,cd ) ;
	}else{
		return zuluExit( 0,cd ) ;
	}
}
Beispiel #11
0
int main(void)
{
  switch_t s;
  chan_t c;
  packet_t p;
  path_t in;
  int sock;

  crypt_init();
  s = switch_new(0);

  if(util_loadjson(s) != 0 || (sock = util_server(0,1000)) <= 0)
  {
    printf("failed to startup %s or %s\n", strerror(errno), crypt_err());
    return -1;
  }

  printf("loaded hashname %s\n",s->id->hexname);

  // create/send a ping packet  
  c = chan_new(s, bucket_get(s->seeds, 0), "link", 0);
  p = chan_packet(c);
  chan_send(c, p);
  util_sendall(s,sock);

  in = path_new("ipv4");
  while(util_readone(s, sock, in) == 0)
  {
    switch_loop(s);

    while((c = switch_pop(s)))
    {
      printf("channel active %d %s %s\n",c->state,c->hexid,c->to->hexname);
      if(util_cmp(c->type,"connect") == 0) ext_connect(c);
      if(util_cmp(c->type,"link") == 0) ext_link(c);
      if(util_cmp(c->type,"path") == 0) ext_path(c);
      while((p = chan_pop(c)))
      {
        printf("unhandled channel packet %.*s\n", p->json_len, p->json);      
        packet_free(p);
      }
      if(c->state == ENDED) chan_free(c);
    }

    util_sendall(s,sock);
  }

  perror("exiting");
  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);
}
Beispiel #13
0
struct crypt *crypt_HKDF_SHA256_new(void)
{
	struct hkdf_priv *hk;
	struct crypt *c;

	c = crypt_init(sizeof(*hk));
	c->c_destroy = hkdf_destroy;
	c->c_set_key = hkdf_set_key;
	c->c_extract = hkdf_extract;
	c->c_expand  = hkdf_expand;

	hk = crypt_priv(c);
	hk->hk_hmac = crypt_HMAC_SHA256_new();

	return c;
}
Beispiel #14
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;
}
Beispiel #15
0
struct crypt *crypt_HMAC_SHA256_new(void)
{
	struct hmac_priv *hp;
	struct crypt *c;

	c = crypt_init(sizeof(*hp));
	c->c_destroy = hmac_destroy;
	c->c_set_key = hmac_set_key;
	c->c_mac     = hmac_mac;

	hp = crypt_priv(c);

	HMAC_CTX_init(&hp->hp_ctx);
	HMAC_Init_ex(&hp->hp_ctx, "a", 1, EVP_sha256(), NULL);

	return c;
}
Beispiel #16
0
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 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 ;
}
Beispiel #18
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 ) ;
}
Beispiel #19
0
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 ) ;
	}
}
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;
}
Beispiel #21
0
static int
crypt_init_arcfour128(LIBSSH2_SESSION * session,
                      const LIBSSH2_CRYPT_METHOD * method,
                      unsigned char *iv, int *free_iv,
                      unsigned char *secret, int *free_secret,
                      int encrypt, void **abstract)
{
    int rc;

    rc = crypt_init (session, method, iv, free_iv, secret, free_secret,
		     encrypt, abstract);
    if (rc == 0) {
	struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
	unsigned char block[8];
	size_t discard = 1536;
	for (; discard; discard -= 8)
	    _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
    }

    return rc;
}
Beispiel #22
0
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;
}
Beispiel #23
0
/*
 * 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( &params,'\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,&params ) == 0 ){
			return zuluExit( 1,cd ) ;
		}else{
			return zuluExit( 0,cd ) ;
		}
	}
}
Beispiel #24
0
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 ) ;
	}
}
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;
}
Beispiel #26
0
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 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 */
			 &params);	/* 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 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;
}
Beispiel #29
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, &params);
	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, &params);
	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, &params);
	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, &params);
	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, &params);
	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);
}
/* Create fake header for original device */
static int backup_fake_header(struct reenc_ctx *rc)
{
	struct crypt_device *cd_new = NULL;
	struct crypt_params_luks1 params = {0};
	char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
	const char *header_file_fake;
	int r;

	log_dbg("Creating fake (cipher_null) header for %s device.",
		(rc->reencrypt_mode == DECRYPT) ? "new" : "original");

	header_file_fake = (rc->reencrypt_mode == DECRYPT) ? rc->header_file_new : rc->header_file_org;

	if (!opt_key_size)
		opt_key_size = DEFAULT_LUKS1_KEYBITS;

	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;
		}
	}

	r = create_empty_header(header_file_fake, NULL, MAX_BCK_SECTORS);
	if (r < 0)
		return r;

	params.hash = opt_hash ?: DEFAULT_LUKS1_HASH;
	params.data_alignment = 0;
	params.data_device = rc->device;

	r = crypt_init(&cd_new, header_file_fake);
	if (r < 0)
		return r;

	r = crypt_format(cd_new, CRYPT_LUKS1, "cipher_null", "ecb",
			 NO_UUID, NULL, opt_key_size / 8, &params);
	if (r < 0)
		goto out;

	r = crypt_keyslot_add_by_volume_key(cd_new, rc->keyslot, NULL, 0,
			rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
	if (r < 0)
		goto out;

	/* The real header is backup header created in backup_luks_headers() */
	if (rc->reencrypt_mode == DECRYPT)
		goto out;

	r = create_empty_header(rc->header_file_new, rc->header_file_org, 0);
	if (r < 0)
		goto out;

	params.data_alignment = ROUND_SECTOR(opt_reduce_size);
	r = create_new_header(rc,
		opt_cipher ? cipher : DEFAULT_LUKS1_CIPHER,
		opt_cipher ? cipher_mode : DEFAULT_LUKS1_MODE,
		NULL, NULL,
		(opt_key_size ? opt_key_size : DEFAULT_LUKS1_KEYBITS) / 8,
		&params);
out:
	crypt_free(cd_new);
	return r;
}