[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[patch RFC]: userspace crypto auditing, v2



Hello,
I'm posting these patches for early review again; users of the code are not in the kernel yet.

Changes since the previous version:
- New record type CRYPTO_AUDIT_CRYPTO_KEY_VALUE, to implement "basic" level from CC
- aureport handles events with multiple crypto records

Record types
------------
This patch set keeps the original single AUDIT_CRYPTO_USERSPACE_OP record type.  Here is a description of all kinds of events that can happen, to facilitate discussion of the requested record types.

The following events cause creation of a CRYPTO_USERSPACE_OP record:
* context_new: A new "crypto context" (within which integer IDs are allocated) was
  set up.
  Fields: context ID
* context_del: A crypto context was destroyed.
  Fields: context ID
* key_wrap: A key was wrapped using another key
  Fields: context ID, wrapping algorithm name, [wrapping key], wrapped key
  If wrapping key is not explicitly recorded, it is the storage master key
* key_unwrap: A key was unwrapped using another key
  Fields: context ID, wrapping algorithm name, [wrapping key], wrapped key
  If wrapping key is not explicitly recorded, it is the storage master key
* key_export: Key material was written to userspace
  Fields: context ID, key algorithm, key
* key_import: Key material was read from userspace
  Fields: context ID, key algorithm, key
* key_zeroize: Key object was cleared
  Fields: context ID, key algorithm, key
  CRYPTO_KEY_VALUE record may follow
* key_gen: A key or key pair was generated
  Fields: context ID, key algorithm, key, [public key]
  One or two CRYPTO_KEY_VALUE records may follow
* key_get_info: Information about a key was provided to userspace
  Fields: context ID, key algorithm, key
* key_derive: A new key was derived from an existing key
  Fields: context ID, key algorithm, source key, new key
* session_init: A new crypto operation context was created
  Fields: context ID, [session ID], operation name, algorithm, [key]
  session ID is missing for sessions that do not span more than one system call
* session_op: An operation within a session was performed
  Fields: context ID, [session ID], operation name, algorithm, [input key]
* session_final: A session was finished
  Fields: context ID, [session ID], operation name, algorithm

In all of the above, "key" in Fields means "integer key ID, longer-term ID byte string".

Looking at the record types proposed earlier, AUDIT_CRYPTO_STORAGE_KEY could perhaps use AUDIT_CRYPTO_PARAM_CHANGE_KERN, and all of the key_* events above can use AUDIT_CRYPTO_KEY_KERN.  There is no good match for the session_* events.

I also think the KEY_VALUE data should use separate records to allow filtering them out while keeping the rest of the information - see below for rationale.

Patch description
-----------------
Three new records are defined; in each case output of records is caused by a syscall, and all other syscall-related data (process identity, syscall result) is audited in the usual records.

AUDIT_CRYPTO_STORAGE_KEY is used when a system-wide storage wrapping key is changed.

AUDIT_CRYPTO_USERSPACE_OP is used when any user-space program performs a crypto operation.  To disable auditing these records by default and to allow the users to selectively enable them using filters, a new filter field AUDIT_CRYPTO_OP is defined; auditing of all crypto operations can thus be enabled using (auditctl -a exit,always -F crypto_op!=0).

AUDIT_CRYPTO_KEY_VALUE is used to record public key components when generating or zeroizing keys (as required for CC "basic" level auditing).  The CRYPTO_KEY_VALUE record always immediately follows a CRYPTO_USERPACE_OP record that describes the performed operation.  Unfortunately the key components can be quite large (a 4096-bit value results in a 1kB field in the record), but there does not seem to be any way to avoid this.  It would probably be possible, as an optimization, to skip creating these records if the *_KEY_VALUE type is filtered out (-a type,never).

Attached for review are:
- A kernel patch
- An userspace audit patch
- A few example audit entries
    Mirek
type=SYSCALL msg=audit(1283346629.795:12190): arch=c000003e syscall=2 success=yes exit=3 a0=400b57 a1=2 a2=0 a3=7fffe965cd20 items=1 ppid=1269 pid=1338 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr-setkey" exe="/home/mitr/cryptodev-linux/userspace/ncr-setkey" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346629.795:12190): crypto_op=context_new ctx=0
type=CWD msg=audit(1283346629.795:12190):  cwd="/root"
type=PATH msg=audit(1283346629.795:12190): item=0 name="/dev/crypto" inode=10233 dev=00:05 mode=020660 ouid=0 ogid=0 rdev=0a:3a obj=system_u:object_r:device_t:s0

type=CRYPTO_STORAGE_KEY msg=audit(1283346629.801:12191): key_size=16
type=SYSCALL msg=audit(1283346629.801:12191): arch=c000003e syscall=16 success=yes exit=128 a0=3 a1=c01863ca a2=7fffe965d050 a3=7fffe965cd20 items=0 ppid=1269 pid=1338 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr-setkey" exe="/home/mitr/cryptodev-linux/userspace/ncr-setkey" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)

type=SYSCALL msg=audit(1283346632.358:12194): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=c02063c6 a2=7fffdbccc770 a3=7fffdbccb470 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.358:12194): crypto_op=key_zeroize ctx=0 algo=unknown key1=0
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.358:12194): crypto_op=key_import ctx=0 algo=cbc(aes) key1=0 key1_id="ab"

