FreeBSD/sys/boot/geli/geliboot.c
/*
 * Read the last sector of the drive or partition pointed to by dsk and see
 * if it is GELI encrypted
 */
Read the last sector of the drive or partition pointed to by dsk and see
if it is GELI encrypted
Read the last sector of the drive or partition pointed to by dsk and see if it is GELI encrypted
int
geli_taste(int read_func(void *vdev, void *priv, off_t off, void *buf,
    size_t bytes), struct dsk *dskp, daddr_t lastsector)
{
	struct g_eli_metadata md;
	u_char buf[DEV_GELIBOOT_BSIZE];
	int error;
	off_t alignsector;
	alignsector = rounddown2(lastsector * DEV_BSIZE, DEV_GELIBOOT_BSIZE);
	if (alignsector + DEV_GELIBOOT_BSIZE > ((lastsector + 1) * DEV_BSIZE)) {
		alignsector = (lastsector * DEV_BSIZE) + DEV_BSIZE
		    - DEV_GELIBOOT_BSIZE;
	}
	error = read_func(NULL, dskp, alignsector, &buf, DEV_GELIBOOT_BSIZE);
	if (error != 0) {
		return (error);
	}
	error = eli_metadata_decode(buf, &md);
	if (error != 0) {
		error = eli_metadata_decode(buf +
		    (DEV_GELIBOOT_BSIZE - DEV_BSIZE), &md);
		if (error != 0) {
			return (error);
		}
	}
	if (!(md.md_flags & G_ELI_FLAG_GELIBOOT)) {
		return (1);
	}
	if ((md.md_flags & G_ELI_FLAG_ONETIME)) {
		return (1);
	}
	if (md.md_iterations < 0) {
		return (1);
	}
	geli_e = malloc(sizeof(struct geli_entry));
	if (geli_e == NULL)
		return (2);
	geli_e->dsk = malloc(sizeof(struct dsk));
	if (geli_e->dsk == NULL)
		return (2);
	memcpy(geli_e->dsk, dskp, sizeof(struct dsk));
	geli_e->part_end = lastsector;
	if (dskp->part == 255) {
		geli_e->dsk->part = dskp->slice;
	}
	geli_e->md = md;
	eli_metadata_softc(&geli_e->sc, &md, DEV_BSIZE,
	    (lastsector + DEV_BSIZE) * DEV_BSIZE);
	SLIST_INSERT_HEAD(&geli_head, geli_e, entries);
	geli_count++;
	return (0);
}
int geli_taste ( int read_func ( void * vdev , void * priv , off_t off , void * buf , size_t bytes ) , struct dsk * dskp , daddr_t lastsector ) { struct g_eli_metadata md ; u_char buf [ DEV_GELIBOOT_BSIZE ] ; int error ; off_t alignsector ; alignsector = rounddown2 ( lastsector * DEV_BSIZE , DEV_GELIBOOT_BSIZE ) ; if ( alignsector + DEV_GELIBOOT_BSIZE > ( ( lastsector + 1 ) * DEV_BSIZE ) ) { alignsector = ( lastsector * DEV_BSIZE ) + DEV_BSIZE - DEV_GELIBOOT_BSIZE ; } error = read_func ( NULL , dskp , alignsector , & buf , DEV_GELIBOOT_BSIZE ) ; if ( error != 0 ) { return ( error ) ; } error = eli_metadata_decode ( buf , & md ) ; if ( error != 0 ) { error = eli_metadata_decode ( buf + ( DEV_GELIBOOT_BSIZE - DEV_BSIZE ) , & md ) ; if ( error != 0 ) { return ( error ) ; } } if ( ! ( md . md_flags & G_ELI_FLAG_GELIBOOT ) ) { return ( 1 ) ; } if ( ( md . md_flags & G_ELI_FLAG_ONETIME ) ) { return ( 1 ) ; } if ( md . md_iterations < 0 ) { return ( 1 ) ; } geli_e = malloc ( sizeof ( struct geli_entry ) ) ; if ( geli_e == NULL ) return ( 2 ) ; geli_e -> dsk = malloc ( sizeof ( struct dsk ) ) ; if ( geli_e -> dsk == NULL ) return ( 2 ) ; memcpy ( geli_e -> dsk , dskp , sizeof ( struct dsk ) ) ; geli_e -> part_end = lastsector ; if ( dskp -> part == 255 ) { geli_e -> dsk -> part = dskp -> slice ; } geli_e -> md = md ; eli_metadata_softc ( & geli_e -> sc , & md , DEV_BSIZE , ( lastsector + DEV_BSIZE ) * DEV_BSIZE ) ; SLIST_INSERT_HEAD ( & geli_head , geli_e , entries ) ; geli_count ++ ; return ( 0 ) ; }
Read the last sector of the drive or partition pointed to by dsk and see
 if it is GELI encrypted
Read the last sector of the drive or partition pointed to by dsk and see if it is GELI encrypted
/* Don't read past the end of the disk */ /* Extract the last 4k sector of the disk. */ /* Try the last 512 byte sector instead. */ /* The GELIBOOT feature is not activated */ /* Swap device, skip it. */ /* XXX TODO: Support loading key files. */ /* Disk does not have a passphrase, skip it. */