xref: /linux/security/apparmor/crypto.c (revision 2fe05e1139a555ae91f00a812cb9520e7d3022ab)
1 /*
2  * AppArmor security module
3  *
4  * This file contains AppArmor policy loading interface function definitions.
5  *
6  * Copyright 2013 Canonical Ltd.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation, version 2 of the
11  * License.
12  *
13  * Fns to provide a checksum of policy that has been loaded this can be
14  * compared to userspace policy compiles to check loaded policy is what
15  * it should be.
16  */
17 
18 #include <crypto/hash.h>
19 
20 #include "include/apparmor.h"
21 #include "include/crypto.h"
22 
23 static unsigned int apparmor_hash_size;
24 
25 static struct crypto_shash *apparmor_tfm;
26 
27 unsigned int aa_hash_size(void)
28 {
29 	return apparmor_hash_size;
30 }
31 
32 char *aa_calc_hash(void *data, size_t len)
33 {
34 	SHASH_DESC_ON_STACK(desc, apparmor_tfm);
35 	char *hash = NULL;
36 	int error = -ENOMEM;
37 
38 	if (!apparmor_tfm)
39 		return NULL;
40 
41 	hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
42 	if (!hash)
43 		goto fail;
44 
45 	desc->tfm = apparmor_tfm;
46 	desc->flags = 0;
47 
48 	error = crypto_shash_init(desc);
49 	if (error)
50 		goto fail;
51 	error = crypto_shash_update(desc, (u8 *) data, len);
52 	if (error)
53 		goto fail;
54 	error = crypto_shash_final(desc, hash);
55 	if (error)
56 		goto fail;
57 
58 	return hash;
59 
60 fail:
61 	kfree(hash);
62 
63 	return ERR_PTR(error);
64 }
65 
66 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
67 			 size_t len)
68 {
69 	SHASH_DESC_ON_STACK(desc, apparmor_tfm);
70 	int error = -ENOMEM;
71 	__le32 le32_version = cpu_to_le32(version);
72 
73 	if (!aa_g_hash_policy)
74 		return 0;
75 
76 	if (!apparmor_tfm)
77 		return 0;
78 
79 	profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
80 	if (!profile->hash)
81 		goto fail;
82 
83 	desc->tfm = apparmor_tfm;
84 	desc->flags = 0;
85 
86 	error = crypto_shash_init(desc);
87 	if (error)
88 		goto fail;
89 	error = crypto_shash_update(desc, (u8 *) &le32_version, 4);
90 	if (error)
91 		goto fail;
92 	error = crypto_shash_update(desc, (u8 *) start, len);
93 	if (error)
94 		goto fail;
95 	error = crypto_shash_final(desc, profile->hash);
96 	if (error)
97 		goto fail;
98 
99 	return 0;
100 
101 fail:
102 	kfree(profile->hash);
103 	profile->hash = NULL;
104 
105 	return error;
106 }
107 
108 static int __init init_profile_hash(void)
109 {
110 	struct crypto_shash *tfm;
111 
112 	if (!apparmor_initialized)
113 		return 0;
114 
115 	tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC);
116 	if (IS_ERR(tfm)) {
117 		int error = PTR_ERR(tfm);
118 		AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
119 		return error;
120 	}
121 	apparmor_tfm = tfm;
122 	apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);
123 
124 	aa_info_message("AppArmor sha1 policy hashing enabled");
125 
126 	return 0;
127 }
128 
129 late_initcall(init_profile_hash);
130