Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'libcrypto-conversions-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux

Pull crypto library conversions from Eric Biggers:
"Convert fsverity and apparmor to use the SHA-2 library functions
instead of crypto_shash. This is simpler and also slightly faster"

* tag 'libcrypto-conversions-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux:
fsverity: Switch from crypto_shash to SHA-2 library
fsverity: Explicitly include <linux/export.h>
apparmor: use SHA-256 library API instead of crypto_shash API

+118 -249
+1 -2
Documentation/filesystems/fsverity.rst
··· 185 185 - ``ENOKEY``: the ".fs-verity" keyring doesn't contain the certificate 186 186 needed to verify the builtin signature 187 187 - ``ENOPKG``: fs-verity recognizes the hash algorithm, but it's not 188 - available in the kernel's crypto API as currently configured (e.g. 189 - for SHA-512, missing CONFIG_CRYPTO_SHA512). 188 + available in the kernel as currently configured 190 189 - ``ENOTTY``: this type of filesystem does not implement fs-verity 191 190 - ``EOPNOTSUPP``: the kernel was not configured with fs-verity 192 191 support; or the filesystem superblock has not had the 'verity'
+2 -4
fs/verity/Kconfig
··· 2 2 3 3 config FS_VERITY 4 4 bool "FS Verity (read-only file-based authenticity protection)" 5 - select CRYPTO 6 5 select CRYPTO_HASH_INFO 7 - # SHA-256 is selected as it's intended to be the default hash algorithm. 8 - # To avoid bloat, other wanted algorithms must be selected explicitly. 9 - select CRYPTO_SHA256 6 + select CRYPTO_LIB_SHA256 7 + select CRYPTO_LIB_SHA512 10 8 help 11 9 This option enables fs-verity. fs-verity is the dm-verity 12 10 mechanism implemented at the file level. On supported
+3 -6
fs/verity/enable.c
··· 7 7 8 8 #include "fsverity_private.h" 9 9 10 - #include <crypto/hash.h> 10 + #include <linux/export.h> 11 11 #include <linux/mount.h> 12 12 #include <linux/sched/signal.h> 13 13 #include <linux/uaccess.h> ··· 24 24 struct block_buffer *cur) 25 25 { 26 26 struct block_buffer *next = cur + 1; 27 - int err; 28 27 29 28 /* 30 29 * Safety check to prevent a buffer overflow in case of a filesystem bug ··· 36 37 /* Zero-pad the block if it's shorter than the block size. */ 37 38 memset(&cur->data[cur->filled], 0, params->block_size - cur->filled); 38 39 39 - err = fsverity_hash_block(params, inode, cur->data, 40 - &next->data[next->filled]); 41 - if (err) 42 - return err; 40 + fsverity_hash_block(params, inode, cur->data, 41 + &next->data[next->filled]); 43 42 next->filled += params->digest_size; 44 43 cur->filled = 0; 45 44 return 0;
+15 -9
fs/verity/fsverity_private.h
··· 20 20 21 21 /* A hash algorithm supported by fs-verity */ 22 22 struct fsverity_hash_alg { 23 - struct crypto_shash *tfm; /* hash tfm, allocated on demand */ 24 23 const char *name; /* crypto API name, e.g. sha256 */ 25 24 unsigned int digest_size; /* digest size in bytes, e.g. 32 for SHA-256 */ 26 25 unsigned int block_size; /* block size in bytes, e.g. 64 for SHA-256 */ ··· 30 31 enum hash_algo algo_id; 31 32 }; 32 33 34 + union fsverity_hash_ctx { 35 + struct sha256_ctx sha256; 36 + struct sha512_ctx sha512; 37 + }; 38 + 33 39 /* Merkle tree parameters: hash algorithm, initial hash state, and topology */ 34 40 struct merkle_tree_params { 35 41 const struct fsverity_hash_alg *hash_alg; /* the hash algorithm */ 36 - const u8 *hashstate; /* initial hash state or NULL */ 42 + /* initial hash state if salted, NULL if unsalted */ 43 + const union fsverity_hash_ctx *hashstate; 37 44 unsigned int digest_size; /* same as hash_alg->digest_size */ 38 45 unsigned int block_size; /* size of data and tree blocks */ 39 46 unsigned int hashes_per_block; /* number of hashes per tree block */ ··· 81 76 82 77 /* hash_algs.c */ 83 78 84 - extern struct fsverity_hash_alg fsverity_hash_algs[]; 79 + extern const struct fsverity_hash_alg fsverity_hash_algs[]; 85 80 86 81 const struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode, 87 82 unsigned int num); 88 - const u8 *fsverity_prepare_hash_state(const struct fsverity_hash_alg *alg, 89 - const u8 *salt, size_t salt_size); 90 - int fsverity_hash_block(const struct merkle_tree_params *params, 91 - const struct inode *inode, const void *data, u8 *out); 92 - int fsverity_hash_buffer(const struct fsverity_hash_alg *alg, 93 - const void *data, size_t size, u8 *out); 83 + union fsverity_hash_ctx * 84 + fsverity_prepare_hash_state(const struct fsverity_hash_alg *alg, 85 + const u8 *salt, size_t salt_size); 86 + void fsverity_hash_block(const struct merkle_tree_params *params, 87 + const struct inode *inode, const void *data, u8 *out); 88 + void fsverity_hash_buffer(const struct fsverity_hash_alg *alg, 89 + const void *data, size_t size, u8 *out); 94 90 void __init fsverity_check_hash_algs(void); 95 91 96 92 /* init.c */
+64 -126
fs/verity/hash_algs.c
··· 7 7 8 8 #include "fsverity_private.h" 9 9 10 - #include <crypto/hash.h> 11 - 12 10 /* The hash algorithms supported by fs-verity */ 13 - struct fsverity_hash_alg fsverity_hash_algs[] = { 11 + const struct fsverity_hash_alg fsverity_hash_algs[] = { 14 12 [FS_VERITY_HASH_ALG_SHA256] = { 15 13 .name = "sha256", 16 14 .digest_size = SHA256_DIGEST_SIZE, ··· 23 25 }, 24 26 }; 25 27 26 - static DEFINE_MUTEX(fsverity_hash_alg_init_mutex); 27 - 28 28 /** 29 - * fsverity_get_hash_alg() - validate and prepare a hash algorithm 29 + * fsverity_get_hash_alg() - get a hash algorithm by number 30 30 * @inode: optional inode for logging purposes 31 31 * @num: the hash algorithm number 32 32 * 33 - * Get the struct fsverity_hash_alg for the given hash algorithm number, and 34 - * ensure it has a hash transform ready to go. The hash transforms are 35 - * allocated on-demand so that we don't waste resources unnecessarily, and 36 - * because the crypto modules may be initialized later than fs/verity/. 33 + * Get the struct fsverity_hash_alg for the given hash algorithm number. 37 34 * 38 - * Return: pointer to the hash alg on success, else an ERR_PTR() 35 + * Return: pointer to the hash alg if it's known, otherwise NULL. 39 36 */ 40 37 const struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode, 41 38 unsigned int num) 42 39 { 43 - struct fsverity_hash_alg *alg; 44 - struct crypto_shash *tfm; 45 - int err; 46 - 47 40 if (num >= ARRAY_SIZE(fsverity_hash_algs) || 48 41 !fsverity_hash_algs[num].name) { 49 42 fsverity_warn(inode, "Unknown hash algorithm number: %u", num); 50 - return ERR_PTR(-EINVAL); 43 + return NULL; 51 44 } 52 - alg = &fsverity_hash_algs[num]; 53 - 54 - /* pairs with smp_store_release() below */ 55 - if (likely(smp_load_acquire(&alg->tfm) != NULL)) 56 - return alg; 57 - 58 - mutex_lock(&fsverity_hash_alg_init_mutex); 59 - 60 - if (alg->tfm != NULL) 61 - goto out_unlock; 62 - 63 - tfm = crypto_alloc_shash(alg->name, 0, 0); 64 - if (IS_ERR(tfm)) { 65 - if (PTR_ERR(tfm) == -ENOENT) { 66 - fsverity_warn(inode, 67 - "Missing crypto API support for hash algorithm \"%s\"", 68 - alg->name); 69 - alg = ERR_PTR(-ENOPKG); 70 - goto out_unlock; 71 - } 72 - fsverity_err(inode, 73 - "Error allocating hash algorithm \"%s\": %ld", 74 - alg->name, PTR_ERR(tfm)); 75 - alg = ERR_CAST(tfm); 76 - goto out_unlock; 77 - } 78 - 79 - err = -EINVAL; 80 - if (WARN_ON_ONCE(alg->digest_size != crypto_shash_digestsize(tfm))) 81 - goto err_free_tfm; 82 - if (WARN_ON_ONCE(alg->block_size != crypto_shash_blocksize(tfm))) 83 - goto err_free_tfm; 84 - 85 - pr_info("%s using implementation \"%s\"\n", 86 - alg->name, crypto_shash_driver_name(tfm)); 87 - 88 - /* pairs with smp_load_acquire() above */ 89 - smp_store_release(&alg->tfm, tfm); 90 - goto out_unlock; 91 - 92 - err_free_tfm: 93 - crypto_free_shash(tfm); 94 - alg = ERR_PTR(err); 95 - out_unlock: 96 - mutex_unlock(&fsverity_hash_alg_init_mutex); 97 - return alg; 45 + return &fsverity_hash_algs[num]; 98 46 } 99 47 100 48 /** 101 49 * fsverity_prepare_hash_state() - precompute the initial hash state 102 50 * @alg: hash algorithm 103 51 * @salt: a salt which is to be prepended to all data to be hashed 104 - * @salt_size: salt size in bytes, possibly 0 52 + * @salt_size: salt size in bytes 105 53 * 106 - * Return: NULL if the salt is empty, otherwise the kmalloc()'ed precomputed 107 - * initial hash state on success or an ERR_PTR() on failure. 54 + * Return: the kmalloc()'ed initial hash state, or NULL if out of memory. 108 55 */ 109 - const u8 *fsverity_prepare_hash_state(const struct fsverity_hash_alg *alg, 110 - const u8 *salt, size_t salt_size) 56 + union fsverity_hash_ctx * 57 + fsverity_prepare_hash_state(const struct fsverity_hash_alg *alg, 58 + const u8 *salt, size_t salt_size) 111 59 { 112 - u8 *hashstate = NULL; 113 - SHASH_DESC_ON_STACK(desc, alg->tfm); 114 60 u8 *padded_salt = NULL; 115 61 size_t padded_salt_size; 116 - int err; 117 - 118 - desc->tfm = alg->tfm; 119 - 120 - if (salt_size == 0) 121 - return NULL; 122 - 123 - hashstate = kmalloc(crypto_shash_statesize(alg->tfm), GFP_KERNEL); 124 - if (!hashstate) 125 - return ERR_PTR(-ENOMEM); 62 + union fsverity_hash_ctx ctx; 63 + void *res = NULL; 126 64 127 65 /* 128 66 * Zero-pad the salt to the next multiple of the input size of the hash ··· 69 135 */ 70 136 padded_salt_size = round_up(salt_size, alg->block_size); 71 137 padded_salt = kzalloc(padded_salt_size, GFP_KERNEL); 72 - if (!padded_salt) { 73 - err = -ENOMEM; 74 - goto err_free; 75 - } 138 + if (!padded_salt) 139 + return NULL; 76 140 memcpy(padded_salt, salt, salt_size); 77 - err = crypto_shash_init(desc); 78 - if (err) 79 - goto err_free; 80 141 81 - err = crypto_shash_update(desc, padded_salt, padded_salt_size); 82 - if (err) 83 - goto err_free; 84 - 85 - err = crypto_shash_export(desc, hashstate); 86 - if (err) 87 - goto err_free; 88 - out: 142 + switch (alg->algo_id) { 143 + case HASH_ALGO_SHA256: 144 + sha256_init(&ctx.sha256); 145 + sha256_update(&ctx.sha256, padded_salt, padded_salt_size); 146 + res = kmemdup(&ctx.sha256, sizeof(ctx.sha256), GFP_KERNEL); 147 + break; 148 + case HASH_ALGO_SHA512: 149 + sha512_init(&ctx.sha512); 150 + sha512_update(&ctx.sha512, padded_salt, padded_salt_size); 151 + res = kmemdup(&ctx.sha512, sizeof(ctx.sha512), GFP_KERNEL); 152 + break; 153 + default: 154 + WARN_ON_ONCE(1); 155 + } 89 156 kfree(padded_salt); 90 - return hashstate; 91 - 92 - err_free: 93 - kfree(hashstate); 94 - hashstate = ERR_PTR(err); 95 - goto out; 157 + return res; 96 158 } 97 159 98 160 /** ··· 100 170 * 101 171 * Hash a single data or hash block. The hash is salted if a salt is specified 102 172 * in the Merkle tree parameters. 103 - * 104 - * Return: 0 on success, -errno on failure 105 173 */ 106 - int fsverity_hash_block(const struct merkle_tree_params *params, 107 - const struct inode *inode, const void *data, u8 *out) 174 + void fsverity_hash_block(const struct merkle_tree_params *params, 175 + const struct inode *inode, const void *data, u8 *out) 108 176 { 109 - SHASH_DESC_ON_STACK(desc, params->hash_alg->tfm); 110 - int err; 177 + union fsverity_hash_ctx ctx; 111 178 112 - desc->tfm = params->hash_alg->tfm; 113 - 114 - if (params->hashstate) { 115 - err = crypto_shash_import(desc, params->hashstate); 116 - if (err) { 117 - fsverity_err(inode, 118 - "Error %d importing hash state", err); 119 - return err; 120 - } 121 - err = crypto_shash_finup(desc, data, params->block_size, out); 122 - } else { 123 - err = crypto_shash_digest(desc, data, params->block_size, out); 179 + if (!params->hashstate) { 180 + fsverity_hash_buffer(params->hash_alg, data, params->block_size, 181 + out); 182 + return; 124 183 } 125 - if (err) 126 - fsverity_err(inode, "Error %d computing block hash", err); 127 - return err; 184 + 185 + switch (params->hash_alg->algo_id) { 186 + case HASH_ALGO_SHA256: 187 + ctx.sha256 = params->hashstate->sha256; 188 + sha256_update(&ctx.sha256, data, params->block_size); 189 + sha256_final(&ctx.sha256, out); 190 + return; 191 + case HASH_ALGO_SHA512: 192 + ctx.sha512 = params->hashstate->sha512; 193 + sha512_update(&ctx.sha512, data, params->block_size); 194 + sha512_final(&ctx.sha512, out); 195 + return; 196 + default: 197 + BUG(); 198 + } 128 199 } 129 200 130 201 /** ··· 134 203 * @data: the data to hash 135 204 * @size: size of data to hash, in bytes 136 205 * @out: output digest, size 'alg->digest_size' bytes 137 - * 138 - * Return: 0 on success, -errno on failure 139 206 */ 140 - int fsverity_hash_buffer(const struct fsverity_hash_alg *alg, 141 - const void *data, size_t size, u8 *out) 207 + void fsverity_hash_buffer(const struct fsverity_hash_alg *alg, 208 + const void *data, size_t size, u8 *out) 142 209 { 143 - return crypto_shash_tfm_digest(alg->tfm, data, size, out); 210 + switch (alg->algo_id) { 211 + case HASH_ALGO_SHA256: 212 + sha256(data, size, out); 213 + return; 214 + case HASH_ALGO_SHA512: 215 + sha512(data, size, out); 216 + return; 217 + default: 218 + BUG(); 219 + } 144 220 } 145 221 146 222 void __init fsverity_check_hash_algs(void)
+1
fs/verity/measure.c
··· 9 9 10 10 #include <linux/bpf.h> 11 11 #include <linux/btf.h> 12 + #include <linux/export.h> 12 13 #include <linux/uaccess.h> 13 14 14 15 /**
+15 -22
fs/verity/open.c
··· 7 7 8 8 #include "fsverity_private.h" 9 9 10 + #include <linux/export.h> 10 11 #include <linux/mm.h> 11 12 #include <linux/slab.h> 12 13 ··· 43 42 memset(params, 0, sizeof(*params)); 44 43 45 44 hash_alg = fsverity_get_hash_alg(inode, hash_algorithm); 46 - if (IS_ERR(hash_alg)) 47 - return PTR_ERR(hash_alg); 45 + if (!hash_alg) 46 + return -EINVAL; 48 47 params->hash_alg = hash_alg; 49 48 params->digest_size = hash_alg->digest_size; 50 49 51 - params->hashstate = fsverity_prepare_hash_state(hash_alg, salt, 52 - salt_size); 53 - if (IS_ERR(params->hashstate)) { 54 - err = PTR_ERR(params->hashstate); 55 - params->hashstate = NULL; 56 - fsverity_err(inode, "Error %d preparing hash state", err); 57 - goto out_err; 50 + if (salt_size) { 51 + params->hashstate = 52 + fsverity_prepare_hash_state(hash_alg, salt, salt_size); 53 + if (!params->hashstate) { 54 + err = -ENOMEM; 55 + goto out_err; 56 + } 58 57 } 59 58 60 59 /* ··· 159 158 * Compute the file digest by hashing the fsverity_descriptor excluding the 160 159 * builtin signature and with the sig_size field set to 0. 161 160 */ 162 - static int compute_file_digest(const struct fsverity_hash_alg *hash_alg, 163 - struct fsverity_descriptor *desc, 164 - u8 *file_digest) 161 + static void compute_file_digest(const struct fsverity_hash_alg *hash_alg, 162 + struct fsverity_descriptor *desc, 163 + u8 *file_digest) 165 164 { 166 165 __le32 sig_size = desc->sig_size; 167 - int err; 168 166 169 167 desc->sig_size = 0; 170 - err = fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), file_digest); 168 + fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), file_digest); 171 169 desc->sig_size = sig_size; 172 - 173 - return err; 174 170 } 175 171 176 172 /* ··· 199 201 200 202 memcpy(vi->root_hash, desc->root_hash, vi->tree_params.digest_size); 201 203 202 - err = compute_file_digest(vi->tree_params.hash_alg, desc, 203 - vi->file_digest); 204 - if (err) { 205 - fsverity_err(inode, "Error %d computing file digest", err); 206 - goto fail; 207 - } 204 + compute_file_digest(vi->tree_params.hash_alg, desc, vi->file_digest); 208 205 209 206 err = fsverity_verify_signature(vi, desc->signature, 210 207 le32_to_cpu(desc->sig_size));
+1
fs/verity/read_metadata.c
··· 8 8 #include "fsverity_private.h" 9 9 10 10 #include <linux/backing-dev.h> 11 + #include <linux/export.h> 11 12 #include <linux/highmem.h> 12 13 #include <linux/sched/signal.h> 13 14 #include <linux/uaccess.h>
+3 -5
fs/verity/verify.c
··· 7 7 8 8 #include "fsverity_private.h" 9 9 10 - #include <crypto/hash.h> 11 10 #include <linux/bio.h> 11 + #include <linux/export.h> 12 12 13 13 static struct workqueue_struct *fsverity_read_workqueue; 14 14 ··· 202 202 unsigned long hblock_idx = hblocks[level - 1].index; 203 203 unsigned int hoffset = hblocks[level - 1].hoffset; 204 204 205 - if (fsverity_hash_block(params, inode, haddr, real_hash) != 0) 206 - goto error; 205 + fsverity_hash_block(params, inode, haddr, real_hash); 207 206 if (memcmp(want_hash, real_hash, hsize) != 0) 208 207 goto corrupted; 209 208 /* ··· 221 222 } 222 223 223 224 /* Finally, verify the data block. */ 224 - if (fsverity_hash_block(params, inode, data, real_hash) != 0) 225 - goto error; 225 + fsverity_hash_block(params, inode, data, real_hash); 226 226 if (memcmp(want_hash, real_hash, hsize) != 0) 227 227 goto corrupted; 228 228 return true;
+1 -2
security/apparmor/Kconfig
··· 59 59 config SECURITY_APPARMOR_HASH 60 60 bool "Enable introspection of sha256 hashes for loaded profiles" 61 61 depends on SECURITY_APPARMOR_INTROSPECT_POLICY 62 - select CRYPTO 63 - select CRYPTO_SHA256 62 + select CRYPTO_LIB_SHA256 64 63 default y 65 64 help 66 65 This option selects whether introspection of loaded policy
+12 -73
security/apparmor/crypto.c
··· 11 11 * it should be. 12 12 */ 13 13 14 - #include <crypto/hash.h> 14 + #include <crypto/sha2.h> 15 15 16 16 #include "include/apparmor.h" 17 17 #include "include/crypto.h" 18 18 19 - static unsigned int apparmor_hash_size; 20 - 21 - static struct crypto_shash *apparmor_tfm; 22 - 23 19 unsigned int aa_hash_size(void) 24 20 { 25 - return apparmor_hash_size; 21 + return SHA256_DIGEST_SIZE; 26 22 } 27 23 28 24 char *aa_calc_hash(void *data, size_t len) 29 25 { 30 - SHASH_DESC_ON_STACK(desc, apparmor_tfm); 31 26 char *hash; 32 - int error; 33 27 34 - if (!apparmor_tfm) 35 - return NULL; 36 - 37 - hash = kzalloc(apparmor_hash_size, GFP_KERNEL); 28 + hash = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL); 38 29 if (!hash) 39 30 return ERR_PTR(-ENOMEM); 40 31 41 - desc->tfm = apparmor_tfm; 42 - 43 - error = crypto_shash_init(desc); 44 - if (error) 45 - goto fail; 46 - error = crypto_shash_update(desc, (u8 *) data, len); 47 - if (error) 48 - goto fail; 49 - error = crypto_shash_final(desc, hash); 50 - if (error) 51 - goto fail; 52 - 32 + sha256(data, len, hash); 53 33 return hash; 54 - 55 - fail: 56 - kfree(hash); 57 - 58 - return ERR_PTR(error); 59 34 } 60 35 61 36 int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start, 62 37 size_t len) 63 38 { 64 - SHASH_DESC_ON_STACK(desc, apparmor_tfm); 65 - int error; 39 + struct sha256_ctx sctx; 66 40 __le32 le32_version = cpu_to_le32(version); 67 41 68 42 if (!aa_g_hash_policy) 69 43 return 0; 70 44 71 - if (!apparmor_tfm) 72 - return 0; 73 - 74 - profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL); 45 + profile->hash = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL); 75 46 if (!profile->hash) 76 47 return -ENOMEM; 77 48 78 - desc->tfm = apparmor_tfm; 79 - 80 - error = crypto_shash_init(desc); 81 - if (error) 82 - goto fail; 83 - error = crypto_shash_update(desc, (u8 *) &le32_version, 4); 84 - if (error) 85 - goto fail; 86 - error = crypto_shash_update(desc, (u8 *) start, len); 87 - if (error) 88 - goto fail; 89 - error = crypto_shash_final(desc, profile->hash); 90 - if (error) 91 - goto fail; 92 - 49 + sha256_init(&sctx); 50 + sha256_update(&sctx, (u8 *)&le32_version, 4); 51 + sha256_update(&sctx, (u8 *)start, len); 52 + sha256_final(&sctx, profile->hash); 93 53 return 0; 94 - 95 - fail: 96 - kfree(profile->hash); 97 - profile->hash = NULL; 98 - 99 - return error; 100 54 } 101 55 102 56 static int __init init_profile_hash(void) 103 57 { 104 - struct crypto_shash *tfm; 105 - 106 - if (!apparmor_initialized) 107 - return 0; 108 - 109 - tfm = crypto_alloc_shash("sha256", 0, 0); 110 - if (IS_ERR(tfm)) { 111 - int error = PTR_ERR(tfm); 112 - AA_ERROR("failed to setup profile sha256 hashing: %d\n", error); 113 - return error; 114 - } 115 - apparmor_tfm = tfm; 116 - apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm); 117 - 118 - aa_info_message("AppArmor sha256 policy hashing enabled"); 119 - 58 + if (apparmor_initialized) 59 + aa_info_message("AppArmor sha256 policy hashing enabled"); 120 60 return 0; 121 61 } 122 - 123 62 late_initcall(init_profile_hash);