enhanced PMP with four security levels


John Hauser
 

As promised, here is my suggestion for modifying the TEE Task Group's
"PMP Enhancements" proposal to have four security levels, to support a
larger set of use cases.

Instead of the two bits MML and MMLA, I propose a single two-bit field,
MSL (Memory Security Level) to control how PMP is interpreted. At
reset, MSL = 0, which causes PMP to act as originally standardized. If
higher security levels are supported, then all values 0 through 3 are
valid for MSL. When MSL = 3, my proposal provides security equal to
the task group's proposal. Values 1 and 2 choose intermediate security
levels between 0 and 3. Between resets, software may increase MSL, but
the hardware prevents decreases except by reset.

I there is also an independent DMC bit (Default Memory Closed). When
DMC = 1, if a memory access is attempted for which no PMP entries match,
an access fault occurs, whereas when DMC = 0, if no PMP entries match
for a memory access, accessibility is determined by the privilege mode
and MSL value. Reset sets DMC = 0. Software may set DMC = 1, but once
set, the hardware prevents clearing DMC except by reset.

In PMP configuration bytes, my proposal expands the single L bit into
a two-bit PL field (Privilege/Locked) in bits 7:6. For each PMP entry,
the PL field and global MSL value together determine the behavior as
follows:

When MSL = 0:

PL | Locked? | M mode | S/U mode

0 | No | All accesses allowed | Apply XWR bits
2 | Yes | Apply XWR bits | Apply XWR bits
default | All accesses allowed | No accesses allowed

At level 0, PMP acts as originally standardized. PL fields cannot be
set to 1 or 3 at this level. Writing a configuration byte with PL = 1
or 3 leaves PL = 0 or 2, respectively.

The "default" line in this and other tables indicates the accessibility
when no PMP entries match and DMC = 0. No accesses are allowed by
default when DMC = 1, of course.

When MSL = 1:

PL | Locked? | M mode | S/U mode

0 | No | Read/write allowed | Apply XWR bits
1 | No | No accesses allowed | Apply XWR bits
2 | Yes | Apply XWR bits | No accesses allowed
3 | No | Apply XWR bits | No accesses allowed
default | All accesses allowed | No accesses allowed

Compared to level 0, entries with PL = 1 or 3 are now supported, and
the permissions of PMP entries with PL = 0 or 2 are more restricted.

When MSL = 2:

PL | Locked? | M mode | S/U mode

0 | No | Read/write allowed | Apply XWR bits
1 | No | No accesses allowed | Apply XWR bits
2 | Yes | Apply XWR bits | No accesses allowed
3 | No | Apply XWR bits | No accesses allowed
default | Read/write allowed | No accesses allowed

The only difference from level 1 is that execute permission is no
longer included in the default for M mode when DMC = 0. (If DMC = 1,
levels 1 and 2 are the same.)

When MSL = 3:

PL | Locked? | M mode | S/U mode

0 | No | Read/write allowed | Apply XWR bits
1 | No | No accesses allowed | Apply XWR bits
2 | Yes | Apply XWR bits | No accesses allowed
3 | Yes | Apply XWR bits | No accesses allowed
default | Read/write allowed | No accesses allowed

In addition, level 3 prevents the configuration of new locked PMP
entries that give execute permission to M mode (PL = 2 or 3, and
bit X = 1). An attempt to configure such an entry is ignored. This
restriction, and the fact that PMP entries with PL = 3 are now locked
(making them identical to ones with PL = 2), are the only differences
between levels 2 and 3.

With this scheme, the most useful levels of enhanced security are
expected to be 2 and 3. As noted, level 3 provides maximal security
equivalent to the task group's proposal. Level 2 is available as a
fallback when level 3 is too constraining. Level 2 keeps the door open
for software to edit M-mode-only PMP entries (those with PL = 3) while
providing as much security as possible under the circumstances.

Level 1 may seem unnecessary, but it's actually a useful stepping stone
to get from level 0 to levels 2 or 3. It also provides a "pretty good"
intermediate level of protection that is less trouble for software and
may require fewer PMP entries, since it grants execute permission by
default while higher levels do not. Even if you believe that makes
level 1 too compromised, please consider that it's a huge step up from
level 0, and there may be those unwilling or unable (e.g., insufficient
number of PMP entries) to raise the security level to 2.

As an example use, the design I've presented supports Tariq Kurd's
system as follows: Shortly after reset, initialization software would
first set MSL = 1, then create an executable PMP entry with PL = 3 to
cover the initialization code itself, and lastly set DMC = 1. After
that preparation, multiple stages of boot software would be free to
create and edit PMP entries with PL = 3 to expand and contract the
regions that are accessible and/or executable. At the end of booting,
the final M-mode configurations can be permanently locked by raising
MSL to 3 before entering the operating state.

Regards,

- John Hauser

Join tech-privileged@lists.riscv.org to automatically receive all group messages.