{'fraction_non_alphanumeric': 0.03152377386746537, 'fraction_numerical': 0.005578435043055036, 'mean_word_length': 5.030932490404155, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
System-on-Chip Security Assertions

Assertions are widely used for functional validation as well as coverage analysis for both software and hardware designs. Assertions enable runtime error detection as well as faster localization of errors. While there is a vast literature on both software and hardware assertions for monitoring functional scenarios, there is limited effort in utilizing assertions to monitor System-on-Chip (SoC) security vulnerabilities. In this paper, we identify common SoC security vulnerabilities by analyzing the design. To monitor these vulnerabilities, we define several classes of assertions to enable runtime checking of security vulnerabilities. Our experimental results demonstrate that the security assertions generated by our proposed approach can detect all the inserted vulnerabilities while the functional assertions generated by state-of-the-art assertion generation techniques fail to detect most of them.


I. INTRODUCTION
System-on-Chip (SoC) security is critical as more and more personal computing needs as well as physical infrastructures are controlled by a chip with the prevalence of Internet-of-Things (IoTs). Attackers take advantage of security vulnerabilities to inject malicious software. Tools such as anti-virus are not enough to protect from these attacks. Security vulnerabilities can arise in any stage, from design to fabrication, as well as post deployment. In contrast to a software vulnerability which can be modified after deployment, fixing a hardware vulnerability becomes more and more difficult and expensive in later stages. Existing approaches try to mask some of the vulnerabilities using firmware patching or utilizing in-built reconfigurable primitives. However, these approaches may not work in all scenarios. Therefore, detecting and removing vulnerabilities in early stages is very important in SoC designs.
Assertion-Based Verification (ABV) is a common practice in industry today for functional validation of Systemon-Chip (SoC) designs [1]. Assertions define the properties that should hold. For example, a functional assertion can check that the output of an adder is equal to the sum of two inputs irrespective of the implementation. In addition to checking the inputs and outputs, assertions can also increase the observability of internal states, which enables runtime error detection as well as faster localization of errors. While there is a vast literature on both software and hardware assertions for monitoring functional scenarios, there is limited effort in utilizing assertions to monitor SoC security vulnerabilities [2].
Existing SoC validation techniques mainly focus on the functional behaviors defined in the specification. Traditionally, SoC security vulnerabilities are not considered as expected functional behaviors. For example, an unspecified transition in finite state machine (FSM) is one of the main sources of First, we perform vulnerability analysis on a given SoC to identify potential vulnerabilities. Next, assertions are generated based on the vulnerabilities and inserted into the design. security vulnerabilities. While ABV is the de facto standard for functional validation, there are limited prior efforts to define and monitor SoC security vulnerabilities. Given the importance of SoC security, we propose a framework for defining and utilizing SoC security assertions as shown in Figure 1. The framework consists of two main steps. First, we perform vulnerability analysis on a given SoC design and identify potential vulnerabilities. Next, security assertions are generated from the vulnerabilities and inserted into the SoC design. The purpose of this paper is not to provide a laundry list of vulnerabilities for SoC designs. Instead, we identify some representative vulnerabilities and propose assertions for them to show how SoC security assertions can be defined and integrated in an existing SoC validation methodology. Specifically, this paper makes three major contributions: 1) We perform a comprehensive review of the literature to identify the common SoC security vulnerabilities. 2) We propose security assertions corresponding to each vulnerability. We plan to upload the security assertions for various open source SoCs in TrustHub [3]. 3) We demonstrate that existing assertion-based validation is not capable of detecting security vulnerabilities. Therefore, security assertions defined in this paper should be part of any security validation methodology. The remainder of this paper is organized as follows. Section II surveys related approaches. Section III provides an overview of SoC security vulnerabilities. Section IV describes the framework for assertion generation for a given set of security vulnerabilities. Section V presents six case studies. Finally, Section VI concludes the paper.

II. BACKGROUND AND RELATED WORK
There are significant prior efforts in classifying softwarelevel vulnerabilities [4], [5]. While there are related works in specific areas (e.g., classifying hardware Trojans), to the best of our knowledge, there are limited previous works on developing a comprehensive classification of potential SoC vulnerabilities. Similarly, there are various efforts on functional assertions in the context of assertion-based validation. However, there are limited prior efforts in defining and utilizing SoC security assertions. In this section, we present the related works in assertion-based validation as well as automated generation of assertions.

