SRAM Scrambling

Both the address as well as data can optionally be scrambled. The goal of the scrambler is not secure data encryption but rather basic obfuscation to impede simple memory dumping by an attacker aiming to recover secrets. The algorithm would be straight forward to break by a trained cryptanalyst. The implementation is intentionally very simple so that the timing overhead on memory read and write transactions is minimal.

The scrambler is disabled by default, but a configuration register field can be set to turn this feature on after booting and the scrambling key is installed. When it is on, all write data transactions will have both the address and data scrambled before performing a write to memory. On read operations, the address will be scrambled in the same fashion as for writes so we have an equivalent address mapping. The read data however must be descrambled. Address data tweaks the key, which means it is mixed in to ensure that the same data at different address locations has a different scrambled value.

The KM ROM writes DRBG output into the key register and then enables and locks the scrambler; the Memory Scrambler Provisioning section of the Key Manager Application ROM appendix in the Programmer’s Guide gives the order.

The scrambler IP consists of a generic top-level module (scrambler) and a set of pre-configured size-specific wrappers that fix the address width to match a particular SRAM depth. The generic module selects the correct address scrambling function at elaboration time through generate blocks keyed on ADDR_WIDTH. The scrambler_addr_tweak submodule expands and mixes the memory address into a 32-bit round key. All cryptographic primitives (S-boxes, permutations, and address scramble functions) are declared as automatic functions in scrambler_pkg.

1. Parameters

The scrambler module accepts three parameters. Only 32-bit data widths are supported in the current implementation.

The parameters and ports of scrambler are listed in scrambler.

2. Port Interface

The scrambler is purely combinational. It has no clock or reset ports.

3. Data Scrambling Algorithm

The scrambling algorithm is an extremely rudimentary, round reduced, block cipher inspired by the PRESENT cipher. PRESENT works on 64 bit blocks, while this scrambler works on 32-bit blocks. PRESENT operates on 32 repeated rounds, while this scrambler performs only a single round. The player (permutation function) is also altered to accommodate the reduced block size i.e. word length.

The data path implements the PRESENT 4-bit S-box (sbox4) from scrambler_pkg. Eight parallel S-box instances process the 32-bit word one nibble at a time. The S-box mapping is shown in SRAM scrambler S-box.

Table 1. SRAM scrambler S-box
x 0 1 2 3 4 5 6 7 8 9 A B C D E F

S(x)

C

5

6

B

9

0

A

D

3

E

F

8

4

7

1

2

The inverse S-box (ibox4) reverses the mapping and is used on the descramble path.

The permutation layer follows the PRESENT structure with progressive offsets of 8 bits rather than 16. Index i indicates the input bit position and P(i) indicates the output bit position.

SRAM scrambler permutation for bits 31 to 16 maps input bits 31 through 16 to their output positions.

Table 2. SRAM scrambler permutation for bits 31 to 16
i 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16

P(i)

0

4

8

12

16

20

24

28

1

5

9

13

17

21

25

29

SRAM scrambler permutation for bits 15 to 0 maps input bits 15 through 0 to their output positions.

Table 3. SRAM scrambler permutation for bits 15 to 0
i 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

P(i)

2

6

10

14

18

22

26

30

3

7

11

15

19

23

27

31

Scrambling Procedure

First the tweaked key is xor’ed with the input write data. The output is split into 8 4-bit nibble lanes and each is fed into an sbox function. The resulting values are concatenated and fed into the player permutation function to form the final scrambled data value which is written to memory.

Descrambling Procedure

The descrambling process is exactly the reverse as scrambling. The scrambled data value is read from memory and we first perform the iplayer inverse permutation operation. This is followed by inverse sbox functions applied to each 4-bit lane, with the outputs concatenated. This word is then xor’ed with the tweaked key to recover the unscrambled read data.

Address Tweaking:

Rkey = scrambler_key[31:0] ^ {addr[N-1:0] repeated to fill 32-bits}

Scrambling:

Write_data_sbi = Write_data ^ Rkey
Write_data_sb = {
    sbox(write_data_ak[31:28]),
    sbox(write_data_ak[27:24]),
    sbox(write_data_ak[23:20]),
    sbox(write_data_ak[19:16]),
    sbox(write_data_ak[15:12]),
    sbox(write_data_ak[11:8]),
    sbox(write_data_ak[7:4]),
    sbox(write_data_ak[3:0])}
Scrambled_write_data = player(Write_data_sb)

Descrambling:

Read_data_sbi = iplayer(Scrambled_read_data)
Read_data_sbo = {
    ibox(Read_data_sbi[31:28]),
    ibox(Read_data_sbi[27:24]),
    ibox(Read_data_sbi[23:20]),
    ibox(Read_data_sbi[19:16]),
    ibox(Read_data_sbi[15:12]),
    ibox(Read_data_sbi[11:8]),
    ibox(Read_data_sbi[7:4]),
    ibox(Read_data_sbi[3:0])}
Read_data = Read_data_sbo ^ Rkey

4. Address Tweaking

As previously mentioned, address tweaking is necessary so that the same data at different addresses scrambles to unique values. Tweaking is performed by simply xor mixing the address with the random scrambler key to form the round key. If the address is less than 32 bits wide, then we just repeatedly concatenate the address with itself until we have 32 bits, truncating any excess bits.

The scrambler_addr_tweak submodule implements this expansion. For power-of-two-aligned widths (8 and 16), the address is replicated exactly to fill 32 bits. For non-power-of-two widths, the address is concatenated three times and the upper portion of the third copy is truncated to produce exactly 32 bits. SRAM scrambler address expansion lists the expansion formula used for each supported width.

