2019-06-01 11:08:55 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2013-08-14 22:27:36 +04:00
/*
* AppArmor security module
*
* This file contains AppArmor policy loading interface function definitions .
*
* Copyright 2013 Canonical Ltd .
*
* Fns to provide a checksum of policy that has been loaded this can be
* compared to userspace policy compiles to check loaded policy is what
* it should be .
*/
2013-09-29 19:39:21 +04:00
# include <crypto/hash.h>
2013-08-14 22:27:36 +04:00
# include "include/apparmor.h"
# include "include/crypto.h"
static unsigned int apparmor_hash_size ;
2013-09-29 19:39:21 +04:00
static struct crypto_shash * apparmor_tfm ;
2013-08-14 22:27:36 +04:00
unsigned int aa_hash_size ( void )
{
return apparmor_hash_size ;
}
2017-01-16 11:42:55 +03:00
char * aa_calc_hash ( void * data , size_t len )
{
2017-04-06 16:55:21 +03:00
SHASH_DESC_ON_STACK ( desc , apparmor_tfm ) ;
2017-01-16 11:42:55 +03:00
char * hash = NULL ;
int error = - ENOMEM ;
if ( ! apparmor_tfm )
return NULL ;
hash = kzalloc ( apparmor_hash_size , GFP_KERNEL ) ;
if ( ! hash )
goto fail ;
2017-04-06 16:55:21 +03:00
desc - > tfm = apparmor_tfm ;
2017-01-16 11:42:55 +03:00
2017-04-06 16:55:21 +03:00
error = crypto_shash_init ( desc ) ;
2017-01-16 11:42:55 +03:00
if ( error )
goto fail ;
2017-04-06 16:55:21 +03:00
error = crypto_shash_update ( desc , ( u8 * ) data , len ) ;
2017-01-16 11:42:55 +03:00
if ( error )
goto fail ;
2017-04-06 16:55:21 +03:00
error = crypto_shash_final ( desc , hash ) ;
2017-01-16 11:42:55 +03:00
if ( error )
goto fail ;
return hash ;
fail :
kfree ( hash ) ;
return ERR_PTR ( error ) ;
}
2013-08-14 22:27:36 +04:00
int aa_calc_profile_hash ( struct aa_profile * profile , u32 version , void * start ,
size_t len )
{
2017-04-06 16:55:21 +03:00
SHASH_DESC_ON_STACK ( desc , apparmor_tfm ) ;
2013-08-14 22:27:36 +04:00
int error = - ENOMEM ;
2017-01-16 11:42:55 +03:00
__le32 le32_version = cpu_to_le32 ( version ) ;
2013-08-14 22:27:36 +04:00
2016-07-25 20:59:07 +03:00
if ( ! aa_g_hash_policy )
return 0 ;
2013-08-14 22:27:36 +04:00
if ( ! apparmor_tfm )
return 0 ;
profile - > hash = kzalloc ( apparmor_hash_size , GFP_KERNEL ) ;
if ( ! profile - > hash )
goto fail ;
2017-04-06 16:55:21 +03:00
desc - > tfm = apparmor_tfm ;
2013-09-29 19:39:21 +04:00
2017-04-06 16:55:21 +03:00
error = crypto_shash_init ( desc ) ;
2013-08-14 22:27:36 +04:00
if ( error )
goto fail ;
2017-04-06 16:55:21 +03:00
error = crypto_shash_update ( desc , ( u8 * ) & le32_version , 4 ) ;
2013-08-14 22:27:36 +04:00
if ( error )
goto fail ;
2017-04-06 16:55:21 +03:00
error = crypto_shash_update ( desc , ( u8 * ) start , len ) ;
2013-08-14 22:27:36 +04:00
if ( error )
goto fail ;
2017-04-06 16:55:21 +03:00
error = crypto_shash_final ( desc , profile - > hash ) ;
2013-08-14 22:27:36 +04:00
if ( error )
goto fail ;
return 0 ;
fail :
kfree ( profile - > hash ) ;
profile - > hash = NULL ;
return error ;
}
static int __init init_profile_hash ( void )
{
2013-09-29 19:39:21 +04:00
struct crypto_shash * tfm ;
2013-08-14 22:27:36 +04:00
if ( ! apparmor_initialized )
return 0 ;
2018-11-14 23:21:11 +03:00
tfm = crypto_alloc_shash ( " sha1 " , 0 , 0 ) ;
2013-08-14 22:27:36 +04:00
if ( IS_ERR ( tfm ) ) {
int error = PTR_ERR ( tfm ) ;
AA_ERROR ( " failed to setup profile sha1 hashing: %d \n " , error ) ;
return error ;
}
apparmor_tfm = tfm ;
2013-09-29 19:39:21 +04:00
apparmor_hash_size = crypto_shash_digestsize ( apparmor_tfm ) ;
2013-08-14 22:27:36 +04:00
aa_info_message ( " AppArmor sha1 policy hashing enabled " ) ;
return 0 ;
}
late_initcall ( init_profile_hash ) ;