A. Assertion-based Validation
There are mainly two types of approaches for defining hardware assertions: language-based and library-based [6]. Language-based approaches provides syntax for formally defining assertions. Two of the most popular assertion specification languages are Property Specification Language (PSL) [7] and System Verilog Assertions (SVA) [8]. Both of these languages support temporal assertions and formally is an extension of temporal logic [9]. Some other examples are For-Spec [10], SALT [11], a SystemC extension [12], etc. On the other hand, library-based approaches adds assertion support to existing languages. One such example is Open Verification Library (OVL) [13]. OVL has support for Verilog, VHDL, PSL and SystemVerilog. Library-based approaches can be used to quickly write common types of assertions. Unfortunately, they are not generic enough to cover all possible scenarios. In this paper, we use SVA to express our SoC security assertions.

B. Automated Assertion Generation
Assertion generation is mostly manual effort -it is timeconsuming to insert enough assertions into an industrial SoC design. Many research efforts have been devoted to automated generation of functional assertions. Rogin et al. [14] proposed to generate properties of a design by analyzing simulation traces. Hertz et al. [15] improved the analysis process using data mining and developed a tool named Goldmine. The generated rules from simulation traces are passed through a formal verification tool to verify the correctness in the design. As the simulation data is inherently incomplete and nondeterministic, the quality of mined assertions cannot be guaranteed. Moreover, as our case studies show, these functional assertions are not suitable for detecting security vulnerabilities.

III. SOC SECURITY VULNERABILITIES
While there is a vast literature on both software and hardware assertions for monitoring functional scenarios, there are limited efforts to define and utilize assertions to monitor System-on-Chip (SoC) security vulnerabilities [2], [16]. We reviewed a wide variety of security vulnerabilities listed in the National Vulnerability Database [5] and related research [2], and identified common SoC security vulnerabilities that are related to SoCs. Note that there is a fundamental difference between exceptions and security vulnerabilities. The exceptions are defined today by SoC designers based on the point of view of functional correctness, whereas the security vulnerabilities outlined in this proposal are solely from security and trust perspectives. For example, an adversary may trigger (e.g., using a Trojan) an exception (e.g., divide by zero) solely to gain a higher privilege level, such that private memory or registers can be accessed. The remainder of this section describes our proposed seven vulnerability classes.

A. Permissions and Privileges
Permissions and privileges are the main components of the access control subsystem. Specifically, different resources are controlled by different permissions and privileges. For example, in ARM7 processor, seven different modes are defined, such as user mode, interrupt mode, and supervisor mode. It is critical to check whether the conditions for triggering privileged modes are satisfied before changing modes.

B. Resource Management
Certain resources should be protected against any illegal access, including accessing special hardware from non-privileged modes, misuse of design-for-debug infrastructures during normal usage, and so on. For example, JTAG allows engineers to trace secure memory during post-silicon validation and debug of security features. However, JTAG should never be enabled during normal usage.

C. Illegal States and Transitions
The behavior of an SoC can be modeled as a finite state machine (FSM). The valid states or transitions can be verified during functional validation. Attackers are more interested in the backdoor that allows undefined states/transitions. To verify the existence of illegal states and transitions, we could use assertions of valid states and transitions to alarm any violation, or enumerate all possible invalid states and transitions to prevent specific vulnerabilities.

D. Buffer Issues
Modern SoCs consist of advanced features (e.g., out-oforder execution and speculative execution) as well as a large number of heterogeneous buffers. Similar to software buffer errors, these buffers in deeper pipelines require significant validation efforts to detect any remaining flaws. For example, prefetched instructions in buffers should be flushed if the branch prediction is incorrect. Otherwise, these flaws can be exploited to mount an attack.

E. Information Leakage
Modern SoCs try to isolate a secure world from a non-secure world. Information from the secure world should never be leaked to non-secure world directly. ARM uses TrustZone as an approach to provide the secure world [17]. There should be safeguards present to prevent non-secure world from accessing TrustZone directly.

F. Numeric Exceptions
Numeric exceptions represent the erroneous/illegal behaviors (e.g., divide by zero) during arithmetic computations. Even if the program does not lead to illegal numeric computation, an attacker can make it happen, and utilize it to create a vulnerability.

