Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/eli/g_eli.c
Show First 20 Lines • Show All 565 Lines • ▼ Show 20 Lines | if (bp->bio_pflags == G_ELI_NEW_BIO) { | ||||
if (sc->sc_flags & G_ELI_FLAG_AUTH) | if (sc->sc_flags & G_ELI_FLAG_AUTH) | ||||
g_eli_auth_run(wr, bp); | g_eli_auth_run(wr, bp); | ||||
else | else | ||||
g_eli_crypto_run(wr, bp); | g_eli_crypto_run(wr, bp); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* | |||||
* Here we generate IV. It is unique for every sector. | |||||
*/ | |||||
void | |||||
g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, | |||||
size_t size) | |||||
{ | |||||
uint8_t off[8]; | |||||
if ((sc->sc_flags & G_ELI_FLAG_NATIVE_BYTE_ORDER) != 0) | |||||
bcopy(&offset, off, sizeof(off)); | |||||
else | |||||
le64enc(off, (uint64_t)offset); | |||||
switch (sc->sc_ealgo) { | |||||
case CRYPTO_AES_XTS: | |||||
bcopy(off, iv, sizeof(off)); | |||||
bzero(iv + sizeof(off), size - sizeof(off)); | |||||
break; | |||||
default: | |||||
{ | |||||
u_char hash[SHA256_DIGEST_LENGTH]; | |||||
SHA256_CTX ctx; | |||||
/* Copy precalculated SHA256 context for IV-Key. */ | |||||
bcopy(&sc->sc_ivctx, &ctx, sizeof(ctx)); | |||||
SHA256_Update(&ctx, off, sizeof(off)); | |||||
SHA256_Final(hash, &ctx); | |||||
bcopy(hash, iv, MIN(sizeof(hash), size)); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
int | int | ||||
g_eli_read_metadata(struct g_class *mp, struct g_provider *pp, | g_eli_read_metadata(struct g_class *mp, struct g_provider *pp, | ||||
struct g_eli_metadata *md) | struct g_eli_metadata *md) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
u_char *buf = NULL; | u_char *buf = NULL; | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp, | ||||
* If detach-on-last-close feature is not enabled and we don't operate | * If detach-on-last-close feature is not enabled and we don't operate | ||||
* on read-only provider, we can simply use g_std_access(). | * on read-only provider, we can simply use g_std_access(). | ||||
*/ | */ | ||||
if (md->md_flags & (G_ELI_FLAG_WO_DETACH | G_ELI_FLAG_RO)) | if (md->md_flags & (G_ELI_FLAG_WO_DETACH | G_ELI_FLAG_RO)) | ||||
gp->access = g_eli_access; | gp->access = g_eli_access; | ||||
else | else | ||||
gp->access = g_std_access; | gp->access = g_std_access; | ||||
sc->sc_version = md->md_version; | eli_metadata_softc(sc, md, bpp->sectorsize, bpp->mediasize); | ||||
sc->sc_inflight = 0; | |||||
sc->sc_crypto = G_ELI_CRYPTO_UNKNOWN; | |||||
sc->sc_flags = md->md_flags; | |||||
/* Backward compatibility. */ | |||||
if (md->md_version < G_ELI_VERSION_04) | |||||
sc->sc_flags |= G_ELI_FLAG_NATIVE_BYTE_ORDER; | |||||
if (md->md_version < G_ELI_VERSION_05) | |||||
sc->sc_flags |= G_ELI_FLAG_SINGLE_KEY; | |||||
if (md->md_version < G_ELI_VERSION_06 && | |||||
(sc->sc_flags & G_ELI_FLAG_AUTH) != 0) { | |||||
sc->sc_flags |= G_ELI_FLAG_FIRST_KEY; | |||||
} | |||||
if (md->md_version < G_ELI_VERSION_07) | |||||
sc->sc_flags |= G_ELI_FLAG_ENC_IVKEY; | |||||
sc->sc_ealgo = md->md_ealgo; | |||||
sc->sc_nkey = nkey; | sc->sc_nkey = nkey; | ||||
if (sc->sc_flags & G_ELI_FLAG_AUTH) { | |||||
sc->sc_akeylen = sizeof(sc->sc_akey) * 8; | |||||
sc->sc_aalgo = md->md_aalgo; | |||||
sc->sc_alen = g_eli_hashlen(sc->sc_aalgo); | |||||
sc->sc_data_per_sector = bpp->sectorsize - sc->sc_alen; | |||||
/* | |||||
* Some hash functions (like SHA1 and RIPEMD160) generates hash | |||||
* which length is not multiple of 128 bits, but we want data | |||||
* length to be multiple of 128, so we can encrypt without | |||||
* padding. The line below rounds down data length to multiple | |||||
* of 128 bits. | |||||
*/ | |||||
sc->sc_data_per_sector -= sc->sc_data_per_sector % 16; | |||||
sc->sc_bytes_per_sector = | |||||
(md->md_sectorsize - 1) / sc->sc_data_per_sector + 1; | |||||
sc->sc_bytes_per_sector *= bpp->sectorsize; | |||||
} | |||||
gp->softc = sc; | gp->softc = sc; | ||||
sc->sc_geom = gp; | sc->sc_geom = gp; | ||||
bioq_init(&sc->sc_queue); | bioq_init(&sc->sc_queue); | ||||
mtx_init(&sc->sc_queue_mtx, "geli:queue", NULL, MTX_DEF); | mtx_init(&sc->sc_queue_mtx, "geli:queue", NULL, MTX_DEF); | ||||
mtx_init(&sc->sc_ekeys_lock, "geli:ekeys", NULL, MTX_DEF); | mtx_init(&sc->sc_ekeys_lock, "geli:ekeys", NULL, MTX_DEF); | ||||
pp = NULL; | pp = NULL; | ||||
Show All 26 Lines | if (req != NULL) { | ||||
bpp->name, error); | bpp->name, error); | ||||
} else { | } else { | ||||
G_ELI_DEBUG(1, "Cannot access %s (error=%d).", | G_ELI_DEBUG(1, "Cannot access %s (error=%d).", | ||||
bpp->name, error); | bpp->name, error); | ||||
} | } | ||||
goto failed; | goto failed; | ||||
} | } | ||||
sc->sc_sectorsize = md->md_sectorsize; | |||||
sc->sc_mediasize = bpp->mediasize; | |||||
if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) | |||||
sc->sc_mediasize -= bpp->sectorsize; | |||||
if (!(sc->sc_flags & G_ELI_FLAG_AUTH)) | |||||
sc->sc_mediasize -= (sc->sc_mediasize % sc->sc_sectorsize); | |||||
else { | |||||
sc->sc_mediasize /= sc->sc_bytes_per_sector; | |||||
sc->sc_mediasize *= sc->sc_sectorsize; | |||||
} | |||||
/* | /* | ||||
* Remember the keys in our softc structure. | * Remember the keys in our softc structure. | ||||
*/ | */ | ||||
g_eli_mkey_propagate(sc, mkey); | g_eli_mkey_propagate(sc, mkey); | ||||
sc->sc_ekeylen = md->md_keylen; | |||||
LIST_INIT(&sc->sc_workers); | LIST_INIT(&sc->sc_workers); | ||||
threads = g_eli_threads; | threads = g_eli_threads; | ||||
if (threads == 0) | if (threads == 0) | ||||
threads = mp_ncpus; | threads = mp_ncpus; | ||||
sc->sc_cpubind = (mp_ncpus > 1 && threads == mp_ncpus); | sc->sc_cpubind = (mp_ncpus > 1 && threads == mp_ncpus); | ||||
for (i = 0; i < threads; i++) { | for (i = 0; i < threads; i++) { | ||||
▲ Show 20 Lines • Show All 491 Lines • Show Last 20 Lines |