apparmor: allow introspecting the loaded policy pre internal transform

Store loaded policy and allow introspecting it through apparmorfs. This
has several uses from debugging, policy validation, and policy checkpoint
and restore for containers.

Signed-off-by: John Johansen <john.johansen@canonical.com>
diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c
index b75dab0..de8dc78 100644
--- a/security/apparmor/crypto.c
+++ b/security/apparmor/crypto.c
@@ -29,6 +29,43 @@ unsigned int aa_hash_size(void)
 	return apparmor_hash_size;
 }
 
+char *aa_calc_hash(void *data, size_t len)
+{
+	struct {
+		struct shash_desc shash;
+		char ctx[crypto_shash_descsize(apparmor_tfm)];
+	} desc;
+	char *hash = NULL;
+	int error = -ENOMEM;
+
+	if (!apparmor_tfm)
+		return NULL;
+
+	hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
+	if (!hash)
+		goto fail;
+
+	desc.shash.tfm = apparmor_tfm;
+	desc.shash.flags = 0;
+
+	error = crypto_shash_init(&desc.shash);
+	if (error)
+		goto fail;
+	error = crypto_shash_update(&desc.shash, (u8 *) data, len);
+	if (error)
+		goto fail;
+	error = crypto_shash_final(&desc.shash, hash);
+	if (error)
+		goto fail;
+
+	return hash;
+
+fail:
+	kfree(hash);
+
+	return ERR_PTR(error);
+}
+
 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
 			 size_t len)
 {
@@ -37,7 +74,7 @@ int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
 		char ctx[crypto_shash_descsize(apparmor_tfm)];
 	} desc;
 	int error = -ENOMEM;
-	u32 le32_version = cpu_to_le32(version);
+	__le32 le32_version = cpu_to_le32(version);
 
 	if (!aa_g_hash_policy)
 		return 0;