KasperskyOS Community Edition 1.0
[Topic kos_overview]

Basic concepts of KasperskyOS

KasperskyOS-based solution

A KasperskyOS-based solution consists of a kernel, security module, and applications and system software integrated for operation within a software/hardware system. In KasperskyOS, processes are called entities. The kernel guarantees that entities are isolated and can interact only through the kernel (using system calls). Each entity in a solution has a static description, which defines the interfaces available to other entities. The specialized languages EDL, CDL and IDL are used to describe interfaces.

Cyber immune approach

A cyber immune approach is used to develop secure KasperskyOS-based solutions. This approach relies on choosing a way to divide the system into entities and setting certain rules governing their interactions (a solution security policy). A security policy is implemented by the Kaspersky Security Module, which is included in the solution.

The cyber immune approach lets you protect trusted components of the system and minimize its attack surface. Even if one component in such a system is compromised, the remaining components will continue to perform security functions.

Details about the cyber immune approach

Kaspersky Security System

Kaspersky Security System technology lets you develop and implement various security policies. Moreover, you can combine several security models, add your own models, and flexibly configure the rules for entity interactions. The specialized language PSL is used to formally describe a solution security policy. A Kaspersky Security Module for use in a specific solution is generated based on the PSL description.

KasperskyOS Community Edition

KasperskyOS Community Edition contains tools for developing secure KasperskyOS-based solutions, including:

  • Image of the KasperskyOS kernel
  • The NK compiler which is designed to generate the Kaspersky Security Module and auxilliary transport code
  • Other tools for solution development (GCC compiler, GDB debugger, binutils toolset, QEMU emulator, and accompanying tools)
  • A set of libraries that provide partial compatibility with the POSIX standard
  • Components of KasperskyOS Community Edition
  • Documentation
  • Examples of basic KasperskyOS-based solutions
Page top
[Topic overview_intro]

Cyber immunity

The idea of cyber immunity is based on the following concepts:

  • Security goals and prerequisites
  • MILS concepts (security domain, separation kernel, reference monitor)
  • Trusted computing base (TCB)

These concepts are considered below. Then definitions of a cyber immune system and cyber immune approach are given.

Security goals and prerequisites

Information system security is not a universal abstract concept. Whether a system is secure or not depends on chosen security goals and prerequisites.

Security goals are requirements placed on an information system, which if achieved, ensure the secure operation of the information system in every possible scenario, taking into account the security prerequisites. Example of a security goal: ensure that data is kept confidential while using a communication channel.

Security prerequisites are additional limitations placed on the conditions in which the system is used, which if satisfied, will achieve the security goals. Example of a security prerequisite: cybercriminals must not have physical access to the hardware.

MILS concepts

In the MILS (Multiple Independent Levels of Security) model, a secure information system consists of isolated security domains and a separation kernel that controls the interactions between domains. The separation kernel isolates domains and controls the information flows between them.

Each attempted interaction between security domains is checked for compliance with certain rules, which are specified by the solution security policy. If an interaction is forbidden by the current policy, then it is not allowed (it is blocked). In a MILS architecture, a separate component (reference monitor) implements the security policy. For each security domain interaction, the reference monitor returns a decision (a boolean value) regarding whether the interaction complies with the security policy. The separation kernel calls the monitor each time one domain references another.

Trusted computing base (TCB)

Trusted Computing Base (TCB) is the set of all programming code, which if vulnerable will prevent an information system from achieving its specified security goals. In the MILS model, the separation kernel and reference monitor underpin the trusted computing base.

The trusted computing base's reliability plays a key role in ensuring the security of an information system.

Cyber immune system

An information system is cyber immune (or possesses cyber immunity) if it is separated into isolated security domains, all interactions between which are independently controlled, and is:

  • a description of its security goals and prerequisites;
  • guarantees of the reliability of the entire trusted computing base, including an execution environment and mechanisms for interaction control;
  • guarantees that security goals will be achieved in all possible use scenarios, given the specified prerequisites and an uncompromised trusted computing base.

Cyber immune approach

The cyber immune approach is a way to build cyber immune systems.

