]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
refuse to open vhds for IO if keyhashes don't look right
authorJake Wires <Jake.Wires@citrix.com>
Wed, 1 Sep 2010 21:25:12 +0000 (14:25 -0700)
committerDaniel Stodden <daniel.stodden@citrix.com>
Tue, 30 Aug 2011 12:50:14 +0000 (13:50 +0100)
drivers/block-crypto.c

index 48b786311e264bf7a6b063364618ce4732d0b3be..ec35a3e7b4f0d85abf83d636067fb761d35bcb4f 100644 (file)
 
 static uint8_t key[AES_XTS_PLAIN_KEYSIZE / 8];
 
+int __vhd_util_calculate_keyhash(struct vhd_keyhash *, const uint8_t *, size_t);
+
+static int
+check_key(const uint8_t *key, unsigned int keysize,
+         const struct vhd_keyhash *vhdhash)
+{
+       int err;
+       struct vhd_keyhash keyhash;
+
+       memcpy(keyhash.nonce, vhdhash->nonce, sizeof(keyhash.nonce));
+       err = __vhd_util_calculate_keyhash(&keyhash, key, keysize);
+       if (err) {
+               DPRINTF("failed to calculate keyhash: %d\n", err);
+               goto out;
+       }
+
+       if (memcmp(keyhash.hash, vhdhash->hash, sizeof(keyhash.hash))) {
+               DPRINTF("key has mismatch\n");
+               goto out;
+       }
+
+out:
+       if (err) {
+               DPRINTF("key check failed\n");
+               err = -ENOKEY;
+       }
+       return err;
+}
+
 int
 vhd_open_crypto(vhd_context_t *vhd, const char *_name)
 {
        const char *keydir;
-       char *name, *basename, *keyfile;
+       struct vhd_keyhash keyhash;
+       char *name, *basename, *ext, *keyfile;
        int err, fd = -1;
 
        if (vhd->xts_tfm)
                return 0;
 
+       err = vhd_get_keyhash(vhd, &keyhash);
+       if (err) {
+               DPRINTF("error getting keyhash: %d\n", err);
+               return err;
+       }
+
        keydir = getenv("TAPDISK2_CRYPTO_KEYDIR");
-       if (keydir == NULL)
+       if (keydir == NULL) {
+               if (keyhash.cookie) {
+                       DPRINTF("this vhd requires TAPDISK2_CRYPTO_KEYDIR\n");
+                       return -ENOKEY;
+               }
                return 0;
+       }
 
        name = strdup(_name);
        if (name == NULL)
@@ -70,7 +111,9 @@ vhd_open_crypto(vhd_context_t *vhd, const char *_name)
                basename++;
 
        /* cut off .vhd extension */
-       basename[strlen(basename) - 4] = 0;
+       ext = strstr(basename, ".vhd");
+       if (ext)
+               basename[ext - basename] = 0;
 
        err = asprintf(&keyfile, "%s/%s,aes-xts-plain,%d.key", keydir,
                       basename, AES_XTS_PLAIN_KEYSIZE);
@@ -82,7 +125,14 @@ vhd_open_crypto(vhd_context_t *vhd, const char *_name)
 
        fd = open(keyfile, O_RDONLY);
        if (fd == -1) {
-               err = errno == ENOENT ? 0 : -errno;
+               if (keyhash.cookie)
+                       err = errno;
+               else
+                       err = errno == ENOENT ? 0 : -errno;
+
+               if (err)
+                       DPRINTF("error opening %s: %d\n", keyfile, err);
+
                goto out;
        }
 
@@ -92,12 +142,17 @@ vhd_open_crypto(vhd_context_t *vhd, const char *_name)
                goto out;
        }
 
+       err = check_key(key, sizeof(key), &keyhash);
+       if (err)
+               goto out;
+
        vhd->xts_tfm = xts_aes_setup();
        if (vhd->xts_tfm == NULL) {
                err = -EINVAL;
                goto out;
        }
 
+       DPRINTF("using keyfile %s\n", keyfile);
        xts_setkey(crypto_blkcipher_tfm(vhd->xts_tfm), key, sizeof(key));
        err = 0;