xref: /openbmc/linux/security/apparmor/crypto.c (revision 6d746795)
1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f8eb8a13SJohn Johansen /*
3f8eb8a13SJohn Johansen  * AppArmor security module
4f8eb8a13SJohn Johansen  *
5f8eb8a13SJohn Johansen  * This file contains AppArmor policy loading interface function definitions.
6f8eb8a13SJohn Johansen  *
7f8eb8a13SJohn Johansen  * Copyright 2013 Canonical Ltd.
8f8eb8a13SJohn Johansen  *
9f8eb8a13SJohn Johansen  * Fns to provide a checksum of policy that has been loaded this can be
10f8eb8a13SJohn Johansen  * compared to userspace policy compiles to check loaded policy is what
11f8eb8a13SJohn Johansen  * it should be.
12f8eb8a13SJohn Johansen  */
13f8eb8a13SJohn Johansen 
1471ac7f62STyler Hicks #include <crypto/hash.h>
15f8eb8a13SJohn Johansen 
16f8eb8a13SJohn Johansen #include "include/apparmor.h"
17f8eb8a13SJohn Johansen #include "include/crypto.h"
18f8eb8a13SJohn Johansen 
19f8eb8a13SJohn Johansen static unsigned int apparmor_hash_size;
20f8eb8a13SJohn Johansen 
2171ac7f62STyler Hicks static struct crypto_shash *apparmor_tfm;
22f8eb8a13SJohn Johansen 
aa_hash_size(void)23f8eb8a13SJohn Johansen unsigned int aa_hash_size(void)
24f8eb8a13SJohn Johansen {
25f8eb8a13SJohn Johansen 	return apparmor_hash_size;
26f8eb8a13SJohn Johansen }
27f8eb8a13SJohn Johansen 
aa_calc_hash(void * data,size_t len)285ac8c355SJohn Johansen char *aa_calc_hash(void *data, size_t len)
295ac8c355SJohn Johansen {
309814448dSNicolas Iooss 	SHASH_DESC_ON_STACK(desc, apparmor_tfm);
31*6d746795SMarkus Elfring 	char *hash;
32*6d746795SMarkus Elfring 	int error;
335ac8c355SJohn Johansen 
345ac8c355SJohn Johansen 	if (!apparmor_tfm)
355ac8c355SJohn Johansen 		return NULL;
365ac8c355SJohn Johansen 
375ac8c355SJohn Johansen 	hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
385ac8c355SJohn Johansen 	if (!hash)
39*6d746795SMarkus Elfring 		return ERR_PTR(-ENOMEM);
405ac8c355SJohn Johansen 
419814448dSNicolas Iooss 	desc->tfm = apparmor_tfm;
425ac8c355SJohn Johansen 
439814448dSNicolas Iooss 	error = crypto_shash_init(desc);
445ac8c355SJohn Johansen 	if (error)
455ac8c355SJohn Johansen 		goto fail;
469814448dSNicolas Iooss 	error = crypto_shash_update(desc, (u8 *) data, len);
475ac8c355SJohn Johansen 	if (error)
485ac8c355SJohn Johansen 		goto fail;
499814448dSNicolas Iooss 	error = crypto_shash_final(desc, hash);
505ac8c355SJohn Johansen 	if (error)
515ac8c355SJohn Johansen 		goto fail;
525ac8c355SJohn Johansen 
535ac8c355SJohn Johansen 	return hash;
545ac8c355SJohn Johansen 
555ac8c355SJohn Johansen fail:
565ac8c355SJohn Johansen 	kfree(hash);
575ac8c355SJohn Johansen 
585ac8c355SJohn Johansen 	return ERR_PTR(error);
595ac8c355SJohn Johansen }
605ac8c355SJohn Johansen 
aa_calc_profile_hash(struct aa_profile * profile,u32 version,void * start,size_t len)61f8eb8a13SJohn Johansen int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
62f8eb8a13SJohn Johansen 			 size_t len)
63f8eb8a13SJohn Johansen {
649814448dSNicolas Iooss 	SHASH_DESC_ON_STACK(desc, apparmor_tfm);
65*6d746795SMarkus Elfring 	int error;
665ac8c355SJohn Johansen 	__le32 le32_version = cpu_to_le32(version);
67f8eb8a13SJohn Johansen 
687616ac70SArnd Bergmann 	if (!aa_g_hash_policy)
697616ac70SArnd Bergmann 		return 0;
707616ac70SArnd Bergmann 
71f8eb8a13SJohn Johansen 	if (!apparmor_tfm)
72f8eb8a13SJohn Johansen 		return 0;
73f8eb8a13SJohn Johansen 
74f8eb8a13SJohn Johansen 	profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
75f8eb8a13SJohn Johansen 	if (!profile->hash)
76*6d746795SMarkus Elfring 		return -ENOMEM;
77f8eb8a13SJohn Johansen 
789814448dSNicolas Iooss 	desc->tfm = apparmor_tfm;
7971ac7f62STyler Hicks 
809814448dSNicolas Iooss 	error = crypto_shash_init(desc);
81f8eb8a13SJohn Johansen 	if (error)
82f8eb8a13SJohn Johansen 		goto fail;
839814448dSNicolas Iooss 	error = crypto_shash_update(desc, (u8 *) &le32_version, 4);
84f8eb8a13SJohn Johansen 	if (error)
85f8eb8a13SJohn Johansen 		goto fail;
869814448dSNicolas Iooss 	error = crypto_shash_update(desc, (u8 *) start, len);
87f8eb8a13SJohn Johansen 	if (error)
88f8eb8a13SJohn Johansen 		goto fail;
899814448dSNicolas Iooss 	error = crypto_shash_final(desc, profile->hash);
90f8eb8a13SJohn Johansen 	if (error)
91f8eb8a13SJohn Johansen 		goto fail;
92f8eb8a13SJohn Johansen 
93f8eb8a13SJohn Johansen 	return 0;
94f8eb8a13SJohn Johansen 
95f8eb8a13SJohn Johansen fail:
96f8eb8a13SJohn Johansen 	kfree(profile->hash);
97f8eb8a13SJohn Johansen 	profile->hash = NULL;
98f8eb8a13SJohn Johansen 
99f8eb8a13SJohn Johansen 	return error;
100f8eb8a13SJohn Johansen }
101f8eb8a13SJohn Johansen 
init_profile_hash(void)102f8eb8a13SJohn Johansen static int __init init_profile_hash(void)
103f8eb8a13SJohn Johansen {
10471ac7f62STyler Hicks 	struct crypto_shash *tfm;
105f8eb8a13SJohn Johansen 
106f8eb8a13SJohn Johansen 	if (!apparmor_initialized)
107f8eb8a13SJohn Johansen 		return 0;
108f8eb8a13SJohn Johansen 
1093d234b33SEric Biggers 	tfm = crypto_alloc_shash("sha1", 0, 0);
110f8eb8a13SJohn Johansen 	if (IS_ERR(tfm)) {
111f8eb8a13SJohn Johansen 		int error = PTR_ERR(tfm);
112f8eb8a13SJohn Johansen 		AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
113f8eb8a13SJohn Johansen 		return error;
114f8eb8a13SJohn Johansen 	}
115f8eb8a13SJohn Johansen 	apparmor_tfm = tfm;
11671ac7f62STyler Hicks 	apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);
117f8eb8a13SJohn Johansen 
118f8eb8a13SJohn Johansen 	aa_info_message("AppArmor sha1 policy hashing enabled");
119f8eb8a13SJohn Johansen 
120f8eb8a13SJohn Johansen 	return 0;
121f8eb8a13SJohn Johansen }
122f8eb8a13SJohn Johansen 
123f8eb8a13SJohn Johansen late_initcall(init_profile_hash);
124