The cyber immune approach is based on:

  • dividing the system into isolated security domains;
  • independent control of all interactions between security domains in accordance with the specified security policy;
  • ensuring the reliability of the trusted computing base.

The specific method of dividing the system into security domains and the choice of a security policy depend on the security goals and prerequisites, the level of trust and integrity of individual components, as well as other factors.

Advantages of the cyber immune approach

The cyber immune approach lets you:

  • reduce the security properties of a system as a whole to the security properties of its separate components;
  • provide guarantees that a system's security goals will be achieved even if any of its untrusted components is compromised;
  • reduce requirements on one or more system components relative to the requirements on the system as a whole;
  • minimize damage to the system as a whole if any one of its component is compromised;
  • simplify the process of system certification.
Page top
[Topic overview_cyberimmunity_basics]

Isolation and interaction between entities

A cyber immune system consists of isolated parts (security domains in MILS terms) that can interact with one another only through a separation kernel, i.e. in a controlled manner. In KasperskyOS, security domains are implemented as entities.

In this section

Entities

Communication of entities (IPC)

Describing entities' interfaces (EDL, CDL, IDL)

IPC transport

Page top
[Topic overview_isolation_and_ipc]

Entities

In KasperskyOS, each process is a subject in a solution security policy. When a process starts, the KasperskyOS kernel associates with it the context necessary for its execution, and with the Kaspersky Security Module – the security context necessary to control its interactions with other processes.

To emphasize each process's link with the security policy, processes in KasperskyOS are called entities.

From the perspective of the KasperskyOS kernel, an entity is a process that has a separate address space and one or more threads of execution. The kernel guarantees isolation of the address spaces of entities. An entity can implement interfaces, and other entities can call the methods of these interfaces through the kernel.

From the perspective of the Kaspersky Security Module, an entity is a subject that other subjects (entities) can interact with. The types of interactions that are possible are specified by a description of the entity's interfaces that must match the implementation. Interface descriptions let the security module check each interaction for compliance with the solution security policy.

Additional information regarding entities

For the Kaspersky Security Module, the kernel is a subject just like an entity. Entities can call kernel methods, and these interactions are controlled like calls to methods of other entities. Accordingly, we will subsequently say that the kernel is a separate entity from the perspective of the Kaspersky Security Module.

Page top
[Topic overview_entities]

Communication of entities (IPC)

KasperskyOS has only one way for entities to interact – through synchronous exchange of IPC messages: via a request and a response. In each interaction, there are two separate roles: client (the entity that initiates the interaction) and server (the entity that handles the request). Additionally, an entity that acts as a client in one interaction can act as a server in another.

The client and server use three system calls: Call(), Recv() and Reply():

  1. The client sends a request to the server. To do this, one of the client's threads calls Call() and blocks until a response is received from the server or kernel (in the event of an error, for example).
  2. A server thread calls Recv() and waits for messages. When a request is received, this thread unblocks, handles the request, and sends a response by calling Reply().
  3. When a response is received (or an error occurs), the client thread unblocks and continues execution.

Thus, in terms of the MILS model, the KasperskyOS kernel is a separation kernel, because all entity interactions happen through it.

Exchanging messages as method calls

An entity's IPC request to a server is a call to one of the interfaces implemented by the server. The IPC request contains input arguments for the called method, the ID of the interface implementation (RIID), and the ID of the called method (MID). Upon receiving a request, the server entity uses these identifiers to find the method's implementation. The server calls the method's implementation, passing in the input arguments from the IPC request. After handling the request, the server entity sends the client a response that contains the method's output arguments.

The Kaspersky Security Module can analyze all components of an IPC message in order to decide whether the message complies with the system's security policy.

IPC channels

To enable two entities to exchange messages, an IPC channel, also referred to as a "channel" or "connection", must be established between them. The channel specifies the entities' roles, i.e. "client" and "server". Additionally, an entity can have several channels in which it is the client, and several channels in which it is the server.

KasperskyOS has two mechanisms for creating IPC channels:

  1. The static mechanism involves creating a channel when the entity is started (when the solution is started). Channels are created statically by the initializing Einit entity.
  2. The dynamic mechanism allows started entities to establish a channel between one another.
