Example #1
0
static int
ddt_zap_update(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx)
{
	uchar_t cbuf[sizeof (dde->dde_phys) + 1];
	uint64_t csize;

	csize = ddt_compress(dde->dde_phys, cbuf,
	    sizeof (dde->dde_phys), sizeof (cbuf));

	return (zap_update_uint64(os, object, (uint64_t *)&dde->dde_key,
	    DDT_KEY_WORDS, 1, csize, cbuf, tx));
}
Example #2
0
static void
dsl_keychain_set_key(dsl_dir_t *dd, dmu_tx_t *tx,
                     caddr_t wkeybuf, size_t wkeylen, uint64_t rekey_date)
{
    objset_t *mos = dd->dd_pool->dp_meta_objset;
    uint64_t keychain_zapobj = dsl_dir_phys(dd)->dd_keychain_obj;
    uint64_t props_zapobj = dsl_dir_phys(dd)->dd_props_zapobj;

    ASSERT(keychain_zapobj != 0);
    VERIFY(zap_update_uint64(mos, keychain_zapobj,
                             (uint64_t *)&tx->tx_txg, 1, 1, wkeylen, wkeybuf, tx) == 0);
    VERIFY(zap_update(mos, props_zapobj,
                      zfs_prop_to_name(ZFS_PROP_REKEYDATE),
                      8, 1, (void *)&rekey_date, tx) == 0);
}
Example #3
0
static void
dsl_keychain_clone_phys(dsl_dataset_t *src, dsl_dir_t *dd,
                        dmu_tx_t *tx, zcrypt_key_t *dwkey)
{
    objset_t *mos = dd->dd_pool->dp_meta_objset;
    uint64_t keychain = dsl_dir_phys(dd)->dd_keychain_obj;
    caddr_t wrappedkey = NULL;
    size_t wkeylen = 0;
    zcrypt_keystore_node_t *kn;
    zcrypt_keychain_node_t *n;
    uint64_t newest_txg = dsl_dataset_phys(src)->ds_creation_txg;

    kn = zcrypt_keystore_find_node(dsl_dataset_get_spa(src),
                                   src->ds_object, B_FALSE);
    if (kn == NULL) {
        kn = zcrypt_keystore_find_node(dsl_dataset_get_spa(src),
                                       dsl_dir_phys(src->ds_dir)->dd_head_dataset_obj, B_FALSE);
    }
    ASSERT(kn != NULL);
    ASSERT(dwkey != NULL);

    /*
     * Walk the in memory AVL tree representation of the keychain
     * creating new keychain entries using our wrappingkey, stopping
     * when we reach keychain entries created after the snapshot we
     * are cloning from.
     */
    mutex_enter(&kn->skn_lock);
    for (n = avl_first(&kn->skn_keychain);
            n != NULL && n->dkn_txg <= newest_txg;
            n = AVL_NEXT(&kn->skn_keychain, n)) {
        VERIFY(zcrypt_wrap_key(dwkey, n->dkn_key, &wrappedkey,
                               &wkeylen, zio_crypt_select_wrap(dwkey->zk_crypt)) == 0);
        VERIFY(zap_update_uint64(mos, keychain, &n->dkn_txg,
                                 1, 1, wkeylen, wrappedkey, tx) == 0);
        kmem_free(wrappedkey, wkeylen);
    }
    mutex_exit(&kn->skn_lock);
}
Example #4
0
/*
 * dsl_crypto_key_change
 *
 * The old key must already be present in memory since the user interface
 * doesn't provide away to prompt or retrieve the old key.
 */
static void
dsl_crypto_key_change_sync(void *arg1, dmu_tx_t *tx)
{
    struct wkey_change_arg *ca = arg1;
    dsl_dataset_t *ds = ca->ca_ds;
    size_t wkeylen;
    char *wkeybuf = NULL;
    zcrypt_key_t *txgkey;
    zap_cursor_t zc;
    zap_attribute_t za;
    objset_t *mos;
    uint64_t keychain_zapobj;
    spa_t *spa;
    zcrypt_keystore_node_t *zkn;

    ASSERT(RRW_WRITE_HELD(&ds->ds_dir->dd_pool->dp_config_rwlock));

    mos = ds->ds_dir->dd_pool->dp_meta_objset;
    keychain_zapobj = dsl_dir_phys(ds->ds_dir)->dd_keychain_obj;

    /*
     * To allow for the case were the keychains of child datasets
     * are not loaded (ie an explicit 'zfs key -u tank/fs/sub' had
     * been done some time before doing 'zfs key -c tank/fs') we itterate
     * over the zap objects on disk rather than copying from the
     * in memory keystore node.
     */
    for (zap_cursor_init(&zc, mos, keychain_zapobj);
            zap_cursor_retrieve(&zc, &za) == 0;
            zap_cursor_advance(&zc)) {
        wkeylen = za.za_num_integers;
        wkeybuf = kmem_alloc(wkeylen, KM_SLEEP);
        VERIFY(zap_lookup_uint64(mos, keychain_zapobj,
                                 (uint64_t *)za.za_name, 1, 1, wkeylen, wkeybuf) == 0);
        VERIFY(zcrypt_unwrap_key(ca->ca_old_key,
                                 ds->ds_objset->os_crypt, wkeybuf, wkeylen, &txgkey) == 0);
        kmem_free(wkeybuf, wkeylen);
        VERIFY(zcrypt_wrap_key(ca->ca_new_key, txgkey,
                               &wkeybuf, &wkeylen,
                               zio_crypt_select_wrap(ds->ds_objset->os_crypt)) == 0);
        zcrypt_key_free(txgkey);
        VERIFY(zap_update_uint64(mos, keychain_zapobj,
                                 (uint64_t *)za.za_name, 1, 1, wkeylen, wkeybuf, tx) == 0);
        kmem_free(wkeybuf, wkeylen);
    }

    zap_cursor_fini(&zc);

    spa = dsl_dataset_get_spa(ds);

    /*
     * If the wrapping key is loaded switch the in memory copy now.
     */
    zkn = zcrypt_keystore_find_node(spa, ds->ds_object, B_FALSE);
    if (zkn != NULL) {
        zcrypt_key_free(zkn->skn_wrapkey);
        zkn->skn_wrapkey = zcrypt_key_copy(ca->ca_new_key);
    }

    spa_history_log_internal(spa, "key change", tx,
                             "succeeded dataset = %llu", ds->ds_object);
}