diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 2a44b3752471d0b34d19fbe4a66305863dfcafb8..9e9e5a6a9ed63a156ddf5a58b726cadc00ef1e3a 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -321,6 +321,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
 			goto error_free_cert;
 	} else if (!prep->trusted) {
 		ret = x509_validate_trust(cert, get_system_trusted_keyring());
+		if (ret)
+			ret = x509_validate_trust(cert, get_ima_mok_keyring());
 		if (!ret)
 			prep->trusted = 1;
 	}
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index b20cd885c1fd84b01d5b5602177777a74ea64810..39fd38cfa8c96512e59360f151eebb07eb74be1f 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -35,4 +35,28 @@ extern int system_verify_data(const void *data, unsigned long len,
 			      enum key_being_used_for usage);
 #endif
 
+#ifdef CONFIG_IMA_MOK_KEYRING
+extern struct key *ima_mok_keyring;
+extern struct key *ima_blacklist_keyring;
+
+static inline struct key *get_ima_mok_keyring(void)
+{
+	return ima_mok_keyring;
+}
+static inline struct key *get_ima_blacklist_keyring(void)
+{
+	return ima_blacklist_keyring;
+}
+#else
+static inline struct key *get_ima_mok_keyring(void)
+{
+	return NULL;
+}
+static inline struct key *get_ima_blacklist_keyring(void)
+{
+	return NULL;
+}
+#endif /* CONFIG_IMA_MOK_KEYRING */
+
+
 #endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 4fec1816a2b3b18385a2ec5c5590e4d72dc7775b..5ade2a7517a6341305ba4aafbb18469cd1ed8db8 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -17,6 +17,7 @@
 #include <linux/key-type.h>
 #include <crypto/public_key.h>
 #include <keys/asymmetric-type.h>
+#include <keys/system_keyring.h>
 
 #include "integrity.h"
 
@@ -32,9 +33,22 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
 
 	pr_debug("key search: \"%s\"\n", name);
 
+	key = get_ima_blacklist_keyring();
+	if (key) {
+		key_ref_t kref;
+
+		kref = keyring_search(make_key_ref(key, 1),
+				     &key_type_asymmetric, name);
+		if (!IS_ERR(kref)) {
+			pr_err("Key '%s' is in ima_blacklist_keyring\n", name);
+			return ERR_PTR(-EKEYREJECTED);
+		}
+	}
+
 	if (keyring) {
 		/* search in specific keyring */
 		key_ref_t kref;
+
 		kref = keyring_search(make_key_ref(keyring, 1),
 				      &key_type_asymmetric, name);
 		if (IS_ERR(kref))
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index e74d66cbfe87a915271d39cf5bd801f85dc528d8..8d5e6e0e0937c0d0a4467a4fb1f80fc74decafb7 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -145,6 +145,24 @@ config IMA_TRUSTED_KEYRING
 
 	   This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING
 
+config IMA_MOK_KEYRING
+	bool "Create IMA machine owner keys (MOK) and blacklist keyrings"
+	depends on SYSTEM_TRUSTED_KEYRING
+	depends on IMA_TRUSTED_KEYRING
+	default n
+	help
+	   This option creates IMA MOK and blacklist keyrings.  IMA MOK is an
+	   intermediate keyring that sits between .system and .ima keyrings,
+	   effectively forming a simple CA hierarchy.  To successfully import a
+	   key into .ima_mok it must be signed by a key which CA is in .system
+	   keyring.  On turn any key that needs to go in .ima keyring must be
+	   signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty
+	   at kernel boot.
+
+	   IMA blacklist keyring contains all revoked IMA keys.  It is consulted
+	   before any other keyring.  If the search is successful the requested
+	   operation is rejected and error is returned to the caller.
+
 config IMA_LOAD_X509
 	bool "Load X509 certificate onto the '.ima' trusted keyring"
 	depends on IMA_TRUSTED_KEYRING
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index d79263d2fdbfd0098666f541db32552c784688ce..a8539f9e060fe359ebb407136aca3f4fe923c9c1 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
 ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 	 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
+obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
new file mode 100644
index 0000000000000000000000000000000000000000..18e37f57f5128288e4e27de0bc23c3060a993718
--- /dev/null
+++ b/security/integrity/ima/ima_mok.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Juniper Networks, Inc.
+ *
+ * Author:
+ * Petko Manolov <petko.manolov@konsulko.com>
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <keys/asymmetric-type.h>
+
+
+struct key *ima_mok_keyring;
+struct key *ima_blacklist_keyring;
+
+/*
+ * Allocate the IMA MOK and blacklist keyrings
+ */
+__init int ima_mok_init(void)
+{
+	pr_notice("Allocating IMA MOK and blacklist keyrings.\n");
+
+	ima_mok_keyring = keyring_alloc(".ima_mok",
+			      KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
+			      (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+			      KEY_USR_VIEW | KEY_USR_READ |
+			      KEY_USR_WRITE | KEY_USR_SEARCH,
+			      KEY_ALLOC_NOT_IN_QUOTA, NULL);
+
+	ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
+				KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
+				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
+				KEY_USR_VIEW | KEY_USR_READ |
+				KEY_USR_WRITE | KEY_USR_SEARCH,
+				KEY_ALLOC_NOT_IN_QUOTA, NULL);
+
+	if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring))
+		panic("Can't allocate IMA MOK or blacklist keyrings.");
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);
+	return 0;
+}
+
+module_init(ima_mok_init);