/**
   * security_init - initializes the security framework
   *
   * This should be called early in the kernel initialization sequence.
   */
  int __init security_init(void)
  {
  	printk(KERN_INFO "Security Framework initialized\n");

  	security_fixup_ops(&default_security_ops);
  	security_ops = &default_security_ops;
  	do_security_initcalls();

  	return 0;
  }

  void reset_security_ops(void)
  {
  	security_ops = &default_security_ops;
  }

  /* Save user chosen LSM */
  static int __init choose_lsm(char *str)
  {
  	strncpy(chosen_lsm, str, SECURITY_NAME_MAX);
  	return 1;
  }
  __setup("security=", choose_lsm);

  /**
   * security_module_enable - Load given security module on boot ?
   * @ops: a pointer to the struct security_operations that is to be checked.
   *
   * Each LSM must pass this method before registering its own operations
   * to avoid security registration races. This method may also be used
   * to check if your LSM is currently loaded during kernel initialization.
   *
   * Return true if:
   *	-The passed LSM is the one chosen by user at boot time,
   *	-or the passed LSM is configured as the default and the user did not
   *	 choose an alternate LSM at boot time.
   * Otherwise, return false.
   */
  int __init security_module_enable(struct security_operations *ops)
  {
  	return !strcmp(ops->name, chosen_lsm);
  }

  /**
   * register_security - registers a security framework with the kernel
   * @ops: a pointer to the struct security_options that is to be registered
   *
   * This function allows a security module to register itself with the
   * kernel security subsystem.  Some rudimentary checking is done on the @ops
   * value passed to this function. You'll need to check first if your LSM
   * is allowed to register its @ops by calling security_module_enable(@ops).
   *
   * If there is already a security module registered with the kernel,
   * an error will be returned.  Otherwise %0 is returned on success.
   */
  int __init register_security(struct security_operations *ops)
  {
  	if (verify(ops)) {
  		printk(KERN_DEBUG "%s could not verify "
  		       "security_operations structure.\n", __func__);
  		return -EINVAL;
  	}

  	if (security_ops != &default_security_ops)
  		return -EAGAIN;

  	security_ops = ops;

  	return 0;
  }
  /**
   * crypto_aes_set_key - Set the AES key.
   * @tfm:	The %crypto_tfm that is used in the context.
   * @in_key:	The input key.
   * @key_len:	The size of the key.
   *
   * Returns 0 on success, on failure the %CRYPTO_TFM_RES_BAD_KEY_LEN flag in tfm
   * is set. The function uses crypto_aes_expand_key() to expand the key.
   * &crypto_aes_ctx _must_ be the private data embedded in @tfm which is
   * retrieved with crypto_tfm_ctx().
   */
  int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  		unsigned int key_len)
  {
  	struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  	u32 *flags = &tfm->crt_flags;
  	int ret;

  	ret = crypto_aes_expand_key(ctx, in_key, key_len);
  	if (!ret)
  		return 0;

  	*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  	return -EINVAL;
  }
  EXPORT_SYMBOL_GPL(crypto_aes_set_key);

  /* encrypt a block of text */

  #define f_rn(bo, bi, n, k)	do {				\
  	bo[n] = crypto_ft_tab[0][byte(bi[n], 0)] ^			\
  		crypto_ft_tab[1][byte(bi[(n + 1) & 3], 1)] ^		\
  		crypto_ft_tab[2][byte(bi[(n + 2) & 3], 2)] ^		\
  		crypto_ft_tab[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n);	\
  } while (0)

  #define f_nround(bo, bi, k)	do {\
  	f_rn(bo, bi, 0, k);	\
  	f_rn(bo, bi, 1, k);	\
  	f_rn(bo, bi, 2, k);	\
  	f_rn(bo, bi, 3, k);	\
  	k += 4;			\
  } while (0)

  #define f_rl(bo, bi, n, k)	do {				\
  	bo[n] = crypto_fl_tab[0][byte(bi[n], 0)] ^			\
  		crypto_fl_tab[1][byte(bi[(n + 1) & 3], 1)] ^		\
  		crypto_fl_tab[2][byte(bi[(n + 2) & 3], 2)] ^		\
  		crypto_fl_tab[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n);	\
  } while (0)

  #define f_lround(bo, bi, k)	do {\
  	f_rl(bo, bi, 0, k);	\
  	f_rl(bo, bi, 1, k);	\
  	f_rl(bo, bi, 2, k);	\
  	f_rl(bo, bi, 3, k);	\
  } while (0)

  static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
  {
  	const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  	const __le32 *src = (const __le32 *)in;
  	__le32 *dst = (__le32 *)out;
  	u32 b0[4], b1[4];
  	const u32 *kp = ctx->key_enc + 4;
  	const int key_len = ctx->key_length;

  	b0[0] = le32_to_cpu(src[0]) ^ ctx->key_enc[0];
  	b0[1] = le32_to_cpu(src[1]) ^ ctx->key_enc[1];
  	b0[2] = le32_to_cpu(src[2]) ^ ctx->key_enc[2];
  	b0[3] = le32_to_cpu(src[3]) ^ ctx->key_enc[3];

  	if (key_len > 24) {
  		f_nround(b1, b0, kp);
  		f_nround(b0, b1, kp);
  	}

  	if (key_len > 16) {
  		f_nround(b1, b0, kp);
  		f_nround(b0, b1, kp);
  	}

  	f_nround(b1, b0, kp);
  	f_nround(b0, b1, kp);
  	f_nround(b1, b0, kp);
  	f_nround(b0, b1, kp);
  	f_nround(b1, b0, kp);
  	f_nround(b0, b1, kp);
  	f_nround(b1, b0, kp);
  	f_nround(b0, b1, kp);
  	f_nround(b1, b0, kp);
  	f_lround(b0, b1, kp);

  	dst[0] = cpu_to_le32(b0[0]);
  	dst[1] = cpu_to_le32(b0[1]);
  	dst[2] = cpu_to_le32(b0[2]);
  	dst[3] = cpu_to_le32(b0[3]);
  }
  /*
   * Cryptographic API.
   *
   * SHA-256, as specified in
   * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
   *
   * SHA-256 code by Jean-Luc Cooke .
   *
   * Copyright (c) Jean-Luc Cooke 
   * Copyright (c) Andrew McDonald 
   * Copyright (c) 2002 James Morris 
   * SHA224 Support Copyright 2007 Intel Corporation 
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
   * Software Foundation; either version 2 of the License, or (at your option)
   * any later version.
   *
   */
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 

  static inline u32 Ch(u32 x, u32 y, u32 z)
  {
  	return z ^ (x & (y ^ z));
  }

  static inline u32 Maj(u32 x, u32 y, u32 z)
  {
  	return (x & y) | (z & (x | y));
  }

  #define e0(x)       (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
  #define e1(x)       (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
  #define s0(x)       (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
  #define s1(x)       (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))

  static inline void LOAD_OP(int I, u32 *W, const u8 *input)
  {
  	W[I] = get_unaligned_be32((__u32 *)input + I);
  }

  static inline void BLEND_OP(int I, u32 *W)
  {
  	W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
  }
  static int sha224_init(struct shash_desc *desc)
{
	struct sha256_state *sctx = shash_desc_ctx(desc);
	sctx->state[0] = SHA224_H0;
	sctx->state[1] = SHA224_H1;
	sctx->state[2] = SHA224_H2;
	sctx->state[3] = SHA224_H3;
	sctx->state[4] = SHA224_H4;
	sctx->state[5] = SHA224_H5;
	sctx->state[6] = SHA224_H6;
	sctx->state[7] = SHA224_H7;
	sctx->count = 0;

	return 0;
}