type=SYSCALL msg=audit(1283346632.360:12195): arch=c000003e syscall=16 success=yes exit=16 a0=3 a1=c02063c5 a2=7fffdbccc7f0 a3=7fffdbccb470 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.360:12195): crypto_op=key_export ctx=0 algo=cbc(aes) key1=0 key1_id="ab"

type=SYSCALL msg=audit(1283346632.361:12196): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=400463c7 a2=7fffdbccc83c a3=7fffdbccb470 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.361:12196): crypto_op=key_zeroize ctx=0 algo=cbc(aes) key1=0 key1_id="ab"

auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.363:12199): crypto_op=key_get_info ctx=0 algo=cbc(aes) key1=0 key1_id=24C7891E08

type=SYSCALL msg=audit(1283346632.364:12201): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=c00c63c1 a2=7fffdbccc7c0 a3=6c626174726f7078 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.364:12201): crypto_op=key_zeroize ctx=0 algo=unknown key1=0
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.364:12201): crypto_op=key_gen ctx=0 algo=cbc(aes) key1=0 key1_id=7576127E2F

type=SYSCALL msg=audit(1283346632.367:12205): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=c00c63d3 a2=7fffdbccc8a0 a3=6c626174726f7078 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.367:12205): crypto_op=session_init ctx=0 operation=encrypt algo=ecb(aes) key1=0 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.367:12205): crypto_op=session_op ctx=0 operation=encrypt algo=ecb(aes)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.367:12205): crypto_op=session_final ctx=0 operation=encrypt algo=ecb(aes)

type=SYSCALL msg=audit(1283346632.788:12240): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=c00c63d0 a2=7fffdbccc6a0 a3=fffffff7 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.788:12240): crypto_op=session_init ctx=0 session=0 operation=sign algo=hmac(md5) key1=2 key1_id="ab"

type=SYSCALL msg=audit(1283346632.789:12241): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=c00c63d1 a2=7fffdbccc810 a3=fffffff7 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.789:12241): crypto_op=session_op ctx=0 session=0 operation=sign algo=hmac(md5)

type=SYSCALL msg=audit(1283346632.789:12243): arch=c000003e syscall=16 success=yes exit=0 a0=3 a1=c00c63d2 a2=7fffdbccc7d0 a3=fffffff7 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.789:12243): crypto_op=session_op ctx=0 session=0 operation=sign algo=hmac(md5)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.789:12243): crypto_op=session_final ctx=0 session=0 operation=sign algo=hmac(md5)

type=SYSCALL msg=audit(1283346632.906:12282): arch=c000003e syscall=3 success=yes exit=0 a0=3 a1=7fffdbccb7b0 a2=7fffdbccc800 a3=7fffdbccc600 items=0 ppid=1269 pid=1339 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="ncr" exe="/home/mitr/cryptodev-linux/examples/ncr" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=context_del ctx=0
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=cbc(aes) key1=0 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=hmac(sha512) key1=1 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=hmac(sha512) key1=2 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=sha1 key1=3 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=cbc(aes) key1=4 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=unknown key1=5
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=cbc(aes) key1=6 key1_id="ab"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=cbc(aes) key1=7 key1_id="ba"
type=CRYPTO_USERSPACE_OP msg=audit(1283346632.906:12282): crypto_op=key_zeroize ctx=0 algo=cbc(aes) key1=8 key1_id="ba"

type=SYSCALL msg=audit(1283346634.776:12284): arch=c000003e syscall=16 success=yes exit=0 a0=4 a1=c01063c2 a2=7fffd049ffd0 a3=e30453144833da9a items=0 ppid=1269 pid=1391 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="pk" exe="/home/mitr/cryptodev-linux/examples/pk" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346634.776:12284): crypto_op=key_zeroize ctx=0 algo=unknown key1=1
type=CRYPTO_USERSPACE_OP msg=audit(1283346634.776:12284): crypto_op=key_zeroize ctx=0 algo=unknown key1=0
type=CRYPTO_USERSPACE_OP msg=audit(1283346634.776:12284): crypto_op=key_gen ctx=0 algo=dh key1=0 key1_id=A6684BA1930FC2E3C01130B1B57B4AE3F2E6BF24 key2=1 key2_id=A6684BA1930FC2E3C01130B1B57B4AE3F2E6BF24
type=CRYPTO_KEY_VALUE msg=audit(1283346634.776:12284):  key_value_y=5F63A9814BA2F475B4689D18A434267F9237FEA120CD93BAE457A5FBE2CAEE4F19931C0C5FC954976A819AAA7AEED6969B6D8670B283722183FA8DE7A03BD4B21CD2349CF76E0ADF3E0EFD0C9459FBC0F98DE57ED700D22741D86AB862F582AED2EAC18682A3AA8B56FA5910915C65725CEF2A88624FE464887A4474E1D144D5