Page top
[Topic overview_ipc]

Describing entities' interfaces (EDL, CDL, IDL)

To control interactions between entities, the structure of the sent IPC messages must be transparent to the security module. In KasperskyOS, this is achieved using a static declaration of entities' interfaces. Special languages are used for this: Entity Definition Language (EDL), Component Definition Language (CDL) and Interface Definition Language (IDL). If an IPC message does not match an interface description, it will be rejected by the security module.

An entity's interface description defines the allowed IPC message structures. This creates a clear link between the implementation of each method and how that method is represented for the security module. Nearly every build tool uses entities' interface descriptions either explicitly or implicitly.

Types of static descriptions

A description of entities' interfaces is built using an "entity-component-interface" model:

  • An IDL description declares an interface, as well as user types and constants (optional). Taken together, all of the IDL descriptions in a solution encompass all the interfaces implemented in the solution.
  • A CDL description lists the interfaces implemented by a component. Components make it possible to group interface implementations. Components can include other components.
  • An entity's EDL description declare instances of the components included in the entity. An entity may include no components.

Example

Below are static declarations of a solution consisting of a Client entity that does not implement a single interface, and a Server entity that implements the FileOps interface.

Client.edl

// The static description consists of only the entity's name

entity Client

Server.edl

// The Server entity contains an instance of the Operations component

entity Server

components {

OpsComp: Operations

}

Operations.cdl

// The Operations component implements the FileOps interface

component Operations

interfaces {

FileOpsImpl: FileOps

}

FileOps.idl

package FileOps

// Declaration of the String user type

typedef array <UInt8, 256> String;

// The FileOps interface contains a single Open method with a 'name' input argument and 'h' output argument

interface {

Open(in String name, out UInt32 h);

}

For more details, refer to Syntax of static declarations.

Page top
[Topic overview_idl_cdl_edl]

IPC transport

To implement entity interactions, we need transport code, which is responsible for properly creating, packing, sending, unpacking, and dispatching IPC messages. Developing solutions for KasperskyOS does not require writing your own transport code. Instead, you can use special tools and libraries included in KasperskyOS Community Edition.

Transport code for developed components

Someone developing new components for KasperskyOS can generate transport code based on static definitions of the components. To achieve this, KasperskyOS Community Edition includes the NK compiler. The NK compiler lets you generate transport methods and types for use by both clients and servers.

Transport code for included components

The functionality of most components included in KasperskyOS Community Edition may be used in a solution both locally (through static linking with the developed code) and via IPC.

The following transport libraries are used to separate a component into a server entity and use it via IPC:

  • The component's client library converts local calls into IPC requests to the driver entity.
  • The component's server library receives IPC requests to the driver entity and converts them into local calls.

To use a component via IPC, it's enough to link its implementation to the server library, and to link the client entity to the client library.

The client library interface does not differ from the interface of the component itself. This means that it is unnecessary to change the code of the client entity in order to switch to using a component via IPC (instead of static linking).

For more details, refer to IPC and transport.

Page top
[Topic overview_ipc_transport]

Interaction control

In a cyber immune system, each attempted interaction between isolated parts of the system (security domains in MILS terms) is checked for compliance with certain rules that are specified by the system's security policy. If an interaction is forbidden by the current policy, then it is not allowed. Below we consider how this principle is implemented in KasperskyOS.

In this section

Kaspersky Security Module

Policy Specification Language (PSL)

Managing access to resources

Page top
[Topic overview_interaction_control]

Kaspersky Security Module

For each developed solution, Kaspersky Security System technology lets you generate code for the Kaspersky Security Module that implements the specified security policy. The security module controls all interactions between entities, i.e. in MILS terms, it is a security monitor.

Controlling IPC messages

The kernel calls the Kaspersky Security Module each time one entity sends a message to another entity. The security module checks whether the message structure corresponds to the description of the called method. If so, then the security module calls all the rules associated with this message and makes a decision: "allowed" or "denied". The kernel enforces the resulting decision, i.e. delivers the message only if the decision is "allowed".

