diff --git a/pom.xml b/pom.xml
index 515bd24..339e615 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,8 +22,8 @@
     <parent>
         <groupId>org.onosproject</groupId>
         <artifactId>onos-dependencies</artifactId>
-        <version>1.10.9</version>
-        <relativePath></relativePath>
+        <version>1.12.1-SNAPSHOT</version>
+        <relativePath>../onos/lib/pom.xml</relativePath>
     </parent>
 
     <groupId>org.opencord</groupId>
@@ -35,7 +35,7 @@
 
     <properties>
         <onos.app.name>org.opencord.aaa</onos.app.name>
-        <onos.version>1.10.9</onos.version>
+        <onos.version>1.12.1-SNAPSHOT</onos.version>
         <onos.app.title>AAA App</onos.app.title>
         <onos.app.category>Security</onos.app.category>
         <onos.app.url>http://opencord.org</onos.app.url>
@@ -44,8 +44,8 @@
               org.onosproject.olt,
               org.opencord.sadis
         </onos.app.requires>
-        <sadis.api.version>2.0.0</sadis.api.version>
-        <olt.api.version>1.3.1</olt.api.version>
+        <sadis.api.version>2.0.1-SNAPSHOT</sadis.api.version>
+        <olt.api.version>1.3.2-SNAPSHOT</olt.api.version>
     </properties>
 
     <dependencies>
@@ -86,6 +86,28 @@
             <artifactId>onlab-junit</artifactId>
             <version>${onos.version}</version>
         </dependency>
+    
+         <dependency>
+              <groupId>org.onosproject</groupId>
+              <artifactId>onos-protocols-netconf-api</artifactId>
+              <version>1.8.5-SNAPSHOT</version>
+          </dependency>
+          <dependency>
+              <groupId>org.onosproject</groupId>
+              <artifactId>onos-protocols-netconf-ctl</artifactId>
+              <version>1.8.5-SNAPSHOT</version>
+          </dependency>
+
+          <dependency>
+              <groupId>org.apache.karaf.shell</groupId>
+              <artifactId>org.apache.karaf.shell.console</artifactId>
+         </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-common</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
 
     </dependencies>
 
diff --git a/src/main/java/org/opencord/aaa/AaaConfig.java b/src/main/java/org/opencord/aaa/AaaConfig.java
index 8ffdf00..99d1589 100644
--- a/src/main/java/org/opencord/aaa/AaaConfig.java
+++ b/src/main/java/org/opencord/aaa/AaaConfig.java
@@ -15,9 +15,6 @@
  */
 package org.opencord.aaa;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-
 import com.google.common.collect.ImmutableSet;
 
 import org.onosproject.core.ApplicationId;
@@ -54,7 +51,8 @@
     private static final String PACKET_CUSTOMIZER = "packetCustomizer";
 
     // RADIUS server IP address
-    protected static final String DEFAULT_RADIUS_IP = "10.128.10.4";
+    //protected static final String DEFAULT_RADIUS_IP = "10.128.10.4";
+    protected static final String DEFAULT_RADIUS_IP = "192.168.1.14";
 
     // RADIUS MAC address
     protected static final String DEFAULT_RADIUS_MAC = "00:00:00:00:01:10";
@@ -66,7 +64,8 @@
     protected static final String DEFAULT_NAS_MAC = "00:00:00:00:10:01";
 
     // RADIUS server shared secret
-    protected static final String DEFAULT_RADIUS_SECRET = "ONOSecret";
+    //protected static final String DEFAULT_RADIUS_SECRET = "ONOSecret";
+    protected static final String DEFAULT_RADIUS_SECRET = "karaf";
 
     // Radius Server UDP Port Number
     protected static final String DEFAULT_RADIUS_SERVER_PORT = "1812";
@@ -83,7 +82,6 @@
     // Packet Customizer Default value
     protected static final String DEFAULT_PACKET_CUSTOMIZER = "default";
 
-
     /**
      * Gets the value of a string property, protecting for an empty
      * JSON object.
@@ -271,7 +269,7 @@
         if (!object.has(RADIUS_SERVER_CONNECTPOINTS)) {
             return ImmutableSet.of();
         }
-
+       /* Following portion to be rewritten with out Guava ImmutableSet...
         ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
         ArrayNode arrayNode = (ArrayNode) object.path(RADIUS_SERVER_CONNECTPOINTS);
         for (JsonNode jsonNode : arrayNode) {
@@ -285,6 +283,7 @@
                 return null;
             }
         }
-        return builder.build();
+        return builder.build();*/
+        return new HashSet<ConnectPoint>();
     }
 }
diff --git a/src/main/java/org/opencord/aaa/AaaManager.java b/src/main/java/org/opencord/aaa/AaaManager.java
index 799064a..972a072 100755
--- a/src/main/java/org/opencord/aaa/AaaManager.java
+++ b/src/main/java/org/opencord/aaa/AaaManager.java
@@ -19,8 +19,10 @@
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.DeserializationException;
 import org.onlab.packet.EAP;
 import org.onlab.packet.EAPOL;
+import org.onlab.packet.EAPOL_MKPDU;
 import org.onlab.packet.EthType;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.MacAddress;
@@ -33,6 +35,7 @@
 import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigEvent;
@@ -43,6 +46,8 @@
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
@@ -57,11 +62,18 @@
 
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
+import java.util.AbstractMap;
 import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
 
 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
 import static org.slf4j.LoggerFactory.getLogger;
 
+import org.onlab.packet.EAPOL_MKPDU_BasicParameterSet.SCI;
+
 /**
  * AAA application for ONOS.
  */
@@ -97,6 +109,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected AccessDeviceService accessDeviceService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
     private final DeviceListener deviceListener = new InternalDeviceListener();
 
     // NAS IP address
@@ -143,20 +158,51 @@
     // latest configuration
     AaaConfig newCfg;
 
+    //MACSec verion
+    private String version;
+
+    //MACSec capability
+    private String capability;
+
+    //Secure Connectivity Association Key NameK
+    private String mkaCkn;
+
+    //Secure Connectivity Association Key
+    private String mkaCak;
+
+    //Default Netconf Device ID
+    private DeviceId defaultNetconfDeviceId;
+
     // Configuration properties factory
     private final ConfigFactory factory =
             new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY,
-                                                         AaaConfig.class,
-                                                         "AAA") {
+                    AaaConfig.class,
+                    "AAA") {
                 @Override
                 public AaaConfig createConfig() {
                     return new AaaConfig();
                 }
             };
 
+    // Configuration properties factory with MACSec
+    private final ConfigFactory factoryWithMacSec =
+            new ConfigFactory<ApplicationId, MacSecConfig>(APP_SUBJECT_FACTORY,
+                    MacSecConfig.class,
+                    "MACSEC") {
+                @Override
+                public MacSecConfig createConfig() {
+                    return new MacSecConfig();
+                }
+            };
+
     // Listener for config changes
     private final InternalConfigListener cfgListener = new InternalConfigListener();
 
+    // MACSec KaY store and SecY drivers
+    private Map<DeviceId, Map.Entry<MacSecKaY, MacSecSecY>>
+            mkaStore = new ConcurrentHashMap<>();
+
+
     /**
      * Builds an EAPOL packet based on the given parameters.
      *
@@ -197,6 +243,12 @@
         appId = coreService.registerApplication(APP_NAME);
         customInfo = new CustomizationInfo(subsService, deviceService);
         cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class));
+
+       /* Enable MACSec configuration Support */
+        netCfgService.registerConfigFactory(factoryWithMacSec);
+        cfgListener.reconfigureNetworkWithMacSec(netCfgService.getConfig(appId, MacSecConfig.class));
+        deviceService.addListener(new InternalDeviceListener());
+
         configureRadiusCommunication();
 
         // register our event handler
@@ -227,6 +279,7 @@
         StateMachine.destroyMaps();
         impl.deactivate();
         deviceService.removeListener(deviceListener);
+        macSecThreadPool.shutdown();
         log.info("Stopped");
     }
 
@@ -280,57 +333,72 @@
 
         switch (radiusPacket.getCode()) {
             case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
-                RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE);
-                byte[] challengeState = null;
-                if (radiusAttrState != null) {
-                    challengeState = radiusAttrState.getValue();
+                try {
+                    RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE);
+                    byte[] challengeState = null;
+                    if (radiusAttrState != null) {
+                        challengeState = radiusAttrState.getValue();
+                    }
+
+                    eapPayload = radiusPacket.decapsulateMessage();
+
+                    stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
+                    eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                            MacAddress.valueOf(nasMacAddress),
+                            stateMachine.vlanId(),
+                            EAPOL.EAPOL_PACKET,
+                            eapPayload, stateMachine.priorityCode());
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+                } catch (DeserializationException e) {
+                    e.printStackTrace();
                 }
-                eapPayload = radiusPacket.decapsulateMessage();
-                stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
-                eth = buildEapolResponse(stateMachine.supplicantAddress(),
-                        MacAddress.valueOf(nasMacAddress),
-                        stateMachine.vlanId(),
-                        EAPOL.EAPOL_PACKET,
-                        eapPayload, stateMachine.priorityCode());
-                sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
                 break;
             case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
-                //send an EAPOL - Success to the supplicant.
-                byte[] eapMessageSuccess =
-                        radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
-                eapPayload = new EAP();
-                eapPayload = (EAP) eapPayload.deserialize(eapMessageSuccess, 0, eapMessageSuccess.length);
-                eth = buildEapolResponse(stateMachine.supplicantAddress(),
-                        MacAddress.valueOf(nasMacAddress),
-                        stateMachine.vlanId(),
-                        EAPOL.EAPOL_PACKET,
-                        eapPayload, stateMachine.priorityCode());
-                sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+                try {
+                    //send an EAPOL - Success to the supplicant.
+                    byte[] eapMessageSuccess =
+                            radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
+                    eapPayload = new EAP();
+                    //eapPayload = (EAP) eapPayload.deserialize(eapMessageSuccess, 0, eapMessageSuccess.length);
+                    eapPayload = eapPayload.deserializer().deserialize(eapMessageSuccess, 0, eapMessageSuccess.length);
+                    eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                            MacAddress.valueOf(nasMacAddress),
+                            stateMachine.vlanId(),
+                            EAPOL.EAPOL_PACKET,
+                            eapPayload, stateMachine.priorityCode());
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
 
-                stateMachine.authorizeAccess();
-
+                    stateMachine.authorizeAccess();
+                } catch (DeserializationException e) {
+                    log.error("Error in processing RADIUS message {}", e);
+                }
                 break;
             case RADIUS.RADIUS_CODE_ACCESS_REJECT:
-                //send an EAPOL - Failure to the supplicant.
-                byte[] eapMessageFailure;
-                eapPayload = new EAP();
-                RADIUSAttribute radiusAttrEap = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE);
-                if (radiusAttrEap == null) {
-                    eapPayload.setCode(EAP.FAILURE);
-                    eapPayload.setIdentifier(stateMachine.challengeIdentifier());
-                    eapPayload.setLength(EAP.EAP_HDR_LEN_SUC_FAIL);
-                } else {
-                    eapMessageFailure = radiusAttrEap.getValue();
-                    eapPayload = (EAP) eapPayload.deserialize(eapMessageFailure, 0, eapMessageFailure.length);
+                try {
+                    //send an EAPOL - Failure to the supplicant.
+                    byte[] eapMessageFailure;
+                    eapPayload = new EAP();
+                    RADIUSAttribute radiusAttrEap = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE);
+                    if (radiusAttrEap == null) {
+                        eapPayload.setCode(EAP.FAILURE);
+                        eapPayload.setIdentifier(stateMachine.challengeIdentifier());
+                        eapPayload.setLength(EAP.EAP_HDR_LEN_SUC_FAIL);
+                    } else {
+                        eapMessageFailure = radiusAttrEap.getValue();
+                        //eapPayload = (EAP) eapPayload.deserialize(eapMessageFailure, 0, eapMessageFailure.length);
+                        eapPayload = (EAP) eapPayload.deserializer()
+                                .deserialize(eapMessageFailure, 0, eapMessageFailure.length);
+                    }
+                    eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                            MacAddress.valueOf(nasMacAddress),
+                            stateMachine.vlanId(),
+                            EAPOL.EAPOL_PACKET,
+                            eapPayload, stateMachine.priorityCode());
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+                    stateMachine.denyAccess();
+                } catch (DeserializationException e) {
+                    log.error("Error in processing RADIUS REJECT {}", e);
                 }
-                eth = buildEapolResponse(stateMachine.supplicantAddress(),
-                        MacAddress.valueOf(nasMacAddress),
-                        stateMachine.vlanId(),
-                        EAPOL.EAPOL_PACKET,
-                        eapPayload, stateMachine.priorityCode());
-                sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
-                stateMachine.denyAccess();
-
                 break;
             default:
                 log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
@@ -346,7 +414,7 @@
     private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) {
         TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build();
         OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(),
-                                                          treatment, ByteBuffer.wrap(ethernetPkt.serialize()));
+                treatment, ByteBuffer.wrap(ethernetPkt.serialize()));
         packetService.emit(packet);
     }
 
@@ -385,20 +453,20 @@
          * Creates and initializes common fields of a RADIUS packet.
          *
          * @param stateMachine state machine for the request
-         * @param eapPacket  EAP packet
+         * @param eapPacket    EAP packet
          * @return RADIUS packet
          */
         private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) {
             RADIUS radiusPayload =
                     new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
-                               eapPacket.getIdentifier());
+                            eapPacket.getIdentifier());
 
             // set Request Authenticator in StateMachine
             stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
 
             radiusPayload.setIdentifier(identifier);
             radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
-                                       stateMachine.username());
+                    stateMachine.username());
 
             radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
                     AaaManager.this.nasIpAddress.getAddress());
@@ -450,11 +518,11 @@
                     //send an EAP Request/Identify to the supplicant
                     EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
                     if (ethPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) {
-                       stateMachine.setPriorityCode(ethPkt.getPriorityCode());
+                        stateMachine.setPriorityCode(ethPkt.getPriorityCode());
                     }
                     Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress),
-                                                      ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
-                                                      eapPayload, stateMachine.priorityCode());
+                            ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
+                            eapPayload, stateMachine.priorityCode());
                     stateMachine.setSupplicantAddress(srcMac);
                     stateMachine.setVlanId(ethPkt.getVlanID());
 
@@ -496,8 +564,8 @@
                                 //send the RADIUS challenge response
                                 radiusPayload =
                                         getRadiusPayload(stateMachine,
-                                                         stateMachine.identifier(),
-                                                         eapPacket);
+                                                stateMachine.identifier(),
+                                                eapPacket);
                                 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
 
                                 if (stateMachine.challengeState() != null) {
@@ -531,6 +599,78 @@
                             return;
                     }
                     break;
