Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Oct 2009 10:33:29 GMT
From:      Gleb Kurtsou <gk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 169676 for review
Message-ID:  <200910221033.n9MAXTLd095895@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=169676

Change 169676 by gk@gk_h1 on 2009/10/22 10:33:29

	more strictly follow hkdf and vmac specifications
	commit breaks compatibility
	remove random magic constants
	reuse first encrypted name block as a nonce for vmac
	handle name alignment
	add 'salsa20' alias for 'salsa20-256'

Affected files ...

.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#10 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#18 edit

Differences ...

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#10 (text+ko) ====

@@ -72,6 +72,7 @@
 	{ "camellia256-ctr", PEFS_ALG_CAMELLIA_CTR, 256 },
 	{ "camellia256", PEFS_ALG_CAMELLIA_CTR, 256 },
 	{ "salsa20-256", PEFS_ALG_SALSA20, 256 },
+	{ "salsa20", PEFS_ALG_SALSA20, 256 },
 	{ NULL, 0, 0 },
 };
 

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#18 (text+ko) ====

@@ -52,8 +52,12 @@
 
 CTASSERT(PEFS_KEY_SIZE <= SHA512_DIGEST_LENGTH);
 CTASSERT(PEFS_TWEAK_SIZE == 64/8);
+CTASSERT(PEFS_NAME_CSUM_SIZE <= sizeof(uint64_t));
+CTASSERT(MAXNAMLEN >= PEFS_NAME_PTON_SIZE(MAXNAMLEN) + PEFS_NAME_BLOCK_SIZE);
 CTASSERT(CAMELLIA_BLOCK_SIZE == PEFS_CTR_BLOCK_SIZE);
 
+static const char magic_keyinfo[] = "PEFSKEY";
+
 typedef void algop_keysetup_t(struct pefs_ctx *ctx, const uint8_t *key,
     uint32_t keybits);
 typedef void algop_ivsetup_t(struct pefs_ctx *ctx, const uint8_t *iv,
@@ -117,24 +121,6 @@
 	pefs_camellia_crypt
 };
 
-/* vmac requirement: first bit of the nonce buffer n must be 0 */
-static const char magic_name_csum_nonce[VMAC_NHBYTES] = {
-	0x00, 0xb1, 0xad, 0xd5, 0x5b, 0xf9, 0x10, 0xe1,
-	0x0a, 0x25, 0x8a, 0xd3, 0x33, 0x91, 0x8a, 0x1a,
-};
-
-static const char magic_ctxinfo_name_key[PEFS_TWEAK_SIZE] = {
-	0xc8, 0x27, 0xa3, 0x7e, 0xcf, 0x86, 0x3d, 0x0d,
-};
-
-static const char magic_ctxinfo_name_csum_key[PEFS_TWEAK_SIZE] = {
-	0x21, 0xe2, 0x71, 0x0a, 0x4a, 0xe6, 0xfd, 0x64,
-};
-
-static const char magic_ctxinfo_data_key[PEFS_TWEAK_SIZE] = {
-	0xe3, 0x74, 0xdc, 0x7f, 0x10, 0x23, 0x55, 0x16,
-};
-
 static uma_zone_t pefs_ctx_zone;
 static uma_zone_t pefs_key_zone;
 
@@ -195,8 +181,8 @@
 	bzero(key, PEFS_KEY_SIZE);
 	hmac_sha512_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
 	hmac_sha512_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
-	hmac_sha512_update(&ctx->o.pctx_hmac, magic_ctxinfo_data_key,
-	    PEFS_TWEAK_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, magic_keyinfo,
+	    sizeof(magic_keyinfo));
 	hmac_sha512_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
 	hmac_sha512_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
 	pk->pk_alg->pa_keysetup(pk->pk_data_ctx, key, pk->pk_keybits);
@@ -204,8 +190,8 @@
 	idx = 2;
 	hmac_sha512_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
 	hmac_sha512_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