# The CRYPTO_KEY_VALUE record is really painful
type=SYSCALL msg=audit(1283346655.629:12322): arch=c000003e syscall=16 success=yes exit=0 a0=4 a1=c02063c9 a2=7fffd04a1790 a3=7fffd04a04a0 items=0 ppid=1269 pid=1391 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty1 ses=1 comm="pk" exe="/home/mitr/cryptodev-linux/examples/pk" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CRYPTO_USERSPACE_OP msg=audit(1283346655.629:12322): crypto_op=key_zeroize ctx=0 algo=rsa key1=10 key1_id=54C47EB2B69755DBFA4B3EE1B6477BD316C1B9FE
type=CRYPTO_KEY_VALUE msg=audit(1283346655.629:12322):  key_value_n=A4CDA49AE5E13334D306DAE4A9F07BB5CFDF8E5FDB4F5F49BD0FA04A78999AC9073CC8FFFAE4E9465F5F0615960B1E5DD7009D008749E884C9700011F0D3B51FA72D2B330A843822E3060299C63762575062BEE4B8574E999C1B341924F269003AA652587359A9A9C9D243D8C3862B864537A5FB54085891A6D76C17CF9AC192DC6D67EAB6B097BEB5C9C4F70F0E85273D81D611A0FA8F647CB5D1E9A6A2043C519E1E2C19C93F695490122A9E09FA3AC00B903C1F6FE524E6CF8065E96E2CF416088288EA15DEE093998AA39F17A50FCF2C5244D5BE53A9227C88CA8964223BF808325D76D9CF361ED7B9A82C04A282BA87E7346316B2DA2A756D5CDF1B6687A0AF414E3D27BC12E426778F05F26A46A9BE68F3AA5A8B7F6ADD8DAEA142426A0DD44084D26E2FD933B39C365EC1C1E6C9561F3AADB935F12FDBA223A2FA3A48D51EF643B3656ADCFD45658FE920437368C4BDEEFEEB1E9BF6BE4F07C5BD0847C9D93518D193757F611E9B2AD31A9EBC9F73BC10E83E4EEB850B29858EC61707520C89B1F8D0050DBAEFB2E42418BB2409B79D4A39E7 key_value_e=010001

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 3c7a358..081fbb0 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -122,6 +122,11 @@
 #define AUDIT_MAC_UNLBL_STCADD	1416	/* NetLabel: add a static label */
 #define AUDIT_MAC_UNLBL_STCDEL	1417	/* NetLabel: del a static label */
 
+#define AUDIT_CRYPTO_STORAGE_KEY    1600 /* Key storage key configured */
+#define AUDIT_CRYPTO_USERSPACE_OP   1601 /* User-space crypto operation */
+#define AUDIT_CRYPTO_KEY_VALUE      1602 /* Public values of a key, immediatelly
+					    follows USERSPACE_OP. */
+
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
 #define AUDIT_ANOM_PROMISCUOUS      1700 /* Device changed promiscuous mode */
@@ -207,6 +212,7 @@
 #define AUDIT_OBJ_TYPE	21
 #define AUDIT_OBJ_LEV_LOW	22
 #define AUDIT_OBJ_LEV_HIGH	23
+#define AUDIT_CRYPTO_OP	24
 
 				/* These are ONLY useful when checking
 				 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -314,6 +320,20 @@ enum {
 #define AUDIT_PERM_READ		4
 #define AUDIT_PERM_ATTR		8
 
+#define AUDIT_CRYPTO_OP_CONTEXT_NEW	1
+#define AUDIT_CRYPTO_OP_CONTEXT_DEL	2
+#define AUDIT_CRYPTO_OP_SESSION_INIT	3
+#define AUDIT_CRYPTO_OP_SESSION_OP	4
+#define AUDIT_CRYPTO_OP_SESSION_FINAL	5
+#define AUDIT_CRYPTO_OP_KEY_IMPORT	6
+#define AUDIT_CRYPTO_OP_KEY_EXPORT	7
+#define AUDIT_CRYPTO_OP_KEY_WRAP	8
+#define AUDIT_CRYPTO_OP_KEY_UNWRAP	9
+#define AUDIT_CRYPTO_OP_KEY_GEN		10
+#define AUDIT_CRYPTO_OP_KEY_DERIVE	11
+#define AUDIT_CRYPTO_OP_KEY_ZEROIZE	12
+#define AUDIT_CRYPTO_OP_KEY_GET_INFO	13
+
 struct audit_status {
 	__u32		mask;		/* Bit mask for valid entries */
 	__u32		enabled;	/* 1 = enabled, 0 = disabled */
@@ -404,6 +424,12 @@ struct audit_field {
 	void				*lsm_rule;
 };
 
+struct audit_crypto_value {
+	char name;
+	void *value;
+	size_t value_size;
+};
+
 #define AUDITSC_INVALID 0
 #define AUDITSC_SUCCESS 1
 #define AUDITSC_FAILURE 2
@@ -479,6 +505,12 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
 				  const struct cred *new,
 				  const struct cred *old);
 extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
