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