G. Malicious Implants
In software community, code injection means allowing attackers to run arbitrary code. Similarly, hardware Trojans, inserted by untrusted third party, allow attackers to execute an arbitrary path after applying specific input patterns. This can lead to information leakage or other unintended consequences. Trojans are usually inserted in hard-to-detect and rare-toactivate areas, making it hard to detect them during validation.

IV. SOC SECURITY ASSERTIONS
This section mainly addresses two important questions: i) how to generate the security assertions, and ii) how to embed them in the SoC design (RTL models).

A. Embedding of Security Assertions
There are two orthogonal ways of embedding assertions in the RTL model of an SoC design: immediate and concurrent assertions. Please note that immediate assertions can be converted to concurrent assertions by modifying the antecedent. However, as described below, it would be natural to use a specific one depending on the type of security vulnerability.
Immediate Assertions: Immediate assertions are powerful in detecting vulnerabilities such as numeric errors. Immediate assertions are flexible and can vary based on the potential statements or blocks. For immediate operations, it is important to find out the exact location, the relevant variable (e.g., trigger) α, and the assertion, assert (P (α)), can be inserted. Immediate assertions are inherent for checking specific operations, such as divide-by-zero checking and out-of-boundary checking.
Concurrent Assertions: Concurrent assertions, on the other hand, are checked each clock cycle, representing expected properties of SoCs. Concurrent assertions are useful to express any FSM related vulnerabilities (e.g., illegal states and transitions). Each concurrent assertion can be defined using assert property (P ). The property P should be derived from the specification of SoCs and vulnerability classes.

B. Generation of Security Assertions
We use static (code) analysis to generate security assertions to detect the existence of the vulnerabilities outlined in Section III, as shown in Figure 2. In this section, we briefly outline the assertion generation for each vulnerability class.
Permissions and Privileges: By analyzing the specification, we need to figure out the variable that represents the privilege level, e.g., CPSR in ARMv7. For each entry to a privileged operation block, we need to generate an assertion. For the ease of illustration, we use user to represent current privilege, and admin to represent root privilege. For each possible entry into the privileged operation block, we need to generate the immediate assertion as: assert(user == admin).
Resource Management: Concurrent assertions are powerful in protecting resources from misuse in an unexpected way. For example, to protect JTAG from getting used during normal operation mode, we need to generate the assertion as: assert property (normal |− > !JTAG_enable).
Illegal States and Transitions: The behaviors of modules as well as their interactions (protocols) can be expressed in FSMs. Therefore, we can express both valid and invalid (illegal) transitions as security assertions. For example, if there is a valid transition from state A to state B when variable a is true, it can be encoded as an assertion: assert property (A && a |− > B). Similarly, the assertion, assert property (!(C|− > A)) can be used to ensure that no transitions are allowed from state C to state A.
Buffer Issues: Assertions can be generated for all boundary cases related to buffers. To prevent access of the buffer index beyond its limits, immediate assertions should be added before each buffer access. Before accessing Buffer[index], the variable index needs to satisfy assert (index >= 0 && index <= limit). In many scenarios, we may require concurrent assertions to ensure global interactions. For example, to ensure the flush of instruction buffer (IB) after branch prediction failure, we can use the assertion assert property (Pre_fail |− > IB_Empty). Information Leakage: To protect secret information from directly leaking to non-secure world, tagging is one potential solution. It assumes that the results of secure world can only be passed to non-secure world through special interface (privileged instructions). For each normal operation consisting of both secure and non-secure variables, we need to check if the result is assigned to a non-secure variable as expected. If s is a secure variable, the assignment of s to a variable v needs to check the tag of v as assert(v t == secure tag).
Numeric Exceptions: Numeric exceptions are more relevant to the implementation of SoC designs. We need to generate one assertion for each possible numeric exception during arithmetic computation. For example, in case of a divide-byzero exception, we can generate an immediate assertion as: assert(divisor != 0).
Malicious Implants: Malicious modifications (e.g., hardware Trojans) can be inserted during pre-silicon or post-silicon stage. In the pre-silicon stage, hardware Trojans are usually hidden in rare-to-activate branches or rare execution of concurrent statements. For example, we can generate assertions for each rare branch by adding an assertion for each rare trigger condition as: assert(rare trigger).
The security assertions are generated based on the vulnerabilities outlined in Section III. More assertions can be added based on designer inputs or application-specific considerations.  Fig. 3: Comparison of our assertions and assertions generated by Goldmine [15] in detecting security vulnerabilities.