+extern int __audit_log_crypto_op(int op, int context, int session,
+				 const char *operation, const char *algorithm,
+				 int key1, void *key1_id, size_t key1_id_size,
+				 int key2, void *key2_id, size_t key2_id_size);
+extern void __audit_log_crypto_values(const struct audit_crypto_value *values,
+				      size_t num_values);
 
 static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
 {
@@ -532,6 +564,27 @@ static inline void audit_log_capset(pid_t pid, const struct cred *new,
 		__audit_log_capset(pid, new, old);
 }
 
+static inline int audit_log_crypto_op(int op, int context, int session,
+				      const char *operation,
+				      const char *algorithm, int key1,
+				      void *key1_id, size_t key1_id_size,
+				      int key2, void *key2_id,
+				      size_t key2_id_size)
+{
+	if (unlikely(!audit_dummy_context()))
+		return __audit_log_crypto_op(op, context, session, operation,
+					     algorithm, key1, key1_id,
+					     key1_id_size, key2, key2_id,
+					     key2_id_size);
+	return 0;
+}
+static inline void audit_log_crypto_values(const struct audit_crypto_value *a,
+					   size_t num_values)
+{
+	if (unlikely(!audit_dummy_context()))
+		__audit_log_crypto_values(a, num_values);
+}
+
 extern int audit_n_rules;
 extern int audit_signals;
 #else
@@ -565,6 +618,8 @@ extern int audit_signals;
 #define audit_mq_getsetattr(d,s) ((void)0)
 #define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
 #define audit_log_capset(pid, ncr, ocr) ((void)0)
+#define audit_log_crypto_op(op, context, session, key1, key1_id, key1_id_size, key2, key2_id, key2_id_size) (0)
+#define audit_log_crypto_values(a, num_values) ((void)0)
 #define audit_ptrace(t) ((void)0)
 #define audit_n_rules 0
 #define audit_signals 0
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index a706040..a25a587 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -363,6 +363,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
 		case AUDIT_DEVMINOR:
 		case AUDIT_EXIT:
 		case AUDIT_SUCCESS:
+		case AUDIT_CRYPTO_OP:
 			/* bit ops are only useful on syscall args */
 			if (f->op == Audit_bitmask || f->op == Audit_bittest)
 				goto exit_free;
@@ -457,6 +458,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
 		case AUDIT_ARG1:
 		case AUDIT_ARG2:
 		case AUDIT_ARG3:
+		case AUDIT_CRYPTO_OP:
 			break;
 		case AUDIT_ARCH:
 			entry->rule.arch_f = f;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index fc0f928..846eabd 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -50,6 +50,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/mount.h>
+#include <linux/ncr.h>
 #include <linux/socket.h>
 #include <linux/mqueue.h>
 #include <linux/audit.h>
@@ -80,6 +81,9 @@
 /* no execve audit message should be longer than this (userspace limits) */
 #define MAX_EXECVE_AUDIT_LEN 7500
 
+/* Number of public key values that can be audited */
+#define AUDIT_MAX_CRYPTO_KEY_VALUES 4
+
 /* number of audit rules */
 int audit_n_rules;
 
@@ -157,6 +161,31 @@ struct audit_aux_data_capset {
 	struct audit_cap_data	cap;
 };
 
+#define AUDIT_CRYPTO_OP_KEY_VALUE -1
+struct audit_crypto_op {
+	struct list_head list;
+	int op;		       /* AUDIT_CRYPTO_OP_KEY_VALUE for key values */
+	union {
+		struct {
+			int context;
+			int session;
+			const char *operation;
+			const char *algorithm;
+			int key1;
+			unsigned char key1_id[MAX_KEY_ID_SIZE];
+			size_t key1_id_size;
+			int key2;
+			unsigned char key2_id[MAX_KEY_ID_SIZE];
+			size_t key2_id_size;
+		} op;
+		struct {
+			size_t num_values;
+			struct audit_crypto_value
+				values[AUDIT_MAX_CRYPTO_KEY_VALUES];
+		} key;
+	} u;
+};
+
 struct audit_tree_refs {
 	struct audit_tree_refs *next;
 	struct audit_chunk *c[31];
@@ -181,6 +210,7 @@ struct audit_context {
 	struct audit_context *previous; /* For nested syscalls */
 	struct audit_aux_data *aux;
 	struct audit_aux_data *aux_pids;
+	struct list_head crypto;
 	struct sockaddr_storage *sockaddr;
 	size_t sockaddr_len;
 				/* Save things to print about task_struct */
@@ -632,6 +662,20 @@ static int audit_filter_rules(struct task_struct *tsk,
 		case AUDIT_FILETYPE:
 			result = audit_match_filetype(ctx, f->val);
 			break;
+		case AUDIT_CRYPTO_OP:
+			if (ctx) {
+				struct audit_crypto_op *ax;
+
+				list_for_each_entry(ax, &ctx->crypto, list) {
+					if (ax->op == AUDIT_CRYPTO_OP_KEY_VALUE)
+						continue;
+					result = audit_comparator(ax->op, f->op,
+								  f->val);
+					if (result)
+						break;
+				}
+			}
+			break;
 		}
 
 		if (!result) {
@@ -824,9 +868,20 @@ static inline void audit_free_names(struct audit_context *context)
 	context->pwd.mnt = NULL;
 }
 
+static void audit_free_crypto_op(struct audit_crypto_op *crypto) {
+	if (crypto->op == AUDIT_CRYPTO_OP_KEY_VALUE) {
+		size_t i;
+
+		for (i = 0; i < crypto->u.key.num_values; i++)
+			kfree(crypto->u.key.values[i].value);
+	}
+	kfree(crypto);
+}
+
 static inline void audit_free_aux(struct audit_context *context)
 {
 	struct audit_aux_data *aux;
+	struct audit_crypto_op *crypto, *tmp;
 
 	while ((aux = context->aux)) {
 		context->aux = aux->next;
@@ -836,6 +891,10 @@ static inline void audit_free_aux(struct audit_context *context)
 		context->aux_pids = aux->next;
 		kfree(aux);
 	}
+	list_for_each_entry_safe(crypto, tmp, &context->crypto, list) {
+		list_del(&crypto->list);
+		audit_free_crypto_op(crypto);
+	}
 }
 
 static inline void audit_zero_context(struct audit_context *context,
@@ -853,6 +912,7 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state)
 	if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
 		return NULL;
 	audit_zero_context(context, state);
+	INIT_LIST_HEAD(&context->crypto);
 	INIT_LIST_HEAD(&context->killed_trees);
 	return context;
 }
@@ -1310,12 +1370,88 @@ static void show_special(struct audit_context *context, int *call_panic)
 	audit_log_end(ab);
 }
 
+static void log_crypto_op(struct audit_context *context,
+			  struct audit_crypto_op *crypto)
+{
+	struct audit_buffer *ab;
+
+	if (crypto->op != AUDIT_CRYPTO_OP_KEY_VALUE) {
+		static const char *const ops[] = {
+			[AUDIT_CRYPTO_OP_CONTEXT_NEW] = "context_new",
+			[AUDIT_CRYPTO_OP_CONTEXT_DEL] = "context_del",
+			[AUDIT_CRYPTO_OP_SESSION_INIT] = "session_init",
+			[AUDIT_CRYPTO_OP_SESSION_OP] = "session_op",
+			[AUDIT_CRYPTO_OP_SESSION_FINAL] = "session_final",
+			[AUDIT_CRYPTO_OP_KEY_IMPORT] = "key_import",
+			[AUDIT_CRYPTO_OP_KEY_EXPORT] = "key_export",
+			[AUDIT_CRYPTO_OP_KEY_WRAP] = "key_wrap",
+			[AUDIT_CRYPTO_OP_KEY_UNWRAP] = "key_unwrap",
+			[AUDIT_CRYPTO_OP_KEY_GEN] = "key_gen",
+			[AUDIT_CRYPTO_OP_KEY_DERIVE] = "key_derive",
+			[AUDIT_CRYPTO_OP_KEY_ZEROIZE] = "key_zeroize",
+			[AUDIT_CRYPTO_OP_KEY_GET_INFO] = "key_get_info",
+		};
+
+		ab = audit_log_start(context, GFP_KERNEL,
+				     AUDIT_CRYPTO_USERSPACE_OP);
+		if (!ab)
+			return;
+		if (crypto->op < ARRAY_SIZE(ops) && ops[crypto->op] != NULL)
+			audit_log_format(ab, "crypto_op=%s", ops[crypto->op]);
+		else
+			audit_log_format(ab, "crypto_op=%d", crypto->op);
+		audit_log_format(ab, " ctx=%d", crypto->u.op.context);
+		if (crypto->u.op.session != -1)
+			audit_log_format(ab, " session=%d",
+					 crypto->u.op.session);
+		if (crypto->u.op.operation != NULL)
+			audit_log_format(ab, " operation=%s",
+					 crypto->u.op.operation);
+		if (crypto->u.op.algorithm != NULL)
+			audit_log_format(ab, " algo=%s",
+					 crypto->u.op.algorithm);
+		if (crypto->u.op.key1 != -1) {
+			audit_log_format(ab, " key1=%d", crypto->u.op.key1);
+			if (crypto->u.op.key1_id_size > 0) {
+				audit_log_format(ab, " key1_id=");
+				audit_log_n_untrustedstring(ab,
+							    crypto->u.op.key1_id,
+							    crypto->u.op.key1_id_size);
+			}
+		}
+		if (crypto->u.op.key2 != -1) {
+			audit_log_format(ab, " key2=%d", crypto->u.op.key2);
+			if (crypto->u.op.key2_id_size > 0) {
+				audit_log_format(ab, " key2_id=");
+				audit_log_n_untrustedstring(ab,
+							    crypto->u.op.key2_id,
+							    crypto->u.op.key2_id_size);
+			}
+		}
+		audit_log_end(ab);
+	} else {
+		const struct audit_crypto_value *v;
+
+		ab = audit_log_start(context, GFP_KERNEL,
+				     AUDIT_CRYPTO_KEY_VALUE);
+		if (!ab)
+			return;
+		for (v = crypto->u.key.values;
+		     v < crypto->u.key.values + crypto->u.key.num_values; v++) {
+			audit_log_format(ab, " key_value_%c=", v->name);
+			audit_log_n_hex(ab, v->value, v->value_size);
+		}
+		audit_log_end(ab);
+	}
+}
+
 static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
 {
 	const struct cred *cred;
 	int i, call_panic = 0;
 	struct audit_buffer *ab;
 	struct audit_aux_data *aux;
+	struct audit_crypto_op *crypto;
 	const char *tty;
 
 	/* tsk == current */
@@ -1442,6 +1578,9 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
 				call_panic = 1;
 	}
 
+	list_for_each_entry(crypto, &context->crypto, list)
+		log_crypto_op(context, crypto);
+
 	if (context->target_pid &&
 	    audit_log_pid_context(context, context->target_pid,
 				  context->target_auid, context->target_uid,
@@ -2486,6 +2625,94 @@ void __audit_log_capset(pid_t pid,
 }
 
 /**
+ * __audit_log_crypto_op - store information about an user-space crypto op
+ * @op: AUDIT_CRYPTO_OP_*
+ * @context: user-space context ID
+ * @session: session ID within @context, or -1
+ * @operation: more detailed operation description, or NULL
+ * @algorithm: algorithm (crypto API transform) name, or NULL
+ * @key1: ID of key 1 within @context, or -1
+ * @key1_id: user-space ID of key 1 set from user-space if @key1 != -1
+ * @key1_id_size: Size of @key1_id
+ * @key2: ID of key 2 within @context, or -1
+ * @key2_id: user-space ID of key 2 set from user-space if @key2 != -1
+ * @key2_id_size: Size of @key2_id
+ */
+int __audit_log_crypto_op(int op, int context, int session,
+			  const char *operation, const char *algorithm,
+			  int key1, void *key1_id, size_t key1_id_size,
+			  int key2, void *key2_id, size_t key2_id_size)
+{
+	struct audit_crypto_op *ax;
+	struct audit_context *ctx = current->audit_context;
+
+	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->op = op;
+	ax->u.op.context = context;
+	ax->u.op.session = session;
+	ax->u.op.operation = operation;
+	ax->u.op.algorithm = algorithm;
+	ax->u.op.key1 = key1;
+	if (key1 != -1) {
+		ax->u.op.key1_id_size = min(key1_id_size,
+					    sizeof(ax->u.op.key1_id));
+		memcpy(ax->u.op.key1_id, key1_id, ax->u.op.key1_id_size);
+	} else
+		ax->u.op.key1_id_size = 0;
+	ax->u.op.key2 = key2;
+	if (key2 != -1) {
+		ax->u.op.key2_id_size = min(key2_id_size,
+					    sizeof(ax->u.op.key2_id));
+		memcpy(ax->u.op.key2_id, key2_id, ax->u.op.key2_id_size);
+	} else
+		ax->u.op.key2_id_size = 0;
+	list_add_tail(&ax->list, &ctx->crypto);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__audit_log_crypto_op);
+
+/**
+ * __audit_log_crypto_op - store information about values of crypto keys
+ * @values: individual byte arrays describing the key.  The "value" members
+ * must be allocated using kmalloc(), this function will take care of freeing
+ * them.
+ * @num_values: number of elements in @values
+ */
+void __audit_log_crypto_values(const struct audit_crypto_value *values,
+			       size_t num_values)
+{
+	struct audit_crypto_op *ax;
+	struct audit_context *ctx = current->audit_context;
+	size_t i;
+
+	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
+	if (!ax)
+		goto free_values;
+
+	ax->op = AUDIT_CRYPTO_OP_KEY_VALUE;
+	BUG_ON(num_values > ARRAY_SIZE(ax->u.key.values));
+	ax->u.key.num_values = num_values;
+	for (i = 0; i < num_values; i++) {
+		struct audit_crypto_value *dst;
+
+		dst = ax->u.key.values + i;
+		dst->name = values[i].name;
+		dst->value = values[i].value;
+		dst->value_size = values[i].value_size;
+	}
+	list_add_tail(&ax->list, &ctx->crypto);
+	return;
+
+free_values:
+	for (i = 0; i < num_values; i++)
+		kfree(values[i].value);
+}
+EXPORT_SYMBOL_GPL(__audit_log_crypto_values);
+
+/**
  * audit_core_dumps - record information about processes that end abnormally
  * @signr: signal value
  *
Index: src/aureport-output.c
===================================================================
--- src/aureport-output.c	(revision 400)
+++ src/aureport-output.c	(working copy)
@@ -600,7 +600,7 @@
 			// auid type success event
 			printf("%s %s %s %lu\n",
 				aulookup_uid(l->s.loginuid, name, sizeof(name)),
-				audit_msg_type_to_name(l->head->type),
+				audit_msg_type_to_name(l->cur->type),
 				aulookup_success(l->s.success),
 				l->e.serial);
 			break;
Index: src/ausearch-llist.c
===================================================================
--- src/ausearch-llist.c	(revision 400)
+++ src/ausearch-llist.c	(working copy)
@@ -245,3 +245,22 @@
 	return NULL;
 }
 
+
+lnode *list_find_next_msg_range(llist *l, int low, int high)
+{
+        register lnode *window;
+
+	if (high <= low)
+		return NULL;
+
+       	window = l->cur->next;
+	while (window) {
+		if (window->type >= low && window->type <= high) {
+			l->cur = window;
+			return window;
+		} else
+			window = window->next;
+	}
+	return NULL;
+}
+
Index: src/aureport-scan.c
===================================================================
--- src/aureport-scan.c	(revision 400)
+++ src/aureport-scan.c	(working copy)
@@ -420,8 +420,12 @@
 		case RPT_CRYPTO:
 			if (list_find_msg_range(l, AUDIT_FIRST_KERN_CRYPTO_MSG,
 						AUDIT_LAST_KERN_CRYPTO_MSG)) {
-				ilist_add_if_uniq(&sd.crypto_list, 
-							l->head->type, 0);
+				do
+					ilist_add_if_uniq(&sd.crypto_list,
+							  l->cur->type, 0);
+				while (list_find_next_msg_range(l,
+						AUDIT_FIRST_KERN_CRYPTO_MSG,
+						AUDIT_LAST_KERN_CRYPTO_MSG));
 			} else {
 				if (list_find_msg_range(l, 
 					AUDIT_FIRST_CRYPTO_MSG,
@@ -663,7 +667,11 @@
 				if (list_find_msg_range(l, 
 						AUDIT_FIRST_KERN_CRYPTO_MSG,
 						AUDIT_LAST_KERN_CRYPTO_MSG)) {
-					print_per_event_item(l);
+					do
+						print_per_event_item(l);
+					while (list_find_next_msg_range(l,
+						AUDIT_FIRST_KERN_CRYPTO_MSG,
+						AUDIT_LAST_KERN_CRYPTO_MSG));
 					rc = 1;
 				} else {
 					if (list_find_msg_range(l, 
Index: src/ausearch-llist.h
===================================================================
--- src/ausearch-llist.h	(revision 400)
+++ src/ausearch-llist.h	(working copy)
@@ -107,5 +107,8 @@
 /* Given two message types, find the first matching node */
 lnode *list_find_msg_range(llist *l, int low, int high);
 
+/* Given two message types, find the next matching node */
+lnode *list_find_next_msg_range(llist *l, int low, int high);
+
 #endif
 
Index: lib/errormsg.h
===================================================================
--- lib/errormsg.h	(revision 400)
+++ lib/errormsg.h	(working copy)
@@ -54,5 +54,6 @@
     { -19,    0,    "Key field needs a watch or syscall given prior to it" },
     { -20,    2,    "-F missing value after operation for" },
     { -21,    2,    "-F value should be number for" },
-    { -22,    2,    "-F missing field name before operator for" }
+    { -22,    2,    "-F missing field name before operator for" },
+    { -23,    2,    "-F unknown crypto_op - " }
 };
Index: lib/fieldtab.h
===================================================================
--- lib/fieldtab.h	(revision 400)
+++ lib/fieldtab.h	(working copy)
@@ -45,6 +45,7 @@
 _S(AUDIT_OBJ_TYPE,     "obj_type"     )
 _S(AUDIT_OBJ_LEV_LOW,  "obj_lev_low"  )
 _S(AUDIT_OBJ_LEV_HIGH, "obj_lev_high" )
+_S(AUDIT_CRYPTO_OP,    "crypto_op"    )
 
 _S(AUDIT_DEVMAJOR,     "devmajor"     )
 _S(AUDIT_DEVMINOR,     "devminor"     )
Index: lib/msg_typetab.h
===================================================================
--- lib/msg_typetab.h	(revision 400)
+++ lib/msg_typetab.h	(working copy)
@@ -122,6 +122,9 @@
 _S(AUDIT_MAC_IPSEC_EVENT,            "MAC_IPSEC_EVENT"               )
 _S(AUDIT_MAC_UNLBL_STCADD,           "MAC_UNLBL_STCADD"              )
 _S(AUDIT_MAC_UNLBL_STCDEL,           "MAC_UNLBL_STCDEL"              )
+_S(AUDIT_CRYPTO_STORAGE_KEY,         "CRYPTO_STORAGE_KEY"            )
+_S(AUDIT_CRYPTO_USERSPACE_OP,        "CRYPTO_USERSPACE_OP"           )
+_S(AUDIT_CRYPTO_KEY_VALUE,           "CRYPTO_KEY_VALUE"              )
 _S(AUDIT_ANOM_PROMISCUOUS,           "ANOM_PROMISCUOUS"              )
 _S(AUDIT_ANOM_ABEND,                 "ANOM_ABEND"                    )
 _S(AUDIT_INTEGRITY_DATA,             "INTEGRITY_DATA"                )
Index: lib/libaudit.c
===================================================================
--- lib/libaudit.c	(revision 400)
+++ lib/libaudit.c	(working copy)
@@ -38,6 +38,8 @@
 #include <fcntl.h>	/* O_NOFOLLOW needs gnu defined */
 #include <limits.h>	/* for PATH_MAX */
 
+#include "gen_tables.h"
+#include "crypto_ops.h"
 #include "libaudit.h"
 #include "private.h"
 #include "errormsg.h"
@@ -1109,6 +1111,21 @@
 			else 
 				return -21;
 			break;
+		case AUDIT_CRYPTO_OP:
+			if (flags != AUDIT_FILTER_EXIT)
+				return -7;
+			if (isdigit((unsigned char)*v))
+				rule->values[rule->field_count] =
+					strtoul(v, NULL, 0);
+			else {
+				int op;
+
+				if (crypto_op_s2i(v, &op) != 0)
+					rule->values[rule->field_count] = op;
+				else
+					return -23;
+			}
+			break;
 		case AUDIT_DEVMAJOR...AUDIT_INODE:
 		case AUDIT_SUCCESS:
 			if (flags != AUDIT_FILTER_EXIT)
Index: lib/libaudit.h
===================================================================
--- lib/libaudit.h	(revision 400)
+++ lib/libaudit.h	(working copy)
@@ -118,6 +118,11 @@
 #endif
 
 #define AUDIT_FIRST_KERN_CRYPTO_MSG	1600
+#define AUDIT_CRYPTO_STORAGE_KEY	1600 /* Key storage key configured */
+#define AUDIT_CRYPTO_USERSPACE_OP	1601 /* User-space crypto operation */
+#define AUDIT_CRYPTO_KEY_VALUE		1602 /* Public values of a key,
+						immediatelly follows
+						USERSPACE_OP. */
 #define AUDIT_LAST_KERN_CRYPTO_MSG	1699
 
 #define AUDIT_FIRST_KERN_ANOM_MSG	1700
@@ -201,7 +206,22 @@
 #define AUDIT_LAST_USER_MSG2   2999
 #endif
 
+#define AUDIT_CRYPTO_OP	24
 
+#define AUDIT_CRYPTO_OP_CONTEXT_NEW	1
+#define AUDIT_CRYPTO_OP_CONTEXT_DEL	2
+#define AUDIT_CRYPTO_OP_SESSION_INIT	3
+#define AUDIT_CRYPTO_OP_SESSION_OP	4
+#define AUDIT_CRYPTO_OP_SESSION_FINAL	5
+#define AUDIT_CRYPTO_OP_KEY_IMPORT	6
+#define AUDIT_CRYPTO_OP_KEY_EXPORT	7
+#define AUDIT_CRYPTO_OP_KEY_WRAP	8
+#define AUDIT_CRYPTO_OP_KEY_UNWRAP	9
+#define AUDIT_CRYPTO_OP_KEY_GEN		10
+#define AUDIT_CRYPTO_OP_KEY_DERIVE	11
+#define AUDIT_CRYPTO_OP_KEY_ZEROIZE	12
+#define AUDIT_CRYPTO_OP_KEY_GET_INFO	13
+
 /* This is related to the filterkey patch */
 #define AUDIT_KEY_SEPARATOR 0x01
 
Index: lib/crypto_ops_table.h
===================================================================
--- lib/crypto_ops_table.h	(revision 0)
+++ lib/crypto_ops_table.h	(revision 0)
@@ -0,0 +1,35 @@
+/* crypto_ops_table.h --
+ * Copyright 2010 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors:
+ *      Miloslav Trmač <mitr redhat com>
+ */
+
+_S(AUDIT_CRYPTO_OP_CONTEXT_NEW,   "context_new")
+_S(AUDIT_CRYPTO_OP_CONTEXT_DEL,   "context_del")
+_S(AUDIT_CRYPTO_OP_SESSION_INIT,  "session_init")
+_S(AUDIT_CRYPTO_OP_SESSION_OP,    "session_op")
+_S(AUDIT_CRYPTO_OP_SESSION_FINAL, "session_final")
+_S(AUDIT_CRYPTO_OP_KEY_IMPORT,    "key_import")
+_S(AUDIT_CRYPTO_OP_KEY_EXPORT,    "key_export")
+_S(AUDIT_CRYPTO_OP_KEY_WRAP,      "key_wrap")
+_S(AUDIT_CRYPTO_OP_KEY_UNWRAP,    "key_unwrap")
+_S(AUDIT_CRYPTO_OP_KEY_GEN,       "key_gen")
+_S(AUDIT_CRYPTO_OP_KEY_DERIVE,    "key_derive")
+_S(AUDIT_CRYPTO_OP_KEY_ZEROIZE,   "key_zeroize")
+_S(AUDIT_CRYPTO_OP_KEY_GET_INFO,  "key_get_info")
Index: lib/Makefile.am
===================================================================
--- lib/Makefile.am	(revision 400)
+++ lib/Makefile.am	(working copy)
@@ -37,7 +37,7 @@
 libaudit_la_LDFLAGS = -Wl,-z,relro -version-info $(VERSION_INFO)
 nodist_libaudit_la_SOURCES = $(BUILT_SOURCES)
 
-BUILT_SOURCES = actiontabs.h errtabs.h fieldtabs.h flagtabs.h \
+BUILT_SOURCES = actiontabs.h crypto_ops.h errtabs.h fieldtabs.h flagtabs.h \
 	ftypetabs.h i386_tables.h ia64_tables.h machinetabs.h \
 	msg_typetabs.h optabs.h ppc_tables.h s390_tables.h \
 	s390x_tables.h x86_64_tables.h
@@ -47,8 +47,8 @@
 if USE_ARMEB
 BUILT_SOURCES += armeb_tables.h
 endif
-noinst_PROGRAMS = gen_actiontabs_h gen_errtabs_h gen_fieldtabs_h \
-	gen_flagtabs_h gen_ftypetabs_h gen_i386_tables_h \
+noinst_PROGRAMS = gen_actiontabs_h gen_crypto_ops_h gen_errtabs_h \
+	gen_fieldtabs_h gen_flagtabs_h gen_ftypetabs_h gen_i386_tables_h \
 	gen_ia64_tables_h gen_machinetabs_h gen_msg_typetabs_h \
 	gen_optabs_h gen_ppc_tables_h gen_s390_tables_h \
 	gen_s390x_tables_h gen_x86_64_tables_h
@@ -77,6 +77,11 @@
 	./gen_armeb_tables_h --lowercase --i2s --s2i armeb_syscall > $@
 endif
 
+gen_crypto_ops_h_SOURCES = gen_tables.c gen_tables.h crypto_ops_table.h
+gen_crypto_ops_h_CFLAGS = $(AM_CFLAGS) '-DTABLE_H="crypto_ops_table.h"'
+crypto_ops.h: gen_crypto_ops_h Makefile
+	./gen_crypto_ops_h --lowercase --s2i crypto_op > $@
+
 gen_errtabs_h_SOURCES = gen_tables.c gen_tables.h errtab.h
 gen_errtabs_h_CFLAGS = $(AM_CFLAGS) '-DTABLE_H="errtab.h"'
 errtabs.h: gen_errtabs_h Makefile

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]