PERFORCE change 169676 for review
Gleb Kurtsou
gk at FreeBSD.org
Thu Oct 22 10:33:30 UTC 2009
http://p4web.freebsd.org/chv.cgi?CH=169676
Change 169676 by gk at 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;
More information about the p4-projects
mailing list