1551 data decryption cross architecture fails in AES_CCM
authorDarren Moffat <darrenm@opensolaris.org>
Mon, 09 Jun 2008 14:58:17 +0100
changeset 13307 3d90d41b6103
parent 13306 f28ab4de4306
child 13308 b11402c5f64b
1551 data decryption cross architecture fails in AES_CCM
usr/src/uts/common/fs/zfs/sha256.c
usr/src/uts/common/fs/zfs/zio.c
usr/src/uts/common/fs/zfs/zio_checksum.c
--- a/usr/src/uts/common/fs/zfs/sha256.c	Sat Jun 07 18:59:39 2008 -0700
+++ b/usr/src/uts/common/fs/zfs/sha256.c	Mon Jun 09 14:58:17 2008 +0100
@@ -80,8 +80,8 @@
 }
 
 /*
- * SHA256 truncated at 128 and stored in the the last two words
- * of the checksum.  The first two words store the MAC.
+ * SHA256 truncated at 128 and stored in the the first two words
+ * of the checksum.  The last two words store the MAC.
  */
 void
 zio_checksum_SHAMAC(const void *buf, uint64_t size, zio_cksum_t *zcp)
@@ -116,6 +116,6 @@
 	(void) crypto_digest(&mech, &ddata, &digest, NULL);
 #endif /* _KERNEL */
 
-	zcp->zc_word[2] = BE_64(tmp.zc_word[0]);
-	zcp->zc_word[3] = BE_64(tmp.zc_word[1]);
+	zcp->zc_word[0] = BE_64(tmp.zc_word[0]);
+	zcp->zc_word[1] = BE_64(tmp.zc_word[1]);
 }
--- a/usr/src/uts/common/fs/zfs/zio.c	Sat Jun 07 18:59:39 2008 -0700
+++ b/usr/src/uts/common/fs/zfs/zio.c	Mon Jun 09 14:58:17 2008 +0100
@@ -1457,7 +1457,7 @@
 	int crypt = zio->io_crypt;
 	int crypt_error;
 	blkptr_t *bp = zio->io_bp;
-	void *mac = NULL;
+	zio_cksum_t *mac = NULL;
 	size_t maclen;
 	void *cbuf;
 	uint64_t cbufsize;
@@ -1490,14 +1490,14 @@
 	 * is needed.  The io_txg is used by some mechansims as input
 	 * into the IV generation routine.
 	 *
-	 * If the algorithm has a mac we store it in the lower part of
-	 * the bp checksum. Note we don't need to pass in the length of
-	 * the mac since it is already checked for in zio_encrypt_data.
+	 * Note we don't need to pass in the length of the mac since 
+	 * it is already checked for in zio_encrypt_data.
 	 * Caller of zio_encrypt_data is responsible for freeing buffers
 	 * including the mac.
 	 */
 	crypt_error = zio_encrypt_data(crypt, zio->io_spa, &zio->io_bookmark,
-	    zio->io_txg, zio->io_data, zio->io_size, &cbuf, &cbufsize, &mac);
+	    zio->io_txg, zio->io_data, zio->io_size, &cbuf, &cbufsize,
+	    (void **)&mac);
 
 	/*
 	 * One possible failure is not having access to the
@@ -1515,13 +1515,15 @@
 		return (ZIO_PIPELINE_STOP);
 	}
 
+	/*
+	 * The mac is stored in the blkptr as the top two words of the checksum.
+	 */
 	maclen = zio_crypt_table[crypt].ci_maclen;
-	if (maclen != 0) {
-		ASSERT3U(maclen, <=, 16);
-		ASSERT3U((uintptr_t)mac, !=, NULL);
-		bcopy(mac, &bp->blk_cksum.zc_word[0], maclen);
-		kmem_free(mac, maclen);
-	}
+	ASSERT3U(maclen, ==, 16);
+	ASSERT3U((uintptr_t)mac, !=, NULL);
+	bp->blk_cksum.zc_word[2] = BE_64(mac->zc_word[0]);
+	bp->blk_cksum.zc_word[3] = BE_64(mac->zc_word[1]);
+	kmem_free(mac, maclen);
 
 	zio_push_transform(zio, cbuf, cbufsize, cbufsize);
 	BP_SET_CRYPT(zio->io_bp, crypt);
@@ -1537,6 +1539,7 @@
 	void *data;
 	uint64_t size;
 	uint64_t bufsize;
+	uint64_t mac[2];
 	int crypt_error;
 
 	if (spa_version(zio->io_spa) < SPA_VERSION_CRYPTO)
@@ -1560,17 +1563,15 @@
 	
 	zio_pop_transform(zio, &data, &size, &bufsize);
 
+	ASSERT3U(16, ==, zio_crypt_table[crypt].ci_maclen);
 	/*
-	 * If the crypt says we have a mac it is stored in the blkptr
-	 * as part of the checksum.
-	 * Pass the checksum data into zio_decrypt_data separate from the real 
-	 * data seems like a good idea, and let it deal with how to pass
-	 * it to the relevant crypto function.
+	 * The mac is stored in the blkptr as the top two words of the checksum.
 	 */
+	mac[0] = BE_64(bp->blk_cksum.zc_word[2]);
+	mac[1] = BE_64(bp->blk_cksum.zc_word[3]);
 
 	crypt_error = zio_decrypt_data(crypt, zio->io_spa, &zio->io_bookmark, 
-	    bp->blk_birth, data, size, &bp->blk_cksum.zc_word[0],
-	    zio->io_data, zio->io_size);
+	    bp->blk_birth, data, size, &mac, zio->io_data, zio->io_size);
 
 	/*
 	 * One possible failure is not having access to the
--- a/usr/src/uts/common/fs/zfs/zio_checksum.c	Sat Jun 07 18:59:39 2008 -0700
+++ b/usr/src/uts/common/fs/zfs/zio_checksum.c	Mon Jun 09 14:58:17 2008 +0100
@@ -165,19 +165,17 @@
 
 
 	/*
-	 * XXX darrenm
 	 * Special case for truncated SHA256 with CCM_MAC
-	 * This may not be the best place to deal with this but it is
-	 * here for now check validate the concept.
+	 * This may not be the best place to deal with this but it is here now.
 	 *
-	 * Words 0 and 1 are the CCM MAC so ignore those because we
+	 * Words 0 and 1 of the checksum are the SHA256 hash.
+	 * Words 2 and 3 are the CCM MAC so ignore those because we
 	 * can't check them until we do the decryption later, nor could
 	 * we do them if the key wasn't present.
-	 * Words 2 and 3 of the checksum are the SHA256 hash
 	 */
 	if (checksum == ZIO_CHECKSUM_SHA256_CCM_MAC) {
-		if (!(0 == ((actual_cksum.zc_word[2] - zc.zc_word[2]) |
-		    (actual_cksum.zc_word[3] - zc.zc_word[3])))) {
+		if (!(0 == ((actual_cksum.zc_word[0] - zc.zc_word[0]) |
+		    (actual_cksum.zc_word[1] - zc.zc_word[1])))) {
 			return (ECKSUM);
 		}
 	} else if (!ZIO_CHECKSUM_EQUAL(actual_cksum, zc)) {