1b886d83cSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2f381c272SMimi Zohar /*
3f381c272SMimi Zohar * Copyright (C) 2009-2010 IBM Corporation
4f381c272SMimi Zohar *
5f381c272SMimi Zohar * Authors:
6f381c272SMimi Zohar * Mimi Zohar <zohar@us.ibm.com>
7f381c272SMimi Zohar */
8f381c272SMimi Zohar
9555d6d71STushar Sugandhi #ifdef pr_fmt
10555d6d71STushar Sugandhi #undef pr_fmt
11555d6d71STushar Sugandhi #endif
12555d6d71STushar Sugandhi
13555d6d71STushar Sugandhi #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14555d6d71STushar Sugandhi
15f381c272SMimi Zohar #include <linux/types.h>
16f381c272SMimi Zohar #include <linux/integrity.h>
17a24d22b2SEric Biggers #include <crypto/sha1.h>
188c54135eSMimi Zohar #include <crypto/hash.h>
19e0751257SDmitry Kasatkin #include <linux/key.h>
202afd020aSStefan Berger #include <linux/audit.h>
21f381c272SMimi Zohar
2245e2472eSDmitry Kasatkin /* iint action cache flags */
23f578c08eSMimi Zohar #define IMA_MEASURE 0x00000001
24f578c08eSMimi Zohar #define IMA_MEASURED 0x00000002
25f578c08eSMimi Zohar #define IMA_APPRAISE 0x00000004
26f578c08eSMimi Zohar #define IMA_APPRAISED 0x00000008
27f578c08eSMimi Zohar /*#define IMA_COLLECT 0x00000010 do not use this flag */
28f578c08eSMimi Zohar #define IMA_COLLECTED 0x00000020
29f578c08eSMimi Zohar #define IMA_AUDIT 0x00000040
30f578c08eSMimi Zohar #define IMA_AUDITED 0x00000080
31da1b0029SMimi Zohar #define IMA_HASH 0x00000100
32da1b0029SMimi Zohar #define IMA_HASHED 0x00000200
3345e2472eSDmitry Kasatkin
34aae6ccbdSMimi Zohar /* iint policy rule cache flags */
35aae6ccbdSMimi Zohar #define IMA_NONACTION_FLAGS 0xff000000
360d73a552SDmitry Kasatkin #define IMA_DIGSIG_REQUIRED 0x01000000
370d73a552SDmitry Kasatkin #define IMA_PERMIT_DIRECTIO 0x02000000
380d73a552SDmitry Kasatkin #define IMA_NEW_FILE 0x04000000
390d73a552SDmitry Kasatkin #define EVM_IMMUTABLE_DIGSIG 0x08000000
409e67028eSMimi Zohar #define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
419044d627SThiago Jung Bauermann #define IMA_MODSIG_ALLOWED 0x20000000
42273df864SNayna Jain #define IMA_CHECK_BLACKLIST 0x40000000
4354f03916SMimi Zohar #define IMA_VERITY_REQUIRED 0x80000000
4445e2472eSDmitry Kasatkin
45*5b6eac63SRoberto Sassu /* Exclude non-action flags which are not rule-specific. */
46*5b6eac63SRoberto Sassu #define IMA_NONACTION_RULE_FLAGS (IMA_NONACTION_FLAGS & ~IMA_NEW_FILE)
47*5b6eac63SRoberto Sassu
48d79d72e0SMimi Zohar #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
49da1b0029SMimi Zohar IMA_HASH | IMA_APPRAISE_SUBMASK)
50d79d72e0SMimi Zohar #define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED | \
51da1b0029SMimi Zohar IMA_HASHED | IMA_COLLECTED | \
52da1b0029SMimi Zohar IMA_APPRAISED_SUBMASK)
53d79d72e0SMimi Zohar
54d79d72e0SMimi Zohar /* iint subaction appraise cache flags */
55da1b0029SMimi Zohar #define IMA_FILE_APPRAISE 0x00001000
56da1b0029SMimi Zohar #define IMA_FILE_APPRAISED 0x00002000
57da1b0029SMimi Zohar #define IMA_MMAP_APPRAISE 0x00004000
58da1b0029SMimi Zohar #define IMA_MMAP_APPRAISED 0x00008000
59da1b0029SMimi Zohar #define IMA_BPRM_APPRAISE 0x00010000
60da1b0029SMimi Zohar #define IMA_BPRM_APPRAISED 0x00020000
61da1b0029SMimi Zohar #define IMA_READ_APPRAISE 0x00040000
62da1b0029SMimi Zohar #define IMA_READ_APPRAISED 0x00080000
63d906c10dSMatthew Garrett #define IMA_CREDS_APPRAISE 0x00100000
64d906c10dSMatthew Garrett #define IMA_CREDS_APPRAISED 0x00200000
65d79d72e0SMimi Zohar #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
66d906c10dSMatthew Garrett IMA_BPRM_APPRAISE | IMA_READ_APPRAISE | \
67d906c10dSMatthew Garrett IMA_CREDS_APPRAISE)
68d79d72e0SMimi Zohar #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
69d906c10dSMatthew Garrett IMA_BPRM_APPRAISED | IMA_READ_APPRAISED | \
70d906c10dSMatthew Garrett IMA_CREDS_APPRAISED)
71f381c272SMimi Zohar
720d73a552SDmitry Kasatkin /* iint cache atomic_flags */
730d73a552SDmitry Kasatkin #define IMA_CHANGE_XATTR 0
740d73a552SDmitry Kasatkin #define IMA_UPDATE_XATTR 1
750d73a552SDmitry Kasatkin #define IMA_CHANGE_ATTR 2
760d73a552SDmitry Kasatkin #define IMA_DIGSIG 3
770d73a552SDmitry Kasatkin #define IMA_MUST_MEASURE 4
780d73a552SDmitry Kasatkin
796be5cc52SDmitry Kasatkin enum evm_ima_xattr_type {
806be5cc52SDmitry Kasatkin IMA_XATTR_DIGEST = 0x01,
816be5cc52SDmitry Kasatkin EVM_XATTR_HMAC,
826be5cc52SDmitry Kasatkin EVM_IMA_XATTR_DIGSIG,
833ea7a560SDmitry Kasatkin IMA_XATTR_DIGEST_NG,
8450b97748SMatthew Garrett EVM_XATTR_PORTABLE_DIGSIG,
85398c42e2SMimi Zohar IMA_VERITY_DIGSIG,
86a48fda9dSDmitry Kasatkin IMA_XATTR_LAST
876be5cc52SDmitry Kasatkin };
886be5cc52SDmitry Kasatkin
896be5cc52SDmitry Kasatkin struct evm_ima_xattr_data {
906be5cc52SDmitry Kasatkin u8 type;
91650b29dbSThiago Jung Bauermann u8 data[];
92650b29dbSThiago Jung Bauermann } __packed;
93650b29dbSThiago Jung Bauermann
94650b29dbSThiago Jung Bauermann /* Only used in the EVM HMAC code. */
95650b29dbSThiago Jung Bauermann struct evm_xattr {
96650b29dbSThiago Jung Bauermann struct evm_ima_xattr_data data;
976be5cc52SDmitry Kasatkin u8 digest[SHA1_DIGEST_SIZE];
98c7c8bb23SDmitry Kasatkin } __packed;
99c7c8bb23SDmitry Kasatkin
100398c42e2SMimi Zohar #define IMA_MAX_DIGEST_SIZE HASH_MAX_DIGESTSIZE
101c7c8bb23SDmitry Kasatkin
102c7c8bb23SDmitry Kasatkin struct ima_digest_data {
103c7c8bb23SDmitry Kasatkin u8 algo;
104c7c8bb23SDmitry Kasatkin u8 length;
1053ea7a560SDmitry Kasatkin union {
1063ea7a560SDmitry Kasatkin struct {
1073ea7a560SDmitry Kasatkin u8 unused;
108c7c8bb23SDmitry Kasatkin u8 type;
1093ea7a560SDmitry Kasatkin } sha1;
1103ea7a560SDmitry Kasatkin struct {
1113ea7a560SDmitry Kasatkin u8 type;
1123ea7a560SDmitry Kasatkin u8 algo;
1133ea7a560SDmitry Kasatkin } ng;
1143ea7a560SDmitry Kasatkin u8 data[2];
1153ea7a560SDmitry Kasatkin } xattr;
116eb492c62SGustavo A. R. Silva u8 digest[];
117c7c8bb23SDmitry Kasatkin } __packed;
1186be5cc52SDmitry Kasatkin
119d3634d0fSDmitry Kasatkin /*
1208c54135eSMimi Zohar * Instead of wrapping the ima_digest_data struct inside a local structure
1218c54135eSMimi Zohar * with the maximum hash size, define ima_max_digest_data struct.
1228c54135eSMimi Zohar */
1238c54135eSMimi Zohar struct ima_max_digest_data {
1248c54135eSMimi Zohar struct ima_digest_data hdr;
1258c54135eSMimi Zohar u8 digest[HASH_MAX_DIGESTSIZE];
1268c54135eSMimi Zohar } __packed;
1278c54135eSMimi Zohar
1288c54135eSMimi Zohar /*
129398c42e2SMimi Zohar * signature header format v2 - for using with asymmetric keys
130398c42e2SMimi Zohar *
131398c42e2SMimi Zohar * The signature_v2_hdr struct includes a signature format version
132398c42e2SMimi Zohar * to simplify defining new signature formats.
133398c42e2SMimi Zohar *
134398c42e2SMimi Zohar * signature format:
135398c42e2SMimi Zohar * version 2: regular file data hash based signature
136398c42e2SMimi Zohar * version 3: struct ima_file_id data based signature
137d3634d0fSDmitry Kasatkin */
138d3634d0fSDmitry Kasatkin struct signature_v2_hdr {
139b1aaab22SDmitry Kasatkin uint8_t type; /* xattr type */
140d3634d0fSDmitry Kasatkin uint8_t version; /* signature format version */
1414e8ae72aSDavid Howells uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */
142bb543e39SThiago Jung Bauermann __be32 keyid; /* IMA key identifier - not X509/PGP specific */
143bb543e39SThiago Jung Bauermann __be16 sig_size; /* signature size */
144eb492c62SGustavo A. R. Silva uint8_t sig[]; /* signature payload */
145d3634d0fSDmitry Kasatkin } __packed;
146d3634d0fSDmitry Kasatkin
147398c42e2SMimi Zohar /*
148398c42e2SMimi Zohar * IMA signature version 3 disambiguates the data that is signed, by
149398c42e2SMimi Zohar * indirectly signing the hash of the ima_file_id structure data,
150398c42e2SMimi Zohar * containing either the fsverity_descriptor struct digest or, in the
151398c42e2SMimi Zohar * future, the regular IMA file hash.
152398c42e2SMimi Zohar *
153398c42e2SMimi Zohar * (The hash of the ima_file_id structure is only of the portion used.)
154398c42e2SMimi Zohar */
155398c42e2SMimi Zohar struct ima_file_id {
156398c42e2SMimi Zohar __u8 hash_type; /* xattr type [enum evm_ima_xattr_type] */
157398c42e2SMimi Zohar __u8 hash_algorithm; /* Digest algorithm [enum hash_algo] */
158398c42e2SMimi Zohar __u8 hash[HASH_MAX_DIGESTSIZE];
159398c42e2SMimi Zohar } __packed;
160398c42e2SMimi Zohar
161f381c272SMimi Zohar /* integrity data associated with an inode */
162f381c272SMimi Zohar struct integrity_iint_cache {
163f381c272SMimi Zohar struct rb_node rb_node; /* rooted in integrity_iint_tree */
1640d73a552SDmitry Kasatkin struct mutex mutex; /* protects: version, flags, digest */
165f381c272SMimi Zohar struct inode *inode; /* back pointer to inode in question */
166f381c272SMimi Zohar u64 version; /* track inode changes */
167f578c08eSMimi Zohar unsigned long flags;
16896d450bbSEric Richter unsigned long measured_pcrs;
1690d73a552SDmitry Kasatkin unsigned long atomic_flags;
170a3116387SMimi Zohar unsigned long real_ino;
171a3116387SMimi Zohar dev_t real_dev;
172d79d72e0SMimi Zohar enum integrity_status ima_file_status:4;
173d79d72e0SMimi Zohar enum integrity_status ima_mmap_status:4;
174d79d72e0SMimi Zohar enum integrity_status ima_bprm_status:4;
175cf222217SMimi Zohar enum integrity_status ima_read_status:4;
176d906c10dSMatthew Garrett enum integrity_status ima_creds_status:4;
177ee866331SDmitry Kasatkin enum integrity_status evm_status:4;
178a35c3fb6SDmitry Kasatkin struct ima_digest_data *ima_hash;
179f381c272SMimi Zohar };
180f381c272SMimi Zohar
181f381c272SMimi Zohar /* rbtree tree calls to lookup, insert, delete
182f381c272SMimi Zohar * integrity data associated with an inode.
183f381c272SMimi Zohar */
184f381c272SMimi Zohar struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
1854892722eSJames Morris
186e3c4abbfSDmitry Kasatkin int integrity_kernel_read(struct file *file, loff_t offset,
187bb543e39SThiago Jung Bauermann void *addr, unsigned long count);
188bb543e39SThiago Jung Bauermann
1898607c501SDmitry Kasatkin #define INTEGRITY_KEYRING_EVM 0
190f4dc3778SDmitry Kasatkin #define INTEGRITY_KEYRING_IMA 1
191c7f7e58fSThiago Jung Bauermann #define INTEGRITY_KEYRING_PLATFORM 2
192d1996776SEric Snowberg #define INTEGRITY_KEYRING_MACHINE 3
193d1996776SEric Snowberg #define INTEGRITY_KEYRING_MAX 4
1948607c501SDmitry Kasatkin
1950c343af8SMatthew Garrett extern struct dentry *integrity_dir;
1960c343af8SMatthew Garrett
19739b07096SThiago Jung Bauermann struct modsig;
19839b07096SThiago Jung Bauermann
199f1be242cSDmitry Kasatkin #ifdef CONFIG_INTEGRITY_SIGNATURE
2008607c501SDmitry Kasatkin
2018607c501SDmitry Kasatkin int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
2028607c501SDmitry Kasatkin const char *digest, int digestlen);
20339b07096SThiago Jung Bauermann int integrity_modsig_verify(unsigned int id, const struct modsig *modsig);
2048607c501SDmitry Kasatkin
205d16a8585SDmitry Kasatkin int __init integrity_init_keyring(const unsigned int id);
2069d03a721SDmitry Kasatkin int __init integrity_load_x509(const unsigned int id, const char *path);
20760740accSNayna Jain int __init integrity_load_cert(const unsigned int id, const char *source,
208028db3e2SLinus Torvalds const void *data, size_t len, key_perm_t perm);
2098607c501SDmitry Kasatkin #else
2108607c501SDmitry Kasatkin
integrity_digsig_verify(const unsigned int id,const char * sig,int siglen,const char * digest,int digestlen)2118607c501SDmitry Kasatkin static inline int integrity_digsig_verify(const unsigned int id,
2128607c501SDmitry Kasatkin const char *sig, int siglen,
2138607c501SDmitry Kasatkin const char *digest, int digestlen)
2148607c501SDmitry Kasatkin {
2158607c501SDmitry Kasatkin return -EOPNOTSUPP;
2168607c501SDmitry Kasatkin }
2178607c501SDmitry Kasatkin
integrity_modsig_verify(unsigned int id,const struct modsig * modsig)21839b07096SThiago Jung Bauermann static inline int integrity_modsig_verify(unsigned int id,
21939b07096SThiago Jung Bauermann const struct modsig *modsig)
22039b07096SThiago Jung Bauermann {
22139b07096SThiago Jung Bauermann return -EOPNOTSUPP;
22239b07096SThiago Jung Bauermann }
22339b07096SThiago Jung Bauermann
integrity_init_keyring(const unsigned int id)2247d2ce232SMimi Zohar static inline int integrity_init_keyring(const unsigned int id)
2257d2ce232SMimi Zohar {
2267d2ce232SMimi Zohar return 0;
2277d2ce232SMimi Zohar }
22860740accSNayna Jain
integrity_load_cert(const unsigned int id,const char * source,const void * data,size_t len,key_perm_t perm)22960740accSNayna Jain static inline int __init integrity_load_cert(const unsigned int id,
23060740accSNayna Jain const char *source,
23160740accSNayna Jain const void *data, size_t len,
232028db3e2SLinus Torvalds key_perm_t perm)
23360740accSNayna Jain {
23460740accSNayna Jain return 0;
23560740accSNayna Jain }
236f1be242cSDmitry Kasatkin #endif /* CONFIG_INTEGRITY_SIGNATURE */
2378607c501SDmitry Kasatkin
238e0751257SDmitry Kasatkin #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
239e0751257SDmitry Kasatkin int asymmetric_verify(struct key *keyring, const char *sig,
240e0751257SDmitry Kasatkin int siglen, const char *data, int datalen);
241e0751257SDmitry Kasatkin #else
asymmetric_verify(struct key * keyring,const char * sig,int siglen,const char * data,int datalen)242e0751257SDmitry Kasatkin static inline int asymmetric_verify(struct key *keyring, const char *sig,
243e0751257SDmitry Kasatkin int siglen, const char *data, int datalen)
244e0751257SDmitry Kasatkin {
245e0751257SDmitry Kasatkin return -EOPNOTSUPP;
246e0751257SDmitry Kasatkin }
247e0751257SDmitry Kasatkin #endif
248e0751257SDmitry Kasatkin
24939b07096SThiago Jung Bauermann #ifdef CONFIG_IMA_APPRAISE_MODSIG
25039b07096SThiago Jung Bauermann int ima_modsig_verify(struct key *keyring, const struct modsig *modsig);
25139b07096SThiago Jung Bauermann #else
ima_modsig_verify(struct key * keyring,const struct modsig * modsig)25239b07096SThiago Jung Bauermann static inline int ima_modsig_verify(struct key *keyring,
25339b07096SThiago Jung Bauermann const struct modsig *modsig)
25439b07096SThiago Jung Bauermann {
25539b07096SThiago Jung Bauermann return -EOPNOTSUPP;
25639b07096SThiago Jung Bauermann }
25739b07096SThiago Jung Bauermann #endif
25839b07096SThiago Jung Bauermann
259fd5f4e90SDmitry Kasatkin #ifdef CONFIG_IMA_LOAD_X509
260fd5f4e90SDmitry Kasatkin void __init ima_load_x509(void);
261fd5f4e90SDmitry Kasatkin #else
ima_load_x509(void)262fd5f4e90SDmitry Kasatkin static inline void ima_load_x509(void)
263fd5f4e90SDmitry Kasatkin {
264fd5f4e90SDmitry Kasatkin }
265fd5f4e90SDmitry Kasatkin #endif
266fd5f4e90SDmitry Kasatkin
2672ce523ebSDmitry Kasatkin #ifdef CONFIG_EVM_LOAD_X509
2682ce523ebSDmitry Kasatkin void __init evm_load_x509(void);
2692ce523ebSDmitry Kasatkin #else
evm_load_x509(void)2702ce523ebSDmitry Kasatkin static inline void evm_load_x509(void)
2712ce523ebSDmitry Kasatkin {
2722ce523ebSDmitry Kasatkin }
2732ce523ebSDmitry Kasatkin #endif
2742ce523ebSDmitry Kasatkin
275d726d8d7SMimi Zohar #ifdef CONFIG_INTEGRITY_AUDIT
276d726d8d7SMimi Zohar /* declarations */
277d726d8d7SMimi Zohar void integrity_audit_msg(int audit_msgno, struct inode *inode,
278d726d8d7SMimi Zohar const unsigned char *fname, const char *op,
279d726d8d7SMimi Zohar const char *cause, int result, int info);
2802afd020aSStefan Berger
2812f845882SLakshmi Ramasubramanian void integrity_audit_message(int audit_msgno, struct inode *inode,
2822f845882SLakshmi Ramasubramanian const unsigned char *fname, const char *op,
2832f845882SLakshmi Ramasubramanian const char *cause, int result, int info,
2842f845882SLakshmi Ramasubramanian int errno);
2852f845882SLakshmi Ramasubramanian
2862afd020aSStefan Berger static inline struct audit_buffer *
integrity_audit_log_start(struct audit_context * ctx,gfp_t gfp_mask,int type)2872afd020aSStefan Berger integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
2882afd020aSStefan Berger {
2892afd020aSStefan Berger return audit_log_start(ctx, gfp_mask, type);
2902afd020aSStefan Berger }
2912afd020aSStefan Berger
292d726d8d7SMimi Zohar #else
integrity_audit_msg(int audit_msgno,struct inode * inode,const unsigned char * fname,const char * op,const char * cause,int result,int info)293d726d8d7SMimi Zohar static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
294d726d8d7SMimi Zohar const unsigned char *fname,
295d726d8d7SMimi Zohar const char *op, const char *cause,
296d726d8d7SMimi Zohar int result, int info)
297d726d8d7SMimi Zohar {
298d726d8d7SMimi Zohar }
2992afd020aSStefan Berger
integrity_audit_message(int audit_msgno,struct inode * inode,const unsigned char * fname,const char * op,const char * cause,int result,int info,int errno)3002f845882SLakshmi Ramasubramanian static inline void integrity_audit_message(int audit_msgno,
3012f845882SLakshmi Ramasubramanian struct inode *inode,
3022f845882SLakshmi Ramasubramanian const unsigned char *fname,
3032f845882SLakshmi Ramasubramanian const char *op, const char *cause,
3042f845882SLakshmi Ramasubramanian int result, int info, int errno)
3052f845882SLakshmi Ramasubramanian {
3062f845882SLakshmi Ramasubramanian }
3072f845882SLakshmi Ramasubramanian
3082afd020aSStefan Berger static inline struct audit_buffer *
integrity_audit_log_start(struct audit_context * ctx,gfp_t gfp_mask,int type)3092afd020aSStefan Berger integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
3102afd020aSStefan Berger {
3112afd020aSStefan Berger return NULL;
3122afd020aSStefan Berger }
3132afd020aSStefan Berger
314d726d8d7SMimi Zohar #endif
31560740accSNayna Jain
31660740accSNayna Jain #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
31760740accSNayna Jain void __init add_to_platform_keyring(const char *source, const void *data,
31860740accSNayna Jain size_t len);
31960740accSNayna Jain #else
add_to_platform_keyring(const char * source,const void * data,size_t len)32060740accSNayna Jain static inline void __init add_to_platform_keyring(const char *source,
32160740accSNayna Jain const void *data, size_t len)
32260740accSNayna Jain {
32360740accSNayna Jain }
32460740accSNayna Jain #endif
325d1996776SEric Snowberg
326d1996776SEric Snowberg #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
327d1996776SEric Snowberg void __init add_to_machine_keyring(const char *source, const void *data, size_t len);
3284cb1ed94SNayna Jain bool __init imputed_trust_enabled(void);
329d1996776SEric Snowberg #else
add_to_machine_keyring(const char * source,const void * data,size_t len)330d1996776SEric Snowberg static inline void __init add_to_machine_keyring(const char *source,
331d1996776SEric Snowberg const void *data, size_t len)
332d1996776SEric Snowberg {
333d1996776SEric Snowberg }
3344cb1ed94SNayna Jain
imputed_trust_enabled(void)3354cb1ed94SNayna Jain static inline bool __init imputed_trust_enabled(void)
3363d6ae1a5SEric Snowberg {
3373d6ae1a5SEric Snowberg return false;
3383d6ae1a5SEric Snowberg }
339d1996776SEric Snowberg #endif
340