Esempio n. 1
0
/* Initialize GCM mode */
void GCM_init(gcm* g,char *key,int niv,char *iv)
{ /* iv size niv is usually 12 bytes (96 bits). AES key is 16 bytes */
	int i;
	uchar H[16];
	for (i=0;i<16;i++) {H[i]=0; g->stateX[i]=0;}

	AES_init(&(g->a),ECB,key,iv);
	AES_ecb_encrypt(&(g->a),H);     /* E(K,0) */
	precompute(g,H);
	
	g->lenA[0]=g->lenC[0]=g->lenA[1]=g->lenC[1]=0;
	if (niv==12)
	{
		for (i=0;i<12;i++) g->a.f[i]=iv[i];
		unpack((unsign32)1,(uchar *)&(g->a.f[12]));  /* initialise IV */
		for (i=0;i<16;i++) g->Y_0[i]=g->a.f[i];
	}
	else
	{
		g->status=GCM_ACCEPTING_CIPHER;
		GCM_ghash(g,iv,niv); /* GHASH(H,0,IV) */
		GCM_wrap(g);
		for (i=0;i<16;i++) {g->a.f[i]=g->stateX[i];g->Y_0[i]=g->a.f[i];g->stateX[i]=0;}
		g->lenA[0]=g->lenC[0]=g->lenA[1]=g->lenC[1]=0;
	}
	g->status=GCM_ACCEPTING_HEADER;
}
Esempio n. 2
0
void
g_bde_crypt_delete(struct g_bde_work *wp)
{
	struct g_bde_softc *sc;
	u_char *d;
	off_t o;
	u_char skey[G_BDE_SKEYLEN];
	keyInstance ki;
	cipherInstance ci;

	sc = wp->softc;
	d = wp->sp->data;
	AES_init(&ci);
	/*
	 * Do not unroll this loop!
	 * Our zone may be significantly wider than the amount of random
	 * bytes arc4rand likes to give in one reseeding, whereas our
	 * sectorsize is far more likely to be in the same range.
	 */
	for (o = 0; o < wp->length; o += sc->sectorsize) {
		arc4rand(d, sc->sectorsize, 0);
		arc4rand(&skey, sizeof skey, 0);
		AES_makekey(&ki, DIR_ENCRYPT, G_BDE_SKEYBITS, skey);
		AES_encrypt(&ci, &ki, d, d, sc->sectorsize);
		d += sc->sectorsize;
	}
	/*
	 * Having written a long random sequence to disk here, we want to
	 * force a reseed, to avoid weakening the next time we use random
	 * data for something important.
	 */
	arc4rand(&o, sizeof o, 1);
}
Esempio n. 3
0
void
g_bde_crypt_write(struct g_bde_work *wp)
{
	u_char *s, *d;
	struct g_bde_softc *sc;
	u_int n;
	off_t o;
	u_char skey[G_BDE_SKEYLEN];
	keyInstance ki;
	cipherInstance ci;

	sc = wp->softc;
	AES_init(&ci);
	o = 0;
	for (n = 0; o < wp->length; n++, o += sc->sectorsize) {

		s = (u_char *)wp->data + o;
		d = (u_char *)wp->sp->data + o;
		arc4rand(&skey, sizeof skey, 0);
		AES_makekey(&ki, DIR_ENCRYPT, G_BDE_SKEYBITS, skey);
		AES_encrypt(&ci, &ki, s, d, sc->sectorsize);

		d = (u_char *)wp->ksp->data + wp->ko + n * G_BDE_SKEYLEN;
		g_bde_kkey(sc, &ki, DIR_ENCRYPT, wp->offset + o);
		AES_encrypt(&ci, &ki, skey, d, sizeof skey);
		bzero(skey, sizeof skey);
	}
	bzero(skey, sizeof skey);
	bzero(&ci, sizeof ci);
	bzero(&ki, sizeof ci);
}
Esempio n. 4
0
void
g_bde_crypt_read(struct g_bde_work *wp)
{
	struct g_bde_softc *sc;
	u_char *d;
	u_int n;
	off_t o;
	u_char skey[G_BDE_SKEYLEN];
	keyInstance ki;
	cipherInstance ci;
	

	AES_init(&ci);
	sc = wp->softc;
	o = 0;
	for (n = 0; o < wp->length; n++, o += sc->sectorsize) {
		d = (u_char *)wp->ksp->data + wp->ko + n * G_BDE_SKEYLEN;
		g_bde_kkey(sc, &ki, DIR_DECRYPT, wp->offset + o);
		AES_decrypt(&ci, &ki, d, skey, sizeof skey);
		d = (u_char *)wp->data + o;
		AES_makekey(&ki, DIR_DECRYPT, G_BDE_SKEYBITS, skey);
		AES_decrypt(&ci, &ki, d, d, sc->sectorsize);
	}
	bzero(skey, sizeof skey);
	bzero(&ci, sizeof ci);
	bzero(&ki, sizeof ci);
}
Esempio n. 5
0
int
g_bde_keyloc_decrypt(u_char *sha2, void *input, uint64_t *output)
{
	keyInstance ki;
	cipherInstance ci;
	u_char buf[16];

	AES_init(&ci);
	AES_makekey(&ki, DIR_DECRYPT, G_BDE_KKEYBITS, sha2 + 0);
	AES_decrypt(&ci, &ki, input, buf, sizeof buf);
	*output = le64dec(buf);
	bzero(buf, sizeof buf);
	bzero(&ci, sizeof ci);
	bzero(&ki, sizeof ki);
	return(0);
}
Esempio n. 6
0
int
g_bde_keyloc_encrypt(u_char *sha2, uint64_t v0, uint64_t v1, void *output)
{
	u_char buf[16];
	keyInstance ki;
	cipherInstance ci;

	le64enc(buf, v0);
	le64enc(buf + 8, v1);
	AES_init(&ci);
	AES_makekey(&ki, DIR_ENCRYPT, G_BDE_KKEYBITS, sha2 + 0);
	AES_encrypt(&ci, &ki, buf, output, sizeof buf);
	bzero(buf, sizeof buf);
	bzero(&ci, sizeof ci);
	bzero(&ki, sizeof ki);
	return (0);
}
Esempio n. 7
0
static int
g_bde_decrypt_lockx(struct g_bde_softc *sc, u_char *meta, off_t mediasize, u_int sectorsize, u_int *nkey)
{
	u_char *buf, *q;
	struct g_bde_key *gl;
	uint64_t off, q1;
	int error, m, i;
	keyInstance ki;
	cipherInstance ci;

	gl = &sc->key;

	/* Try to decrypt the metadata */
	error = g_bde_keyloc_decrypt(sc->sha2, meta, &off);
	if (error)
		return (error);

	/* If it points into thin blue air, forget it */
	if (off + G_BDE_LOCKSIZE > (uint64_t)mediasize) {
		off = 0;
		return (EINVAL);
	}

	/* The lock data may span two physical sectors. */

	m = 1;
	if (off % sectorsize > sectorsize - G_BDE_LOCKSIZE)
		m++;

	/* Read the suspected sector(s) */
	buf = g_read_data(sc->consumer,
		off - (off % sectorsize),
		m * sectorsize, &error);
	if (buf == NULL) {
		off = 0;
		return(error);
	}

	/* Find the byte-offset of the stored byte sequence */
	q = buf + off % sectorsize;

	/* If it is all zero, somebody nuked our lock sector */
	q1 = 0;
	for (i = 0; i < G_BDE_LOCKSIZE; i++)
		q1 += q[i];
	if (q1 == 0) {
		off = 0;
		g_free(buf);
		return (ESRCH);
	}

	/* Decrypt the byte-sequence in place */
	AES_init(&ci);
	AES_makekey(&ki, DIR_DECRYPT, 256, sc->sha2 + 16);
	AES_decrypt(&ci, &ki, q, q, G_BDE_LOCKSIZE);

	/* Decode the byte-sequence */
	i = g_bde_decode_lock(sc, gl, q);
	q = NULL;
	if (i < 0) {
		off = 0;
		return (EDOOFUS);	/* Programming error */
	} else if (i > 0) {
		off = 0;
		return (ENOTDIR);	/* Hash didn't match */
	}

	bzero(buf, sectorsize * m);
	g_free(buf);

	/* If the masterkey is all zeros, user destroyed it */
	q1 = 0;
	for (i = 0; i < (int)sizeof(gl->mkey); i++)
		q1 += gl->mkey[i];
	if (q1 == 0)
		return (ENOENT);

	/* If we have an unsorted lock-sequence, refuse */
	for (i = 0; i < G_BDE_MAXKEYS - 1; i++)
		if (gl->lsector[i] >= gl->lsector[i + 1])
			return (EINVAL);

	/* Finally, find out which key was used by matching the byte offset */
	for (i = 0; i < G_BDE_MAXKEYS; i++)
		if (nkey != NULL && off == gl->lsector[i])
			*nkey = i;
	off = 0;
	return (0);
}