V. CASE STUDY
To demonstrate the necessity of security assertions, we analyzed six benchmarks and inserted security assertions introduced in Section IV. Then, Goldmine [15] was applied on all the benchmarks to generate as many assertions as possible.
To evaluate the effectiveness of our security assertions, we randomly inserted 10 vulnerabilities into the design to form 10 vulnerable instances and applied directed test to activate these vulnerabilities. If any assertion generated by the two methods (ours versus Goldmine) got activated during simulation, we claim the corresponding method detects the vulnerability. The types of potential vulnerabilities of each benchmark and the detected instances are shown in Table I and Figure 3, respectively. Note that the number of instances are more than the number of vulnerability types, as each type may contain multiple instances. In the remainder of this section, we describe each type of vulnerability and inserted instances in detail. Overall, our approach is able to detect all of the vulnerabilities while the assertions generated by Goldmine fail to detect most of them.

A. Arbiter
We first analyzed a simple design, Arbiter, as shown in & gnt2)) should be added to the design. However, the number of invalid states and transitions would be exponential when time is involved. For example, when we consider two consecutive cycles, assert(!(gnt1 | => (gnt2 != req2))) should hold. We limit the number of assertions to 10 in this example. The assertions generated by Goldmine are shown in Listing 1. As Goldmine analyzes the golden design by mining the traces of random simulation, it is able to capture reachable states and transitions by the specific simulation.

B. PCI
Top module pci master32 sm from Opencores [18] contains eight modules such as pci frame crit and pci irdy out crit. To mimic SoC design, which contains different parts from untrusted third party, we inserted invalid states and transitions to the subordinate modules (8 out of 10) as well as the top modules (2 out of 10). Goldmine generated 19 assertions. To generate vulnerable instances, we randomly changed operators in all the modules. As shown in Figure 3, Goldmine was able to capture the two vulnerabilities, but failed to detect the remaining eight vulnerabilities.

C. USB Protocol
USB protocol defines the packet fields and its corresponding operations. We analyzed the USB protocol module usbf pa.v along with CRC module from Opencores [18] and identified two types of vulnerabilities. The USB protocol depends on the packet ID (PID) to identify the types of packets including token, data, handshake, and special. For each type of packets, PIDs will not overlap. In the module, the output of PID is stored in tx data whose value depends on the input selectors. The two types of vulnerabilities are shown below: 1) Resource management: As the PIDs define the resources of USB, it is critical to make sure that each type of packet gets expected PID. For example, a token packet should not get any of the PIDs belonging to data packets, such as DATA0, DATA1. Similarly, a handshake packet should stick to its own type, e.g., ACK, NAK. We inserted 8 assertions of this type. 2) Invalid states and transitions: We inserted one vulnerability in CRC module and one vulnerability in the top module. As this is a common vulnerability in almost every design, we will skip inserting this type of vulnerability in the remaining benchmarks.
The vulnerable instances were generated accordingly. As shown in Figure 3, while Goldmine can only detect one vulnerability from state transition in top module, our assertions can detect all of them.

D. A Simplified Memory Design
This design is created to mimic the behavior of a simplified Trusted Hardware (TH) implementation of memory, as shown in Listing 2. Trusted Hardware, e.g., Intels Software Guard Extensions (SGX) [19], allows remote clients to upload private computation and data to a secure container of a server with a TH. One key implementation of SGX is the introduction of Process Reserved Memory and Enclave Page Cache (EPC), inhibiting invalid accesses even from the kernel. The simplified design is shown in Listing 2 which contains input signal sc to denote whether it is a secure access or not. The memory space is denoted by an array named mem with size of 1MB.