static int sha256_init(struct shash_desc *desc)
{
	struct sha256_state *sctx = shash_desc_ctx(desc);
	sctx->state[0] = SHA256_H0;
	sctx->state[1] = SHA256_H1;
	sctx->state[2] = SHA256_H2;
	sctx->state[3] = SHA256_H3;
	sctx->state[4] = SHA256_H4;
	sctx->state[5] = SHA256_H5;
	sctx->state[6] = SHA256_H6;
	sctx->state[7] = SHA256_H7;
	sctx->count = 0;

	return 0;
}

  #include 
  #include 
  #include 
  #include 

  /* iint action cache flags */
  #define IMA_MEASURE		0x00000001
  #define IMA_MEASURED		0x00000002
  #define IMA_APPRAISE		0x00000004
  #define IMA_APPRAISED		0x00000008
  /*#define IMA_COLLECT		0x00000010  do not use this flag */
  #define IMA_COLLECTED		0x00000020
  #define IMA_AUDIT		0x00000040
  #define IMA_AUDITED		0x00000080

  /* iint cache flags */
  #define IMA_ACTION_FLAGS	0xff000000
  #define IMA_DIGSIG		0x01000000
  #define IMA_DIGSIG_REQUIRED	0x02000000
  #define IMA_PERMIT_DIRECTIO	0x04000000
  #define IMA_NEW_FILE		0x08000000

  #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
  				 IMA_APPRAISE_SUBMASK)
  #define IMA_DONE_MASK		(IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED | \
  				 IMA_COLLECTED | IMA_APPRAISED_SUBMASK)

  /* iint subaction appraise cache flags */
  #define IMA_FILE_APPRAISE	0x00000100
  #define IMA_FILE_APPRAISED	0x00000200
  #define IMA_MMAP_APPRAISE	0x00000400
  #define IMA_MMAP_APPRAISED	0x00000800
  #define IMA_BPRM_APPRAISE	0x00001000
  #define IMA_BPRM_APPRAISED	0x00002000
  #define IMA_MODULE_APPRAISE	0x00004000
  #define IMA_MODULE_APPRAISED	0x00008000
  #define IMA_FIRMWARE_APPRAISE	0x00010000
  #define IMA_FIRMWARE_APPRAISED	0x00020000
  #define IMA_APPRAISE_SUBMASK	(IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
  				 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
  				 IMA_FIRMWARE_APPRAISE)
  #define IMA_APPRAISED_SUBMASK	(IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
  				 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
  				 IMA_FIRMWARE_APPRAISED)

  enum evm_ima_xattr_type {
  	IMA_XATTR_DIGEST = 0x01,
  	EVM_XATTR_HMAC,
  	EVM_IMA_XATTR_DIGSIG,
  	IMA_XATTR_DIGEST_NG,
  	IMA_XATTR_LAST
  };

  struct evm_ima_xattr_data {
  	u8 type;
  	u8 digest[SHA1_DIGEST_SIZE];
  } __packed;

  #define IMA_MAX_DIGEST_SIZE	64

  struct ima_digest_data {
  	u8 algo;
  	u8 length;
  	union {
  		struct {
  			u8 unused;
  			u8 type;
  		} sha1;
  		struct {
  			u8 type;
  			u8 algo;
  		} ng;
  		u8 data[2];
  	} xattr;
  	u8 digest[0];
  } __packed;

  /*
   * signature format v2 - for using with asymmetric keys
   */
  struct signature_v2_hdr {
  	uint8_t type;		/* xattr type */
  	uint8_t version;	/* signature format version */
  	uint8_t	hash_algo;	/* Digest algorithm [enum pkey_hash_algo] */
  	uint32_t keyid;		/* IMA key identifier - not X509/PGP specific */
  	uint16_t sig_size;	/* signature size */
  	uint8_t sig[0];		/* signature payload */
  } __packed;

  /* integrity data associated with an inode */
  struct integrity_iint_cache {
  	struct rb_node rb_node;	/* rooted in integrity_iint_tree */
  	struct inode *inode;	/* back pointer to inode in question */
  	u64 version;		/* track inode changes */
  	unsigned long flags;
  	enum integrity_status ima_file_status:4;
  	enum integrity_status ima_mmap_status:4;
  	enum integrity_status ima_bprm_status:4;
  	enum integrity_status ima_module_status:4;
  	enum integrity_status ima_firmware_status:4;
  	enum integrity_status evm_status:4;
  	struct ima_digest_data *ima_hash;
  };

  /* rbtree tree calls to lookup, insert, delete
   * integrity data associated with an inode.
   */
  struct integrity_iint_cache *integrity_iint_find(struct inode *inode);

  int integrity_kernel_read(struct file *file, loff_t offset,
  			  char *addr, unsigned long count);
  int __init integrity_read_file(const char *path, char **data);

  #define INTEGRITY_KEYRING_EVM		0
  #define INTEGRITY_KEYRING_MODULE	1
  #define INTEGRITY_KEYRING_IMA		2
  #define INTEGRITY_KEYRING_MAX		3

  #ifdef CONFIG_INTEGRITY_SIGNATURE

  int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
  			    const char *digest, int digestlen);

  int __init integrity_init_keyring(const unsigned int id);
  int __init integrity_load_x509(const unsigned int id, char *path);
  #else

  static inline int integrity_digsig_verify(const unsigned int id,
  					  const char *sig, int siglen,
  					  const char *digest, int digestlen)
  {
  	return -EOPNOTSUPP;
  }