http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageMvccUpdateTxStateHintRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageMvccUpdateTxStateHintRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageMvccUpdateTxStateHintRecord.java
index 7e53609..fd77728 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageMvccUpdateTxStateHintRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageMvccUpdateTxStateHintRecord.java
@@ -50,7 +50,7 @@ public class DataPageMvccUpdateTxStateHintRecord extends 
PageDeltaRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         DataPageIO io = PageIO.getPageIO(pageAddr);
 
-        io.updateTxState(pageAddr, itemId, pageMem.pageSize(), txState);
+        io.updateTxState(pageAddr, itemId, pageMem.realPageSize(groupId()), 
txState);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageRemoveRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageRemoveRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageRemoveRecord.java
index f7776be..abc84ea 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageRemoveRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageRemoveRecord.java
@@ -53,7 +53,7 @@ public class DataPageRemoveRecord extends PageDeltaRecord {
         throws IgniteCheckedException {
         AbstractDataPageIO io = PageIO.getPageIO(pageAddr);
 
-        io.removeRow(pageAddr, itemId, pageMem.pageSize());
+        io.removeRow(pageAddr, itemId, pageMem.realPageSize(groupId()));
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageUpdateRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageUpdateRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageUpdateRecord.java
index ed469a4..6f5d8fd 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageUpdateRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/DataPageUpdateRecord.java
@@ -71,7 +71,7 @@ public class DataPageUpdateRecord extends PageDeltaRecord {
 
         AbstractDataPageIO io = PageIO.getPageIO(pageAddr);
 
-        io.updateRow(pageAddr, itemId, pageMem.pageSize(), payload, null, 0);
+        io.updateRow(pageAddr, itemId, pageMem.realPageSize(groupId()), 
payload, null, 0);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/InitNewPageRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/InitNewPageRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/InitNewPageRecord.java
index c177a04..d0ba2aa 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/InitNewPageRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/InitNewPageRecord.java
@@ -57,7 +57,7 @@ public class InitNewPageRecord extends PageDeltaRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         PageIO io = PageIO.getPageIO(ioType, ioVer);
 
-        io.initNewPage(pageAddr, newPageId, pageMem.pageSize());
+        io.initNewPage(pageAddr, newPageId, pageMem.realPageSize(groupId()));
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageAddRootRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageAddRootRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageAddRootRecord.java
index 4972155..9bf3aef 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageAddRootRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageAddRootRecord.java
@@ -44,7 +44,7 @@ public class MetaPageAddRootRecord extends PageDeltaRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         BPlusMetaIO io = BPlusMetaIO.VERSIONS.forPage(pageAddr);
 
-        io.addRoot(pageAddr, rootId, pageMem.pageSize());
+        io.addRoot(pageAddr, rootId, pageMem.realPageSize(groupId()));
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageCutRootRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageCutRootRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageCutRootRecord.java
index 5b896f6..1383a38 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageCutRootRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageCutRootRecord.java
@@ -38,7 +38,7 @@ public class MetaPageCutRootRecord extends PageDeltaRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         BPlusMetaIO io = BPlusMetaIO.VERSIONS.forPage(pageAddr);
 
-        io.cutRoot(pageAddr, pageMem.pageSize());
+        io.cutRoot(pageAddr, pageMem.realPageSize(groupId()));
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRecord.java
index ca995bf..7b3f3a9 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRecord.java
@@ -76,7 +76,7 @@ public class MetaPageInitRecord extends InitNewPageRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         PageMetaIO io = PageMetaIO.getPageIO(ioType, ioVer);
 
-        io.initNewPage(pageAddr, newPageId, pageMem.pageSize());
+        io.initNewPage(pageAddr, newPageId, pageMem.realPageSize(groupId()));
 
         io.setTreeRoot(pageAddr, treeRoot);
         io.setReuseListRoot(pageAddr, reuseListRoot);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootInlineRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootInlineRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootInlineRecord.java
index 0d3c155..71ae85d 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootInlineRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootInlineRecord.java
@@ -51,7 +51,7 @@ public class MetaPageInitRootInlineRecord extends 
MetaPageInitRootRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         BPlusMetaIO io = BPlusMetaIO.VERSIONS.forPage(pageAddr);
 
-        io.initRoot(pageAddr, rootId, pageMem.pageSize());
+        io.initRoot(pageAddr, rootId, pageMem.realPageSize(groupId()));
         io.setInlineSize(pageAddr, inlineSize);
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootRecord.java
index 78a7e4f..7eca278 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageInitRootRecord.java
@@ -44,7 +44,7 @@ public class MetaPageInitRootRecord extends PageDeltaRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         BPlusMetaIO io = BPlusMetaIO.VERSIONS.forPage(pageAddr);
 
-        io.initRoot(pageAddr, rootId, pageMem.pageSize());
+        io.initRoot(pageAddr, rootId, pageMem.realPageSize(groupId()));
         io.setInlineSize(pageAddr, 0);
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/NewRootInitRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/NewRootInitRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/NewRootInitRecord.java
index 4b8f747..1d78033 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/NewRootInitRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/NewRootInitRecord.java
@@ -71,7 +71,8 @@ public class NewRootInitRecord<L> extends PageDeltaRecord {
 
     /** {@inheritDoc} */
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
-        io.initNewRoot(pageAddr, newRootId, leftChildId, null, rowBytes, 
rightChildId, pageMem.pageSize(), false);
+        io.initNewRoot(pageAddr, newRootId, leftChildId, null, rowBytes, 
rightChildId, pageMem.realPageSize(groupId()),
+            false);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListAddPageRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListAddPageRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListAddPageRecord.java
index 6c7fc71..6f877b9 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListAddPageRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListAddPageRecord.java
@@ -54,7 +54,7 @@ public class PagesListAddPageRecord extends PageDeltaRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         PagesListNodeIO io = PagesListNodeIO.VERSIONS.forPage(pageAddr);
 
-        int cnt = io.addPage(pageAddr, dataPageId, pageMem.pageSize());
+        int cnt = io.addPage(pageAddr, dataPageId, 
pageMem.realPageSize(groupId()));
 
         assert cnt >= 0 : cnt;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListInitNewPageRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListInitNewPageRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListInitNewPageRecord.java
index b2512aa..53c23b1 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListInitNewPageRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PagesListInitNewPageRecord.java
@@ -76,11 +76,11 @@ public class PagesListInitNewPageRecord extends 
InitNewPageRecord {
     @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws 
IgniteCheckedException {
         PagesListNodeIO io = PageIO.getPageIO(PageIO.T_PAGE_LIST_NODE, ioVer);
 
-        io.initNewPage(pageAddr, pageId(), pageMem.pageSize());
+        io.initNewPage(pageAddr, pageId(), pageMem.realPageSize(groupId()));
         io.setPreviousId(pageAddr, prevPageId);
 
         if (addDataPageId != 0L) {
-            int cnt = io.addPage(pageAddr, addDataPageId, pageMem.pageSize());
+            int cnt = io.addPage(pageAddr, addDataPageId, 
pageMem.realPageSize(groupId()));
 
             assert cnt == 0 : cnt;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/TrackingPageDeltaRecord.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/TrackingPageDeltaRecord.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/TrackingPageDeltaRecord.java
index 089eb9a..3f11c58 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/TrackingPageDeltaRecord.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/TrackingPageDeltaRecord.java
@@ -76,7 +76,7 @@ public class TrackingPageDeltaRecord extends PageDeltaRecord {
             pageIdToMark,
             nextSnapshotId,
             lastSuccessfulSnapshotId,
-            pageMem.pageSize());
+            pageMem.realPageSize(groupId()));
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
index ded37e7..d1598cd 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
@@ -97,9 +97,6 @@ public class IgniteAuthenticationProcessor extends 
GridProcessorAdapter implemen
     /** Whan the future is done the node is ready for authentication. */
     private final GridFutureAdapter<Void> readyForAuthFut = new 
GridFutureAdapter<>();
 
-    /** Random is used to get random server node to authentication from client 
node. */
-    private static final Random RND = new Random(System.currentTimeMillis());
-
     /** Operation mutex. */
     private final Object mux = new Object();
 
@@ -313,18 +310,7 @@ public class IgniteAuthenticationProcessor extends 
GridProcessorAdapter implemen
                 AuthenticateFuture fut;
 
                 synchronized (mux) {
-                    Collection<ClusterNode> aliveNodes = 
ctx.discovery().aliveServerNodes();
-
-                    int rndIdx = RND.nextInt(aliveNodes.size()) + 1;
-
-                    int i = 0;
-                    ClusterNode rndNode = null;
-
-                    for (Iterator<ClusterNode> it = aliveNodes.iterator(); i < 
rndIdx && it.hasNext(); i++)
-                        rndNode = it.next();
-
-                    if (rndNode == null)
-                        assert rndNode != null;
+                    ClusterNode rndNode = U.randomServerNode(ctx);
 
                     fut = new AuthenticateFuture(rndNode.id());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
index 8bed063..6ab4e67 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
@@ -158,17 +158,6 @@ class ClusterCachesInfo {
     }
 
     /**
-     * @param cacheName Cache name.
-     * @param grpName Group name.
-     * @return Group ID.
-     */
-    private int cacheGroupId(String cacheName, @Nullable String grpName) {
-        assert cacheName != null;
-
-        return grpName != null ? CU.cacheId(grpName) : CU.cacheId(cacheName);
-    }
-
-    /**
      * @param checkConsistency {@code True} if need check cache configurations 
consistency.
      * @throws IgniteCheckedException If failed.
      */
@@ -363,6 +352,9 @@ class ClusterCachesInfo {
                     "Query parallelism", locAttr.qryParallelism(), 
rmtAttr.qryParallelism(), true);
             }
         }
+
+        CU.checkAttributeMismatch(log, rmtAttr.cacheName(), rmt, 
"isEncryptionEnabled",
+            "Cache encrypted", locAttr.isEncryptionEnabled(), 
rmtAttr.isEncryptionEnabled(), true);
     }
 
     /**
@@ -574,7 +566,8 @@ class ClusterCachesInfo {
                             ccfg,
                             cacheId,
                             req.initiatingNodeId(),
-                            req.deploymentId());
+                            req.deploymentId(),
+                            req.encryptionKey());
 
                         DynamicCacheDescriptor startDesc = new 
DynamicCacheDescriptor(ctx,
                             ccfg,
@@ -1536,7 +1529,7 @@ class ClusterCachesInfo {
                     ", conflictingCacheName=" + desc.cacheName() + ']';
         }
 
-        int grpId = cacheGroupId(cfg.getName(), cfg.getGroupName());
+        int grpId = CU.cacheGroupId(cfg.getName(), cfg.getGroupName());
 
         if (cfg.getGroupName() != null) {
             if (cacheGroupByName(cfg.getGroupName()) == null) {
@@ -1647,7 +1640,8 @@ class ClusterCachesInfo {
             cfg,
             cacheId,
             nodeId,
-            joinData.cacheDeploymentId());
+            joinData.cacheDeploymentId(),
+            null);
 
         ctx.discovery().setCacheFilter(
             cacheId,
@@ -1761,6 +1755,7 @@ class ClusterCachesInfo {
      * @param cacheId Cache ID.
      * @param rcvdFrom Node ID cache was recived from.
      * @param deploymentId Deployment ID.
+     * @param encKey Encryption key.
      * @return Group descriptor.
      */
     private CacheGroupDescriptor registerCacheGroup(
@@ -1769,7 +1764,8 @@ class ClusterCachesInfo {
         CacheConfiguration<?, ?> startedCacheCfg,
         Integer cacheId,
         UUID rcvdFrom,
-        IgniteUuid deploymentId) {
+        IgniteUuid deploymentId,
+        @Nullable byte[] encKey) {
         if (startedCacheCfg.getGroupName() != null) {
             CacheGroupDescriptor desc = 
cacheGroupByName(startedCacheCfg.getGroupName());
 
@@ -1780,7 +1776,7 @@ class ClusterCachesInfo {
             }
         }
 
-        int grpId = cacheGroupId(startedCacheCfg.getName(), 
startedCacheCfg.getGroupName());
+        int grpId = CU.cacheGroupId(startedCacheCfg.getName(), 
startedCacheCfg.getGroupName());
 
         Map<String, Integer> caches = 
Collections.singletonMap(startedCacheCfg.getName(), cacheId);
 
@@ -1798,6 +1794,9 @@ class ClusterCachesInfo {
             persistent,
             null);
 
+        if (startedCacheCfg.isEncryptionEnabled())
+            ctx.encryption().beforeCacheGroupStart(grpId, encKey);
+
         if (ctx.cache().context().pageStore() != null)
             ctx.cache().context().pageStore().beforeCacheGroupStart(grpDesc);
 
@@ -1930,6 +1929,9 @@ class ClusterCachesInfo {
             CU.validateCacheGroupsAttributesMismatch(log, cfg, startCfg, 
"backups", "Backups",
                 cfg.getBackups(), startCfg.getBackups(), true);
         }
+
+        CU.validateCacheGroupsAttributesMismatch(log, cfg, startCfg, 
"encryptionEnabled", "Encrypted",
+            cfg.isEncryptionEnabled(), startCfg.isEncryptionEnabled(), true);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java
index 2b942b0..5b8a89c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java
@@ -95,6 +95,9 @@ public class DynamicCacheChangeRequest implements 
Serializable {
     /** */
     private transient boolean locallyConfigured;
 
+    /** Encryption key. */
+    @Nullable private byte[] encKey;
+
     /**
      * @param reqId Unique request ID.
      * @param cacheName Cache stop name.
@@ -424,6 +427,20 @@ public class DynamicCacheChangeRequest implements 
Serializable {
         this.disabledAfterStart = disabledAfterStart;
     }
 
+    /**
+     * @param encKey Encryption key.
+     */
+    public void encryptionKey(@Nullable byte[] encKey) {
+        this.encKey = encKey;
+    }
+
+    /**
+     * @return Encryption key.
+     */
+    @Nullable public byte[] encryptionKey() {
+        return encKey;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return "DynamicCacheChangeRequest [cacheName=" + cacheName() +

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAttributes.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAttributes.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAttributes.java
index 01daee2..230320a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAttributes.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAttributes.java
@@ -353,6 +353,13 @@ public class GridCacheAttributes implements Serializable {
     }
 
     /**
+     * @return Is cache encryption enabled.
+     */
+    public boolean isEncryptionEnabled() {
+        return ccfg.isEncryptionEnabled();
+    }
+
+    /**
      * @param obj Object to get class of.
      * @return Class name or {@code null}.
      */
@@ -364,4 +371,4 @@ public class GridCacheAttributes implements Serializable {
     @Override public String toString() {
         return S.toString(GridCacheAttributes.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 16e1799..f595ecf 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -25,6 +25,7 @@ import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
@@ -61,6 +62,7 @@ import org.apache.ignite.configuration.MemoryConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.configuration.TransactionConfiguration;
 import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.spi.encryption.EncryptionSpi;
 import org.apache.ignite.events.EventType;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
@@ -136,6 +138,7 @@ import org.apache.ignite.internal.util.F0;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.lang.GridPlainClosure;
 import org.apache.ignite.internal.util.lang.IgniteOutClosureX;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.CIX1;
@@ -149,6 +152,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgniteFuture;
+import org.apache.ignite.lang.IgniteInClosure;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.lifecycle.LifecycleAware;
@@ -598,6 +602,22 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
                 }
             }
         }
+
+        if (cc.isEncryptionEnabled() && !ctx.clientNode()) {
+            if (!CU.isPersistentCache(cc, c.getDataStorageConfiguration())) {
+                throw new IgniteCheckedException("Using encryption is not 
allowed" +
+                    " for not persistent cache  [cacheName=" + cc.getName() + 
", groupName=" + cc.getGroupName() +
+                    ", cacheType=" + cacheType + "]");
+            }
+
+            EncryptionSpi encSpi = c.getEncryptionSpi();
+
+            if (encSpi == null) {
+                throw new IgniteCheckedException("EncryptionSpi should be 
configured to use encrypted cache " +
+                    "[cacheName=" + cc.getName() + ", groupName=" + 
cc.getGroupName() +
+                    ", cacheType=" + cacheType + "]");
+            }
+        }
     }
 
     /**
@@ -903,6 +923,15 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
                 ", configuredAtomicityMode=" + cfg.getAtomicityMode() +
                 ", storedAtomicityMode=" + cfgFromStore.getAtomicityMode() + 
"]");
         }
+
+        boolean staticCfgVal = cfg.isEncryptionEnabled();
+
+        boolean storedVal = cfgFromStore.isEncryptionEnabled();
+
+        if (storedVal != staticCfgVal) {
+            throw new IgniteCheckedException("Encrypted flag value differs. 
Static config value is '" + staticCfgVal +
+                "' and value stored on the disk is '" + storedVal + "'");
+        }
     }
 
     /**
@@ -1311,7 +1340,8 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
                 ", mode=" + cfg.getCacheMode() +
                 ", atomicity=" + cfg.getAtomicityMode() +
                 ", backups=" + cfg.getBackups() +
-                ", mvcc=" + cacheCtx.mvccEnabled() +']');
+                ", mvcc=" + cacheCtx.mvccEnabled() +']' +
+                ", encryptionEnabled=" + cfg.isEncryptionEnabled() +']');
         }
     }
 
@@ -3107,7 +3137,9 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
         if (checkThreadTx)
             checkEmptyTransactions();
 
-        try {
+        GridPlainClosure<Collection<byte[]>, IgniteInternalFuture<Boolean>> 
startCacheClsr = (grpKeys) -> {
+            assert ccfg == null || !ccfg.isEncryptionEnabled() || 
!grpKeys.isEmpty();
+
             DynamicCacheChangeRequest req = prepareCacheChangeRequest(
                 ccfg,
                 cacheName,
@@ -3117,7 +3149,8 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
                 failIfExists,
                 failIfNotStarted,
                 false,
-                null);
+                null,
+                ccfg != null && ccfg.isEncryptionEnabled() ? 
grpKeys.iterator().next() : null);
 
             if (req != null) {
                 if (req.clientStartOnly())
@@ -3127,6 +3160,16 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
             }
             else
                 return new GridFinishedFuture<>();
+        };
+
+        try {
+            if (ccfg != null && ccfg.isEncryptionEnabled()) {
+                ctx.encryption().checkEncryptedCacheSupported();
+
+                return generateEncryptionKeysAndStartCacheAfter(1, 
startCacheClsr);
+            }
+
+            return startCacheClsr.apply(Collections.EMPTY_SET);
         }
         catch (Exception e) {
             return new GridFinishedFuture<>(e);
@@ -3134,6 +3177,48 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
     }
 
     /**
+     * Send {@code GenerateEncryptionKeyRequest} and execute {@code after} 
closure if succeed.
+     *
+     * @param keyCnt Count of keys to generate.
+     * @param after Closure to execute after encryption keys would be 
generated.
+     */
+    private IgniteInternalFuture<Boolean> 
generateEncryptionKeysAndStartCacheAfter(int keyCnt,
+        GridPlainClosure<Collection<byte[]>, IgniteInternalFuture<Boolean>> 
after) {
+        IgniteInternalFuture<Collection<byte[]>> genEncKeyFut = 
ctx.encryption().generateKeys(keyCnt);
+
+        GridFutureAdapter<Boolean> res = new GridFutureAdapter<>();
+
+        genEncKeyFut.listen(new 
IgniteInClosure<IgniteInternalFuture<Collection<byte[]>>>() {
+            @Override public void 
apply(IgniteInternalFuture<Collection<byte[]>> fut) {
+                try {
+                    Collection<byte[]> grpKeys = fut.result();
+
+                    if (F.size(grpKeys, F.alwaysTrue()) != keyCnt)
+                        res.onDone(false, fut.error());
+
+                    IgniteInternalFuture<Boolean> dynStartCacheFut = 
after.apply(grpKeys);
+
+                    dynStartCacheFut.listen(new 
IgniteInClosure<IgniteInternalFuture<Boolean>>() {
+                        @Override public void 
apply(IgniteInternalFuture<Boolean> fut) {
+                            try {
+                                res.onDone(fut.get(), fut.error());
+                            }
+                            catch (IgniteCheckedException e) {
+                                res.onDone(false, e);
+                            }
+                        }
+                    });
+                }
+                catch (Exception e) {
+                    res.onDone(false, e);
+                }
+            }
+        });
+
+        return res;
+    }
+
+    /**
      * @param startReqs Start requests.
      * @param cachesToClose Cache tp close.
      * @return Future for cache change operation.
@@ -3167,7 +3252,7 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
      * @param disabledAfterStart If true, cache proxies will be only activated 
after {@link #restartProxies()}.
      * @return Future that will be completed when all caches are deployed.
      */
-    public IgniteInternalFuture<?> 
dynamicStartCaches(Collection<CacheConfiguration> ccfgList, boolean 
failIfExists,
+    public IgniteInternalFuture<Boolean> 
dynamicStartCaches(Collection<CacheConfiguration> ccfgList, boolean 
failIfExists,
         boolean checkThreadTx, boolean disabledAfterStart) {
         return dynamicStartCachesByStoredConf(
             
ccfgList.stream().map(StoredCacheData::new).collect(Collectors.toList()),
@@ -3186,7 +3271,7 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
      * @param disabledAfterStart If true, cache proxies will be only activated 
after {@link #restartProxies()}.
      * @return Future that will be completed when all caches are deployed.
      */
-    public IgniteInternalFuture<?> dynamicStartCachesByStoredConf(
+    public IgniteInternalFuture<Boolean> dynamicStartCachesByStoredConf(
         Collection<StoredCacheData> storedCacheDataList,
         boolean failIfExists,
         boolean checkThreadTx,
@@ -3194,11 +3279,15 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
         if (checkThreadTx)
             checkEmptyTransactions();
 
-        List<DynamicCacheChangeRequest> srvReqs = null;
-        Map<String, DynamicCacheChangeRequest> clientReqs = null;
+        GridPlainClosure<Collection<byte[]>, IgniteInternalFuture<Boolean>> 
startCacheClsr = (grpKeys) -> {
+            List<DynamicCacheChangeRequest> srvReqs = null;
+            Map<String, DynamicCacheChangeRequest> clientReqs = null;
+
+            Iterator<byte[]> grpKeysIter = grpKeys.iterator();
 
-        try {
             for (StoredCacheData ccfg : storedCacheDataList) {
+                assert !ccfg.config().isEncryptionEnabled() || 
grpKeysIter.hasNext();
+
                 DynamicCacheChangeRequest req = prepareCacheChangeRequest(
                     ccfg.config(),
                     ccfg.config().getName(),
@@ -3208,7 +3297,8 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
                     failIfExists,
                     true,
                     disabledAfterStart,
-                    ccfg.queryEntities());
+                    ccfg.queryEntities(),
+                    ccfg.config().isEncryptionEnabled() ? grpKeysIter.next() : 
null);
 
                 if (req != null) {
                     if (req.clientStartOnly()) {
@@ -3225,16 +3315,14 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
                     }
                 }
             }
-        }
-        catch (Exception e) {
-            return new GridFinishedFuture<>(e);
-        }
 
-        if (srvReqs != null || clientReqs != null) {
+            if (srvReqs == null && clientReqs == null)
+                return new GridFinishedFuture<>();
+
             if (clientReqs != null && srvReqs == null)
                 return startClientCacheChange(clientReqs, null);
 
-            GridCompoundFuture<?, ?> compoundFut = new GridCompoundFuture<>();
+            GridCompoundFuture<?, Boolean> compoundFut = new 
GridCompoundFuture<>();
 
             for (DynamicCacheStartFuture fut : initiateCacheChanges(srvReqs))
                 compoundFut.add((IgniteInternalFuture)fut);
@@ -3248,9 +3336,16 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
             compoundFut.markInitialized();
 
             return compoundFut;
+        };
+
+        int encGrpCnt = 0;
+
+        for (StoredCacheData ccfg : storedCacheDataList) {
+            if (ccfg.config().isEncryptionEnabled())
+                encGrpCnt++;
         }
-        else
-            return new GridFinishedFuture<>();
+
+        return generateEncryptionKeysAndStartCacheAfter(encGrpCnt, 
startCacheClsr);
     }
 
     /** Resolve cache type for input cacheType */
@@ -4539,6 +4634,7 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
      * @param failIfNotStarted If {@code true} fails if cache is not started.
      * @param disabledAfterStart If true, cache proxies will be only activated 
after {@link #restartProxies()}.
      * @param qryEntities Query entities.
+     * @param encKey Encryption key.
      * @return Request or {@code null} if cache already exists.
      * @throws IgniteCheckedException if some of pre-checks failed
      * @throws CacheExistsException if cache exists and failIfExists flag is 
{@code true}
@@ -4552,7 +4648,8 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
         boolean failIfExists,
         boolean failIfNotStarted,
         boolean disabledAfterStart,
-        @Nullable Collection<QueryEntity> qryEntities
+        @Nullable Collection<QueryEntity> qryEntities,
+        @Nullable byte[] encKey
     ) throws IgniteCheckedException {
         DynamicCacheDescriptor desc = cacheDescriptor(cacheName);
 
@@ -4564,6 +4661,8 @@ public class GridCacheProcessor extends 
GridProcessorAdapter implements Metastor
 
         req.disabledAfterStart(disabledAfterStart);
 
+        req.encryptionKey(encKey);
+
         if (ccfg != null) {
             cloneCheckSerializable(ccfg);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index 91a449f..c316621 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -58,6 +58,7 @@ import 
org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.TransactionConfiguration;
+import org.apache.ignite.spi.encryption.EncryptionSpi;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -1149,6 +1150,17 @@ public class GridCacheUtils {
     }
 
     /**
+     * @param cacheName Cache name.
+     * @param grpName Group name.
+     * @return Group ID.
+     */
+    public static int cacheGroupId(String cacheName, @Nullable String grpName) 
{
+        assert cacheName != null;
+
+        return grpName != null ? CU.cacheId(grpName) : CU.cacheId(cacheName);
+    }
+
+    /**
      * @param cfg Grid configuration.
      * @param cacheName Cache name.
      * @return {@code True} in this is IGFS data or meta cache.
@@ -1900,6 +1912,17 @@ public class GridCacheUtils {
     }
 
     /**
+     * @param pageSize Page size.
+     * @param encSpi Encryption spi.
+     * @return Page size without encryption overhead.
+     */
+    public static int encryptedPageSize(int pageSize, EncryptionSpi encSpi) {
+        return pageSize
+            - (encSpi.encryptedSizeNoPadding(pageSize) - pageSize)
+            - encSpi.blockSize(); /* For CRC. */
+    }
+
+    /**
      * @param sctx Shared context.
      * @param cacheIds Cache ids.
      * @return First partitioned cache or {@code null} in case no partitioned 
cache ids are in list.

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index a968737..0182c8a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -3139,7 +3139,8 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
 
             DataPageIO iox = (DataPageIO)io;
 
-            int offset = iox.getPayloadOffset(pageAddr, itemId, 
grp.dataRegion().pageMemory().pageSize(), MVCC_INFO_SIZE);
+            int offset = iox.getPayloadOffset(pageAddr, itemId,
+                grp.dataRegion().pageMemory().realPageSize(grp.groupId()), 
MVCC_INFO_SIZE);
 
             long newCrd = iox.newMvccCoordinator(pageAddr, offset);
             long newCntr = iox.newMvccCounter(pageAddr, offset);
@@ -3168,8 +3169,8 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
 
             DataPageIO iox = (DataPageIO)io;
 
-            int pageSize = grp.dataRegion().pageMemory().pageSize();
-            int offset = iox.getPayloadOffset(pageAddr, itemId, pageSize, 
MVCC_INFO_SIZE);
+            int offset = iox.getPayloadOffset(pageAddr, itemId,
+                grp.dataRegion().pageMemory().realPageSize(grp.groupId()), 
MVCC_INFO_SIZE);
 
             long crd = iox.mvccCoordinator(pageAddr, offset);
             long cntr = iox.mvccCounter(pageAddr, offset);
@@ -3222,7 +3223,8 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
 
             DataPageIO iox = (DataPageIO)io;
 
-            int offset = iox.getPayloadOffset(pageAddr, itemId, 
grp.dataRegion().pageMemory().pageSize(), MVCC_INFO_SIZE);
+            int offset = iox.getPayloadOffset(pageAddr, itemId,
+                grp.dataRegion().pageMemory().realPageSize(grp.groupId()), 
MVCC_INFO_SIZE);
 
             long crd = iox.mvccCoordinator(pageAddr, offset);
             long cntr = iox.mvccCounter(pageAddr, offset);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index f43afa0..2052c36 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -1052,6 +1052,8 @@ public class GridDhtPartitionsExchangeFuture extends 
GridDhtTopologyFutureAdapte
 
                     registerCachesFuture = 
cctx.affinity().onCacheChangeRequest(this, crd, exchActions);
 
+                    
cctx.kernalContext().encryption().onDeActivate(cctx.kernalContext());
+
                     if (log.isInfoEnabled()) {
                         log.info("Successfully deactivated data structures, 
services and caches [" +
                             "nodeId=" + cctx.localNodeId() +

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
index 896c9aa..a659245 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
@@ -577,7 +577,8 @@ public class MvccUtils {
             try{
                 DataPageIO dataIo = DataPageIO.VERSIONS.forPage(pageAddr);
 
-                int offset = dataIo.getPayloadOffset(pageAddr, itemId(link), 
pageMem.pageSize(), MVCC_INFO_SIZE);
+                int offset = dataIo.getPayloadOffset(pageAddr, itemId(link), 
pageMem.realPageSize(grpId),
+                    MVCC_INFO_SIZE);
 
                 long mvccCrd = dataIo.mvccCoordinator(pageAddr, offset);
                 long mvccCntr = dataIo.mvccCounter(pageAddr, offset);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
index 574e6d5..8b44ff6 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
@@ -155,7 +155,7 @@ public class CacheDataRowAdapter implements CacheDataRow {
 
                     DataPagePayload data = io.readPayload(pageAddr,
                         itemId(nextLink),
-                        pageMem.pageSize());
+                        pageMem.realPageSize(grpId));
 
                     nextLink = data.nextLink();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
index 0177407..c23a970 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
@@ -387,10 +387,10 @@ public abstract class DataStructure implements 
PageLockListener {
     }
 
     /**
-     * @return Page size.
+     * @return Page size without encryption overhead.
      */
-    protected final int pageSize() {
-        return pageMem.pageSize();
+    protected int pageSize() {
+        return pageMem.realPageSize(grpId);
     }
 
     @Override public void onBeforeWriteLock(int cacheId, long pageId, long 
page) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index d54a64f..b2f2f33 100755
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -1430,6 +1430,9 @@ public class GridCacheDatabaseSharedManager extends 
IgniteCacheDatabaseSharedMan
             grpIds.add(tup.get1().groupId());
 
             pageMem.onCacheGroupDestroyed(tup.get1().groupId());
+
+            if (tup.get2())
+                
cctx.kernalContext().encryption().onCacheGroupDestroyed(gctx.groupId());
         }
 
         Collection<IgniteInternalFuture<Void>> clearFuts = new 
ArrayList<>(destroyed.size());

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
index 801703b..c6f8415 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
@@ -482,8 +482,6 @@ public class GridCacheOffheapManager extends 
IgniteCacheOffheapManagerImpl imple
             try {
                 final long curAddr = pageMem.writeLock(grpId, curId, curPage);
 
-                int pageSize = pageMem.pageSize();
-
                 assert curAddr != 0;
 
                 try {
@@ -492,12 +490,12 @@ public class GridCacheOffheapManager extends 
IgniteCacheOffheapManagerImpl imple
                     if (init) {
                         partCntrIo = PagePartitionCountersIO.VERSIONS.latest();
 
-                        partCntrIo.initNewPage(curAddr, curId, pageSize);
+                        partCntrIo.initNewPage(curAddr, curId, 
pageMem.realPageSize(grpId));
                     }
                     else
                         partCntrIo = PageIO.getPageIO(curAddr);
 
-                    written += partCntrIo.writeCacheSizes(pageSize, curAddr, 
data, written);
+                    written += 
partCntrIo.writeCacheSizes(pageMem.realPageSize(grpId), curAddr, data, written);
 
                     nextId = partCntrIo.getNextCountersPageId(curAddr);
 
@@ -727,7 +725,7 @@ public class GridCacheOffheapManager extends 
IgniteCacheOffheapManagerImpl imple
                 if (PageIO.getType(pageAddr) != PageIO.T_META) {
                     PageMetaIO pageIO = PageMetaIO.VERSIONS.latest();
 
-                    pageIO.initNewPage(pageAddr, metaId, pageMem.pageSize());
+                    pageIO.initNewPage(pageAddr, metaId, 
pageMem.realPageSize(grpId));
 
                     metastoreRoot = pageMem.allocatePage(grpId, 
PageIdAllocator.INDEX_PARTITION, PageMemory.FLAG_IDX);
                     reuseListRoot = pageMem.allocatePage(grpId, 
PageIdAllocator.INDEX_PARTITION, PageMemory.FLAG_IDX);
@@ -1464,7 +1462,7 @@ public class GridCacheOffheapManager extends 
IgniteCacheOffheapManagerImpl imple
                     if (PageIO.getType(pageAddr) != PageIO.T_PART_META) {
                         PagePartitionMetaIO io = 
PagePartitionMetaIO.VERSIONS.latest();
 
-                        io.initNewPage(pageAddr, partMetaId, 
pageMem.pageSize());
+                        io.initNewPage(pageAddr, partMetaId, 
pageMem.realPageSize(grpId));
 
                         treeRoot = pageMem.allocatePage(grpId, partId, 
PageMemory.FLAG_DATA);
                         reuseListRoot = pageMem.allocatePage(grpId, partId, 
PageMemory.FLAG_DATA);
@@ -1478,8 +1476,10 @@ public class GridCacheOffheapManager extends 
IgniteCacheOffheapManagerImpl imple
                         io.setReuseListRoot(pageAddr, reuseListRoot);
                         io.setPendingTreeRoot(pageAddr, pendingTreeRoot);
 
-                        if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, 
partMetaId, partMetaPage, wal, null))
-                            wal.log(new PageSnapshot(new 
FullPageId(partMetaId, grpId), pageAddr, pageMem.pageSize()));
+                        if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, 
partMetaId, partMetaPage, wal, null)) {
+                            wal.log(new PageSnapshot(new 
FullPageId(partMetaId, grpId), pageAddr,
+                                pageMem.pageSize(), 
pageMem.realPageSize(grpId)));
+                        }
 
                         allocated = true;
                     }
@@ -1508,8 +1508,11 @@ public class GridCacheOffheapManager extends 
IgniteCacheOffheapManagerImpl imple
 
                             io.setPendingTreeRoot(pageAddr, pendingTreeRoot);
 
-                            if (PageHandler.isWalDeltaRecordNeeded(pageMem, 
grpId, partMetaId, partMetaPage, wal, null))
-                                wal.log(new PageSnapshot(new 
FullPageId(partMetaId, grpId), pageAddr, pageMem.pageSize()));
+                            if (PageHandler.isWalDeltaRecordNeeded(pageMem, 
grpId, partMetaId, partMetaPage, wal,
+                                null)) {
+                                wal.log(new PageSnapshot(new 
FullPageId(partMetaId, grpId), pageAddr,
+                                    pageMem.pageSize(), 
pageMem.realPageSize(grpId)));
+                            }
 
                             pendingTreeAllocated = true;
                         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIO.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIO.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIO.java
new file mode 100644
index 0000000..008a728
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIO.java
@@ -0,0 +1,371 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.persistence.file;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import org.apache.ignite.spi.encryption.EncryptionSpi;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
+import 
org.apache.ignite.internal.processors.cache.persistence.wal.crc.PureJavaCrc32;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+
+/**
+ * Implementation of {@code FileIO} that supports encryption(decryption) of 
pages written(readed) to(from) file.
+ *
+ * @see EncryptedFileIOFactory
+ */
+public class EncryptedFileIO implements FileIO {
+    /**
+     * Underlying file.
+     */
+    private final FileIO plainFileIO;
+
+    /**
+     * Group id.
+     */
+    private final int groupId;
+
+    /**
+     * Size of plain data page in bytes.
+     */
+    private final int pageSize;
+
+    /**
+     * Size of file header in bytes.
+     */
+    private final int headerSize;
+
+    /**
+     * Shared database manager.
+     */
+    private final GridEncryptionManager encMgr;
+
+    /**
+     * Shared database manager.
+     */
+    private final EncryptionSpi encSpi;
+
+    /**
+     * Encryption key.
+     */
+    private Serializable encKey;
+
+    /**
+     * Extra bytes added by encryption.
+     */
+    private final int encryptionOverhead;
+
+    /**
+     * Array of zeroes to fulfill tail of decrypted page.
+     */
+    private final byte[] zeroes;
+
+    /**
+     * @param plainFileIO Underlying file.
+     * @param groupId Group id.
+     * @param pageSize Size of plain data page in bytes.
+     * @param headerSize Size of file header in bytes.
+     * @param encMgr Encryption manager.
+     */
+    EncryptedFileIO(FileIO plainFileIO, int groupId, int pageSize, int 
headerSize,
+        GridEncryptionManager encMgr, EncryptionSpi encSpi) {
+        this.plainFileIO = plainFileIO;
+        this.groupId = groupId;
+        this.pageSize = pageSize;
+        this.headerSize = headerSize;
+        this.encMgr = encMgr;
+        this.encSpi = encSpi;
+
+        this.encryptionOverhead = pageSize - CU.encryptedPageSize(pageSize, 
encSpi);
+        this.zeroes =  new byte[encryptionOverhead];
+    }
+
+    /** {@inheritDoc} */
+    @Override public long position() throws IOException {
+        return plainFileIO.position();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void position(long newPosition) throws IOException {
+        plainFileIO.position(newPosition);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int read(ByteBuffer destBuf) throws IOException {
+        assert position() == 0;
+
+        return plainFileIO.read(destBuf);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int readFully(ByteBuffer destBuf) throws IOException {
+        return read(destBuf);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int read(ByteBuffer destBuf, long position) throws 
IOException {
+        assert destBuf.remaining() >= pageSize;
+        assert position() != 0;
+
+        ByteBuffer encrypted = ByteBuffer.allocate(pageSize);
+
+        int res = plainFileIO.read(encrypted, position);
+
+        if (res < 0)
+            return res;
+
+        if (res != pageSize) {
+            throw new IllegalStateException("Expecting to read whole page[" + 
pageSize + " bytes], " +
+                "but read only " + res + " bytes");
+        }
+
+        encrypted.rewind();
+
+        decrypt(encrypted, destBuf);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int readFully(ByteBuffer destBuf, long position) throws 
IOException {
+        assert destBuf.capacity() == pageSize;
+        assert position() != 0;
+
+        ByteBuffer encrypted = ByteBuffer.allocate(pageSize);
+
+        int res = plainFileIO.readFully(encrypted, position);
+
+        if (res < 0)
+            return res;
+
+        if (res != pageSize) {
+            throw new IllegalStateException("Expecting to read whole page[" + 
pageSize + " bytes], " +
+                "but read only " + res + " bytes");
+        }
+
+        encrypted.rewind();
+
+        decrypt(encrypted, destBuf);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int read(byte[] buf, int off, int len) throws IOException 
{
+        throw new UnsupportedOperationException("Encrypted File doesn't 
support this operation");
+    }
+
+    /** {@inheritDoc} */
+    @Override public int readFully(byte[] buf, int off, int len) throws 
IOException {
+        return read(buf, off, len);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int write(ByteBuffer srcBuf) throws IOException {
+        assert position() == 0;
+        assert headerSize == srcBuf.capacity();
+
+        return plainFileIO.write(srcBuf);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int writeFully(ByteBuffer srcBuf) throws IOException {
+        return write(srcBuf);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int write(ByteBuffer srcBuf, long position) throws 
IOException {
+        ByteBuffer encrypted = ByteBuffer.allocate(pageSize);
+
+        encrypt(srcBuf, encrypted);
+
+        encrypted.rewind();
+
+        return plainFileIO.write(encrypted, position);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int writeFully(ByteBuffer srcBuf, long position) throws 
IOException {
+        ByteBuffer encrypted = ByteBuffer.allocate(pageSize);
+
+        encrypt(srcBuf, encrypted);
+
+        encrypted.rewind();
+
+        return plainFileIO.writeFully(encrypted, position);
+    }
+
+    /**
+     * @param srcBuf Source buffer.
+     * @param res Destination buffer.
+     * @throws IOException If failed.
+     */
+    private void encrypt(ByteBuffer srcBuf, ByteBuffer res) throws IOException 
{
+        assert position() != 0;
+        assert srcBuf.remaining() >= pageSize;
+        assert tailIsEmpty(srcBuf, PageIO.getType(srcBuf));
+
+        int srcLimit = srcBuf.limit();
+
+        srcBuf.limit(srcBuf.position() + plainDataSize());
+
+        encSpi.encryptNoPadding(srcBuf, key(), res);
+
+        res.rewind();
+
+        storeCRC(res);
+
+        srcBuf.limit(srcLimit);
+        srcBuf.position(srcBuf.position() + encryptionOverhead);
+    }
+
+    /**
+     * @param encrypted Encrypted buffer.
+     * @param destBuf Destination buffer.
+     */
+    private void decrypt(ByteBuffer encrypted, ByteBuffer destBuf) throws 
IOException {
+        assert encrypted.remaining() >= pageSize;
+        assert encrypted.limit() >= pageSize;
+
+        checkCRC(encrypted);
+
+        encrypted.limit(encryptedDataSize());
+
+        encSpi.decryptNoPadding(encrypted, key(), destBuf);
+
+        destBuf.put(zeroes); //Forcibly purge page buffer tail.
+    }
+
+    /**
+     * Stores CRC in res.
+     *
+     * @param res Destination buffer.
+     */
+    private void storeCRC(ByteBuffer res) {
+        int crc = PureJavaCrc32.calcCrc32(res, encryptedDataSize());
+
+        res.put((byte) (crc >> 24));
+        res.put((byte) (crc >> 16));
+        res.put((byte) (crc >> 8));
+        res.put((byte) crc);
+    }
+
+    /**
+     * Checks encrypted data integrity.
+     *
+     * @param encrypted Encrypted data buffer.
+     */
+    private void checkCRC(ByteBuffer encrypted) throws IOException {
+        int crc = PureJavaCrc32.calcCrc32(encrypted, encryptedDataSize());
+
+        int storedCrc = 0;
+
+        storedCrc |= (int)encrypted.get() << 24;
+        storedCrc |= ((int)encrypted.get() & 0xff) << 16;
+        storedCrc |= ((int)encrypted.get() & 0xff) << 8;
+        storedCrc |= encrypted.get() & 0xff;
+
+        if(crc != storedCrc) {
+            throw new IOException("Content of encrypted page is broken. 
[StoredCrc=" + storedCrc +
+                ", calculatedCrd=" + crc + "]");
+        }
+
+        encrypted.position(encrypted.position() - (encryptedDataSize() + 4 /* 
CRC size. */));
+    }
+
+    /**
+     * @return Encrypted data size.
+     */
+    private int encryptedDataSize() {
+        return pageSize - encSpi.blockSize();
+    }
+
+    /**
+     * @return Plain data size.
+     */
+    private int plainDataSize() {
+        return pageSize - encryptionOverhead;
+    }
+
+    /** */
+    private boolean tailIsEmpty(ByteBuffer src, int pageType) {
+        int srcPos = src.position();
+
+        src.position(srcPos + plainDataSize());
+
+        for (int i = 0; i < encryptionOverhead; i++)
+            assert src.get() == 0 : "Tail of src should be empty [i=" + i + ", 
pageType=" + pageType + "]";
+
+        src.position(srcPos);
+
+        return true;
+    }
+
+    /**
+     * @return Encryption key.
+     */
+    private Serializable key() {
+        if (encKey == null)
+            return encKey = encMgr.groupKey(groupId);
+
+        return encKey;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int write(byte[] buf, int off, int len) throws 
IOException {
+        throw new UnsupportedOperationException("Encrypted File doesn't 
support this operation");
+    }
+
+    /** {@inheritDoc} */
+    @Override public int writeFully(byte[] buf, int off, int len) throws 
IOException {
+        return write(buf, off, len);
+    }
+
+    /** {@inheritDoc} */
+    @Override public MappedByteBuffer map(int sizeBytes) throws IOException {
+        throw new UnsupportedOperationException("Encrypted File doesn't 
support this operation");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void force() throws IOException {
+        plainFileIO.force();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void force(boolean withMetadata) throws IOException {
+        plainFileIO.force(withMetadata);
+    }
+
+    /** {@inheritDoc} */
+    @Override public long size() throws IOException {
+        return plainFileIO.size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear() throws IOException {
+        plainFileIO.clear();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void close() throws IOException {
+        plainFileIO.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIOFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIOFactory.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIOFactory.java
new file mode 100644
index 0000000..336aab6
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/EncryptedFileIOFactory.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.persistence.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.OpenOption;
+import org.apache.ignite.spi.encryption.EncryptionSpi;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
+
+/**
+ * Factory to produce {@code EncryptedFileIO}.
+ */
+public class EncryptedFileIOFactory implements FileIOFactory {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /**
+     * Factory to produce underlying {@code FileIO} instances.
+     */
+    private FileIOFactory plainIOFactory;
+
+    /**
+     * Size of plain data page in bytes.
+     */
+    private int pageSize;
+
+    /**
+     * Size of file header in bytes.
+     */
+    private int headerSize;
+
+    /**
+     * Group id.
+     */
+    private int groupId;
+
+    /**
+     * Encryption manager.
+     */
+    private GridEncryptionManager encMgr;
+
+    /**
+     * Encryption spi.
+     */
+    private EncryptionSpi encSpi;
+
+    /**
+     * @param plainIOFactory Underlying file factory.
+     * @param groupId Group id.
+     * @param pageSize Size of plain data page in bytes.
+     * @param encMgr Encryption manager.
+     */
+    EncryptedFileIOFactory(FileIOFactory plainIOFactory, int groupId, int 
pageSize, GridEncryptionManager encMgr,
+        EncryptionSpi encSpi) {
+        this.plainIOFactory = plainIOFactory;
+        this.groupId = groupId;
+        this.pageSize = pageSize;
+        this.encMgr = encMgr;
+        this.encSpi = encSpi;
+    }
+
+    /** {@inheritDoc} */
+    @Override public FileIO create(File file) throws IOException {
+        FileIO io = plainIOFactory.create(file);
+
+        return new EncryptedFileIO(io, groupId, pageSize, headerSize, encMgr, 
encSpi);
+    }
+
+    /** {@inheritDoc} */
+    @Override public FileIO create(File file, OpenOption... modes) throws 
IOException {
+        FileIO io = plainIOFactory.create(file, modes);
+
+        return new EncryptedFileIO(io, groupId, pageSize, headerSize, encMgr, 
encSpi);
+    }
+
+    /**
+     * Sets size of file header in bytes.
+     *
+     * @param headerSize Size of file header in bytes.
+     */
+    void headerSize(int headerSize) {
+        this.headerSize = headerSize;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
index 110807c..2e07867 100755
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
@@ -235,11 +235,8 @@ public class FilePageStore implements PageStore {
         return fileSize;
     }
 
-    /**
-     * @param delete {@code True} to delete file.
-     * @throws StorageException If failed in case of underlying I/O exception.
-     */
-    public void stop(boolean delete) throws StorageException {
+    /** {@inheritDoc} */
+    @Override public void stop(boolean delete) throws StorageException {
         lock.writeLock().lock();
 
         try {
@@ -264,13 +261,8 @@ public class FilePageStore implements PageStore {
         }
     }
 
-    /**
-     * Truncates and deletes partition file.
-     *
-     * @param tag New partition tag.
-     * @throws StorageException If failed in case of underlying I/O exception.
-     */
-    public void truncate(int tag) throws StorageException {
+    /** {@inheritDoc} */
+    @Override public void truncate(int tag) throws StorageException {
         init();
 
         lock.writeLock().lock();
@@ -298,10 +290,8 @@ public class FilePageStore implements PageStore {
         }
     }
 
-    /**
-     *
-     */
-    public void beginRecover() {
+    /** {@inheritDoc} */
+    @Override public void beginRecover() {
         lock.writeLock().lock();
 
         try {
@@ -312,10 +302,8 @@ public class FilePageStore implements PageStore {
         }
     }
 
-    /**
-     * @throws StorageException If failed in case of underlying I/O exception.
-     */
-    public void finishRecover() throws StorageException {
+    /** {@inheritDoc} */
+    @Override public void finishRecover() throws StorageException {
         lock.writeLock().lock();
 
         try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
index fe93d07..2fb1d50 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
@@ -20,6 +20,7 @@ package 
org.apache.ignite.internal.processors.cache.persistence.file;
 import java.io.File;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.pagemem.PageIdAllocator;
+import org.apache.ignite.internal.pagemem.store.PageStore;
 import 
org.apache.ignite.internal.processors.cache.persistence.AllocatedPageTracker;
 
 /**
@@ -32,5 +33,5 @@ public interface FilePageStoreFactory {
      * @param type Data type, can be {@link PageIdAllocator#FLAG_IDX} or 
{@link PageIdAllocator#FLAG_DATA}.
      * @param file File Page store file.
      */
-    public FilePageStore createPageStore(byte type, File file, 
AllocatedPageTracker allocatedTracker) throws IgniteCheckedException;
+    PageStore createPageStore(byte type, File file, AllocatedPageTracker 
allocatedTracker) throws IgniteCheckedException;
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
index 101a33d..c6cd9e5 100755
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
@@ -262,7 +262,7 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
         for (CacheStoreHolder holder : idxCacheStores.values()) {
             holder.idxStore.beginRecover();
 
-            for (FilePageStore partStore : holder.partStores)
+            for (PageStore partStore : holder.partStores)
                 partStore.beginRecover();
         }
     }
@@ -273,7 +273,7 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
             for (CacheStoreHolder holder : idxCacheStores.values()) {
                 holder.idxStore.finishRecover();
 
-                for (FilePageStore partStore : holder.partStores)
+                for (PageStore partStore : holder.partStores)
                     partStore.finishRecover();
             }
         }
@@ -292,7 +292,8 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
                 new File(storeWorkDir, workingDir),
                 cacheId,
                 partitions,
-                tracker
+                tracker,
+                cctx.cacheContext(cacheId) != null && 
cctx.cacheContext(cacheId).config().isEncryptionEnabled()
             );
 
             CacheStoreHolder old = idxCacheStores.put(cacheId, holder);
@@ -321,9 +322,10 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
         if (!idxCacheStores.containsKey(grpId)) {
             CacheStoreHolder holder = initDir(
                 new File(storeWorkDir, META_STORAGE_NAME),
-                grpId,
-                1,
-                AllocatedPageTracker.NO_OP );
+                    grpId,
+                    1,
+                    AllocatedPageTracker.NO_OP,
+                    false);
 
             CacheStoreHolder old = idxCacheStores.put(grpId, holder);
 
@@ -400,9 +402,7 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
 
         PageStore store = getStore(grpId, partId);
 
-        assert store instanceof FilePageStore : store;
-
-        ((FilePageStore)store).truncate(tag);
+        store.truncate(tag);
     }
 
     /** {@inheritDoc} */
@@ -521,7 +521,8 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
             cacheWorkDir,
             grpDesc.groupId(),
             grpDesc.config().getAffinity().partitions(),
-            allocatedTracker
+            allocatedTracker,
+            ccfg.isEncryptionEnabled()
         );
     }
 
@@ -530,13 +531,15 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
      * @param grpId Group ID.
      * @param partitions Number of partitions.
      * @param allocatedTracker Metrics updater.
+     * @param encrypted {@code True} if this cache encrypted.
      * @return Cache store holder.
      * @throws IgniteCheckedException If failed.
      */
     private CacheStoreHolder initDir(File cacheWorkDir,
         int grpId,
         int partitions,
-        AllocatedPageTracker allocatedTracker) throws IgniteCheckedException {
+        AllocatedPageTracker allocatedTracker,
+        boolean encrypted) throws IgniteCheckedException {
         try {
             boolean dirExisted = checkAndInitCacheWorkDir(cacheWorkDir);
 
@@ -545,19 +548,48 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
             if (dirExisted && !idxFile.exists())
                 grpsWithoutIdx.add(grpId);
 
-            FilePageStoreFactory pageStoreFactory = new 
FileVersionCheckingFactory(
-                pageStoreFileIoFactory, pageStoreV1FileIoFactory, 
igniteCfg.getDataStorageConfiguration());
 
-            FilePageStore idxStore =
+            FileIOFactory pageStoreFileIoFactory = this.pageStoreFileIoFactory;
+            FileIOFactory pageStoreV1FileIoFactory = 
this.pageStoreV1FileIoFactory;
+
+            if (encrypted) {
+                pageStoreFileIoFactory = new EncryptedFileIOFactory(
+                    this.pageStoreFileIoFactory,
+                    grpId,
+                    pageSize(),
+                    cctx.kernalContext().encryption(),
+                    cctx.gridConfig().getEncryptionSpi());
+
+                pageStoreV1FileIoFactory = new EncryptedFileIOFactory(
+                    this.pageStoreV1FileIoFactory,
+                    grpId,
+                    pageSize(),
+                    cctx.kernalContext().encryption(),
+                    cctx.gridConfig().getEncryptionSpi());
+            }
+
+            FileVersionCheckingFactory pageStoreFactory = new 
FileVersionCheckingFactory(
+                pageStoreFileIoFactory,
+                pageStoreV1FileIoFactory,
+                igniteCfg.getDataStorageConfiguration());
+
+            if (encrypted) {
+                int headerSize = 
pageStoreFactory.headerSize(pageStoreFactory.latestVersion());
+
+                
((EncryptedFileIOFactory)pageStoreFileIoFactory).headerSize(headerSize);
+                
((EncryptedFileIOFactory)pageStoreV1FileIoFactory).headerSize(headerSize);
+            }
+
+            PageStore idxStore =
             pageStoreFactory.createPageStore(
                 PageMemory.FLAG_IDX,
                 idxFile,
                 allocatedTracker);
 
-            FilePageStore[] partStores = new FilePageStore[partitions];
+            PageStore[] partStores = new PageStore[partitions];
 
             for (int partId = 0; partId < partStores.length; partId++) {
-                FilePageStore partStore =
+                PageStore partStore =
                     pageStoreFactory.createPageStore(
                         PageMemory.FLAG_DATA,
                         getPartitionFile(cacheWorkDir, partId),
@@ -885,7 +917,7 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
         @Nullable IgniteCheckedException aggr) {
         aggr = shutdown(holder.idxStore, cleanFile, aggr);
 
-        for (FilePageStore store : holder.partStores) {
+        for (PageStore store : holder.partStores) {
             if (store != null)
                 aggr = shutdown(store, cleanFile, aggr);
         }
@@ -942,7 +974,7 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
      * @param aggr Aggregating exception.
      * @return Aggregating exception, if error occurred.
      */
-    private IgniteCheckedException shutdown(FilePageStore store, boolean 
cleanFile, IgniteCheckedException aggr) {
+    private IgniteCheckedException shutdown(PageStore store, boolean 
cleanFile, IgniteCheckedException aggr) {
         try {
             if (store != null)
                 store.stop(cleanFile);
@@ -978,7 +1010,7 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
         if (partId > PageIdAllocator.MAX_PARTITION_ID)
             throw new IgniteCheckedException("Partition ID is reserved: " + 
partId);
 
-        FilePageStore store = holder.partStores[partId];
+        PageStore store = holder.partStores[partId];
 
         if (store == null)
             throw new IgniteCheckedException("Failed to get page store for the 
given partition ID " +
@@ -1038,15 +1070,15 @@ public class FilePageStoreManager extends 
GridCacheSharedManagerAdapter implemen
      */
     private static class CacheStoreHolder {
         /** Index store. */
-        private final FilePageStore idxStore;
+        private final PageStore idxStore;
 
         /** Partition stores. */
-        private final FilePageStore[] partStores;
+        private final PageStore[] partStores;
 
         /**
          *
          */
-        CacheStoreHolder(FilePageStore idxStore, FilePageStore[] partStores) {
+        public CacheStoreHolder(PageStore idxStore, PageStore[] partStores) {
             this.idxStore = idxStore;
             this.partStores = partStores;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
index bc938a5..af478de 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
@@ -62,14 +62,6 @@ public class FileVersionCheckingFactory implements 
FilePageStoreFactory {
         this.memCfg = memCfg;
     }
 
-    /**
-     * @param fileIOFactory File IO factory for V1 & V2 page store and for 
version checking.
-     * @param memCfg Memory configuration.
-     */
-    public FileVersionCheckingFactory(FileIOFactory fileIOFactory, 
DataStorageConfiguration memCfg) {
-        this(fileIOFactory, fileIOFactory, memCfg);
-    }
-
     /** {@inheritDoc} */
     @Override public FilePageStore createPageStore(
         byte type,
@@ -140,4 +132,21 @@ public class FileVersionCheckingFactory implements 
FilePageStoreFactory {
                 throw new IllegalArgumentException("Unknown version of file 
page store: " + ver + " for file [" + file.getAbsolutePath() + "]");
         }
     }
+
+    /**
+     * @param ver Version.
+     * @return Header size.
+     */
+    public int headerSize(int ver) {
+        switch (ver) {
+            case FilePageStore.VERSION:
+                return FilePageStore.HEADER_SIZE;
+
+            case FilePageStoreV2.VERSION:
+                return memCfg.getPageSize();
+
+            default:
+                throw new IllegalArgumentException("Unknown version of file 
page store.");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index 831465d..f1cc32a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -276,7 +276,9 @@ public abstract class PagesList extends DataStructure {
                     int tailIdx = 0;
 
                     while (tailIdx < tails.length) {
-                        int written = curPage != 0L ? 
curIo.addTails(pageMem.pageSize(), curAddr, bucket, tails, tailIdx) : 0;
+                        int written = curPage != 0L ?
+                            curIo.addTails(pageMem.realPageSize(grpId), 
curAddr, bucket, tails, tailIdx) :
+                            0;
 
                         if (written == 0) {
                             if (nextPageId == 0L) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ae9c180/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
index 556d997..3981d4d 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
@@ -361,6 +361,7 @@ public class MetaStorage implements DbCheckpointListener, 
ReadOnlyMetastorage, R
                         // Initialize new page.
                         PagePartitionMetaIO io = 
PagePartitionMetaIO.VERSIONS.latest();
 
+                        //MetaStorage never encrypted so realPageSize == 
pageSize.
                         io.initNewPage(pageAddr, partMetaId, 
pageMem.pageSize());
 
                         treeRoot = pageMem.allocatePage(METASTORAGE_CACHE_ID, 
partId, PageMemory.FLAG_DATA);
@@ -537,6 +538,7 @@ public class MetaStorage implements DbCheckpointListener, 
ReadOnlyMetastorage, R
                     try {
                         SimpleDataPageIO io = 
(SimpleDataPageIO)ioVersions().forPage(pageAddr);
 
+                        //MetaStorage never encrypted so realPageSize == 
pageSize.
                         DataPagePayload data = io.readPayload(pageAddr, 
itemId(nextLink), pageMem.pageSize());
 
                         nextLink = data.nextLink();

Reply via email to