1) Permissions and privileges. Assume the lower 1kB
of memory is allocated to EPC. Since EPC should be accessed through secure container/process, each access to the lower 1kB should be checked. Although one conditional checking is already in place, assertions may also help when implementation error, fault injection or Hardware Trojans exist, e.g., assert(address <= 1024 | => sc) can be inserted before any access to memory. 2) Information leakage. In this simplified memory implementation, it does not explicitly describe the state of out signal when we want to write. For a buggy CPU design which connects to this memory, a process may be able to read the previous access of another process from the out port (including secure processes) with interleaved memory access. We may add a concurrent assertion with (assert property (wr | => out == 0)). 3) Buffer errors. Memory as one type of buffer should be checked for buffer errors. Each access to memory should be checked with assertions to test if address is in the range of memory size. In this example, the memory size is 1MB (2 20 ) and the length of address is 32 bits. We need assert(address < 2 * * 20) to check out-of-boundary accesses.  We inserted a vulnerability related to permissions and privileges, by removing sc checking in the first if statement. For vulnerabilities related to information leakage, we assume that attackers are able to connect one specific location to out when it is a write operation. Experimental results show that Goldmine failed to detect any of these vulnerabilities while our approach can detect all of them.

E. Gaussian Noise Generator (GNG)
We next inspected a computation-intensive design called Gaussian Noise Generator (GNG). The design is downloaded from Opencores [18]. One possible numeric error in this design is the assignments between signed and unsigned values as shown in the snippet of code in Listing 3. The first assignment assigns an unsigned variable to a signed variable. Next assignment is the computation between signed values. The final assignment assigns a signed value to an unsigned value. We are concerned with the automatic transformation between signed and unsigned values. For example, when the 32 th bit of mul1 is 1, mul1 new is interpreted as a negative value using a two's complement representation. Then mul new is added to a positive number and converted to an unsigned number again. The behavior may or may not be the original intention of this code. We want to generate assertions, e.g., assert(mul1[32] != 1), and guide the test plan of debug. The developer should decide if it is a numeric error or the expected behavior. Since we view this design as "buggy" by itself, we did not generate vulnerable instances for it. Rather, we use 10 direct tests to force mul1[32] to become 1 and check if the assertions by Goldmine can catch the potential vulnerability. As shown in Figure 3, Goldmine failed to detect any of them since it only analyzes the traces of random simulation but never inspects the specification/implementation.

F. AES
Advanced Encryption Standard (AES) is a very commonly used crypto core, consisting of ten rounds of block ciphers (substitution permutation networks). The substitution is shown in Listing 4. We also inserted JTAG to dump internal variables during debug. The identified vulnerabilities are: 1) Resource management: As JTAG is for debug purpose only, it should be disabled during normal usage. As a result, the dump signal should contains nothing related to any internal signals. We inserted an concurrent assertion assert property (!JTAG |-> (JTAG_out == 0)) to prevent attackers from bypassing the JTAG checking and dump internal signals to infer the plaintext. 2) Malicious implants: As module S contains a lot of rare branches, attackers are able to construct rare trigger conditions for hardware Trojans. For example, the probability of (out == 32'h7c7c7c7c) is 2 −32 when (in == 8'h01) is true for all S 0, S 1, S 2 and S 3 together. Assertions like assert(out != 32'h7c7c7c7c) in module S4 can guide the designer of a test plan to cover this specific potential trigger condition. As the combinations of rare branches are potentially infinite, we restricted the number of assertions to be 10.
One of our vulnerable instances is a design bypassing JTAG checking directly. For the other 9 instances, we construct random hardware Trojans from the rare branches. As shown in Figure 3, our approach is able to detect the vulnerabilities. Goldmine cannot detect any of them. Overall, the security assertions generated by our approach are able to detect all the security vulnerabilities whereas the assertions generated by state-of-the-art technique (Goldmine) fail to detect most of them.

VI. CONCLUSION
SoCs are widely used today in both embedded systems and IoT devices. While SoC security is paramount, there are limited prior efforts in defining and detecting a wide variety of SoC security vulnerabilities. In this paper, we developed seven classes of SoC security vulnerabilities. Based on these vulnerabilities, we proposed a framework for generating security assertions. Using a diverse set of benchmarks, we demonstrated that the functional assertions generated by stateof-the-art assertion generation technique cannot eliminate the need for our dedicated security assertions. Specifically, our security assertions are able to detect all the implanted security vulnerabilities while the state-of-the-art method failed to detect most of them. We envision that the SoC designers will embed security assertions in their designs in the near future as part of their assertion-based security validation methodology. This will open up several research directions in terms of how to generate automated tests to activate these security assertions as well as how to utilize these security assertions (properties) for automated property checking.