In this way, the code that makes decisions (Policy Decision Point) is separate from the code that enforces them (Policy Enforcement Point).

IPC responses are controlled just like IPC requests. This may be used, for example, to guarantee the integrity of responses.

The kernel delivers the IPC message only if Kaspersky Security Module allows delivery

Controlling startup of entities

The kernel also calls the security module each time when an entity is started. This is usually used to initialize the entity's security context.

Security interface

Entities can directly query the Kaspersky Security Module using the security interface to report information about their state or the context of some event. Additionally, the security module enforces all rules associated with the called method of the security interface. Then the entity itself can use the decision received from the security module. The security interface is used, for example, to implement entities that control access to resources.

Page top
[Topic overview_ksm]

Policy Specification Language (PSL)

The most important part of Kaspersky Security System technology is the PSL language (Policy Specification Language). It lets you describe a solution security policy formally, close to the terms of the task itself. The resulting PSL description is used to generate the code of a Kaspersky Security Module for the specific solution. This is done by using the NK compiler provided in KasperskyOS Community Edition. Thus, a solution's PSL description is the connecting link between the informal description of a policy and its implementation.

The PSL language lets you use various data structures and combine several security models.

Page top
[Topic overview_psl]

Managing access to resources

Types of resources

KasperskyOS has two types of resources:

  • System resources, which are managed by the kernel. Some examples of these include processes, memory regions, and interrupts.
  • User resources, which are managed by processes. Examples of user resources: files, input-output devices, data storage.

Handles

Both system resources and user resources are identified by handles. By receiving a handle, a process obtains access to the resource that is identified by this handle. Processes can transfer handles to other processes. The same resource can be identified by multiple handles used by different processes.

Security identifiers (SID)

The KasperskyOS kernel assigns security identifiers to system resources and user resources. A security identifier (SID) is a global unique ID of a resource (in other words, a resource can have only one SID but can have multiple handles). The Kaspersky Security Module identifies resources based on their SID.

When transmitting an IPC message containing handles, the kernel modifies the message so that it contains SID values instead of handles when the message is checked by the security module. When the IPC message is delivered to its recipient, it will contain the handles.

The kernel also has an SID like other resources.

Security context

Kaspersky Security System technology lets you employ security mechanisms that receive SID values as inputs. When employing these mechanisms, the Kaspersky Security Module distinguishes resources (and the KasperskyOS kernel) and binds security contexts to them. A security context consists of data that is associated with an SID and used by the security module to make decisions.

The contents of a security context depend on the security models being used. For example, a security context may contain the state of a resource and the levels of integrity of subjects and/or access objects. If a security context stores the state of a resource, this lets you allow certain actions to be taken on a resource only if the resource is in a specific state, for example.

The security module can modify a security context when it makes a decision. For example, it can modify information about the state of a resource (the security module used the security context to verify that a file is in the "not in use" state and allowed the file to be opened for write access and wrote a new state called "opened for write access" into the security context of this file).

Resource access management by the KasperskyOS kernel

The KasperskyOS kernel manages access to resources by using two mutually complementary methods at the same time: implementing the decisions of the Kaspersky Security Module and implementing a security mechanism based on object capabilities (OCap).

Each handle is associated with rights to access the resource identified by this handle, which means it is a capability in OCap terms. By receiving a handle, a process obtains the rights to access the resource that is identified by this handle. The kernel assigns rights to access system resources and verifies these rights when processes attempt to use the system resources. The kernel also prohibits the expansion of access rights when handles are transferred among processes (when a handle is transferred, access rights can only be restricted).

Resource access management by resource providers

Processes that manage user resources and manage access to those resources for other processes are referred to as resource providers. For example, drivers are resource providers. Resource providers manage access to resources by using two mutually complementary methods: implementing the decisions of the Kaspersky Security Module and using the OCap mechanism that is implemented by the KasperskyOS kernel.

If a resource is queried by its name (for example, to open it), the security module cannot be used to manage access to the resource without the involvement of the resource provider. This is because the security module identifies a resource by its SID, not by its name. In such cases, the resource provider finds the resource handle based on the resource name and forwards this handle (together with other data, such as the required state of the resource) to the security module via the security interface (the security module receives the SID corresponding to the transferred handle). The security module makes a decision and returns it to the resource provider. The resource provider implements the decision of the security module.