+                case EAPOL.EAPOL_MKA:
+
+                    // Received MACSec PDU from supplicant.
+
+                    /* For version 1.0 Logon Process (IEEE802.1X 2010 Clause 12.5) starts here.
+                     * Currently only authenticated & secure connections are supported.
+                     * */
+
+                    /* TODO : Ensure AAA authentication is success. */
+
+                    /* Perform Sanity Check */
+                    EAPOL_MKPDU mkpdu = (EAPOL_MKPDU) eapol.getPayload();
+
+                    /* TODO :  Sanity checking
+                    if(!MKPDUSanityCheck(mkpdu)) {
+                        log.warn("Sanity failed for MKPDU from {}, dropping it.", srcMac);
+                        return;
+                    }*/
+
+                    // Load participant details(key <device><port>) and let it process packet.
+                    Map.Entry<MacSecKaY, MacSecSecY> mka = mkaStore.getOrDefault(deviceId, null);
+                    if (mka == null) {
+                        log.error("EAPOL-MKA received from undetected device {}. Ignoring.", deviceId);
+                        return;
+                    }
+                    MacSecKaY kaY = mka.getKey();
+                    MkaParticipant participant = kaY.lookupParticipantByID(sessionId);
+                    if (participant != null) {
+                        participant.receive(mkpdu);
+                    } else {
+                        // New MKA actor; prepare default resources.
+
+                        /* TODO : Locate CAK, CKN for <device>:<port>.
+                         * Currently global CAK & CKN. */
+                        byte[] cak = MkaKeyUtils.hexStringToByteArray(mkaCak);
+                        byte[] ckn = MkaKeyUtils.hexStringToByteArray(mkaCkn);
+
+                        // Initialize participant details
+                        Port port = deviceService.getPort(deviceId, portNumber);
+                        MacAddress portMac = null;
+                        Optional<MacAddress> macAddress = interfaceService.getInterfacesByPort(inPacket.receivedFrom())
+                                .stream()
+                                .map(Interface::mac).findFirst();
+                        if (macAddress.isPresent()) {
+                            portMac = macAddress.get();
+                        } else {
+                            log.warn("Fetching EAPOL-MKA ingress port MAC from annotations.");
+                            portMac = MacAddress.valueOf(port.annotations().value("portMac"));
+                        }
+                        participant = new MkaParticipant(stateMachine, packetService,
+                                macSecThreadPool,
+                                kaY, mka.getValue(), cak, ckn,
+                                new SCI(portMac.toBytes(), (short) (port.number().toLong())),
+                                deviceId, port);
+
+                        // Initialize CP state machine.
+                        CpStateMachine cpSM = new CpStateMachine(participant, mka.getValue(),
+                                kaY.defaultCipherSuit(), participant.latestKI(),
+                                participant.latestAN(), macSecThreadPool);
+
+                        // Update per port details in store
+                        kaY.addPortDetails(stateMachine.sessionId(), participant, cpSM);
+
+                        // Handover EAPOL_MKPDU to participant to handle it.
+                        participant.receive(mkpdu);
+
+                        // Start participant Hello timer & CP state machine.
+                        participant.startTicking();
+                        cpSM.startStateMachine();
+                    }
+
+                    break;
                 default:
                     log.trace("Skipping EAPOL message {}", eapol.getEapolType());
             }
@@ -595,6 +735,37 @@
             }
         }
 
+        /**
+         * Reconfigures the AAA application according to the
+         * configuration parameters passed.
+         *
+         * @param cfg configuration object
+         **/
+        private void reconfigureNetworkWithMacSec(MacSecConfig cfg) {
+            MacSecConfig newCfg;
+            if (cfg == null) {
+                newCfg = new MacSecConfig();
+            } else {
+                newCfg = cfg;
+            }
+            if (newCfg.version() != null) {
+                version = newCfg.version();
+            }
+            if (newCfg.capability() != null) {
+                capability = newCfg.capability();
+            }
+            if (newCfg.ckn() != null) {
+                mkaCkn = newCfg.ckn();
+            }
+            if (newCfg.cak() != null) {
+                mkaCak = newCfg.cak();
+            }
+            if (newCfg.netConfDeviceId() != null) {
+                defaultNetconfDeviceId = newCfg.netConfDeviceId();
+            }
+        }
+
+
         @Override
         public void event(NetworkConfigEvent event) {
 
@@ -604,6 +775,9 @@
 
                 AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class);
                 reconfigureNetwork(cfg);
+                //Include MACSec
+                MacSecConfig cfgMacSec = netCfgService.getConfig(appId, MacSecConfig.class);
+                reconfigureNetworkWithMacSec(cfgMacSec);
 
                 log.info("Reconfigured");
             }
@@ -613,10 +787,9 @@
     private class InternalDeviceListener implements DeviceListener {
         @Override
         public void event(DeviceEvent event) {
-
+            DeviceId devId = event.subject().id();
             switch (event.type()) {
                 case PORT_REMOVED:
-                    DeviceId devId = event.subject().id();
                     PortNumber portNumber = event.port().number();
                     String sessionId = devId.toString() + portNumber.toString();
 
@@ -626,10 +799,42 @@
                         StateMachine.deleteStateMachineMapping(removed);
                     }
 
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                    // Derive paired netconf device id from openflow device id
+                    DeviceId netconfId = getNetconfPairId(devId);
+                    if (netconfId == null) {
+                        netconfId = defaultNetconfDeviceId;
+                    // netconfId = DeviceId.deviceId("netconf:192.168.1.2:2022");
+                    }
+
+                    // Update store with KaY and SecY device details.
+                    MacSecSecY secY = new MacSecSecY(netconfId);
+                    MacSecKaY kaY = new MacSecKaY(secY);
+                    mkaStore.put(devId,
+                            new AbstractMap.SimpleEntry<MacSecKaY, MacSecSecY>(kaY, secY));
                     break;
+
+                case DEVICE_REMOVED:
+                    mkaStore.remove(devId);
+                    break;
+
                 default:
                     return;
             }
         }
+
+        // Openflow device to netconf device mapping logic for MACSec SecY switches
+        private DeviceId getNetconfPairId(DeviceId deviceID) {
+            /* TODO : Finalize and implement logic */
+            return null;
+        }
     }
+
+    // Device listener for MACSec capability loading.
+    // MACSec Thread Pool. TODO: Pool Size Fixing.
+    private static final int MACSEC_THREAD_POOL_SIZE = 10;
+    private ScheduledExecutorService macSecThreadPool =
+            Executors.newScheduledThreadPool(MACSEC_THREAD_POOL_SIZE);
+
 }