Table 4. SRAM scrambler address expansion
ADDR_WIDTH Expansion to 32 bits

8

{addr, addr, addr, addr}

9

{addr, addr, addr, addr[8:4]} (9+9+9+5 = 32)

10

{addr, addr, addr, addr[9:8]} (10+10+10+2 = 32)

11

{addr, addr, addr[10:1]} (11+11+10 = 32)

12

{addr, addr, addr[11:4]} (12+12+8 = 32)

13

{addr, addr, addr[12:7]} (13+13+6 = 32)

16

{addr, addr}

32

Identity (no expansion).

The expanded address is XORed with scrambler_key_i to produce the 32-bit round_key_o.

5. Address Scrambling

Address scrambling is done in a similar fashion as data scrambling with an arbitrary permutation function. The address bits are first xor’ed with the key bits according to the address width. The result is then split into 3 or 4 bit lanes, and passed through one sbox per lane. Finally the sbox results are concatenated and fed through a linear permutation network. There is no descrambling operation on the address, only scrambling.

Each supported address width has a dedicated addr_scrambleN function in scrambler_pkg. These functions partition the address-key-XOR result into lanes of 3 or 4 bits, apply sbox3 (Pyjamask) or sbox4 (PRESENT) to each lane, concatenate the S-box outputs, and pass the result through the corresponding permN fixed permutation. The lane partitioning varies by width to ensure the full address is covered without padding.

SRAM scrambler address lanes identifies the S-box lanes and permutation used at each address width.

Table 5. SRAM scrambler address lanes
Width S-box Lane Partition S-box Types Permutation

6

[5:3], [2:0]

sbox3, sbox3

perm6

7

[6:3], [2:0]

sbox4, sbox3

perm7

8

[7:4], [3:0]

sbox4, sbox4

perm8

9

[8:6], [5:3], [2:0]

sbox3 x3

perm9

10

[9:6], [5:3], [2:0]

sbox4, sbox3 x2

perm10

11

[10:8], [7:4], [3:0]

sbox3, sbox4 x2

perm11

12

[11:8], [7:4], [3:0]

sbox4 x3

perm12

13

[12:9], [8:6], [5:3], [2:0]

sbox4, sbox3 x3

perm13

6. Byte-Wise Scrambling Mode

When the BYTE_WISE parameter is set to 1, the permutation layer operates on each byte independently rather than across the full 32-bit word. On the write path, the eight S-box outputs are grouped into four byte lanes and each lane is permuted with perm8. On the read path, iperm8 is applied per byte lane before the inverse S-box stage. The S-box and round-key XOR stages are identical regardless of the BYTE_WISE setting.

This mode is used in the Key Manager SRAM interface where byte-level write strobes require that scrambling of one byte lane does not depend on data in other lanes.

7. Instantiation Variants

Five pre-configured modules are provided, each fixing the ADDR_WIDTH parameter for a specific SRAM depth. All variants default to DATA_WIDTH = 32 and BYTE_WISE = 0, though the BYTE_WISE parameter can be overridden at instantiation.

SRAM scrambler module variants relates each preconfigured module to its SRAM depth and address-scramble function.

Table 6. SRAM scrambler module variants
Module ADDR_WIDTH SRAM Depth Address Scramble Function

scrambler_512x32

9

512 words

addr_scramble9

scrambler_1024x32

10

1024 words

addr_scramble10

scrambler_2048x32

11

2048 words

addr_scramble11

scrambler_4096x32

12

4096 words

addr_scramble12

scrambler_8192x32

13

8192 words

addr_scramble13

8. Integration in the Key Manager

The Key Manager SRAM interface (km_sram_interface) instantiates two scrambler_8192x32 instances with BYTE_WISE = 1, whose 13-bit address covers the 8192 words of the 32 KiB SRAM. The first instance (u_req_scrambler) scrambles the write data and address on the request path. The second instance (u_rsp_descrambler) descrambles read data on the response path using the address captured when the SRAM accepts the read.

The scrambler is controlled through the SCRAMBLER_KEY and SCRAMBLER_CTRL registers in the Key Manager CSR block (km_csr). The SCRAMBLER_CTRL register has two fields: enable at bit 0 and lock at bit 1. When lock is written to 1, the transition is permanent until the next reset. Once locked, the key register reads as zero, writes to it are ignored, and the scrambler is forced into the enabled state. This prevents firmware from disabling scrambling or reading back the key after provisioning.

A bypass multiplexer gates the scrambled data path. When scrambler_en_i is deasserted, addresses and data pass through unmodified. Parity is always computed on the plaintext data before scrambling, ensuring that the parity check on the read path operates on the descrambled value.

SRAM scrambler datapath shows the address and data scrambling paths at the SRAM interface.

Scrambler datapath: address tweak, address scramble, write-path S-boxes and permutation, and read-path inverse permutation and S-boxes
Figure 1. SRAM scrambler datapath

Inputs enter on the left and the memory side is on the right. The write path runs left to right along the middle row and the read path right to left along the bottom row. Both paths use the same round_key from u_addr_tweak, so the read path must be given the address the read data was fetched from. BYTE_WISE selects between the whole-word permutations and the per-byte permutations shown in each permutation box. The enable multiplexer and the parity logic belong to the caller, not to scrambler.

The Key and Policy Vault (km_kpv) also instantiates scrambler_1024x32 (u_scrambler_km, BYTE_WISE = 0) in front of its key register file, keyed by the KPV’s own scrambler key.