xref: /openbmc/linux/security/apparmor/crypto.c (revision 2891f2d5)
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 	struct {
35 		struct shash_desc shash;
36 		char ctx[crypto_shash_descsize(apparmor_tfm)];
37 	} desc;
38 	char *hash = NULL;
39 	int error = -ENOMEM;
40 
41 	if (!apparmor_tfm)
42 		return NULL;
43 
44 	hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
45 	if (!hash)
46 		goto fail;
47 
48 	desc.shash.tfm = apparmor_tfm;
49 	desc.shash.flags = 0;
50 
51 	error = crypto_shash_init(&desc.shash);
52 	if (error)
53 		goto fail;
54 	error = crypto_shash_update(&desc.shash, (u8 *) data, len);
55 	if (error)
56 		goto fail;
57 	error = crypto_shash_final(&desc.shash, hash);
58 	if (error)
59 		goto fail;
60 
61 	return hash;
62 
63 fail:
64 	kfree(hash);
65 
66 	return ERR_PTR(error);
67 }
68 
69 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
70 			 size_t len)
71 {
72 	struct {
73 		struct shash_desc shash;
74 		char ctx[crypto_shash_descsize(apparmor_tfm)];
75 	} desc;
76 	int error = -ENOMEM;
77 	__le32 le32_version = cpu_to_le32(version);
78 
79 	if (!aa_g_hash_policy)
80 		return 0;
81 
82 	if (!apparmor_tfm)
83 		return 0;
84 
85 	profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
86 	if (!profile->hash)
87 		goto fail;
88 
89 	desc.shash.tfm = apparmor_tfm;
90 	desc.shash.flags = 0;
91 
92 	error = crypto_shash_init(&desc.shash);
93 	if (error)
94 		goto fail;
95 	error = crypto_shash_update(&desc.shash, (u8 *) &le32_version, 4);
96 	if (error)
97 		goto fail;
98 	error = crypto_shash_update(&desc.shash, (u8 *) start, len);
99 	if (error)
100 		goto fail;
101 	error = crypto_shash_final(&desc.shash, profile->hash);
102 	if (error)
103 		goto fail;
104 
105 	return 0;
106 
107 fail:
108 	kfree(profile->hash);
109 	profile->hash = NULL;
110 
111 	return error;
112 }
113 
114 static int __init init_profile_hash(void)
115 {
116 	struct crypto_shash *tfm;
117 
118 	if (!apparmor_initialized)
119 		return 0;
120 
121 	tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC);
122 	if (IS_ERR(tfm)) {
123 		int error = PTR_ERR(tfm);
124 		AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
125 		return error;
126 	}
127 	apparmor_tfm = tfm;
128 	apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);
129 
130 	aa_info_message("AppArmor sha1 policy hashing enabled");
131 
132 	return 0;
133 }
134 
135 late_initcall(init_profile_hash);
136