-	hmac_sha512_update(&ctx->o.pctx_hmac, magic_ctxinfo_name_key,
-	    PEFS_TWEAK_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, magic_keyinfo,
+	    sizeof(magic_keyinfo));
 	hmac_sha512_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
 	hmac_sha512_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
 	pefs_aes_keysetup(pk->pk_name_ctx, key, 128);
@@ -213,12 +199,13 @@
 	idx = 3;
 	hmac_sha512_init(&ctx->o.pctx_hmac, masterkey, PEFS_KEY_SIZE);
 	hmac_sha512_update(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
-	hmac_sha512_update(&ctx->o.pctx_hmac, magic_ctxinfo_name_key,
-	    PEFS_TWEAK_SIZE);
+	hmac_sha512_update(&ctx->o.pctx_hmac, magic_keyinfo,
+	    sizeof(magic_keyinfo));
 	hmac_sha512_update(&ctx->o.pctx_hmac, &idx, sizeof(idx));
 	hmac_sha512_final(&ctx->o.pctx_hmac, key, PEFS_KEY_SIZE);
 	vmac_set_key(key, &pk->pk_name_csum_ctx->o.pctx_vmac);
 
+	bzero(key, PEFS_KEY_SIZE);
 	pefs_ctx_free(ctx);
 
 }
@@ -471,18 +458,35 @@
 pefs_name_checksum(struct pefs_ctx *ctx, struct pefs_key *pk, char *csum,
     char *name, size_t size)
 {
-	CTASSERT(PEFS_NAME_CSUM_SIZE <= sizeof(uint64_t));
+	uint64_t buf[howmany(MAXNAMLEN + 1, sizeof(uint64_t))];
+	uint64_t nonce[2];
 	uint64_t csum_int;
+	char *data;
 
-	MPASS(size > PEFS_NAME_CSUM_SIZE &&
+	MPASS(size >= PEFS_NAME_CSUM_SIZE + (PEFS_TWEAK_SIZE * 2) &&
 	    size <= MAXNAMLEN &&
 	    (size - PEFS_NAME_CSUM_SIZE) % PEFS_NAME_BLOCK_SIZE == 0);
 
+	/*
+	 * First block of encrypted name contains 64bit random tweak.
+	 * Considering AES strong cipher reuse it as a nonce. It's rather far
+	 * from what VMAC specification suggests, but storing additional random
+	 * data in file name is too expensive and decrypting before running vmac
+	 * degrades performance dramatically.
+	 * Use separate key for name checksum.
+	 */
+	memcpy(nonce, name + PEFS_NAME_CSUM_SIZE, PEFS_TWEAK_SIZE * 2);
+	((char *)nonce)[15] &= 0xfe; /* VMAC requirement */
+
+	size -= PEFS_NAME_CSUM_SIZE;
+	data = name + PEFS_NAME_CSUM_SIZE;
+	if (((uintptr_t)data & (__alignof__(uint64_t) - 1)) != 0) {
+		memcpy(buf, data, size);
+		data = (char *)buf;
+	}
+
 	pefs_ctx_cpy(ctx, pk->pk_name_csum_ctx);
-	csum_int = vmac(name + PEFS_NAME_CSUM_SIZE,
-	    size - PEFS_NAME_CSUM_SIZE,
-	    magic_name_csum_nonce,
-	    NULL, &ctx->o.pctx_vmac);
+	csum_int = vmac(data, size, (char *)nonce, NULL, &ctx->o.pctx_vmac);
 	memcpy(csum, &csum_int, PEFS_NAME_CSUM_SIZE);
 }
 
@@ -541,8 +545,6 @@
 pefs_name_encrypt(struct pefs_ctx *ctx, struct pefs_tkey *ptk,
     const char *plain, size_t plain_len, char *enc, size_t enc_size)
 {
-	CTASSERT(MAXNAMLEN >=
-	    PEFS_NAME_PTON_SIZE(MAXNAMLEN) + PEFS_NAME_BLOCK_SIZE);
 	char buf[MAXNAMLEN + 1];
 	size_t size;
 	int free_ctx = 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910221033.n9MAXTLd095895>