On the example of KasperskyOS
There are generally accepted principles that developers of all secure operating systems strive to apply, but there can be completely different approaches to implementing these principles. A secure operating system can be developed from an existing OS by improving certain characteristics that are the cause (or the consequence) of that operating system’s insecure behavior, or it can be developed from scratch. The former approach has the clear advantage of lower development costs and compatibility with a broad range of software.
Let’s consider this approach in the context of systems that are part of the critical infrastructure. Two factors are important for such systems:
The ability to fulfil special security requirements, which may involve not only preserving certain general properties of information (such as confidentiality), but such things as tracking certain commands and data flows, having no impact on process execution in the system, etc.
The provision of guarantees that the system will work securely and will not be compromised.
Building a secure system based on a popular OS commonly involves implementing additional mechanisms of access control (e.g., based on the mandatory access control model), strengthened authentication, data encryption, security event auditing, and application execution control. As a rule, these are standard security measures, with the system’s special requirements addressed at the application level. As a result, special (and often also general) security measures rely on the implementation of numerous components, each of which can be compromised. Examples include: SELinux, RSBAC, AppArmor, TrustedBSD, МСВС, and Astra Linux, etc.
To improve security, tools that make it more difficult to exploit some vulnerabilities, including those inherent in the system due to its insecure original design, can be built into the system. Examples include: Grsecurity, AppArmor, Hardened Gentoo, Atlix, YANUX, and Astra Linux, etc.
Only a few years ago, a commonly used approach was to provide “security” guarantees based on scanning software code for errors and vulnerabilities and checking software integrity by comparing checksums. That approach was used in Openwall Linux, and some operating systems developed in Russia.
Although these measures lead to an overall improvement in the characteristics of general-purpose systems, they cannot address the special requirements for systems that are part of the critical infrastructure or guarantee security with a high degree of confidence.
However, operating systems originally designed as secure cannot always guarantee that specific security policies will be enforced. Objective reasons for this include the difficulty of specifying clear security goals for such a relatively versatile IT product as an operating system, as well as the large number and variety of threats posed by the environment.
If an operating system is designed for specific uses on a more or less fixed range of hardware, with specific software running under it within defined operating scenarios, then security goals can be defined with sufficient accuracy and a threat model can be built. To achieve security goals, the model is used to develop a specific list of security requirements and trust requirements. Fulfilling these requirements is sufficient to guarantee the system’s secure behavior. Examples include specialized embedded solutions from LynuxWorks, Wind River, and Green Hills.
For a general-purpose operating system, achieving the same guarantees is more difficult due to a broader definition of security goals (which is necessary for the system to support a broader range of secure execution scenarios). As a rule, this requires support for a whole class of policies that are needed for a specific access control type (discretionary, mandatory, role-based), customary authentication mechanisms, and other protection tools whose management does not require specialist knowledge. This requires implementing relatively universal security mechanisms. Sometimes, provided that the OS runs on a fixed hardware platform (usually from the same vendor), compliance of these mechanisms with a certain standard or security profile can be guaranteed with a sufficient degree of confidence. Examples include: Oracle Solaris with Trusted Extensions, XTS-400, and OpenVMS, AS/400.
Finally, for a general-purpose operating system that runs on an arbitrary hardware platform, achieving high security guarantees is even harder because in this case the threat model grows out of all proportion.
This problem can be solved using an approach based on building a modular system from trusted components which are small and which implement standardized interfaces. The architecture of a secure system built in this way makes it possible to port a relatively small amount of software code to various hardware platforms and verify it, while keeping top-level modules so that they can be reused. Potentially, this makes it possible to provide security guarantees for each specific use of the OS.
The first step towards creating a modular operating system is using a microkernel-based architecture. The microkernel is the system’s only method of interaction and data exchange, providing total access control.
However, access control provided by the microkernel cannot implement properties of the system related to supporting specific security policies. KasperskyOS implements the principle of separating access-related decisions based on the policy defined from access control implemented at the microkernel level. Access decisions based on computing security policy compliance verdicts are made by a dedicated component – the security server. Flask is the best known architecture based on this principle.
It should be noted that a number of enhanced-security operating systems (SELinux, SEBSD) based on general-purpose systems have been built using the Flask architecture, but these systems use a large monolithic kernel. In fact, Flask does not require using a microkernel, but it works best with one.
KasperskyOS does not reproduce the Flask architecture in full but develops its ideas to provide better security and flexibility of use in target systems. The original Flask architecture describes interfaces and requirements for the two main components involved in applying security policies to interaction – a security server, which computes security verdicts, and an object manager, which provides access based on these verdicts. The development of KasperskyOS is, to a large extent, focused on preserving trust not only for mechanisms that compute and apply verdicts, but also for the configuration based on which this computation is performed. Basic security policies are combined into more sophisticated rules using a configuration language. These rules are then compiled into a component that acts as an intermediary between the security server and the microkernel, enabling verdicts to be computed in a way that provides the required business logic.
As a result, KasperskyOS provides configuration of overall security policy parameters (system-wide configuration at the security server level) and rules for applying policies to each operation performed by each entity in the system (through configuration of verdict computation).
The trusted code obtained by compiling configurations connects application software with the security model in the system, specifying which operations performed by programs should be governed by which security policies. Importantly, the code does not include any information about operations or policies except references to them.
Of course, a microkernel-based system that has Flask-like architecture is not a unique idea invented by KasperskyOS developers. There is a history of successful microkernel development (seL4, PikeOS, Feniks/Febos), including microkernels with formally verified security properties. This work can be used to implement an OS that can guarantee security domain isolation (provide “security through isolation”) – an architecture known as MILS (Multiple Independent Domains of Safety/Security).
However, this case involves developing not just a microkernel but a fully-functional operating system that provides not only the separation of security domains and isolation of incompatible information processing environments, but also control of security policy compliance within these domains. Importantly, the microkernel, the infrastructure of the OS based on it and the security policies are developed by the same vendor. Using third-party work, even if it is of high quality, always imposes limitations.
The greatest shortcoming of operating systems built from scratch is the lack of support for existing software. In part, this shortcoming can be compensated for by maintaining compatibility with popular programming interfaces, the best known of which is POSIX.
This shortcoming is also successfully remedied by using virtualization. A secure operating system in whose environment a hypervisor for virtualizing a general-purpose system can be launched, will be able to execute software for that OS. KasperskyOS, together with Kaspersky Secure Hypervisor, provides this capability. Provided that certain conditions are met, an insecure general-purpose IS can inherit the security properties of the host OS.
To summarize, the KasperskyOS secure operating system is not an extension or improvement of existing operating systems, but this does not narrow the range of its applications. The system can be used as a foundation for developing solutions that have special security requirements. Capabilities related to providing flexible and effective application execution control are inherent in the architecture of KasperskyOS. The system’s development is based on security product implementation best practices and supported by scientific and practical research.