Processes that use the resources provided by resource providers or by the kernel are referred to as resource consumers. When a resource consumer opens a user resource, the resource provider sends the consumer the handle associated with the rights to access this resource. In addition, the resource provider decides which specific rights for accessing the resource will be granted to the resource consumer. Before actions are taken on a resource requested by a consumer, the resource provider verifies that the consumer has sufficient rights. If the consumer does not have sufficient rights, the resource provider rejects the request of the consumer.

Page top
[Topic overview_resource_acces_control]

TCB reliability

A cyber immune system must provide guarantees regarding the reliability of the entire trusted computing base (TCB). These guarantees can be provided only if the trusted computing base is sufficiently compact. Below we will consider how this requirement is achieved in KasperskyOS-based solutions.

In this section

Microkernel architecture

Reliability of trusted components

Page top
[Topic overview_trusty_tcb]

Microkernel architecture

The foundation of any solution's trusted computing base is the kernel. The KasperskyOS kernel consists of just three system calls and performs only a small number of the most important functions, including the isolation and interaction of entities, scheduling, and memory management. As a result, the kernel is compact and has a small attack surface, which minimizes the number of potential vulnerabilities.

Moreover, device drivers and resource providers (for example, file system implementations) are user applications. Potential errors in them cannot affect the stability of the kernel. However, a KasperskyOS-based solution may have a potentially untrusted device driver or resource provider. This reduces the solution's trusted computing base and increases its reliability.

The combination of a microkernel architecture and security module makes it possible to control all interactions between a driver (or resource provider) and other entities, as well as all interactions with the kernel to ensure compliance with the specified solution security policy.

KasperskyOS kernel services (such as creating a thread or allocating memory) are called by using the same IPC mechanism and the same Call() system call as when calling methods of another entity. From this perspective, the KasperskyOS kernel serves as a separate entity that implements interfaces described in IDL.

Page top
[Topic overview_microkernel_architecture]

Reliability of trusted components

A solution's trusted computing base may include various trusted components, in addition to the KasperskyOS microkernel and security module. Depending on the security goals and prerequisites, device drivers and resource provider may be trusted components. The KasperskyOS architecture and toolset lets you increase the reliability of trusted components.

Removing a trusted component into a separate entity

A solution developer can increase TCB reliability by reducing the size of trusted components. To achieve this, they should be separated from the remaining (untrusted) code, i.e. removed into separate entities. KasperskyOS Community Edition includes transport libraries and tools for generating transport code, which lets you implement nearly any component as a separate entity for which every interaction is controlled.

Creating duplicate components

Another way to raise TCB reliability is to limit the influence of untrusted components on trusted components by separating their threads. To do this, a component can be used independently in several entities. For example, the VFS component is responsible for implementing file systems and the network stack in KasperskyOS. If we include VFS instances in different entities, each of them will work with its own implementation of the file system and/or network stack. This is how separation of the threads of trusted and untrusted entities are separated and, accordingly, how TCB reliability is increased.

The method of separating user code into trusted and untrusted code depends on the security goals and prerequisites of the specific solution.

Page top
[Topic overview_trusted_components]

KasperskyOS-based solution image

The boot image of a final KasperskyOS-based solution contains the following:

  • Image of the KasperskyOS kernel
  • Security module
  • Einit entity, which starts all other entities
  • All entities included in the solution, including drivers, service entities, and entities that implement the business logic

All entities are contained in a ROM file system (ROMFS) image.

Building a solution image

A solution image is built using a specialized script that is provided in KasperskyOS Community Edition.

The KasperskyOS kernel image, service entities and driver entities are included in KasperskyOS Community Edition. A security module and Einit entity are built for each specific solution.

Starting a solution

A solution is started as follows:

  1. The bootloader loads the KasperskyOS kernel.
  2. The kernel finds the security module and loads it.
  3. The kernel starts the Einit entity.
  4. The Einit entity starts all other entities that are part of the solution.
Page top
[Topic arch_solution_image]