diff --git a/src/main/java/org/opencord/aaa/AescMac.java b/src/main/java/org/opencord/aaa/AescMac.java
new file mode 100644
index 0000000..65a5dda
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/AescMac.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2018-present. * Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * AES-CMAC Algorithm. RFC 4493.
+ * Cipher-based Message Authentication Code(CMAC),
+ * a keyed hash function based on a symmetric key block cipher: Advanced Encryption Standard(AES).
+ * Reference: https://github.com/E3V3A/androsmex/blob/master/src/de/tsenger/androsmex/tools/AESCMac.java
+ */
+public class AescMac {
+
+    private static byte[] constZero = MkaKeyUtils.hexStringToByteArray("00000000000000000000000000000000");
+    private static byte[] constRb = MkaKeyUtils.hexStringToByteArray("00000000000000000000000000000087");
+    private byte[] key;
+    private ByteArrayOutputStream catInput;
+
+    /**
+     * AES 128-bit encryption using JDK built-in classes.
+     */
+    private static class AesCrypto {
+
+        static Cipher aesEcb = null;
+
+        static {
+            try {
+                aesEcb = Cipher.getInstance("AES/ECB/NOPADDING");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        /**
+         * Encrypt AES 128 bit key.
+         * @param zeroConst - Zero-constant
+         * @param key - Input key value
+         * @return Encrypted Key
+         */
+        private static byte[] encryptAES128(byte[] zeroConst, byte[] key) {
+            SecretKey aesKey = new SecretKeySpec(key, 0, 16, "AES");
+            try {
+                synchronized (aesEcb) {
+                    aesEcb.init(Cipher.ENCRYPT_MODE, aesKey);
+                    return aesEcb.doFinal(zeroConst);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        }
+
+        static Cipher aesKeyWrapper = null;
+
+        static {
+            try {
+                aesKeyWrapper = Cipher.getInstance("AESWrap");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        /**
+         * AES Key Wrapper.
+         * @param message - Message to be wrapped
+         * @param key - Key-Encryption Key
+         * @return Wrapped key
+         */
+        private static byte[] keyWrap(byte[] key, byte[] message) {
+            SecretKey aesKey = new SecretKeySpec(key, 0, 16, "AES");
+            SecretKey messageKey = new SecretKeySpec(message, 0, 16, "AES");
+            try {
+                synchronized (aesKeyWrapper) {
+                    aesKeyWrapper.init(Cipher.WRAP_MODE, aesKey);
+                    byte[] wrappedKey = aesKeyWrapper.wrap(messageKey);
+
+                    /* Unwrap the key */
+                    aesKeyWrapper.init(Cipher.UNWRAP_MODE, aesKey);
+                    messageKey = (SecretKey) aesKeyWrapper.unwrap(wrappedKey, "AES/CTR/NOPADDING", Cipher.SECRET_KEY);
+
+                    return wrappedKey;
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        }
+
+    }
+
+    public AescMac() {
+
+    }
+
+    /**
+     * Wrap a message.
+     * @param message - Message to be wrapped
+     * @param key - Key-Encryption Key
+     * @return Wrapped key
+     */
+    public byte[] wrap(byte[] key, byte[] message) {
+        return AesCrypto.keyWrap(key, message);
+    }
+
+    /**
+     * Generate AES message authentication code.
+     * @param key - Key derivation key
+     * @param m - Message to be authenticated
+     * @param len - Length of message in octets
+     * @return Message Authentication Code
+     */
+    public byte[] generateAescMac(byte[] key, byte[] m, int len) {
+
+        initialize(key);
+        update(m, 0, len);
+        return generateMac();
+    }
+
+    /**
+     * Initialize data members.
+     * @param key Key derivation key
+     */
+    private void initialize(byte[] key) {
+        this.key = key;
+        catInput = new ByteArrayOutputStream();
+    }
+
+    /**
+     *  Update the message byte array with offset and length.
+     * @param msg - Message to be authenticated
+     * @param offset - Offset to be added
+     * @param len - Length of the message
+     */
+    private void update(byte[] msg, int offset, int len) {
+        catInput.write(msg, offset, len);
+    }
+
+    /**
+     * Generate MAC.
+     * @return Message authentication code
+     */
+    private byte[] generateMac() {
+        // Step 1
+        Object[] keys = generateSubKey(key);
+        byte[] k1 = (byte[]) keys[0];
+        byte[] k2 = (byte[]) keys[1];
+        byte[] input = catInput.toByteArray();
+
+        // Step 2
+        int numberOfRounds = (input.length + 15) / 16;
+        boolean lastBlockComplete;
+
+        // Step 3
+        if (numberOfRounds == 0) {
+            numberOfRounds = 1;
+            lastBlockComplete = false;
+        } else {
+            lastBlockComplete = (input.length % 16 == 0);
+        }
+
+        byte[] mLast;
+        int srcPos = 16 * (numberOfRounds - 1);
+
+        // Step 4
+        if (lastBlockComplete) {
+            byte[] partInput = new byte[16];
+
+            System.arraycopy(input, srcPos, partInput, 0, 16);
+            mLast = xor128(partInput, k1);
+        } else {
+            byte[] partInput = new byte[input.length % 16];
+
+            System.arraycopy(input, srcPos, partInput, 0, input.length % 16);
+            byte[] padded = padTo16(partInput);
+            mLast = xor128(padded, k2);
+        }
+
+        // Step 5
+        byte[] x = constZero.clone();
+        byte[] partInput = new byte[16];
+        byte[] y;
+
+        // Step 6
+        for (int i = 0; i < numberOfRounds - 1; i++) {
+            srcPos = 16 * i;
+            System.arraycopy(input, srcPos, partInput, 0, 16);
+
+            y = xor128(partInput, x); // Y := Mi (+) X
+            x = AesCrypto.encryptAES128(y, key);
+        }
+
+        y = xor128(x, mLast);
+        x = AesCrypto.encryptAES128(y, key);
+
+        // Step 7
+        return x;
+    }
+
+    /**
+     * Pad to 16 bytes.
+     * @param input - Value to be padded
+     * @return Padded byte array
+     */
+    private byte[] padTo16(byte[] input) {
+        byte[] padded = new byte[16];
+
+        for (int j = 0; j < 16; j++) {
+            if (j < input.length) {
+                padded[j] = input[j];
+            } else if (j == input.length) {
+                padded[j] = (byte) 0x80;
+            } else {
+                padded[j] = (byte) 0x00;
+            }
+        }
+        return padded;
+    }
+
+    /**
+     * Generate Subkey.
+     * @param key - Input key to generate the subkeys
+     * @return Array of two subkeys
+     */
+    private static Object[] generateSubKey(byte[] key) {
+        // Step 1
+        byte[] l = AesCrypto.encryptAES128(constZero, key);
+
+        // Step 2
+        byte[] k1;
+        if ((l[0] & 0x80) == 0) { // If MSB(L) = 0, then K1 = L << 1
+            k1 = leftShiftBit(l);
+        } else {    //Else K1 = ( L << 1 ) (+) Rb
+            byte[] tmp = leftShiftBit(l);
+            k1 = xor128(tmp, constRb);
+        }
+
+        // Step 3
+        byte[] k2;
+        if ((k1[0] & 0x80) == 0) {
+            k2 = leftShiftBit(k1);
+        } else {
+            byte[] tmp = leftShiftBit(k1);
+            k2 = xor128(tmp, constRb);
+        }
+
+        // Step 4
+        Object[] result = new Object[2];
+        result[0] = k1;
+        result[1] = k2;
+        return result;
+    }
+
+    /**
+     * XOR two values.
+     * @param input1 - java.util.byte[]
+     * @param input2 - java.util.byte[]
+     * @return XORed byte array
+     */
+    private static byte[] xor128(byte[] input1, byte[] input2) {
+        byte[] output = new byte[input1.length];
+        for (int i = 0; i < input1.length; i++) {
+            output[i] = (byte) (((int) input1[i] ^ (int) input2[i]) & 0xFF);
+        }
+        return output;
+    }
+
+    /**
+     * Shift left by one bit.
+     * @param input - Value to be shifted
+     * @return Shifted result
+     */
+    private static byte[] leftShiftBit(byte[] input) {
+        byte[] output = new byte[input.length];
+        byte overflow = 0;
+        for (int i = (input.length - 1); i >= 0; i--) {
+            output[i] = (byte) ((int) input[i] << 1 & 0xFF);
+            output[i] |= overflow;
+            overflow = ((input[i] & 0x80) != 0) ? (byte) 1 : (byte) 0;
+        }
+
+        return output;
+    }
+}
+
diff --git a/src/main/java/org/opencord/aaa/CpStateMachine.java b/src/main/java/org/opencord/aaa/CpStateMachine.java
new file mode 100644
index 0000000..8b1ea10
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/CpStateMachine.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright 2018-present. * Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class CpStateMachine {
+    private final Logger log = getLogger(getClass());
+    /* State, Transition details. IEEE802.1X-2010. Figure 12-2 */
+    private boolean portValid, newSak;
+    private boolean lrx, ltx, orx, otx;
+    private boolean chgdServer, controlledPortEnabled, chgdCipher;
+    private boolean usingReceiveSAs;
+    private boolean serverTransmitting, usingTransmitSA;
+    private boolean electedSelf, allReceiving, newInfo;
+    private byte[] lki, oki, distributedKI;
+    private byte distributedAN, lan, oan;
+    private long transmitWhen, transmitDelay, retireWhen, retireDelay;
+    /* MACSec management & control */
+    private boolean protectFrames;
+    private boolean replayProtect;
+    private int replayProtectWindow;
+
+    enum MacSecValidate {
+        Disabled, Checked, Strict
+    }
+
+    private MacSecValidate validateFrames;
+    private final int defaultReplayProtectWindow = 10;
+    private final int defaultTransmitDelay = 6000;
+    private final int defaultSakRetireTime = 5000;
+    /* Ciphersuit management & control */
+    private MacSecCipherSuit cipherSuit;
+    enum ConnectType { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE }
+    ConnectType connectType;
+    enum StateIndex {
+        BEGIN, INIT, CHANGE, ALLOWED, AUTHENTICATED, SECURED,
+        RECEIVE, RECEIVING, READY, TRANSMIT, TRANSMITTING, ABANDON, RETIRE
+    }
+
+    protected boolean changedConnect() {
+        return (connectType != ConnectType.SECURE) || chgdServer || chgdCipher;
+    }
+
+    abstract class State {
+        StateIndex index;
+        Logger logger;
+        State(StateIndex index, Logger logger) {
+            this.index = index;
+            this.logger = logger;
+        }
+        /**
+         * State Machine state based action function.
+         */
+        public void enter() {
+            logger.trace("Entering state : {} ", index.name());
+        }
+        /**
+         * State Machine state stepping function.
+         * Assumes that before calling "step" atleast once "enter" of the state should be called.
+         * @return null
+         */
+        public StateIndex step() {
+            logger.trace("Stepping from state : {}", index.name());
+            return null;
+        }
+    }
+    class Begin extends State {
+        Begin(Logger logger) {
+            super(StateIndex.BEGIN, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            return StateIndex.INIT;
+        }
+    }
+    class Init extends State {
+        Init(Logger logger) {
+            super(StateIndex.INIT, logger);
+        }
+        @Override
+        public void enter() {
+            controlledPortEnabled = false;
+            /* TODO : */
+            // secY.enablePort(portName, controlledPortEnabled);
+            portValid = false;
+            lki = null;
+            oki = null;
+            lrx = false;
+            ltx = false;
+            orx = false;
+            otx = false;
+        }
+        @Override
+        public StateIndex step() {
+            return StateIndex.CHANGE;
+        }
+    }
+
+    class Change extends State {
+        Change(Logger logger) {
+            super(StateIndex.CHANGE, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            portValid = false;
+            controlledPortEnabled = false;
+            secY.enablePort(portName, controlledPortEnabled);
+            /* TODO : Delete SAs associated with keys. */
+            if (lki != null) {
+                participant.deleteSAs(lki);
+            }
+            if (oki != null) {
+                participant.deleteSAs(oki);
+            }
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex index = StateIndex.CHANGE;
+            switch (connectType) {
+                case UNAUTHENTICATED:
+                    index = StateIndex.ALLOWED;
+                    break;
+                case AUTHENTICATED:
+                    index = StateIndex.AUTHENTICATED;
+                    break;
+                case SECURE:
+                    index = StateIndex.SECURED;
+                default:
+                     break;
+            }
+            return index;
+        }
+    }
+    class Allowed extends State {
+        Allowed(Logger logger) {
+            super(StateIndex.ALLOWED, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            protectFrames = false;
+            replayProtect = false;
+            validateFrames = MacSecValidate.Checked;
+            portValid = false;
+            controlledPortEnabled = true;
+            /* Update SecY */
+            secY.enablePort(portName, controlledPortEnabled);
+            secY.protectFrames(portName, protectFrames);
+            secY.validateFrames(portName, validateFrames);
+            secY.replayProtect(portName, replayProtect, replayProtectWindow);
+        }
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.ALLOWED;
+            if (connectType != ConnectType.UNAUTHENTICATED) {
+                nextState = StateIndex.CHANGE;
+            }
+            return nextState;
+        }
+    }
+    class Authenticated extends State {
+        Authenticated(Logger logger) {
+            super(StateIndex.AUTHENTICATED, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            protectFrames = false;
+            replayProtect = false;
+            validateFrames = MacSecValidate.Checked;
+            portValid = false;
+            controlledPortEnabled = true;
+            /* Update SecY */
+            secY.enablePort(portName, controlledPortEnabled);
+            secY.protectFrames(portName, protectFrames);
+            secY.validateFrames(portName, validateFrames);
+            secY.replayProtect(portName, replayProtect, replayProtectWindow);
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.AUTHENTICATED;
+            if (connectType != ConnectType.AUTHENTICATED) {
+                nextState = StateIndex.CHANGE;
+            }
+            return nextState;
+        }
+    }
+    class Secured extends State {
+        Secured(Logger logger) {
+            super(StateIndex.SECURED, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            chgdServer = false;
+            /* TODO : Load from per port configuration. */
+            protectFrames = true;
+            validateFrames = MacSecValidate.Strict;
+            replayProtect = true;
+            replayProtectWindow = defaultReplayProtectWindow;
+            portValid = true;
+            /* Update SecY */
+            secY.setCurrentCipherSuit(portName, cipherSuit.id());
+            /* TODO: Update confidentiality offset from ciphersuit. */
+            secY.protectFrames(portName, protectFrames);
+            secY.validateFrames(portName, validateFrames);
+            secY.replayProtect(portName, replayProtect, replayProtectWindow);
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.SECURED;
+            if (changedConnect()) {
+                nextState = StateIndex.CHANGE;
+            } else if (newSak) {
+                nextState = StateIndex.RECEIVE;
+            }
+            return nextState;
+        }
+    }
+    /**
+     * Receive state slighlty differ from IEEE 802.1X 2010 Figure 12-2.
+     * Refer : wpa_supplicant-2.6/src/pae/ieee802_1x_cp.c
+     */
+    class Receive extends State {
+        Receive(Logger logger) {
+            super(StateIndex.RECEIVE, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            oki = lki;
+            orx = lrx;
+            otx = ltx;
+            oan = lan;
+            lki = distributedKI;
+            lan = distributedAN;
+            newSak = false;
+            /* Update SecY */
+            participant.setOldSAAttributes(oki, oan, orx, otx);
+            participant.setLatestSAAttributes(lki, lan, ltx, lrx);
+            participant.createSAs(lki);
+            participant.enableReceiveSAs(lki);
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.RECEIVE;
+            if (usingReceiveSAs) {
+                nextState = StateIndex.RECEIVING;
+            }
+            return nextState;
+        }
+    }
+    class Receiving extends State {
+        Receiving(Logger logger) {
+            super(StateIndex.RECEIVING, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            lrx = true;
+            participant.setLatestSAAttributes(lki, lan, ltx, lrx);
+            transmitWhen = transmitDelay;
+            /* TODO : CP Timout reset. */
+            usingReceiveSAs = false;
+            serverTransmitting = false;
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.RECEIVING;
+            if (newSak || changedConnect()) {
+                nextState = StateIndex.ABANDON;
+            }
+            if (!electedSelf) {
+                nextState = StateIndex.READY;
+            }
+            /* IEEE 802.1X-2010 Figure 12-2 deviation. !controlPortEnabled removed from check. */
+            if (electedSelf && (allReceiving || (transmitWhen == 0))) {
+                nextState = StateIndex.TRANSMIT;
+            }
+            return nextState;
+        }
+    }
+    class Ready extends State {
+        Ready(Logger logger) {
+            super(StateIndex.READY, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            newInfo = true;
+            // TODO : participant.enableNewInfo();
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.READY;
+            if (newSak || changedConnect()) {
+                nextState = StateIndex.ABANDON;
+            }
+            if (serverTransmitting) {
+                nextState = StateIndex.TRANSMIT;
+            }
+            return nextState;
+        }
+    }
+    class Transmit extends State {
+        Transmit(Logger logger) {
+            super(StateIndex.TRANSMIT, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            controlledPortEnabled = true;
+            secY.enablePort(portName, controlledPortEnabled);
+            ltx = true;
+            participant.setLatestSAAttributes(lki, lan, ltx, lrx);
+            participant.enableTransmitSA(lki);
+            allReceiving = false;
+            serverTransmitting = false;
+        }
+        @Override
+        public StateIndex step() {
+            super.enter();
+            StateIndex nextState = StateIndex.TRANSMIT;
+            if (usingTransmitSA) {
+                nextState = StateIndex.TRANSMITTING;
+            }
+            return nextState;
+        }
+    }
+    class Transmitting extends State {
+        Transmitting(Logger logger) {
+            super(StateIndex.TRANSMITTING, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            retireWhen = orx ? retireDelay : 0;
+            otx = false;
+            participant.setOldSAAttributes(oki, oan, otx, orx);
+            newInfo = true;
+            // TODO: participant.enableNewInfo();
+            /* TODO : Reset retire when timeout. */
+            usingTransmitSA = false;
+        }
+        @Override
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.TRANSMITTING;
+            if ((retireWhen == 0) || changedConnect()) {
+                nextState = StateIndex.RETIRE;
+            }
+            return nextState;
+        }
+    }
+    class Abandon extends State {
+        Abandon(Logger logger) {
+            super(StateIndex.ABANDON, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            lrx = false;
+            participant.setLatestSAAttributes(lki, lan, ltx, lrx);
+            participant.deleteSAs(lki);
+            lki = null;
+            participant.setLatestSAAttributes(lki, lan, ltx, lrx);
+            newSak = false;
+        }
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.ABANDON;
+            if (changedConnect()) {
+                nextState = StateIndex.RETIRE;
+            } else if (newSak) {
+                nextState = StateIndex.RECEIVE;
+            }
+            return nextState;
+        }
+    }
+    class Retire extends State {
+        Retire(Logger logger) {
+            super(StateIndex.RETIRE, logger);
+        }
+        @Override
+        public void enter() {
+            super.enter();
+            /* IEEE 802.1X-2010 Figure 12-2 deviation. Only clearing old keys. */
+            oki = null;
+            orx = false;
+            otx = false;
+            participant.setOldSAAttributes(oki, oan, otx, orx);
+            /* TODO : deleteSA(oki) ? */
+        }
+        public StateIndex step() {
+            super.step();
+            StateIndex nextState = StateIndex.RETIRE;
+            if (changedConnect()) {
+                nextState = StateIndex.CHANGE;
+            } else if (newSak) {
+                nextState = StateIndex.RECEIVE;
+            }
+            return nextState;
+        }
+    }
+    private final Logger logger = getLogger(getClass());
+    Map<StateIndex, State> states = new HashMap<StateIndex, State>() {{
+        put(StateIndex.BEGIN, new Begin(logger));
+        put(StateIndex.INIT, new Init(logger));
+        put(StateIndex.CHANGE, new Change(logger));
+        put(StateIndex.ALLOWED, new Allowed(logger));
+        put(StateIndex.AUTHENTICATED, new Authenticated(logger));
+        put(StateIndex.SECURED, new Secured(logger));
+        put(StateIndex.RECEIVE, new Receive(logger));
+        put(StateIndex.RECEIVING, new Receiving(logger));
+        put(StateIndex.READY, new Ready(logger));
+        put(StateIndex.TRANSMIT, new Transmit(logger));
+        put(StateIndex.TRANSMITTING, new Transmitting(logger));
+        put(StateIndex.ABANDON, new Abandon(logger));
+        put(StateIndex.RETIRE, new Retire(logger));
+    }};
+    StateIndex currentStateIndex;
+    /* Real worker for State Machine. */
+    private class Worker implements Runnable {
+        public int maxSmIterCount = 100;
+        @Override
+        public void run() {
+            while (true) {
+                try {
+                /* Maximum maxSmIterCount state changes per turn. */
+                    int count = maxSmIterCount;
+                    StateIndex previousState = null;
+                    State currentState = null;
+                    while (count-- > 0) {
+                        previousState = currentStateIndex;
+                        currentState = states.getOrDefault(currentStateIndex, null);
+                        if (currentState != null && (currentState.step() != previousState)) {
+                            currentState.enter();
+                            currentStateIndex = currentState.step();
+                        } else {
+                            break;
+                        }
+                    }
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    log.trace("Interruption in CP SM scheduling. {}", e.getMessage());
+                }
+            }
+        }
+    }
+    Worker worker = new Worker();
+    /* State Machine thread pool related components. */
+    ScheduledExecutorService executor;
+    ScheduledFuture<?> future;
+    /* KaY, SecY connections. */
+    MkaParticipant participant;
+    MacSecSecY secY;
+    String portName;
+    /**
+     * Needs participant created properly.
+     *
+     * @param participant   details.
+     * @param secY          SecY interface details.
+     * @param cipherSuit    details.
+     * @param distributedKI KeyIdentifier
+     * @param distributedAN association number
+     * @param executor      scheduled service
+     */
+    public CpStateMachine(MkaParticipant participant, MacSecSecY secY,
+                          MacSecCipherSuit cipherSuit,
+                          byte[] distributedKI,
+                          byte distributedAN,
+                          ScheduledExecutorService executor) {
+        this.secY = secY;
+        this.participant = participant;
+        portName = participant.port().number().name();
+        this.executor = executor;
+        /* Generation default settings. */
+        protectFrames = true;
+        connectType = ConnectType.SECURE;
+        newSak = true;
+        usingReceiveSAs = true;
+        usingTransmitSA = true;
+        /* Validation default settings. */
+        validateFrames = MacSecValidate.Strict;
+        replayProtect = false;
+        replayProtectWindow = defaultReplayProtectWindow;
+        /* Other settings */
+        lrx = true;
+        ltx = true;
+        lki = null;
+        orx = false;
+        otx = false;
+        oki = null;
+        controlledPortEnabled = false;
+        chgdServer = false;
+        this.distributedAN = distributedAN;
+        this.distributedKI = distributedKI;
+        electedSelf = true;
+        /* Ciphersuit */
+        this.cipherSuit = cipherSuit;
+        /* Timers */
+        // TODO : Needs timeout on transmitDelay & retireDelay
+        // transmitDelay = defaultTransmitDelay;
+        transmitDelay = 0;
+        retireDelay = defaultSakRetireTime;
+        currentStateIndex = StateIndex.BEGIN;
+        /* Really apply SecY settings. */
+        secY.setCurrentCipherSuit(portName, cipherSuit.id());
+        secY.protectFrames(portName, protectFrames);
+        secY.validateFrames(portName, validateFrames);
+        secY.replayProtect(portName, replayProtect, replayProtectWindow);
+        secY.enablePort(portName, controlledPortEnabled);
+    }
+    public void startStateMachine() {
+        future = executor.scheduleWithFixedDelay(worker, 1, 1, TimeUnit.MICROSECONDS);
+    }
+    public void stepStateMachine() {
+        future.cancel(false);
+        future = executor.scheduleWithFixedDelay(worker, 1, 1, TimeUnit.MICROSECONDS);
+    }
+    public void setDistributedKI(byte[] ki) {
+        distributedKI = ki;
+    }
+    public void setDistributedAN(byte an) {
+        distributedAN = an;
+    }
+    public void setUsingReceiveSAs(boolean status) {
+        usingReceiveSAs = status;
+    }
+    public void setUsingTransmitSA(boolean status) {
+        usingTransmitSA = status;
+    }
+    public MacSecCipherSuit cipherSuit() {
+        return cipherSuit;
+    }
+    public boolean macSecReplayProtect() {
+        return replayProtect;
+    }
+    public boolean macSecProtect() {
+        return protectFrames;
+    }
+    public MacSecValidate macSecValidate() {
+        return validateFrames; } }
diff --git a/src/main/java/org/opencord/aaa/CustomizationInfo.java b/src/main/java/org/opencord/aaa/CustomizationInfo.java
index d0709f2..1183e67 100755
--- a/src/main/java/org/opencord/aaa/CustomizationInfo.java
+++ b/src/main/java/org/opencord/aaa/CustomizationInfo.java
@@ -19,8 +19,6 @@
 import org.onosproject.net.device.DeviceService;
 import org.opencord.sadis.SubscriberAndDeviceInformationService;
 
-//import java.util.Map;
-
 /**
  * Info required to do customization to packets.
  */
diff --git a/src/main/java/org/opencord/aaa/MacSecAlgorithmAgility.java b/src/main/java/org/opencord/aaa/MacSecAlgorithmAgility.java
new file mode 100644
index 0000000..df04f42
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecAlgorithmAgility.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-present. * Open Networking Foundation .
+ *
+ * Licensed 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.opencord.aaa;
+
+/**
+ * Algorithm Agility.
+ */
+public interface MacSecAlgorithmAgility {
+
+    /* Misc information */
+    public byte[] getParameter();
+
+    /* Various Key Lengths */
+    public int getCakLength();
+    public int getKekLength();
+    public int getIckLength();
+    public int getIcvLength();
+    public int getSakLength();
+
+    /* Transformation Functions */
+    public byte[] generateCak(byte[] msk, byte[] mac1, byte[] mac2);
+    public byte[] generateCkn(byte[] msk, byte[] mac1, byte[] mac2, byte[] sid);
+    public byte[] generateKek(byte[] cak, byte[] ckn);
+    public byte[] generateIck(byte[] cak, byte[] ckn);
+    public byte[] generateIcv(byte[] ick, byte[] msg);
+
+    public byte[] generateSak(byte[] cak, byte[] ksNonce, byte[] memberIDs, int keyNumber);
+
+}
diff --git a/src/main/java/org/opencord/aaa/MacSecCapabilities.java b/src/main/java/org/opencord/aaa/MacSecCapabilities.java
new file mode 100644
index 0000000..8ecbb09
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecCapabilities.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018-present. * Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+/*
+ * MACSec Capabalities. IEEE 802.1x; Table 11-6
+ */
+public enum MacSecCapabilities {
+    /* Not implemented */
+    NOT_IMPLEMENTED,
+
+    /* 'Integrity without confidentiality' */
+    INTEGRITY,
+
+    /* 'Integrity without confidentiality' and
+       'Integrity and confidentiality' with a confidentiality offset of 0*/
+    INTEGRITY_AND_CONFIDENTIALITY,
+
+    /* 'Integrity without confidentiality' and
+       'Integrity and confidentiality' with a confidentiality offset of 0, 30, 50 */
+    INTEGRITY_AND_CONFIDENTIALITY_0_30_50
+}
diff --git a/src/main/java/org/opencord/aaa/MacSecCipherSuit.java b/src/main/java/org/opencord/aaa/MacSecCipherSuit.java
new file mode 100644
index 0000000..747a36e
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecCipherSuit.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2017-present. * Open Networking Foundation .
+ *
+ * Licensed 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.opencord.aaa;
+
+/*
+ * Cipher Suit representation. IEEE 802.1AE 2006; Clause 14
+ */
+class MacSecCipherSuit {
+    private Long id;
+    private String name;
+    private MacSecCapabilities capabilities;
+    private MacSecConfidentialityOffset confidentialityOffset;
+    private int keyLength;
+
+    /*
+    * MACSec Capabalities. IEEE 802.1x; Table 11-6
+    */
+    public enum MacSecCapabilities {
+        /* Not implemented */
+        NOT_IMPLEMENTED,
+
+        /* 'Integrity without confidentiality' */
+        INTEGRITY,
+
+        /* 'Integrity without confidentiality' and
+           'Integrity and confidentiality' with a confidentiality offset of 0*/
+        INTEGRITY_AND_CONFIDENTIALITY,
+
+        /* 'Integrity without confidentiality' and
+           'Integrity and confidentiality' with a confidentiality offset of 0, 30, 50 */
+        INTEGRITY_AND_CONFIDENTIALITY_0_30_50
+    }
+
+    /* Confidentiality Offset. */
+    public enum MacSecConfidentialityOffset {
+        /* No confidentiality. */
+        CONFIDENTIALITY_NONE,
+        CONFIDENTIALITY_OFFSET_0,
+        CONFIDENTIALITY_OFFSET_30,
+        CONFIDENTIALITY_OFFSET_50,
+    }
+
+    MacSecCipherSuit() {
+
+        /* Default Cipher Suit. GCM-AES-128. Clause 14.4 */
+        this.id = Long.parseLong("800200"); //Long.parseLong("0080020001000001");
+        this.name = "GCM-AES-128";
+        this.capabilities = MacSecCapabilities.INTEGRITY_AND_CONFIDENTIALITY_0_30_50;
+        keyLength = 16; /* Unit: bytes. ie. 128bits = 16 bytes */
+        confidentialityOffset = MacSecConfidentialityOffset.CONFIDENTIALITY_OFFSET_0;
+    }
+
+    MacSecCipherSuit(Long id, String name, MacSecCapabilities capabilities,
+                     MacSecConfidentialityOffset confidentialityOffset, int keyLength) {
+        this.id = id;
+        this.name = name;
+        this.capabilities = capabilities;
+        this.keyLength = keyLength;
+        this.confidentialityOffset = confidentialityOffset;
+    }
+
+    public int getKeyLength() {
+        return keyLength;
+    }
+
+    public MacSecConfidentialityOffset getConfidentialityOffset() {
+        return confidentialityOffset;
+    }
+
+    public long id() {
+        return id.longValue();
+    }
+}
diff --git a/src/main/java/org/opencord/aaa/MacSecConfig.java b/src/main/java/org/opencord/aaa/MacSecConfig.java
new file mode 100644
index 0000000..47f578b
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecConfig.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2018-present. * Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.basics.BasicElementConfig;
+
+/**
+ * MACSec config for the AAA app.
+ */
+public class MacSecConfig extends Config<ApplicationId> {
+
+    private static final String VERSION = "version";
+    private static final String CAPABILITY = "capability";
+    private static final String CKN = "ckn";
+    private static final String CAK = "cak";
+    private static final String DEFAULT_NETCONF_DEVICE_ID = "netconfDeviceId";
+
+    //MACSec verion
+    protected static final String DEFAULT_VERSION = "1";
+
+    //MACSec capability
+    protected static final String DEFAULT_CAPABILITY = "0";
+
+    //secure Connectivity Association Key Name
+    protected static final String DEFAULT_CKN = "96437a93ccf10d9dfe347846cce52c7d";
+
+    //secure Connectivity Association Key
+    protected static final String DEFAULT_CAK = "135bd758b0ee5c11c55ff6ab19fdb199";
+
+    //Netconf Device Default value
+    protected static final String DEFAULT_NETCONF_DEVICE = "netconf:192.168.1.2:2022";
+
+    /**
+     * Gets the value of a string property, protecting for an empty JSON object.
+     *
+     * @param name name of the property
+     * @param defaultValue default value if none has been specified
+     * @return String value if one os found, default value otherwise
+     */
+    private String getStringProperty(String name, String defaultValue) {
+        if (object == null) {
+            return defaultValue;
+        }
+        return get(name, defaultValue);
+    }
+
+    /**
+     * Version of MACSEC.
+     * @return MACSec version or null if not set.
+     */
+    public String version() {
+        return getStringProperty(VERSION, DEFAULT_VERSION);
+    }
+
+    /**
+     * Sets the MACSec version.
+     *
+     * @param ver New version; null to clear
+     * @return self
+     */
+    public BasicElementConfig version(String ver) {
+        return (BasicElementConfig) setOrClear(VERSION, ver);
+    }
+
+    /**
+     * Capability of MACSEC.
+     *
+     * @return MACSec capability or null if not set
+     */
+    public String capability() {
+        return getStringProperty(CAPABILITY, DEFAULT_CAPABILITY);
+    }
+
+    /**
+     * Sets the MACSec capability.
+     *
+     * @param cap New capability; null to clear
+     * @return self
+     */
+    public BasicElementConfig capability(String cap) {
+        return (BasicElementConfig) setOrClear(CAPABILITY, cap);
+    }
+
+    /**
+     * CKN.
+     *
+     * @return ckn or null if not set
+     */
+    public String ckn() {
+        return getStringProperty(CKN, DEFAULT_CKN);
+    }
+
+    /**
+     * Sets the CKN.
+     *
+     * @param keyName New CKN; null to clear
+     * @return self
+     */
+    public BasicElementConfig ckn(String keyName) {
+        return (BasicElementConfig) setOrClear(CKN, keyName);
+    }
+
+    /**
+     * CAK.
+     *
+     * @return cak or null if not set
+     */
+    public String cak() {
+        return getStringProperty(CAK, DEFAULT_CAK);
+    }
+
+    /**
+     * Sets the CAK.
+     *
+     * @param key New CAK; null to clear
+     * @return self
+     */
+    public BasicElementConfig cak(String key) {
+        return (BasicElementConfig) setOrClear(CAK, key);
+    }
+
+    /*
+    * Returns default Netconf device Id for SecY interface.
+    * @return Device ID
+    * */
+    public DeviceId netConfDeviceId() {
+        return DeviceId.deviceId(getStringProperty(DEFAULT_NETCONF_DEVICE_ID, DEFAULT_NETCONF_DEVICE));
+    }
+}
+
diff --git a/src/main/java/org/opencord/aaa/MacSecDefaultAlgorithmAgility.java b/src/main/java/org/opencord/aaa/MacSecDefaultAlgorithmAgility.java
new file mode 100644
index 0000000..bff4599
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecDefaultAlgorithmAgility.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2017-present .* Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+import java.util.Arrays;
+import java.nio.ByteBuffer;
+import java.io.ByteArrayOutputStream;
+import java.math.BigInteger;
+
+/**
+ * Default algorithm agility implementation. IEEE Std. 802.1X-2009
+ */
+public class MacSecDefaultAlgorithmAgility implements MacSecAlgorithmAgility {
+
+    /* IEEE 802.1X, Table 9-1 */
+    private byte[] parameter = {(byte) 0x00, (byte) 0x80, (byte) 0xC2, (byte) 0x01};
+
+    /* 128 bits for CAK, KEK, ICK, ICV */
+    private int defaultKeyLength = 16;
+
+    /* KDF Parameters */
+    private int kdfContextLength = 16;
+
+    /* Default agility initialization. */
+    MacSecDefaultAlgorithmAgility() {
+    }
+
+    @Override
+    public byte[] getParameter() {
+        return parameter;
+    }
+
+    @Override
+    public int getCakLength() {
+        return defaultKeyLength * 8;
+    }
+
+    @Override
+    public int getKekLength() {
+        return defaultKeyLength * 8;
+    }
+
+    @Override
+    public int getIckLength() {
+        return defaultKeyLength * 8;
+    }
+
+    @Override
+    public int getIcvLength() {
+        return defaultKeyLength * 8;
+    }
+
+    @Override
+    public int getSakLength() {
+        return defaultKeyLength * 8;
+    }
+
+    @Override
+    public byte[] generateCak(byte[] msk, byte[] mac1, byte[] mac2) {
+        /* IEEE 802.1X 2010, Clause 6.2.2. */
+        byte[] cak = null;
+        byte[] label = "IEEE8021 EAP CAK".getBytes();
+        byte[] context = new byte[mac1.length + mac2.length];
+        ByteBuffer contextBuffer = ByteBuffer.wrap(context);
+        contextBuffer.put(mac1);
+        contextBuffer.put(mac2);
+        cak = deriveKey(msk, label, context, (short) getCakLength());
+        return cak;
+    }
+
+    @Override
+    public byte[] generateCkn(byte[] msk, byte[] mac1, byte[] mac2, byte[] sid) {
+        /* IEEE 802.1X 2010, Clause 6.2.2. */
+        byte[] ckn = null;
+        byte[] label = "IEEE8021 EAP CKN".getBytes();
+        byte[] context = new byte[sid.length + mac1.length + mac2.length];
+        ByteBuffer contextBuffer = ByteBuffer.wrap(context);
+        contextBuffer.put(sid);
+        contextBuffer.put(mac1);
+        contextBuffer.put(mac2);
+        ckn = deriveKey(msk, label, context, (short) (defaultKeyLength * 8));
+        return ckn;
+    }
+
+    @Override
+    public byte[] generateKek(byte[] cak, byte[] ckn) {
+        /* IEEE 802.1X 2010, Clause 9.3.3. */
+        byte[] kek = null;
+        byte[] label = "IEEE8021 KEK".getBytes();
+        byte[] keyID = Arrays.copyOfRange(ckn, 0, kdfContextLength);
+        kek = deriveKey(cak, label, keyID, (short) getKekLength());
+        return kek;
+    }
+
+    @Override
+    public byte[] generateIck(byte[] cak, byte[] ckn) {
+        /* IEEE 802.1X 2010, Clause 9.3.3. */
+        byte[] ick = null;
+        byte[] label = "IEEE8021 ICK".getBytes();
+        byte[] keyID = Arrays.copyOfRange(ckn, 0, kdfContextLength);
+        ick = deriveKey(cak, label, keyID, (short) getIckLength());
+        return ick;
+    }
+
+    @Override
+    public byte[] generateIcv(byte[] ick, byte[] msg) {
+        /* IEEE 802.1X-2010 9.4.1
+         * ICV = AES-CMAC(ICK, M, 128) */
+        byte[] icv = null;
+        // icv = prf(ick, msg, 128);
+        icv = prf(ick, msg, msg.length);
+        return icv;
+
+        //return MkaKeyUtils.hexStringToByteArray("045205925831ae59c14550ed59cc003d");
+    }
+
+    @Override
+    public byte[] generateSak(byte[] cak, byte[] ksNonce, byte[] memberIDs, int keyNumber) {
+        byte[] sak = null;
+        byte[] label = "IEEE8021 SAK".getBytes();
+        byte[] kn = ByteBuffer.allocate(4).putInt(keyNumber).array();
+        byte[] context = new byte[ksNonce.length + memberIDs.length + kn.length];
+        ByteBuffer contextBuffer = ByteBuffer.wrap(context);
+        contextBuffer.put(ksNonce);
+        contextBuffer.put(memberIDs);
+        contextBuffer.put(kn);
+        sak = deriveKey(cak, label, context, (short) getSakLength());
+        return sak;
+    }
+
+    /**
+     * Key Derivation Function(KDF). IEEE 802.1X-2010, 6.2.1
+     *
+     * @param key       - Key derivation key either 128 or 256 bits
+     * @param label     - String identifying the purpose of keys derived using KDF
+     * @param context   - Bit string that provides context to identify derived key
+     * @param keyLength - Length of output key in bits encoded in two octets with the most significant octet first
+     * @return Derived Key
+     */
+    private byte[] deriveKey(byte[] key, byte[] label, byte[] context, short keyLength) {
+
+        byte[] length = ByteBuffer.allocate(2).putShort(keyLength).array();
+        int iterations, h;
+        double r = 32;
+
+        // Convert key length into bytes
+        h = key.length;
+
+        // Number of iterations to perform
+        iterations = (key.length * 8 + (h - 1)) / h;
+
+        // Check if iterations exceeds limit of integer capacity
+        if (iterations > (Math.pow(2, r) - 1)) {
+            return null;
+        }
+
+        // Perform key generation
+        ByteArrayOutputStream message = new ByteArrayOutputStream();
+        ByteArrayOutputStream catStream = new ByteArrayOutputStream();
+        try {
+            for (short i = 1; i < iterations; i++) {
+                message.write(i);
+                message.write(label);
+                message.write(0x00);
+                message.write(context);
+                message.write(length);
+                byte[] cat = message.toByteArray();
+                catStream.write(prf(key, cat, cat.length));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+        byte[] result = catStream.toByteArray();
+
+        /* Perform shift operation to get the first Length-bits of the result */
+        int bitsToShift = (result.length * 8) - key.length * 8;
+        BigInteger shiftInt = new BigInteger(result).shiftRight(bitsToShift);
+        return shiftInt.toByteArray();
+    }
+
+
+    /**
+     * Pseudo Random Function - Currently AES_CMAC.
+     *
+     * @param key     - Input key.
+     * @param message - Message to be hashed/authenticated.
+     * @param length  - Length of message.
+     * @return Message Authentication Code (MAC).
+     */
+    private static byte[] prf(byte[] key, byte[] message, int length) {
+        return (new AescMac()).generateAescMac(key, message, length);
+    }
+
+}
diff --git a/src/main/java/org/opencord/aaa/MacSecKaY.java b/src/main/java/org/opencord/aaa/MacSecKaY.java
new file mode 100644
index 0000000..b519233
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecKaY.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017-present.* Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * MKA KaY( MAC Key Agreement Protocol Entity) per device information.
+ * IEEE 802.1X-2010 Clause 9.16, Figure 12-3.
+ */
+public class MacSecKaY {
+    /* KaY activation  */
+    boolean enable;
+
+    /* MKA Version */
+    private byte mkaVersion = 0x01;
+
+    /* SecY interface */
+    MacSecSecY secY = null;
+
+    /* Algorithm Agility. IEEE 802.1X 2010; Table 9.1.
+     * Currently standard supports only one. List is used considering future additions. */
+    private List<MacSecAlgorithmAgility> agilities = new ArrayList<>();
+    private static int defaultAlgorithmAgility = 0;
+
+    /* CipherSuits supported by device. */
+    private List<MacSecCipherSuit> cipherSuits = new ArrayList<>();
+    private static int defaultCipherSuitOffset = 0;
+
+    /* Participants & CP state machine store.  */
+    private Map<String, Map.Entry<MkaParticipant, CpStateMachine>> portStoreMap =
+            new ConcurrentHashMap<>();
+
+    /* Load all SecY supporting CipherSuits */
+    private void loadCipherSuits() {
+        /* TODO : Load CipherSuits using SecY. */
+    }
+
+    MacSecKaY(MacSecSecY secY) {
+        /* Initialize default algorithm agility. IEEE 802.1X; Table 9.1*/
+        agilities.add(defaultAlgorithmAgility, new MacSecDefaultAlgorithmAgility());
+
+        /* Initialize CipherSuits.
+         * All devices should support default CipherSuit GCM–AES–128. IEEE 802.1AE 14.5
+         */
+        this.secY = secY;
+        cipherSuits.add(defaultCipherSuitOffset, new MacSecCipherSuit());
+        loadCipherSuits();
+    }
+
+    /**
+     * Adding participants & CP state machine to KaY.
+     *
+     * @param id             value in <Device ID><Port ID> format
+     * @param participant    details
+     * @param cpStateMachine details
+     */
+    public void addPortDetails(String id, MkaParticipant participant, CpStateMachine cpStateMachine) {
+        portStoreMap.put(id, new AbstractMap.SimpleEntry<>(participant, cpStateMachine));
+    }
+
+    /* Retrieve Participant using CAK */
+    public MkaParticipant participant(byte[] ckn) {
+        Optional<Map.Entry<String, Map.Entry<MkaParticipant, CpStateMachine>>> participant =
+                portStoreMap.entrySet().stream()
+                        .filter(entry -> entry.getValue().getKey().cak().equals(ckn))
+                        .findFirst();
+        return participant.isPresent() ? participant.get().getValue().getKey() : null;
+    }
+
+    /* Participant by ID. */
+    public MkaParticipant lookupParticipantByID(String id) {
+        Map.Entry<MkaParticipant, CpStateMachine> portDetails = portStoreMap.getOrDefault(id, null);
+        return (portDetails != null) ? portDetails.getKey() : null;
+    }
+
+    /* CP state machine by ID */
+    public CpStateMachine lookupCPStateMachineByID(String id) {
+        Map.Entry<MkaParticipant, CpStateMachine> portDetails = portStoreMap.getOrDefault(id, null);
+        return (portDetails != null) ? portDetails.getValue() : null;
+    }
+
+    /* Default algorithm agility. */
+    public MacSecAlgorithmAgility defaultAlgorithmAgility() {
+        return agilities.get(defaultAlgorithmAgility);
+    }
+
+    /* Default cipher suit. */
+    public MacSecCipherSuit defaultCipherSuit() {
+        return cipherSuits.get(defaultCipherSuitOffset);
+    }
+
+    /* Version */
+    public byte mkaVersion() {
+        return mkaVersion;
+    }
+ }
diff --git a/src/main/java/org/opencord/aaa/MacSecSecY.java b/src/main/java/org/opencord/aaa/MacSecSecY.java
new file mode 100644
index 0000000..d7792ec
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MacSecSecY.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2017-present. * Open Networking Foundation .
+ *
+ * Licensed 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.opencord.aaa;
+
+import org.slf4j.Logger;
+
+import org.onlab.packet.EAPOL_MKPDU_BasicParameterSet.SCI;
+
+import org.onosproject.net.DeviceId;
+
+import org.opencord.aaa.CpStateMachine.MacSecValidate;
+
+import java.util.List;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class MacSecSecY {
+
+    private final Logger log = getLogger(getClass());
+    DeviceId deviceId;
+
+    MacSecSecY(DeviceId deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    /* Verification */
+    public boolean validateFrames(String portName, MacSecValidate validate) {
+        log.trace("Request for Validate Frames: {} {}", portName, validate);
+        return true;
+    }
+
+    /* Generation */
+    public boolean protectFrames(String portName, boolean status) {
+        log.trace("Request for enabling/disabling Protect Frames : {} {}", portName, status);
+        return true;
+    }
+
+    /* Transmit & Receive SCs & SAs. */
+    public boolean createTransmitSC(String portName, SCI sci) {
+        log.trace("Transmit SC creation request : {}, {}", portName, sci);
+        return true;
+    }
+
+    public boolean deleteTransmitSC(String portName, SCI sci) {
+        log.trace("Transmit SC delete request : [{}, {}]", portName, sci);
+        return true;
+    }
+
+    public boolean createTransmitSA(String portName, SCI sci, int an, long pn) {
+        log.trace("Transmit SA creation request : [{}, {}, {}, {}]", portName, sci, an, pn);
+        return true;
+    }
+
+    public boolean deleteTransmitSA(String portName, SCI sci, int an) {
+        log.trace("Transmit SA deletion request : [{},{},{},{}]", portName, sci, an);
+        return true;
+    }
+
+    public boolean enableTransmitSA(String portName, SCI sci, int an) {
+        log.trace("Transmit SA enable request : [{},{},{},{}]", portName, sci, an);
+        return true;
+    }
+
+    public boolean createReceiveSC(String portName, SCI sci) {
+        log.trace("Receive SC creation request : [{}, {}]", portName, sci);
+        return true;
+    }
+
+    public boolean deleteReceiveSC(String portName, SCI sci) {
+        log.trace("Receive SC deletion request : [{}, {}]", portName, sci);
+        return true;
+    }
+
+    public boolean createReceiveSA(String portName, SCI sci, int an, long pn, long lowestPn) {
+        log.trace("Receive SA creation request : [{}, {}, {}, {}, {}]", portName, sci, an, pn,
+                lowestPn);
+        return true;
+    }
+
+    public boolean deleteReceiveSA(String portName, SCI sci, int an) {
+        log.trace("Receive SA deletion request : [{},{},{},{}]", portName, sci, an);
+        return true;
+    }
+
+    public boolean enableReceiveSA(String portName, SCI sci, int an) {
+        log.trace("Receive SA enable request : [{},{},{},{}]", portName, sci, an);
+        return true;
+    }
+
+    /* SAK Keys. */
+    public boolean installKey(String portName, int index, byte[] key, byte[] keyIdentifier,
+                              boolean transmits, boolean receives) {
+        log.trace("Received Key Installation request : {} {} {} {} {} {}", portName, index, key,
+                keyIdentifier, transmits, receives);
+        return true;
+    }
+
+    public boolean removeKey(String portName, int index) {
+        log.trace("Received Key Removal request : {} {}", portName, index);
+        return true;
+    }
+
+    /* CipherSuit configuration. */
+    public boolean addCipherSuite(int cipherSuitID, boolean enable,
+                                     boolean confidentiality) {
+        return true;
+    }
+
+    public boolean setCurrentCipherSuit(String portName, long cipherSuitID) {
+        log.trace("Request for setting current Cipher Suit : {} {}", portName, cipherSuitID);
+        return true;
+    }
+
+    public List<MacSecCipherSuit> getCipherSuites() {
+        return null;
+    }
+
+    /* Port enable/disable*/
+    public boolean enablePort(String portName, boolean status) {
+        log.trace("Enable port request : {} {} {}", portName, status);
+        return true;
+    }
+
+    public boolean replayProtect(String portName, boolean status, int window) {
+        log.trace("Replay protection request : {} {} {}", portName, status, window);
+        return true;
+    }
+}
+
diff --git a/src/main/java/org/opencord/aaa/MkaKeyUtils.java b/src/main/java/org/opencord/aaa/MkaKeyUtils.java
new file mode 100644
index 0000000..3aa7a1e
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MkaKeyUtils.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018-present. * Open Networking Foundation.
+ *
+ * Licensed 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.opencord.aaa;
+
+/**
+ * Misc. MKA key utility.
+ */
+public final class MkaKeyUtils {
+
+    static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+    private MkaKeyUtils(){
+
+    }
+    /**
+     * Convert hex string to byte array.
+     *
+     * @param s - Hex string to be converted to byte array
+     * @return byte array formed from the string
+     */
+    public static byte[] hexStringToByteArray(String s) {
+        int len;
+        byte[] data;
+        if (s == null) {
+            return null;
+        }
+
+        len = s.length();
+        data = new byte[len / 2]; /* Two characters forms one byte. */
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
+        }
+        return data;
+    }
+
+    /**
+     * Utility to convert byte to hex string.
+     *
+     * @param data - Byte array to be converted to hex string
+     * @return - String representing ASCII hex string of given data.
+     */
+    public static String byteArrayToHexString(byte[] data) {
+        final char[] hexString = new char[data.length << 1];
+        if (data == null) {
+            return null;
+        }
+
+        for (int i = 0, j = 0; i < data.length; i++) {
+            hexString[j++] = HEX_DIGITS[(data[i] & 0xF0) >>> 4];
+            hexString[j++] = HEX_DIGITS[data[i] & 0x0F];
+        }
+        return new String(hexString);
+    }
+
+}
diff --git a/src/main/java/org/opencord/aaa/MkaParticipant.java b/src/main/java/org/opencord/aaa/MkaParticipant.java
new file mode 100644
index 0000000..63fa6a6
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/MkaParticipant.java
@@ -0,0 +1,1340 @@
+/*
+ * Copyright 2017-present. * Open Networking Foundation .
+ *
+ * Licensed 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.opencord.aaa;
+
+// import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
+
+
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.EAPOL_MKPDU;
+import org.onlab.packet.EAPOL_MKPDU_ParameterSet;
+import org.onlab.packet.EAPOL_MKPDU_BasicParameterSet;
+import org.onlab.packet.EAPOL_MKPDU_BasicParameterSet.SCI;
+import org.onlab.packet.EAPOL_MKPDU_PeerListParameterSet;
+import org.onlab.packet.EAPOL_MKPDU_PeerListParameterSet.MemberDetails;
+import org.onlab.packet.EAPOL_MKPDU_MACSecUseParameterSet;
+import org.onlab.packet.EAPOL_MKPDU_DistributedSAKParameterSet;
+import org.onlab.packet.EAPOL_MKPDU_ICVIndicatorParameterSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketService;
+
+import java.nio.ByteBuffer;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * MKA KaY( MAC Key Agreement Protocol Entity) participants coming under one CA.
+ * IEEE 802.1X-2010 Clause 9.16, Figure 12-3
+ */
+public class MkaParticipant {
+
+    /* Logger */
+    private final Logger log = getLogger(getClass());
+
+    /* KaY(parent), SecY interfaces*/
+    MacSecKaY kay;
+    MacSecSecY secY;
+
+    /* SCI */
+    private SCI actorSci;
+
+    /* Key Details */
+    private byte[] cak;
+    private byte[] ckn;
+    private byte[] kek;
+    private byte[] ick;
+    private byte[] sak;
+
+    /* Actor Details. ie. myself as Actor. */
+    private byte actorPriority;
+    private byte[] mi;
+    private int mn;
+
+    /* Port specific management, monitor & control */
+    private boolean active;
+
+    public enum ActivateType {
+        DEFAULT,
+        DISABLED,
+        ON_OPER_UP,
+        ALWAYS
+    }
+
+    private ActivateType activate;
+    private boolean principal;
+
+    /* MACSec specific management, monitor & control. */
+    /* MACSec Capabalities. IEEE 802.1x; Table 11-6 */
+    private MacSecCipherSuit.MacSecCapabilities macSecCapability;
+    private boolean macSecDesired;
+
+    private List<MkaPeer> livePeers = new ArrayList<>();
+    private List<MkaPeer> potentialPeers = new ArrayList<>();
+
+    /* Latest Key Server Details. ie. Details of Key Server for current SAK.  */
+    private byte[] latestKI;
+    private int latestKN;
+    private boolean latestTX;
+    private boolean latestRX;
+    private byte latestAN;
+
+    /* Old Key Server Details. ie. Details of Key Server for previous SAK. */
+    private byte[] oldKI;
+    private int oldKN;
+    private boolean oldTX;
+    private boolean oldRX;
+    private byte oldAN;
+
+    private final byte[] emptyKI = new byte[EAPOL_MKPDU_ParameterSet.FIELD_MI_LENGTH];
+
+    /* AAA State-Machine; for Device, Supplicant access  */
+    private StateMachine sm;
+
+    /* Packet Service for packet transmission. */
+    private PacketService ps;
+    private DeviceId deviceId;
+    private Port port;
+
+    /* Key Store */
+    public class KeyStore {
+        class Key {
+            int keyIndex;
+            ByteBuffer keyIdentifier;
+            ByteBuffer key;
+            long createdTime;
+            boolean transmits, receives;
+
+            Key(int keyIndex, byte[] keyIdentifier, byte[] key) {
+                this.keyIndex = keyIndex;
+                this.keyIdentifier = ByteBuffer.wrap(keyIdentifier);
+                this.key = ByteBuffer.wrap(key);
+                createdTime = System.currentTimeMillis();
+                transmits = true;
+                receives = true;
+            }
+
+            public byte[] key() {
+                return key.array();
+            }
+
+            public ByteBuffer keyBuffer() {
+                return key;
+            }
+
+            public byte[] keyIdentifier() {
+                return keyIdentifier.array();
+            }
+
+            public int keyIndex() {
+                return keyIndex;
+            }
+
+            public ByteBuffer keyIdentifierBuffer() {
+                return keyIdentifier;
+            }
+
+
+         /*   @Override
+            public boolean equals(Object object) {
+
+                if ((object instanceof Key) && ((Key) object).keyBuffer().equals(key))
+                    return true;
+                else if ((object instanceof ByteBuffer) && ((ByteBuffer) object).equals(keyIdentifier))
+                    return true;
+                return false;
+            }*/
+
+            @Override
+            public int hashCode() {
+                return keyIdentifier().hashCode();
+            }
+
+            public void setTransmits(boolean status) {
+                transmits = status;
+            }
+
+            public boolean isTransmits() {
+                return transmits;
+            }
+
+            public void setReceives(boolean status) {
+                receives = status;
+            }
+
+            public boolean isReceives() {
+                return receives;
+            }
+        }
+
+        class Store {
+            Map<Key, List<SecureAssociation>> store = new LinkedHashMap<>();
+
+            public void put(Key key, List<SecureAssociation> value) {
+                store.put(key, value);
+            }
+
+            public List<SecureAssociation> get(ByteBuffer keyID) {
+                Optional<Key> key = store.keySet().stream()
+                        .filter(k -> k.keyIdentifierBuffer().equals(keyID))
+                        .findFirst();
+                List<SecureAssociation> x = key.isPresent() ? store.get(key.get()) : null;
+                return x;
+//                return (key != null) ? store.get(key) : null;
+            }
+
+            public Set<Key> keySet() {
+                return store.keySet();
+            }
+
+        }
+
+        Store store = null;
+        AtomicInteger indexSequence = null;
+
+        KeyStore() {
+            store = new Store();
+            indexSequence = new AtomicInteger();
+        }
+
+        public void storeSA(byte[] keyIdentifier, SecureAssociation sa) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            List<SecureAssociation> saList = store.get(keyIDBuffer);
+            if (saList != null) {
+                saList.add(sa);
+            }
+        }
+
+        public List<SecureAssociation> retrieveSAs(byte[] keyIdentifier) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            return store.get(keyIDBuffer);
+
+            //return store.get(keyIDBuffer);
+        }
+
+        public void transmits(byte[] keyIdentifier, boolean status) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            Optional<Key> keyEntry = store.keySet().stream()
+                    .filter(k -> k.equals(keyIDBuffer))
+                    .findFirst();
+            keyEntry.ifPresent(k -> k.setTransmits(status));
+        }
+
+        public boolean isTransmits(byte[] keyIdentifier) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            Key keyEntry = store.keySet().stream()
+                    .filter(k -> k.equals(keyIDBuffer))
+                    .findFirst()
+                    .get();
+            return (keyEntry != null) ? keyEntry.isTransmits() : false;
+        }
+
+        public void receives(byte[] keyIdentifier, boolean status) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            Optional<Key> keyEntry = store.keySet().stream()
+                    .filter(k -> k.equals(keyIDBuffer))
+                    .findFirst();
+            keyEntry.ifPresent(k -> k.setReceives(status));
+        }
+
+        public boolean isReceives(byte[] keyIdentifier) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            Key keyEntry = store.keySet().stream()
+                    .filter(k -> k.equals(keyIDBuffer))
+                    .findFirst()
+                    .get();
+            return (keyEntry != null) ? keyEntry.isReceives() : false;
+        }
+
+        public void createKey(byte[] keyIdentifier, byte[] key) {
+            ByteBuffer keyIDBuffer = ByteBuffer.wrap(keyIdentifier);
+            List<SecureAssociation> saList = store.get(keyIDBuffer);
+            if (saList == null) {
+                saList = new LinkedList<>();
+                Key index = new Key(indexSequence.getAndIncrement() % Byte.MAX_VALUE,
+                        keyIdentifier, key);
+                store.put(index, saList);
+                secY.installKey(port.number().name(), index.keyIndex(), index.key(),
+                        index.keyIdentifier(), index.isTransmits(), index.isReceives());
+            }
+        }
+    }
+
+    KeyStore keyStore = null;
+
+    /* General Secure Connection & Secure Associations. IEEE 802.1AE SecY YANG model. */
+    enum SCType {
+        GENERATION, VERIFICATION
+    }
+
+    abstract class SecureConnection {
+        SCI sci = null;
+        long createdTime;
+        SCType type;
+        AtomicInteger anIndex = new AtomicInteger();
+        List<SecureAssociation> sas = new LinkedList<>();
+
+        SecureConnection(SCI sci, SCType type) {
+            this.sci = sci;
+            this.type = type;
+            createdTime = System.currentTimeMillis();
+        }
+
+        public void attachSA(SecureAssociation sa) {
+            sas.add(sa);
+        }
+
+        public void detachSA(SecureAssociation sa) {
+            sas.removeIf(s -> s.equals(sa));
+        }
+
+        public byte getNextAvailableAN() {
+            return (byte) (anIndex.getAndIncrement() % Byte.MAX_VALUE);
+        }
+
+        public SCI sci() {
+            return sci;
+        }
+
+        public SCType type() {
+            return type;
+        }
+    }
+
+    abstract class SecureAssociation {
+        SecureConnection parent;
+        byte an;
+        long createdTime;
+        boolean inUse;
+
+        SecureAssociation(SecureConnection sc, byte an) {
+            parent = sc;
+            this.an = an;
+            createdTime = System.currentTimeMillis();
+            inUse = false;
+        }
+
+        public SecureConnection parent() {
+            return parent;
+        }
+
+        public byte an() {
+            return an;
+        }
+
+        public void setInUse(boolean status) {
+            inUse = status;
+        }
+    }
+
+    /* Transmit SC. */
+    class TransmitSC extends SecureConnection {
+        byte encodingSA;
+        boolean transmitting;
+
+        /* Transmit SAs */
+        class TransmitSA extends SecureAssociation {
+            long nextPN;
+            boolean confidentiality;
+
+            TransmitSA(TransmitSC sc, byte an, long nextPN) {
+                super(sc, an);
+                this.nextPN = nextPN;
+
+                /* TODO : Confidentiality determine from offset. */
+                /* confidentiality = ? */
+            }
+
+            public long nextPN() {
+                return nextPN;
+            }
+        }
+
+        TransmitSC(SCI sci) {
+            super(sci, SCType.GENERATION);
+            encodingSA = (byte) 0x00;
+            transmitting = false;
+        }
+
+        public SecureAssociation createSA(byte an, long nextPN) {
+            TransmitSA sa = new TransmitSA(this, an, nextPN);
+            attachSA(sa);
+            return sa;
+        }
+    }
+
+    TransmitSC txSC = null;
+
+    /* Receive SC. IEEE 802.1AE SecY YANG model. */
+    class ReceiveSC extends SecureConnection {
+
+        boolean receiving;
+
+        ReceiveSC(SCI sci) {
+            super(sci, SCType.VERIFICATION);
+            receiving = false;
+        }
+
+        class ReceiveSA extends SecureAssociation {
+            long nextPN, lowestPN;
+
+            ReceiveSA(ReceiveSC sc, byte an, long pn, long lpn) {
+                super(sc, an);
+                nextPN = pn;
+                lowestPN = lpn;
+            }
+
+            public long nextPN() {
+                return nextPN;
+            }
+
+            public long lowestPN() {
+                return lowestPN;
+            }
+
+        }
+
+        public SecureAssociation createSA(byte an, long pn, long lpn) {
+            ReceiveSA sa = new ReceiveSA(this, an, pn, lpn);
+            attachSA(sa);
+            return sa;
+        }
+
+    }
+
+    LinkedList<ReceiveSC> rxSCList = new LinkedList<>();
+
+    /* EAPOL-MKPDU serialization/de-serialization supporters.
+     * ie. ParameterSet Creators & Processors  */
+    abstract class ParameterSetCreator {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        public ParameterSetCreator(MacSecKaY kaY, MkaParticipant participant) {
+            this.kaY = kaY;
+            this.participant = participant;
+        }
+
+        /* Building parameter set. */
+        abstract EAPOL_MKPDU_ParameterSet buildParameterSet();
+
+        /* Identifying type of parameter set supporting. */
+        abstract int parameterSetType();
+    }
+
+    /* Basic Parameter Set Creator */
+    class BasicParameterSetCreator extends ParameterSetCreator {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        BasicParameterSetCreator(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        EAPOL_MKPDU_ParameterSet buildParameterSet() {
+            EAPOL_MKPDU_BasicParameterSet bps = new EAPOL_MKPDU_BasicParameterSet();
+            bps.setMkaVersion(kay.mkaVersion());
+            bps.setKeyServerPriority(participant.actorPriority());
+                /* TODO: KeyServer Election not done.
+                 * So setting myself as infrastructure key server.
+                 */
+            bps.setKeyServer(true);
+            bps.setMacSecDesired(participant.macSecDesired);
+            bps.setMacSecCapability((byte) participant.macSecCapability.ordinal());
+            bps.setSci(participant.actorSci());
+            bps.setActorMI(participant.actorMI());
+            bps.setActorMN(participant.retrieveAndUpdateMN());
+            bps.setAlgAgility(kay.defaultAlgorithmAgility().getParameter());
+            bps.setCKN(participant.ckn());
+            return (EAPOL_MKPDU_ParameterSet) bps;
+        }
+        @Override
+        int parameterSetType() {
+            return EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_BASIC;
+        }
+    }
+
+    /* Live Peer List Parameter Set Creator */
+    class LivePeerListCreator extends ParameterSetCreator {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        LivePeerListCreator(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        EAPOL_MKPDU_ParameterSet buildParameterSet() {
+                /* Ensure Live Peers are existing. */
+            List<MkaPeer> peers = participant.allLivePeers();
+            if (peers.isEmpty()) {
+                return null;
+            }
+                /* Populate Peer list. */
+            EAPOL_MKPDU_PeerListParameterSet lplps =
+                    new EAPOL_MKPDU_PeerListParameterSet();
+            lplps.setPeerListType(EAPOL_MKPDU_PeerListParameterSet.PEERLIST_TYPE_LIVE);
+            peers.forEach((peer) -> {
+                lplps.addMember(peer.mi(), peer.mn());
+            });
+            return (EAPOL_MKPDU_ParameterSet) lplps;
+        }
+        @Override
+        int parameterSetType() {
+            return EAPOL_MKPDU_PeerListParameterSet.PEERLIST_TYPE_LIVE;
+        }
+    }
+
+    /* Potential Parameter Set Creator */
+    class PotentialPeerListCreator extends ParameterSetCreator {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        PotentialPeerListCreator(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        EAPOL_MKPDU_ParameterSet buildParameterSet() {
+                /* Ensure Potential Peers are existing. */
+            List<MkaPeer> peers = participant.allPotentialPeers();
+            if (peers.isEmpty()) {
+                return null;
+            }
+                /* Populate Peer list. */
+            EAPOL_MKPDU_PeerListParameterSet pplps =
+                    new EAPOL_MKPDU_PeerListParameterSet();
+            pplps.setPeerListType(EAPOL_MKPDU_PeerListParameterSet.PEERLIST_TYPE_POTENTIAL);
+            peers.forEach((i) -> {
+                pplps.addMember(i.mi(), i.mn());
+            });
+            return (EAPOL_MKPDU_ParameterSet) pplps;
+        }
+        @Override
+        int parameterSetType() {
+            return EAPOL_MKPDU_PeerListParameterSet.PEERLIST_TYPE_POTENTIAL;
+        }
+    }
+
+    /* MACSec Use Parameter Set Creator */
+    class MacSecUseCreator extends ParameterSetCreator {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        MacSecUseCreator(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        EAPOL_MKPDU_ParameterSet buildParameterSet() {
+            EAPOL_MKPDU_MACSecUseParameterSet ups =
+                    new EAPOL_MKPDU_MACSecUseParameterSet();
+            CpStateMachine cpSM = kay.lookupCPStateMachineByID(sm.sessionId());
+            ups.setDelayProtect(cpSM.macSecReplayProtect());
+            ups.setPlainTX(!cpSM.macSecProtect());
+            ups.setPlainRX((cpSM.macSecValidate() == CpStateMachine.MacSecValidate.Disabled) ? true : false);
+
+            // Latest Key Server Details
+            ups.setLatestKI(participant.latestKI());
+            ups.setLatestKN(participant.latestKN());
+            ups.setLatestTX(participant.latestTX());
+            ups.setLatestRX(participant.latestRX());
+            ups.setLatestAN(participant.latestAN());
+
+            /* TODO: Filling Latest Lowest Acceptable PN. */
+            // Retrieve PN for Key Server.
+            // int pn = DEVICE-Abstract-Layer.getPN(participant.latestKI())
+            // ups.setLatestLAPN(pn)
+
+            // Old Key Server Details.
+            /* TODO: Needs rethinking for newly joined actors. */
+            ups.setOldKI(participant.oldKI());
+            ups.setOldKN(participant.oldKN());
+            ups.setOldTX(participant.oldTX());
+            ups.setOldRX(participant.oldRX());
+            ups.setOldAN(participant.oldAN());
+
+            /* TODO: Filling Old Lowest Acceptable PN. */
+            // Retrieve PN for Key Server.
+            // int opn = DEVICE-Abstract-Layer.getPN(participant.oldKI())
+            // ups.setLatestLAPN(opn)
+            return (EAPOL_MKPDU_ParameterSet) ups; }
+        @Override
+        int parameterSetType() {
+            return EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_MACSEC_SAK_USE;
+        }
+    }
+
+    /* Distributed SAK Parameter Set Creator */
+    class DistributedSakCreator extends ParameterSetCreator {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        DistributedSakCreator(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        EAPOL_MKPDU_ParameterSet buildParameterSet() {
+            EAPOL_MKPDU_DistributedSAKParameterSet dsps =
+                    new EAPOL_MKPDU_DistributedSAKParameterSet();
+            dsps.setDistributedAN(participant.latestAN());
+            CpStateMachine cpSM = kay.lookupCPStateMachineByID(sm.sessionId());
+            dsps.setConfidentialityOffset((byte) cpSM.cipherSuit()
+                    .getConfidentialityOffset().ordinal());
+            dsps.setKeyNumber(participant.latestKN());
+            dsps.setSAK(participant.sak());
+            dsps.setKeyWrapper((byte[] key) -> {
+                byte[] wrappedKey = new AescMac().wrap(participant.kek(), key);
+                return wrappedKey;
+            });
+            return (EAPOL_MKPDU_ParameterSet) dsps;
+        }
+        @Override
+        int parameterSetType() {
+            return EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_DISTRIBUTED_SAK;
+        }
+    }
+
+    /* ICV Parameter Set Creator */
+    class IcvCreator extends  ParameterSetCreator {
+
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        IcvCreator(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        EAPOL_MKPDU_ParameterSet buildParameterSet() {
+            EAPOL_MKPDU_ICVIndicatorParameterSet icvps = new EAPOL_MKPDU_ICVIndicatorParameterSet();
+                /* Populate PS fields. */
+//                icvps.setKey(participant.ick());
+//                 class AESCMAC_128_HashCreator implements EAPOL_MKPDU_ICVIndicatorParameterSet.HashGenerator<byte[]> {
+//                     @Override
+//                     public byte[] generateHash(byte[] key, byte[] msg) {
+//                         return participant.kay.defaultAlgorithmAgility().generateICV(key, msg);
+//                     }
+//                 }
+//                 icvps.setHashCreator(new AESCMAC_128_HashCreator());
+//                icvps.setHashCreator((byte[] key, byte[] msg)
+//                                      -> (kay.defaultAlgorithmAgility().generateICV(key, msg)));
+            return (EAPOL_MKPDU_ParameterSet) icvps;
+        }
+        @Override
+        int parameterSetType() {
+            return EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_ICV_INDICATOR;
+        }
+    }
+
+    Map<Byte, ParameterSetCreator> psCreators = new LinkedHashMap<>();
+
+    /* Parameter Set Processors */
+    abstract class ParameterSetProcessor {
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        public ParameterSetProcessor(MacSecKaY kaY, MkaParticipant participant) {
+            this.kaY = kaY;
+            this.participant = participant;
+        }
+
+        /* Process Parameter Set */
+        abstract boolean process(EAPOL_MKPDU mkpdu, EAPOL_MKPDU_ParameterSet parameterSet);
+    }
+
+    /* Basic Parameter Set Processor */
+    class BasicParameterSetProcessor extends ParameterSetProcessor {
+
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        BasicParameterSetProcessor(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        public boolean process(EAPOL_MKPDU mkpdu, EAPOL_MKPDU_ParameterSet parameterSet) {
+            EAPOL_MKPDU_BasicParameterSet bps = (EAPOL_MKPDU_BasicParameterSet) parameterSet;
+            byte[] mi = bps.getActorMI();
+            int mn = bps.getActorMN();
+
+            /* MKPDU received from new participant then populate in Potential Peer List */
+            MkaPeer livePeer = participant.isLivePeer(mi);
+            MkaPeer potentialPeer = participant.isPotentialPeer(mi);
+            if ((livePeer == null) && (potentialPeer == null)) {
+                MkaPeer peer = new MkaPeer(bps.getSci(), mi, mn);
+                peer.setKeyServer(bps.getKeyServer());
+                peer.setKeyServerPriority(bps.getKeyServerPriority());
+                peer.setMacSecDesired(bps.getMacSecDesired());
+                peer.setMacSecCapability(bps.getMacSecCapacity());
+                peer.setTimestamp(System.currentTimeMillis());
+                participant.addPotentialPeer(peer);
+            } else {
+                /* Already exiting actor, update details.*/
+                MkaPeer currentPeer = (livePeer != null) ? livePeer : potentialPeer;
+                if (currentPeer.mn() < mn) {
+                    currentPeer.setMN(mn);
+                    currentPeer.setKeyServer(bps.getKeyServer());
+                    currentPeer.setKeyServerPriority(bps.getKeyServerPriority());
+                    currentPeer.setMacSecDesired(bps.getMacSecDesired());
+                    currentPeer.setMacSecCapability(bps.getMacSecCapacity());
+                    currentPeer.setTimestamp(System.currentTimeMillis());
+                    /* (livePeer != null) ? participant.updateLivePeer(currentPeer)
+                                : participant.updatePotentialPeer(currentPeer); */
+                }
+            }
+            /* Myself in peer's peer list and peer is in Potential Peer List */
+            // if ((potentialPeer != null) &&
+            //         (participant.myselfPeerOfRemotePeer(eapolMkpdu.getPeerListParameterSet()) == true)) {
+            //     /* Update Live Peer list : */
+            //     participant.addLivePeer(participant.removePotentialPeer(mi));
+            // }
+            return true;
+        }
+    }
+
+    /* Live Peer List Parameter Set Processor. */
+    class LivePeerListProcessor extends ParameterSetProcessor {
+
+        MacSecKaY kaY;
+        MkaParticipant participant;
+
+        LivePeerListProcessor(MacSecKaY kaY, MkaParticipant participant) {
+            super(kaY, participant);
+            this.kaY = kay;
+            this.participant = participant;
+        }
+
+        @Override
+        boolean process(EAPOL_MKPDU mkpdu, EAPOL_MKPDU_ParameterSet parameterSet) {
+                /* Actor basic details. */
+            EAPOL_MKPDU_BasicParameterSet bps = mkpdu.getBasicParameterSet();
+            final byte[] actorMI = bps.getActorMI();
+            int actorMN = bps.getActorMN();
+                /* Process each peer details in Live Parameter Set */
+            EAPOL_MKPDU_PeerListParameterSet lplPS = (EAPOL_MKPDU_PeerListParameterSet) parameterSet;
+            List<MemberDetails> lplMembers = lplPS.getMembers();
+            lplMembers.forEach(m -> {
+                byte[] mID = m.getMemberID();
+                int mn = m.getMessageNo();
+                    /* Live peer is myself. */
+                if (Arrays.equals(mID, participant.mi)) {
+                        /* Check peer is in Potential Peer list, if so update to Live Peers list.  */
+                    if (participant.isPotentialPeer(actorMI) != null) {
+                        MkaPeer peer = participant.removePotentialPeer(actorMI);
+                        participant.addLivePeer(peer);
+                        participant.createReceiveSC(peer.getSci());
+                        secY.createReceiveSA(port.number().name(), peer.getSci(), txSC.getNextAvailableAN(),
+                                1, 1);
+                    }
+                    return;
+                }
+                    /* Update if peer is in live list, otherwise add new in potential list. */
+                MkaPeer peer = participant.isLivePeer(mID);
+                if (peer != null) {
+                    peer.setMN(mn);
+                    peer.setTimestamp(System.currentTimeMillis());
+                } else {
+                    MkaPeer potentialPeer = new MkaPeer(peer.getSci(), mID, mn);
+                    potentialPeer.setTimestamp(System.currentTimeMillis());
+                    participant.addPotentialPeer(potentialPeer);
+                }
+            });
+            return false;
+        }
+    }
+
+    Map<Byte, ParameterSetProcessor> psProcessors = new LinkedHashMap<>();
+
+    /* Hello Timer Executor */
+    ScheduledExecutorService executorService;
+
+    /* PAE Group Address. */
+    public static final byte[] HELLO_MKPDU_SEND_ADDRESS = {(byte) 0x01, (byte) 0x80, (byte) 0xC2,
+            (byte) 0x00, (byte) 0x00, (byte) 0x03};
+
+    /* Constructor using Key & KeyName */
+    MkaParticipant(StateMachine sm, PacketService ps,
+                   ScheduledExecutorService executerService, MacSecKaY kay, MacSecSecY secY, byte[] key,
+                   byte[] keyName, SCI actorSci, DeviceId deviceId, Port port) {
+
+        /* Sanitize. Evaluate CAK & CKN */
+        if ((key == null) || (keyName == null)) {
+            /* TODO : */
+        }
+        if ((kay.defaultAlgorithmAgility().getCakLength() != key.length)) {
+            /* TODO : */
+        }
+
+        /* Initialize KaY, SM, Packet Service etc. */
+        this.kay = kay;
+        this.secY = secY;
+        this.sm = sm;
+        this.ps = ps;
+        this.executorService = executerService;
+
+        /* Default MACSec RX/TX Protection Features. */
+        macSecCapability = MacSecCipherSuit.MacSecCapabilities.INTEGRITY_AND_CONFIDENTIALITY;
+        macSecDesired = true;
+
+        /* KeyStore, SC & SA details */
+        keyStore = new KeyStore();
+        this.actorSci = actorSci;
+        this.port = port;
+        txSC = new TransmitSC(actorSci);
+        secY.createTransmitSC(port.number().name(), actorSci);
+
+        /* Key details update. */
+        cak = key;
+        ckn = keyName;
+
+        /* Clear Member ID */
+        resetMI();
+
+        /* Initialize Key Server Details. */
+        this.deviceId = deviceId;
+        latestKI = mi;
+        latestKN = 1; /* TODO: Starting KeyNumber Configurable. */
+        latestTX = true;
+        latestRX = true;
+        latestAN = 0x01; /* TODO: Association Number should be initialized using standard method. */
+        oldKI = emptyKI; /* Cleared old Member ID. */
+        oldKN = 0;
+        oldTX = latestTX;
+        oldRX = latestRX;
+        oldAN = 0X00; /* Cleared old AN. */
+
+        /* Derive KEK, ICK from CAK, CKN */
+        MacSecAlgorithmAgility algorithmAgility = kay.defaultAlgorithmAgility();
+        kek = algorithmAgility.generateKek(cak, ckn);
+        ick = algorithmAgility.generateIck(cak, ckn);
+
+        /* Derive SAK from CAK */
+        byte[] ksNonce = new byte[16];
+        SecureRandom randomGenerator = new SecureRandom();
+        randomGenerator.nextBytes(ksNonce);
+        sak = algorithmAgility.generateSak(cak, ksNonce, mi, 1);
+        keyStore.createKey(latestKI, sak);
+
+        /* Initialize Parameter Creators. */
+        psCreators.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_BASIC,
+                new BasicParameterSetCreator(kay, this));
+        psCreators.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_LIVE_PEER_LIST,
+                new LivePeerListCreator(kay, this));
+        psCreators.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_POTENTIAL_PEER_LIST,
+                new PotentialPeerListCreator(kay, this));
+        psCreators.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_MACSEC_SAK_USE,
+                new MacSecUseCreator(kay, this));
+        psCreators.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_DISTRIBUTED_SAK,
+                new DistributedSakCreator(kay, this));
+        /* TODO: Other parameter sets filling. */
+        psCreators.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_ICV_INDICATOR,
+                new IcvCreator(kay, this));
+
+        /* Initialize Parameter Processors. */
+        psProcessors.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_BASIC,
+                new BasicParameterSetProcessor(kay, this));
+        psProcessors.put(EAPOL_MKPDU_ParameterSet.PARAMETERSET_TYPE_LIVE_PEER_LIST,
+                new LivePeerListProcessor(kay, this));
+        /* TODO : Other parameter set processing. */
+    }
+
+    /* Actor SCI */
+    public SCI actorSci() {
+        return actorSci;
+    }
+    public void setActorSci(SCI sci) {
+        this.actorSci = sci;
+    }
+
+    /* Outbound device details for packet transmission. */
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+    public void setDeviceId(DeviceId deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    /* Outbound port details for packet transmission. */
+    public Port port() {
+        return port;
+    }
+    public void setPort(Port port) {
+        this.port = port;
+    }
+
+    /* Process received EAPOL-MKPDU */
+    public void receive(EAPOL_MKPDU mkpdu) {
+        /* Process Various Parameter Sets */
+        ((LinkedHashMap<Byte, ParameterSetProcessor>) psProcessors).forEach((key, psp) -> {
+            EAPOL_MKPDU_ParameterSet ps = mkpdu.getParameterSet(key);
+            if ((ps != null) && (psp != null)) {
+                psp.process(mkpdu, ps);
+            }
+        });
+        return;
+    }
+
+    /* Start ticking heartbeat. ie enables Timers. */
+    public void startTicking() {
+        /* Initialize Hello Timer.  */
+        class WorkerThread implements Runnable {
+            MkaParticipant participant;
+            WorkerThread(MkaParticipant participant) {
+                this.participant = participant;
+            }
+            public void run() {
+                /* TODO: Make sure my lifespan exists. */
+                /* TODO: Clear expired Live Peers. */
+                /* TODO : Clear expired Potential Peers. */
+                /* TODO: Regenerate SAK if needed snd send it. */
+                /* Build & Send MKPDU */
+                log.info("Hello-Timer : Transmitting EAPOL-MKPDU....");
+                participant.transmitMkpdu();
+                log.info("Done.");
+            }
+        }
+        executorService.scheduleAtFixedRate(new WorkerThread(this), 5, 5, TimeUnit.SECONDS);
+    }
+
+    /* Building & Sending EAPOL-MKPDU. Hello Timer's routine. */
+    public void transmitMkpdu() {
+
+        /* EAPOL-MKA packet building & populating Parameter Sets*/
+        EAPOL_MKPDU mkpdu = new EAPOL_MKPDU();
+        for (Map.Entry<Byte, ParameterSetCreator> entry : psCreators.entrySet()) {
+            ParameterSetCreator c = entry.getValue();
+            mkpdu.addParameterSet(entry.getKey(), c.buildParameterSet());
+        }
+
+        /* EAPOL Header Filling */
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(EAPOL.EAPOL_MKA);
+        eapol.setPacketLength(mkpdu.packetLength());
+        eapol.setPayload(mkpdu);
+
+        /* Ethernet Header Filling. */
+        Ethernet ethernet = new Ethernet();
+        ethernet.setDestinationMACAddress(HELLO_MKPDU_SEND_ADDRESS);
+        ethernet.setSourceMACAddress(this.actorSci().address());
+        ethernet.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        ethernet.setVlanID(Ethernet.VLAN_UNTAGGED);
+        ethernet.setPayload(eapol);
+        ethernet.setPad(false);
+
+        /* ICV Calculation and Populating */
+        ByteBuffer frame = ByteBuffer.wrap(ethernet.serialize());
+        byte[] frameWoIcv = new byte[frame.capacity() -
+                kay.defaultAlgorithmAgility().getIcvLength() / 8];
+        frame.get(frameWoIcv);
+        byte[] icv = kay.defaultAlgorithmAgility().generateIcv(ick, frameWoIcv);
+        frame.position(frame.capacity() -
+                kay.defaultAlgorithmAgility().getIcvLength() / 8);
+        frame.put(icv);
+
+        /* Send packet to supplicant.  */
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(port.number()).build();
+        OutboundPacket packet = new DefaultOutboundPacket(deviceId, treatment, frame);
+        ps.emit(packet);
+        log.info("Flushed out Hello-Timer EAPOL-MKA PDU.");
+    }
+
+    /* CP state machine KaY interactions. IEEE 802.1X 2010 Figure 12-2. */
+    public void createReceiveSC(SCI sci) {
+        if (sci == null) {
+            log.info("Invalid SCI provided for SC creation.");
+            return;
+        }
+        rxSCList.add(new ReceiveSC(sci));
+        secY.createReceiveSC(port.number().name(), sci);
+    }
+
+    /* Creating Receive & Transmit SAs /*/
+    public void createSAs(byte[] keyIdentifier) {
+        List<SecureAssociation> sas = keyStore.retrieveSAs(keyIdentifier);
+        if (sas != null && sas.size() > 0) {
+            log.error("Improper keystore stage : {}", keyIdentifier);
+            return;
+        }
+
+        /* Create Transmit SAs */
+        SecureAssociation sa = txSC.createSA(txSC.getNextAvailableAN(), 1);
+        keyStore.storeSA(keyIdentifier, sa);
+        secY.createTransmitSA(port.number().name(), txSC.sci(), sa.an(), 1);
+        keyStore.transmits(keyIdentifier, true);
+
+        /* Create Receive SAs */
+        rxSCList.stream().forEach(sc -> {
+            SecureAssociation rxSA = sc.createSA(sc.getNextAvailableAN(), 1, 1);
+            keyStore.storeSA(keyIdentifier, rxSA);
+            secY.createReceiveSA(port.number().name(), sc.sci(), rxSA.an(), 1, 1);
+        });
+        keyStore.receives(keyIdentifier, true);
+    }
+
+    /* Deleting SAs associated with certain key. */
+    public void deleteSAs(byte[] keyIdentifier) {
+        List<SecureAssociation> saList = keyStore.retrieveSAs(keyIdentifier);
+        if (saList == null) {
+            log.error("Failed looking up key store. Key ID : {}", keyIdentifier);
+            return;
+        }
+        saList.stream().forEach(sa -> {
+            SecureConnection sc = sa.parent();
+            if (sc.type() == SCType.GENERATION) {
+                secY.deleteTransmitSA(port.number().name(), sc.sci(), sa.an());
+            } else {
+                secY.deleteReceiveSA(port.number().name(), sc.sci(), sa.an());
+            }
+            sc.detachSA(sa);
+        });
+        keyStore.transmits(keyIdentifier, false);
+        keyStore.receives(keyIdentifier, false);
+    }
+
+    public void enableReceiveSAs(byte[] keyIdentifier) {
+        List<SecureAssociation> saList = keyStore.retrieveSAs(keyIdentifier);
+        if (saList == null) {
+            log.error("Failed looking up key store. Key ID : {}", keyIdentifier);
+            return;
+        }
+
+        // Iterate by filtering receive SAs in store and enable it
+        CpStateMachine cpSM = kay.lookupCPStateMachineByID(sm.sessionId());
+        saList.stream().filter(sa -> sa.parent().type() == SCType.GENERATION)
+                .forEach(sa -> {
+                    SecureConnection sc = sa.parent();
+                    sa.setInUse(true);
+                    secY.enableReceiveSA(port.number().name(), sc.sci(), sa.an());
+                    cpSM.setUsingReceiveSAs(true);
+                    cpSM.stepStateMachine();
+                });
+        return;
+    }
+
+    public void enableTransmitSA(byte[] keyIdentifier) {
+        List<SecureAssociation> saList = keyStore.retrieveSAs(keyIdentifier);
+        if (saList == null) {
+            log.error("Failed looking up key store. Key ID : {}", keyIdentifier);
+            return;
+        }
+
+        // Iterate by filtering receive SAs in store and enable it
+        CpStateMachine cpSM = kay.lookupCPStateMachineByID(sm.sessionId());
+        saList.stream().filter(sa -> sa.parent().type() == SCType.GENERATION)
+                .forEach(sa -> {
+                    SecureConnection sc = sa.parent();
+                    sa.setInUse(true);
+                    secY.enableTransmitSA(port.number().name(), sc.sci(), sa.an());
+                    cpSM.setUsingTransmitSA(true);
+                    cpSM.stepStateMachine();
+                });
+        return;
+    }
+
+    public void setOldSAAttributes(byte[] ki, byte an, boolean tx, boolean rx) {
+        oldKI = (ki == null) ? emptyKI : ki;
+        oldAN = an; oldTX = tx; oldRX = rx;
+    }
+
+    public void setLatestSAAttributes(byte[] ki, byte an, boolean tx, boolean rx) {
+        latestKI = (ki == null) ? emptyKI : ki;
+        latestAN = an; latestTX = tx; latestRX = rx;
+    }
+
+    /* Peer details storing. */
+    protected class MkaPeer {
+        /* Basic Parameter Set details.*/
+        SCI sci;
+        private byte[] mi;
+        private int mn;
+        private boolean isKeyServer;
+        private byte keyServerPriority;
+        private boolean macSecDesired;
+        private byte macSecCapbility;
+        /* Expire time details */
+        private long expireTimestamp;
+        MkaPeer(SCI sci, byte[] mi, int mn) {
+            this.sci = sci;
+            this.mi = mi;
+            this.mn = mn;
+        }
+        /* Member Identifier */
+        public byte[] mi() {
+            return mi;
+        }
+        /* Message Number */
+        public int mn() {
+            return mn;
+        }
+        public void setMN(int mn) {
+            this.mn = mn;
+        }
+        /* Key Server Status */
+        public boolean keyServer() {
+            return isKeyServer;
+        }
+        public void setKeyServer(boolean keyServer) {
+            this.isKeyServer = keyServer;
+        }
+        /* Key Server Priority */
+        public byte keyServerPriority() {
+            return keyServerPriority;
+        }
+        public void setKeyServerPriority(byte keyServerPriority) {
+            this.keyServerPriority = keyServerPriority;
+        }
+        /* MACSec desirability */
+        public boolean macSecDesired() {
+            return macSecDesired;
+        }
+        public void setMacSecDesired(boolean macSecDesired) {
+            this.macSecDesired = macSecDesired;
+        }
+        /* MACSec capability */
+        public byte macSecCapability() {
+            return macSecCapbility;
+        }
+        public void setMacSecCapability(byte macSecCapbility) {
+            this.macSecCapbility = macSecCapbility;
+        }
+        /* Expire time details. */
+        public void setTimestamp(long timestamp) {
+            expireTimestamp = timestamp;
+        }
+        public long getTimestamp() {
+            return expireTimestamp;
+        }
+        public SCI getSci() {
+            return sci;
+        }
+    }
+
+    /* Live peer or not ? */
+    protected MkaPeer isLivePeer(byte[] mi) {
+        MkaPeer p = livePeers.stream()
+                .filter((q) -> Arrays.equals(q.mi(), mi))
+                .findAny()
+                .orElse(null);
+        return p;
+    }
+
+    /* Live peers at a time. */
+    protected List<MkaPeer> allLivePeers() {
+        return livePeers;
+    }
+
+    /* Potential peer or not ? */
+    protected MkaPeer isPotentialPeer(byte[] mi) {
+        MkaPeer p = potentialPeers.stream()
+                .filter((q) -> Arrays.equals(q.mi(), mi))
+                .findAny()
+                .orElse(null);
+        // if( p != null ) {
+        //     /* Update MN if new. */
+        //     if (p.getMN() <  mn) p.setMN(mn);
+        // }
+        return p;
+    }
+
+    /* All Potential Peers at a time. */
+    protected List<MkaPeer> allPotentialPeers() {
+        return potentialPeers;
+    }
+
+    /* Populate Potential Peer */
+    protected void addPotentialPeer(MkaPeer p) {
+        if (p != null && (isPotentialPeer(p.mi()) == null)) {
+            potentialPeers.add(p);
+        }
+        return;
+    }
+
+    /* Remove Potential Peer */
+    protected MkaPeer removePotentialPeer(byte[] mi) {
+        MkaPeer p = potentialPeers.stream()
+                .filter((q) -> Arrays.equals(q.mi(), (mi)))
+                .findAny()
+                .orElse(null);
+        if (p != null) {
+            potentialPeers.remove(p);
+        }
+        return p;
+    }
+
+    /* Populate Live Peer */
+    protected void addLivePeer(MkaPeer p) {
+        if (p != null && (isLivePeer(p.mi()) == null)) {
+            livePeers.add(p);
+        }
+        return;
+    }
+
+    /* Check myself present in remote peer's peer list */
+    protected boolean myselfPeerOfRemotePeer(EAPOL_MKPDU_PeerListParameterSet peerList) {
+        /* Handle Non-Peer List cases. */
+        if (peerList == null) {
+            return false;
+        }
+        if (peerList.getParameterSetType() != EAPOL_MKPDU_PeerListParameterSet.PEERLIST_TYPE_LIVE) {
+            return false;
+        }
+        return peerList.memberExists(mi);
+    }
+
+    /* Resets MI & MN */
+    protected void resetMI() {
+        SecureRandom random = new SecureRandom();
+        mi = new byte[EAPOL_MKPDU_ParameterSet.FIELD_MI_LENGTH];
+        random.nextBytes(mi);
+        /* TODO : Check IEEE 802.1X and finalize. */
+        mn = 1;
+    }
+
+    /* Key Server Priority */
+    protected byte actorPriority() {
+        return actorPriority;
+    }
+
+    /* Key Server MI */
+    protected byte[] actorMI() {
+        return mi;
+    }
+
+    /* Key Server MN */
+    protected int actorMN() {
+        return mn;
+    }
+
+    /* Retrieve and update Key Server MN */
+    protected int retrieveAndUpdateMN() {
+        int currentMN = mn;
+        /* Update MN for each Tx. */
+        mn += 1;
+        return currentMN;
+    }
+
+    /* Various Getters & Setters. */
+
+    /* Various Keys. */
+    protected byte[] cak() {
+        return cak;
+    }
+
+    protected byte[] ckn() {
+        return ckn;
+    }
+
+    protected byte[] sak() {
+        return sak;
+    }
+
+    protected byte[] ick() {
+        return ick;
+    }
+
+    protected byte[] kek() {
+        return kek;
+    }
+
+    /* Current Key Server Key Number */
+    protected int latestKN() {
+        return latestKN;
+    }
+
+    /* Current Key Server Identifier */
+    protected byte[] latestKI() {
+        return latestKI;
+    }
+
+    /* Current Key Server Association Number */
+    protected byte latestAN() {
+        return latestAN;
+    }
+
+    /* Current Key Server used for TX protection ? */
+    protected boolean latestTX() {
+        return latestTX;
+    }
+
+    /* Current Key Server used for RX protection ? */
+    protected boolean latestRX() {
+        return latestRX;
+    }
+
+    /* Old Key Server Identifier */
+    protected byte[] oldKI() {
+        return oldKI;
+    }
+
+    /* Old Key Server Key Number */
+    protected int oldKN() {
+        return oldKN;
+    }
+
+    /* Old Key Server Association Number */
+    protected byte oldAN() {
+        return oldAN;
+    }
+
+    /* Old Key Server used for TX protection ? */
+    protected boolean oldTX() {
+        return oldTX;
+    }
+
+    /* Old Key Server used for RX protection ? */
+    protected boolean oldRX() {
+        return oldRX;
+    }
+}
diff --git a/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java b/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java
index cf53b68..9210ad0 100755
--- a/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java
+++ b/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java
@@ -49,8 +49,6 @@
 
 import org.slf4j.Logger;
 
-import com.google.common.collect.Maps;
-
 import static org.onosproject.net.packet.PacketPriority.CONTROL;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -58,6 +56,7 @@
 import java.nio.ByteBuffer;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Handles communication with the RADIUS server through ports
@@ -125,7 +124,8 @@
         this.pktCustomizer = pktCustomizer;
         this.aaaManager = aaaManager;
 
-        ipToSnMap = Maps.newConcurrentMap();
+        //ipToSnMap = Maps.newConcurrentMap();
+        ipToSnMap = new ConcurrentHashMap<>();
         mastershipService.addListener(changeListener);
         deviceService.addListener(deviceListener);
 
diff --git a/src/main/java/org/opencord/aaa/StateMachine.java b/src/main/java/org/opencord/aaa/StateMachine.java
index 6795c43..d4c7904 100644
--- a/src/main/java/org/opencord/aaa/StateMachine.java
+++ b/src/main/java/org/opencord/aaa/StateMachine.java
@@ -18,6 +18,7 @@
 package org.opencord.aaa;
 
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
@@ -27,8 +28,6 @@
 
 import org.slf4j.Logger;
 
-import com.google.common.collect.Maps;
-
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -118,8 +117,10 @@
     private static Map<Integer, StateMachine> identifierMap;
 
     public static void initializeMaps() {
-        sessionIdMap = Maps.newConcurrentMap();
-        identifierMap = Maps.newConcurrentMap();
+        //sessionIdMap = Maps.newConcurrentMap();
+        sessionIdMap =  new ConcurrentHashMap<>();
+        //identifierMap = Maps.newConcurrentMap();
+        identifierMap = new ConcurrentHashMap<>();
         identifier = -1;
     }
 
