diff options
author | attilio <attilio@FreeBSD.org> | 2011-05-08 14:56:02 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2011-05-08 14:56:02 +0000 |
commit | 7ff10cb598d55bfe8ced2b56f014c4dca7b432e9 (patch) | |
tree | 762b070eea5b970647293823ae548d0a9715786e /sys/geom | |
parent | 060cccb5372db4bb6441c43f1c99bfab65c6b010 (diff) | |
parent | b838671bb4661d8bd3ad95d511c0b7bcd93a5c4b (diff) | |
download | FreeBSD-src-7ff10cb598d55bfe8ced2b56f014c4dca7b432e9.zip FreeBSD-src-7ff10cb598d55bfe8ced2b56f014c4dca7b432e9.tar.gz |
MFC
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/eli/g_eli.c | 15 | ||||
-rw-r--r-- | sys/geom/eli/g_eli.h | 34 | ||||
-rw-r--r-- | sys/geom/eli/g_eli_ctl.c | 7 | ||||
-rw-r--r-- | sys/geom/eli/g_eli_integrity.c | 4 | ||||
-rw-r--r-- | sys/geom/eli/g_eli_key_cache.c | 14 | ||||
-rw-r--r-- | sys/geom/part/g_part_apm.c | 7 | ||||
-rw-r--r-- | sys/geom/part/g_part_bsd.c | 4 | ||||
-rw-r--r-- | sys/geom/part/g_part_ebr.c | 4 | ||||
-rw-r--r-- | sys/geom/part/g_part_mbr.c | 4 | ||||
-rw-r--r-- | sys/geom/part/g_part_pc98.c | 4 | ||||
-rw-r--r-- | sys/geom/part/g_part_vtoc8.c | 7 |
11 files changed, 73 insertions, 31 deletions
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 6466aef..30497a4 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -57,6 +57,9 @@ MALLOC_DEFINE(M_ELI, "eli data", "GEOM_ELI Data"); SYSCTL_DECL(_kern_geom); SYSCTL_NODE(_kern_geom, OID_AUTO, eli, CTLFLAG_RW, 0, "GEOM_ELI stuff"); +static int g_eli_version = G_ELI_VERSION; +SYSCTL_INT(_kern_geom_eli, OID_AUTO, version, CTLFLAG_RD, &g_eli_version, 0, + "GELI version"); int g_eli_debug = 0; TUNABLE_INT("kern.geom.eli.debug", &g_eli_debug); SYSCTL_INT(_kern_geom_eli, OID_AUTO, debug, CTLFLAG_RW, &g_eli_debug, 0, @@ -329,7 +332,12 @@ g_eli_newsession(struct g_eli_worker *wr) crie.cri_klen = sc->sc_ekeylen; if (sc->sc_ealgo == CRYPTO_AES_XTS) crie.cri_klen <<= 1; - crie.cri_key = sc->sc_ekey; + if ((sc->sc_flags & G_ELI_FLAG_FIRST_KEY) != 0) { + crie.cri_key = g_eli_key_hold(sc, 0, + LIST_FIRST(&sc->sc_geom->consumer)->provider->sectorsize); + } else { + crie.cri_key = sc->sc_ekey; + } if (sc->sc_flags & G_ELI_FLAG_AUTH) { bzero(&cria, sizeof(cria)); cria.cri_alg = sc->sc_aalgo; @@ -368,6 +376,9 @@ g_eli_newsession(struct g_eli_worker *wr) panic("%s: invalid condition", __func__); } + if ((sc->sc_flags & G_ELI_FLAG_FIRST_KEY) != 0) + g_eli_key_drop(sc, crie.cri_key); + return (error); } @@ -708,6 +719,8 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp, sc->sc_flags |= G_ELI_FLAG_NATIVE_BYTE_ORDER; if (md->md_version < 5) sc->sc_flags |= G_ELI_FLAG_SINGLE_KEY; + if (md->md_version < 6 && (sc->sc_flags & G_ELI_FLAG_AUTH) != 0) + sc->sc_flags |= G_ELI_FLAG_FIRST_KEY; sc->sc_ealgo = md->md_ealgo; sc->sc_nkey = nkey; diff --git a/sys/geom/eli/g_eli.h b/sys/geom/eli/g_eli.h index e0fa616..68f92e5 100644 --- a/sys/geom/eli/g_eli.h +++ b/sys/geom/eli/g_eli.h @@ -63,10 +63,19 @@ * 2 - Added G_ELI_FLAG_READONLY. * 3 - Added 'configure' subcommand. * 4 - IV is generated from offset converted to little-endian - * (flag G_ELI_FLAG_NATIVE_BYTE_ORDER will be set for older versions). + * (the G_ELI_FLAG_NATIVE_BYTE_ORDER flag will be set for older versions). * 5 - Added multiple encrypton keys and AES-XTS support. + * 6 - Fixed usage of multiple keys for authenticated providers (the + * G_ELI_FLAG_FIRST_KEY flag will be set for older versions). */ -#define G_ELI_VERSION 5 +#define G_ELI_VERSION_00 0 +#define G_ELI_VERSION_01 1 +#define G_ELI_VERSION_02 2 +#define G_ELI_VERSION_03 3 +#define G_ELI_VERSION_04 4 +#define G_ELI_VERSION_05 5 +#define G_ELI_VERSION_06 6 +#define G_ELI_VERSION G_ELI_VERSION_06 /* ON DISK FLAGS. */ /* Use random, onetime keys. */ @@ -92,6 +101,8 @@ #define G_ELI_FLAG_SINGLE_KEY 0x00080000 /* Device suspended. */ #define G_ELI_FLAG_SUSPEND 0x00100000 +/* Provider uses first encryption key. */ +#define G_ELI_FLAG_FIRST_KEY 0x00200000 #define G_ELI_NEW_BIO 255 @@ -254,7 +265,7 @@ eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) } static __inline int -eli_metadata_decode_v1v2v3v4v5(const u_char *data, struct g_eli_metadata *md) +eli_metadata_decode_v1v2v3v4v5v6(const u_char *data, struct g_eli_metadata *md) { MD5_CTX ctx; const u_char *p; @@ -285,15 +296,16 @@ eli_metadata_decode(const u_char *data, struct g_eli_metadata *md) bcopy(data, md->md_magic, sizeof(md->md_magic)); md->md_version = le32dec(data + sizeof(md->md_magic)); switch (md->md_version) { - case 0: + case G_ELI_VERSION_00: error = eli_metadata_decode_v0(data, md); break; - case 1: - case 2: - case 3: - case 4: - case 5: - error = eli_metadata_decode_v1v2v3v4v5(data, md); + case G_ELI_VERSION_01: + case G_ELI_VERSION_02: + case G_ELI_VERSION_03: + case G_ELI_VERSION_04: + case G_ELI_VERSION_05: + case G_ELI_VERSION_06: + error = eli_metadata_decode_v1v2v3v4v5v6(data, md); break; default: error = EINVAL; @@ -509,8 +521,6 @@ void g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb); void g_eli_read_done(struct bio *bp); void g_eli_write_done(struct bio *bp); int g_eli_crypto_rerun(struct cryptop *crp); -uint8_t *g_eli_crypto_key(struct g_eli_softc *sc, off_t offset, - size_t blocksize); void g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, size_t size); diff --git a/sys/geom/eli/g_eli_ctl.c b/sys/geom/eli/g_eli_ctl.c index a5de30b..65672d5 100644 --- a/sys/geom/eli/g_eli_ctl.c +++ b/sys/geom/eli/g_eli_ctl.c @@ -1014,7 +1014,12 @@ g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb) gctl_error(req, "No '%s' argument.", "version"); return; } - if (*version != G_ELI_VERSION) { + while (*version != G_ELI_VERSION) { + if (G_ELI_VERSION == G_ELI_VERSION_06 && + *version == G_ELI_VERSION_05) { + /* Compatible. */ + break; + } gctl_error(req, "Userland and kernel parts are out of sync."); return; } diff --git a/sys/geom/eli/g_eli_integrity.c b/sys/geom/eli/g_eli_integrity.c index d37bacb..50f2a31 100644 --- a/sys/geom/eli/g_eli_integrity.c +++ b/sys/geom/eli/g_eli_integrity.c @@ -149,7 +149,7 @@ g_eli_auth_read_done(struct cryptop *crp) bp->bio_error = crp->crp_etype; } sc = bp->bio_to->geom->softc; - g_eli_key_drop(sc, crp->crp_desc->crd_key); + g_eli_key_drop(sc, crp->crp_desc->crd_next->crd_key); /* * Do we have all sectors already? */ @@ -513,6 +513,8 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) crde->crd_skip = sc->sc_alen; crde->crd_len = data_secsize; crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; + if ((sc->sc_flags & G_ELI_FLAG_FIRST_KEY) == 0) + crde->crd_flags |= CRD_F_KEY_EXPLICIT; if (bp->bio_cmd == BIO_WRITE) crde->crd_flags |= CRD_F_ENCRYPT; crde->crd_alg = sc->sc_ealgo; diff --git a/sys/geom/eli/g_eli_key_cache.c b/sys/geom/eli/g_eli_key_cache.c index 9dc65a2..0a5a9ca 100644 --- a/sys/geom/eli/g_eli_key_cache.c +++ b/sys/geom/eli/g_eli_key_cache.c @@ -57,9 +57,13 @@ static uint64_t g_eli_key_cache_misses; SYSCTL_UQUAD(_kern_geom_eli, OID_AUTO, key_cache_misses, CTLFLAG_RW, &g_eli_key_cache_misses, 0, "Key cache misses"); +#define G_ELI_KEY_MAGIC 0xe11341c + struct g_eli_key { /* Key value, must be first in the structure. */ uint8_t gek_key[G_ELI_DATAKEYLEN]; + /* Magic. */ + int gek_magic; /* Key number. */ uint64_t gek_keyno; /* Reference counter. */ @@ -98,6 +102,7 @@ g_eli_key_fill(struct g_eli_softc *sc, struct g_eli_key *key, uint64_t keyno) sizeof(hmacdata), key->gek_key, 0); key->gek_keyno = keyno; key->gek_count = 0; + key->gek_magic = G_ELI_KEY_MAGIC; } static struct g_eli_key * @@ -150,6 +155,7 @@ g_eli_key_replace(struct g_eli_softc *sc, struct g_eli_key *key, uint64_t keyno) { mtx_assert(&sc->sc_ekeys_lock, MA_OWNED); + KASSERT(key->gek_magic == G_ELI_KEY_MAGIC, ("Invalid magic.")); RB_REMOVE(g_eli_key_tree, &sc->sc_ekeys_tree, key); TAILQ_REMOVE(&sc->sc_ekeys_queue, key, gek_next); @@ -167,7 +173,7 @@ g_eli_key_remove(struct g_eli_softc *sc, struct g_eli_key *key) { mtx_assert(&sc->sc_ekeys_lock, MA_OWNED); - + KASSERT(key->gek_magic == G_ELI_KEY_MAGIC, ("Invalid magic.")); KASSERT(key->gek_count == 0, ("gek_count=%d", key->gek_count)); RB_REMOVE(g_eli_key_tree, &sc->sc_ekeys_tree, key); @@ -276,6 +282,8 @@ g_eli_key_hold(struct g_eli_softc *sc, off_t offset, size_t blocksize) /* We have all the keys, so avoid some overhead. */ key = RB_FIND(g_eli_key_tree, &sc->sc_ekeys_tree, &keysearch); KASSERT(key != NULL, ("No key %ju found.", (uintmax_t)keyno)); + KASSERT(key->gek_magic == G_ELI_KEY_MAGIC, + ("Invalid key magic.")); return (key->gek_key); } @@ -306,6 +314,8 @@ g_eli_key_hold(struct g_eli_softc *sc, off_t offset, size_t blocksize) key->gek_count++; mtx_unlock(&sc->sc_ekeys_lock); + KASSERT(key->gek_magic == G_ELI_KEY_MAGIC, ("Invalid key magic.")); + return (key->gek_key); } @@ -317,6 +327,8 @@ g_eli_key_drop(struct g_eli_softc *sc, uint8_t *rawkey) if ((sc->sc_flags & G_ELI_FLAG_SINGLE_KEY) != 0) return; + KASSERT(key->gek_magic == G_ELI_KEY_MAGIC, ("Invalid key magic.")); + if (sc->sc_ekeys_total == sc->sc_ekeys_allocated) return; diff --git a/sys/geom/part/g_part_apm.c b/sys/geom/part/g_part_apm.c index 9806bb8..cd318c7 100644 --- a/sys/geom/part/g_part_apm.c +++ b/sys/geom/part/g_part_apm.c @@ -255,7 +255,7 @@ g_part_apm_create(struct g_part_table *basetable, struct g_part_parms *gpp) return (ENOSPC); /* APM uses 32-bit LBAs. */ - last = MIN(pp->mediasize / pp->sectorsize, 0xffffffff) - 1; + last = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX) - 1; basetable->gpt_first = 2 + basetable->gpt_entries; basetable->gpt_last = last; @@ -398,6 +398,8 @@ g_part_apm_probe(struct g_part_table *basetable, struct g_consumer *cp) g_free(buf); if (table->ddr.ddr_blksize != pp->sectorsize) return (ENXIO); + if (table->ddr.ddr_blkcount > pp->mediasize / pp->sectorsize) + return (ENXIO); } else { /* * Check for Tivo drives, which have no DDR and a different @@ -412,7 +414,8 @@ g_part_apm_probe(struct g_part_table *basetable, struct g_consumer *cp) } table->ddr.ddr_sig = APM_DDR_SIG; /* XXX */ table->ddr.ddr_blksize = pp->sectorsize; /* XXX */ - table->ddr.ddr_blkcount = pp->mediasize / pp->sectorsize;/* XXX */ + table->ddr.ddr_blkcount = + MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); table->tivo_series1 = 1; g_free(buf); } diff --git a/sys/geom/part/g_part_bsd.c b/sys/geom/part/g_part_bsd.c index 61fe89a..269b943 100644 --- a/sys/geom/part/g_part_bsd.c +++ b/sys/geom/part/g_part_bsd.c @@ -206,7 +206,7 @@ g_part_bsd_create(struct g_part_table *basetable, struct g_part_parms *gpp) if (BBSIZE % pp->sectorsize) return (ENOTBLK); - msize = MIN(pp->mediasize / pp->sectorsize, 0xffffffff); + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); secpercyl = basetable->gpt_sectors * basetable->gpt_heads; ncyls = msize / secpercyl; @@ -365,7 +365,7 @@ g_part_bsd_read(struct g_part_table *basetable, struct g_consumer *cp) pp = cp->provider; table = (struct g_part_bsd_table *)basetable; - msize = pp->mediasize / pp->sectorsize; + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); table->bbarea = g_read_data(cp, 0, BBSIZE, &error); if (table->bbarea == NULL) diff --git a/sys/geom/part/g_part_ebr.c b/sys/geom/part/g_part_ebr.c index 5f665ca..f6278cc 100644 --- a/sys/geom/part/g_part_ebr.c +++ b/sys/geom/part/g_part_ebr.c @@ -288,7 +288,7 @@ g_part_ebr_create(struct g_part_table *basetable, struct g_part_parms *gpp) if (strcmp(psn, "MBR")) return (ENXIO); - msize = MIN(pp->mediasize / pp->sectorsize, 0xffffffff); + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); msize -= msize % basetable->gpt_sectors; basetable->gpt_first = 0; basetable->gpt_last = msize - 1; @@ -464,7 +464,7 @@ g_part_ebr_read(struct g_part_table *basetable, struct g_consumer *cp) pp = cp->provider; table = (struct g_part_ebr_table *)basetable; - msize = pp->mediasize / pp->sectorsize; + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); lba = 0; while (1) { diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c index 63b7e64..4fa829a 100644 --- a/sys/geom/part/g_part_mbr.c +++ b/sys/geom/part/g_part_mbr.c @@ -262,7 +262,7 @@ g_part_mbr_create(struct g_part_table *basetable, struct g_part_parms *gpp) if (pp->sectorsize < MBRSIZE) return (ENOSPC); - msize = MIN(pp->mediasize / pp->sectorsize, 0xffffffff); + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); basetable->gpt_first = basetable->gpt_sectors; basetable->gpt_last = msize - (msize % basetable->gpt_sectors) - 1; @@ -433,7 +433,7 @@ g_part_mbr_read(struct g_part_table *basetable, struct g_consumer *cp) pp = cp->provider; table = (struct g_part_mbr_table *)basetable; - msize = pp->mediasize / pp->sectorsize; + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); buf = g_read_data(cp, 0L, pp->sectorsize, &error); if (buf == NULL) diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c index d8aa87d..693fad8 100644 --- a/sys/geom/part/g_part_pc98.c +++ b/sys/geom/part/g_part_pc98.c @@ -261,7 +261,7 @@ g_part_pc98_create(struct g_part_table *basetable, struct g_part_parms *gpp) cyl = basetable->gpt_heads * basetable->gpt_sectors; - msize = MIN(pp->mediasize / SECSIZE, 0xffffffff); + msize = MIN(pp->mediasize / SECSIZE, UINT32_MAX); basetable->gpt_first = cyl; basetable->gpt_last = msize - (msize % cyl) - 1; @@ -451,7 +451,7 @@ g_part_pc98_read(struct g_part_table *basetable, struct g_consumer *cp) pp = cp->provider; table = (struct g_part_pc98_table *)basetable; - msize = pp->mediasize / SECSIZE; + msize = MIN(pp->mediasize / SECSIZE, UINT32_MAX); buf = g_read_data(cp, 0L, BOOTSIZE, &error); if (buf == NULL) diff --git a/sys/geom/part/g_part_vtoc8.c b/sys/geom/part/g_part_vtoc8.c index e59c8e4..245d1f9 100644 --- a/sys/geom/part/g_part_vtoc8.c +++ b/sys/geom/part/g_part_vtoc8.c @@ -198,9 +198,7 @@ g_part_vtoc8_create(struct g_part_table *basetable, struct g_part_parms *gpp) table = (struct g_part_vtoc8_table *)basetable; - msize = pp->mediasize / pp->sectorsize; - if (msize > 0xffffffffu) - msize = 0xffffffffu; + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); table->secpercyl = basetable->gpt_sectors * basetable->gpt_heads; pcyls = msize / table->secpercyl; acyls = 2; @@ -392,8 +390,7 @@ g_part_vtoc8_read(struct g_part_table *basetable, struct g_consumer *cp) bcopy(buf, &table->vtoc, sizeof(table->vtoc)); g_free(buf); - msize = pp->mediasize / pp->sectorsize; - + msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); sectors = be16dec(&table->vtoc.nsecs); if (sectors < 1) goto invalid_label; |