Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Revision 605bdf68df0f239ac2c74b752cc65b3e3bbe4275 authored by dependabot[bot] on 01 November 2024, 13:22:26 UTC, committed by GitHub on 01 November 2024, 13:22:26 UTC
Bump libopencm3 from `1f3abd4` to `201f5bc`
Bumps [libopencm3](https://github.com/libopencm3/libopencm3) from `1f3abd4` to `201f5bc`.
- [Commits](https://github.com/libopencm3/libopencm3/compare/1f3abd43763fa39d23e737602b6d0011a45c70b2...201f5bcfb3fa70ee34818152463e7139f24db377)

---
updated-dependencies:
- dependency-name: libopencm3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
1 parent 3200c9e
  • Files
  • Changes
  • 91eae56
  • /
  • common
  • /
  • aes-keyschedule.S
Raw File Download
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • revision
  • directory
  • content
revision badge
swh:1:rev:605bdf68df0f239ac2c74b752cc65b3e3bbe4275
directory badge Iframe embedding
swh:1:dir:d376b3f4e65914f88ce37b5814b27eec41c0664d
content badge Iframe embedding
swh:1:cnt:246bc5f215c568858617304ac264682c245b8c4e
Citations

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • revision
  • directory
  • content
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
aes-keyschedule.S
/******************************************************************************
* ARM assembly implemetnations of the AES-128 and AES-256 key schedule to
* match fixslicing.
* Note that those implementations are fully bitsliced and do not rely on any
* Look-Up Table (LUT).
*
* See the paper at https://eprint.iacr.org/2020/1123.pdf for more details.
*
* @author   Alexandre Adomnicai, Nanyang Technological University, Singapore
*           alexandre.adomnicai@ntu.edu.sg
*
* @date     October 2020
******************************************************************************/

.syntax unified
.thumb

/******************************************************************************
* Macro to compute the SWAPMOVE technique: swap the bits in 'in1' masked by 'm'
* by the bits in 'in0' masked by 'm << n' and put the results in 'out0', 'out1'
******************************************************************************/
.macro swpmv out0, out1, in0, in1, m, n, tmp
    eor     \tmp, \in1, \in0, lsr \n
    and     \tmp, \m
    eor     \out1, \in1, \tmp
    eor     \out0, \in0, \tmp, lsl \n
.endm

/******************************************************************************
* Packing routine. Note that it is the same as the one used in the encryption
* function so some code size could be saved by merging the two files.
******************************************************************************/
.align 2
packing:
    movw    r3, #0x0f0f
    movt    r3, #0x0f0f             // r3 <- 0x0f0f0f0f (mask for SWAPMOVE)
    eor     r2, r3, r3, lsl #2      // r2 <- 0x33333333 (mask for SWAPMOVE)
    eor     r1, r2, r2, lsl #1      // r1 <- 0x55555555 (mask for SWAPMOVE)
    swpmv   r8, r4, r8, r4, r1, #1, r12
    swpmv   r9, r5, r9, r5, r1, #1, r12
    swpmv   r10, r6, r10, r6, r1, #1, r12
    swpmv   r11, r7, r11, r7, r1, #1, r12
    swpmv   r0, r4, r5, r4, r2, #2, r12
    swpmv   r9, r5, r9, r8, r2, #2, r12
    swpmv   r7, r8, r7, r6, r2, #2, r12
    swpmv   r11, r2, r11, r10, r2, #2, r12
    swpmv   r8, r4, r8, r4, r3, #4, r12
    swpmv   r10, r6, r7, r0, r3, #4, r12
    swpmv   r11, r7, r11, r9, r3, #4, r12
    swpmv   r9, r5, r2, r5, r3, #4, r12
    bx      lr

/******************************************************************************
* Subroutine that computes S-box. Note that the same code is used in the
* encryption function, so some code size could be saved by merging the 2 files.
* Credits to https://github.com/Ko-/aes-armcortexm.
******************************************************************************/
.align 2
sbox:
    str     r14, [sp, #52]
    eor     r1, r7, r9              //Exec y14 = U3 ^ U5; into r1
    eor     r3, r4, r10             //Exec y13 = U0 ^ U6; into r3
    eor     r2, r3, r1              //Exec y12 = y13 ^ y14; into r2
    eor     r0, r8, r2              //Exec t1 = U4 ^ y12; into r0
    eor     r14, r0, r9             //Exec y15 = t1 ^ U5; into r14
    and     r12, r2, r14            //Exec t2 = y12 & y15; into r12
    eor     r8, r14, r11            //Exec y6 = y15 ^ U7; into r8
    eor     r0, r0, r5              //Exec y20 = t1 ^ U1; into r0
    str.w   r2, [sp, #44]           //Store r2/y12 on stack
    eor     r2, r4, r7              //Exec y9 = U0 ^ U3; into r2
    str     r0, [sp, #40]           //Store r0/y20 on stack
    eor     r0, r0, r2              //Exec y11 = y20 ^ y9; into r0
    str     r2, [sp, #36]           //Store r2/y9 on stack
    and     r2, r2, r0              //Exec t12 = y9 & y11; into r2
    str     r8, [sp, #32]           //Store r8/y6 on stack
    eor     r8, r11, r0             //Exec y7 = U7 ^ y11; into r8
    eor     r9, r4, r9              //Exec y8 = U0 ^ U5; into r9
    eor     r6, r5, r6              //Exec t0 = U1 ^ U2; into r6
    eor     r5, r14, r6             //Exec y10 = y15 ^ t0; into r5
    str     r14, [sp, #28]          //Store r14/y15 on stack
    eor     r14, r5, r0             //Exec y17 = y10 ^ y11; into r14
    str.w   r1, [sp, #24]           //Store r1/y14 on stack
    and     r1, r1, r14             //Exec t13 = y14 & y17; into r1
    eor     r1, r1, r2              //Exec t14 = t13 ^ t12; into r1
    str     r14, [sp, #20]          //Store r14/y17 on stack
    eor     r14, r5, r9             //Exec y19 = y10 ^ y8; into r14
    str.w   r5, [sp, #16]           //Store r5/y10 on stack
    and     r5, r9, r5              //Exec t15 = y8 & y10; into r5
    eor     r2, r5, r2              //Exec t16 = t15 ^ t12; into r2
    eor     r5, r6, r0              //Exec y16 = t0 ^ y11; into r5
    str.w   r0, [sp, #12]           //Store r0/y11 on stack
    eor     r0, r3, r5              //Exec y21 = y13 ^ y16; into r0
    str     r3, [sp, #8]            //Store r3/y13 on stack
    and     r3, r3, r5              //Exec t7 = y13 & y16; into r3
    str     r5, [sp, #4]            //Store r5/y16 on stack
    str     r11, [sp, #0]           //Store r11/U7 on stack
    eor     r5, r4, r5              //Exec y18 = U0 ^ y16; into r5
    eor     r6, r6, r11             //Exec y1 = t0 ^ U7; into r6
    eor     r7, r6, r7              //Exec y4 = y1 ^ U3; into r7
    and     r11, r7, r11            //Exec t5 = y4 & U7; into r11
    eor     r11, r11, r12           //Exec t6 = t5 ^ t2; into r11
    eor     r11, r11, r2            //Exec t18 = t6 ^ t16; into r11
    eor     r14, r11, r14           //Exec t22 = t18 ^ y19; into r14
    eor     r4, r6, r4              //Exec y2 = y1 ^ U0; into r4
    and     r11, r4, r8             //Exec t10 = y2 & y7; into r11
    eor     r11, r11, r3            //Exec t11 = t10 ^ t7; into r11
    eor     r2, r11, r2             //Exec t20 = t11 ^ t16; into r2
    eor     r2, r2, r5              //Exec t24 = t20 ^ y18; into r2
    eor     r10, r6, r10            //Exec y5 = y1 ^ U6; into r10
    and     r11, r10, r6            //Exec t8 = y5 & y1; into r11
    eor     r3, r11, r3             //Exec t9 = t8 ^ t7; into r3
    eor     r3, r3, r1              //Exec t19 = t9 ^ t14; into r3
    eor     r3, r3, r0              //Exec t23 = t19 ^ y21; into r3
    eor     r0, r10, r9             //Exec y3 = y5 ^ y8; into r0
    ldr     r11, [sp, #32]          //Load y6 into r11
    and     r5, r0, r11             //Exec t3 = y3 & y6; into r5
    eor     r12, r5, r12            //Exec t4 = t3 ^ t2; into r12
    ldr     r5, [sp, #40]           //Load y20 into r5
    str     r7, [sp, #32]           //Store r7/y4 on stack
    eor     r12, r12, r5            //Exec t17 = t4 ^ y20; into r12
    eor     r1, r12, r1             //Exec t21 = t17 ^ t14; into r1
    and     r12, r1, r3             //Exec t26 = t21 & t23; into r12
    eor     r5, r2, r12             //Exec t27 = t24 ^ t26; into r5
    eor     r12, r14, r12           //Exec t31 = t22 ^ t26; into r12
    eor     r1, r1, r14             //Exec t25 = t21 ^ t22; into r1
    and     r7, r1, r5              //Exec t28 = t25 & t27; into r7
    eor     r14, r7, r14            //Exec t29 = t28 ^ t22; into r14
    and     r4, r14, r4             //Exec z14 = t29 & y2; into r4
    and     r8, r14, r8             //Exec z5 = t29 & y7; into r8
    eor     r7, r3, r2              //Exec t30 = t23 ^ t24; into r7
    and     r12, r12, r7            //Exec t32 = t31 & t30; into r12
    eor     r12, r12, r2            //Exec t33 = t32 ^ t24; into r12
    eor     r7, r5, r12             //Exec t35 = t27 ^ t33; into r7
    and     r2, r2, r7              //Exec t36 = t24 & t35; into r2
    eor     r5, r5, r2              //Exec t38 = t27 ^ t36; into r5
    and     r5, r14, r5             //Exec t39 = t29 & t38; into r5
    eor     r1, r1, r5              //Exec t40 = t25 ^ t39; into r1
    eor     r5, r14, r1             //Exec t43 = t29 ^ t40; into r5
    ldr.w   r7, [sp, #4]            //Load y16 into r7
    and     r7, r5, r7              //Exec z3 = t43 & y16; into r7
    eor     r8, r7, r8              //Exec tc12 = z3 ^ z5; into r8
    str     r8, [sp, #40]           //Store r8/tc12 on stack
    ldr     r8, [sp, #8]            //Load y13 into r8
    and     r8, r5, r8              //Exec z12 = t43 & y13; into r8
    and     r10, r1, r10            //Exec z13 = t40 & y5; into r10
    and     r6, r1, r6              //Exec z4 = t40 & y1; into r6
    eor     r6, r7, r6              //Exec tc6 = z3 ^ z4; into r6
    eor     r3, r3, r12             //Exec t34 = t23 ^ t33; into r3
    eor     r3, r2, r3              //Exec t37 = t36 ^ t34; into r3
    eor     r1, r1, r3              //Exec t41 = t40 ^ t37; into r1
    ldr.w   r5, [sp, #16]           //Load y10 into r5
    and     r2, r1, r5              //Exec z8 = t41 & y10; into r2
    and     r9, r1, r9              //Exec z17 = t41 & y8; into r9
    str     r9, [sp, #16]           //Store r9/z17 on stack
    eor     r5, r12, r3             //Exec t44 = t33 ^ t37; into r5
    ldr     r9, [sp, #28]           //Load y15 into r9
    ldr.w   r7, [sp, #44]           //Load y12 into r7
    and     r9, r5, r9              //Exec z0 = t44 & y15; into r9
    and     r7, r5, r7              //Exec z9 = t44 & y12; into r7
    and     r0, r3, r0              //Exec z10 = t37 & y3; into r0
    and     r3, r3, r11             //Exec z1 = t37 & y6; into r3
    eor     r3, r3, r9              //Exec tc5 = z1 ^ z0; into r3
    eor     r3, r6, r3              //Exec tc11 = tc6 ^ tc5; into r3
    ldr     r11, [sp, #32]          //Load y4 into r11
    ldr.w   r5, [sp, #20]           //Load y17 into r5
    and     r11, r12, r11           //Exec z11 = t33 & y4; into r11
    eor     r14, r14, r12           //Exec t42 = t29 ^ t33; into r14
    eor     r1, r14, r1             //Exec t45 = t42 ^ t41; into r1
    and     r5, r1, r5              //Exec z7 = t45 & y17; into r5
    eor     r6, r5, r6              //Exec tc8 = z7 ^ tc6; into r6
    ldr     r5, [sp, #24]           //Load y14 into r5
    str     r4, [sp, #32]           //Store r4/z14 on stack
    and     r1, r1, r5              //Exec z16 = t45 & y14; into r1
    ldr     r5, [sp, #12]           //Load y11 into r5
    ldr     r4, [sp, #36]           //Load y9 into r4
    and     r5, r14, r5             //Exec z6 = t42 & y11; into r5
    eor     r5, r5, r6              //Exec tc16 = z6 ^ tc8; into r5
    and     r4, r14, r4             //Exec z15 = t42 & y9; into r4
    eor     r14, r4, r5             //Exec tc20 = z15 ^ tc16; into r14
    eor     r4, r4, r1              //Exec tc1 = z15 ^ z16; into r4
    eor     r1, r0, r4              //Exec tc2 = z10 ^ tc1; into r1
    eor     r0, r1, r11             //Exec tc21 = tc2 ^ z11; into r0
    eor     r7, r7, r1              //Exec tc3 = z9 ^ tc2; into r7
    eor     r1, r7, r5              //Exec S0 = tc3 ^ tc16; into r1
    eor     r7, r7, r3              //Exec S3 = tc3 ^ tc11; into r7
    eor     r3, r7, r5              //Exec S1 = S3 ^ tc16 ^ 1; into r3
    eor     r11, r10, r4            //Exec tc13 = z13 ^ tc1; into r11
    ldr.w   r4, [sp, #0]            //Load U7 into r4
    and     r12, r12, r4            //Exec z2 = t33 & U7; into r12
    eor     r9, r9, r12             //Exec tc4 = z0 ^ z2; into r9
    eor     r12, r8, r9             //Exec tc7 = z12 ^ tc4; into r12
    eor     r2, r2, r12             //Exec tc9 = z8 ^ tc7; into r2
    eor     r2, r6, r2              //Exec tc10 = tc8 ^ tc9; into r2
    ldr.w   r4, [sp, #32]           //Load z14 into r4
    eor     r12, r4, r2             //Exec tc17 = z14 ^ tc10; into r12
    eor     r0, r0, r12             //Exec S5 = tc21 ^ tc17; into r0
    eor     r6, r12, r14            //Exec tc26 = tc17 ^ tc20; into r6
    ldr.w   r4, [sp, #16]           //Load z17 into r4
    ldr     r12, [sp, #40]          //Load tc12 into r12
    eor     r6, r6, r4              //Exec S2 = tc26 ^ z17 ^ 1; into r6
    eor     r12, r9, r12            //Exec tc14 = tc4 ^ tc12; into r12
    eor     r14, r11, r12           //Exec tc18 = tc13 ^ tc14; into r14
    eor     r2, r2, r14             //Exec S6 = tc10 ^ tc18 ^ 1; into r2
    eor     r11, r8, r14            //Exec S7 = z12 ^ tc18 ^ 1; into r11
    ldr     r14, [sp, #52]          // restore link register
    eor     r8, r12, r7             //Exec S4 = tc14 ^ S3; into r8
    bx      lr
    // [('r0', 'S5'), ('r1', 'S0'), ('r2', 'S6'), ('r3', 'S1'),
    // ('r6', 'S2'),('r7', 'S3'), ('r8', 'S4'), ('r11', 'S7')]

/******************************************************************************
* Subroutine that XORs the columns after the S-box during the AES-128 key
* schedule round function, for rounds i such that (i % 4) == 0.
* Note that the code size could be reduced at the cost of some instructions
* since some redundant code is applied on different registers.
******************************************************************************/
.align 2
aes128_xorcolumns_rotword:
    ldr     r12, [sp, #56]          // restore 'rkeys' address
    ldr.w   r5, [r12, #28]          // load rkey word of rkey from prev round
    movw    r4, #0xc0c0
    movt    r4, #0xc0c0             // r4 <- 0xc0c0c0c0
    eor     r11, r5, r11, ror #2    // r11<- r5 ^ (r11 >>> 2)
    bic     r11, r4, r11            // r11<- ~r11 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #2      // r9 <- r9 & 0x30303030
    orr     r11, r11, r9            // r11<- r11 | r9
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #4      // r9 <- r9 & 0x0c0c0c0c
    orr     r11, r11, r9            // r11<- r11 | r9
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #6      // r9 <- r9 & 0x03030303
    orr     r11, r11, r9            // r11<- r11 | r9
    mvn     r9, r5                  // NOT omitted in sbox
    ldr.w   r5, [r12, #24]          // load rkey word of rkey from prev round
    str     r9, [r12, #28]          // store new rkey word after NOT
    str     r11, [r12, #60]         // store new rkey word in 'rkeys'
    eor     r10, r5, r2, ror #2     // r10<- r5 ^ (r2 >>> 2)
    bic     r10, r4, r10            // r10<- ~r10 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #2      // r9 <- r9 & 0x30303030
    orr     r10, r10, r9            // r10<- r10 | r9
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #4      // r9 <- r9 & 0x0c0c0c0c
    orr     r10, r10, r9            // r10<- r10 | r9
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #6      // r9 <- r9 & 0x03030303
    orr     r10, r10, r9            // r10<- r10 | r9
    mvn     r9, r5                  // NOT omitted in sbox
    ldr.w   r2, [r12, #20]          // load rkey word of rkey from prev round
    str     r9, [r12, #24]          // store new rkey word after NOT
    str     r10, [r12, #56]         // store new rkey word in 'rkeys'
    eor     r9, r2, r0, ror #2      // r9 <- r2 ^ (r9 >>> 2)
    and     r9, r4, r9              // r9 <- r9 & 0xc0c0c0c0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r9, r9, r0              // r9 <- r9 | r0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r9, r9, r0              // r9 <- r9 | r0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r9, r9, r0              // r9 <- r9 | r0
    ldr.w   r2, [r12, #16]          // load rkey word of rkey from prev round
    str.w   r9, [r12, #52]          // store new rkey word in 'rkeys'
    eor     r8, r2, r8, ror #2      // r8 <- r2 ^ (r8 >>> 2)
    and     r8, r4, r8              // r8 <- r8 & 0xc0c0c0c0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r8, r8, r0              // r8 <- r8 | r0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r8, r8, r0              // r8 <- r8 | r0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r8, r8, r0              // r8 <- r8 | r0
    ldr.w   r2, [r12, #12]          // load rkey word of rkey from prev round
    str.w   r8, [r12, #48]          // store new rkey word in 'rkeys'
    eor     r7, r2, r7, ror #2      // r7 <- r2 ^ (r7 >>> 2)
    and     r7, r4, r7              // r7 <- r7 & 0xc0c0c0c0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r7, r7, r0              // r7 <- r7 | r0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r7, r7, r0              // r7 <- r7 | r0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r7, r7, r0              // r7 <- r7 | r0
    ldr.w   r2, [r12, #8]           // load rkey word of rkey from prev round
    str.w   r7, [r12, #44]          // store new rkey word in 'rkeys'
    eor     r6, r2, r6, ror #2      // r6 <- r2 ^ (r6 >>> 2)
    bic     r6, r4, r6              // r6 <- ~r6 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r6, r6, r0              // r6 <- r6 | r0
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r6, r6, r0              // r6 <- r6 | r0
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r6, r6, r0              // r6 <- r6 | r0
    mvn     r0, r2                  // NOT omitted in sbox
    ldr.w   r2, [r12, #4]           // load rkey word of rkey from prev round
    str.w   r0, [r12, #8]           // store new rkey word after NOT
    str.w   r6, [r12, #40]          // store new rkey word in 'rkeys'
    eor     r5, r2, r3, ror #2      // r5 <- r2 ^ (r3 >>> 2)
    bic     r5, r4, r5              // r5 <- ~r5 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r5, r5, r0              // r5 <- r5 | r0
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r5, r5, r0              // r5 <- r5 | r0
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r5, r5, r0              // r5 <- r5 | r0
    mvn     r0, r2                  // NOT omitted in sbox
    ldr.w   r2, [r12], #32          // load rkey word of rkey from prev round
    str.w   r0, [r12, #-28]         // store new rkey word after NOT
    str.w   r5, [r12, #4]           // store new rkey word in 'rkeys'
    eor     r3, r2, r1, ror #2      // r3 <- r2 ^ (r1 >>> 2)
    and     r3, r4, r3              // r3 <- r3 & 0xc0c0c0c0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r3, r3, r0              // r3 <- r3 | r0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r3, r3, r0              // r3 <- r3 | r0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r4, r3, r0              // r4 <- r3 | r0
    str.w   r4, [r12]
    str.w   r12, [sp, #56]          // store the new rkeys address on the stack
    bx      lr

/******************************************************************************
* Subroutine that XORs the columns after the S-box during the AES-256 key
* schedule round function, for rounds i such that (i % 4) == 0.
* Differs from 'aes128_xorcolumns_rotword' by the rkeys' indexes to be involved
* in XORs.
******************************************************************************/
.align 2
aes256_xorcolumns_rotword:
    ldr     r12, [sp, #56]          // restore 'rkeys' address
    ldr.w   r5, [r12, #28]          // load rkey word of rkey from prev round
    movw    r4, #0xc0c0
    movt    r4, #0xc0c0             // r4 <- 0xc0c0c0c0
    eor     r11, r5, r11, ror #2    // r11<- r5 ^ (r11 >>> 2)
    bic     r11, r4, r11            // r11<- ~r11 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #2      // r9 <- r9 & 0x30303030
    orr     r11, r11, r9            // r11<- r11 | r9
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #4      // r9 <- r9 & 0x0c0c0c0c
    orr     r11, r11, r9            // r11<- r11 | r9
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #6      // r9 <- r9 & 0x03030303
    orr     r11, r11, r9            // r11<- r11 | r9
    mvn     r9, r5                  // NOT omitted in sbox
    ldr.w   r5, [r12, #24]          // load rkey word of rkey from prev round
    str     r9, [r12, #28]          // store new rkey word after NOT
    str     r11, [r12, #92]         // store new rkey word in 'rkeys'
    eor     r10, r5, r2, ror #2     // r10<- r5 ^ (r2 >>> 2)
    bic     r10, r4, r10            // r10<- ~r10 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #2      // r9 <- r9 & 0x30303030
    orr     r10, r10, r9            // r10<- r10 | r9
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #4      // r9 <- r9 & 0x0c0c0c0c
    orr     r10, r10, r9            // r10<- r10 | r9
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #6      // r9 <- r9 & 0x03030303
    orr     r10, r10, r9            // r10<- r10 | r9
    mvn     r9, r5                  // NOT omitted in sbox
    ldr.w   r2, [r12, #20]          // load rkey word of rkey from prev round
    str     r9, [r12, #24]          // store new rkey word after NOT
    str     r10, [r12, #88]         // store new rkey word in 'rkeys'
    eor     r9, r2, r0, ror #2      // r9 <- r2 ^ (r9 >>> 2)
    and     r9, r4, r9              // r9 <- r9 & 0xc0c0c0c0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r9, r9, r0              // r9 <- r9 | r0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r9, r9, r0              // r9 <- r9 | r0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r9, r9, r0              // r9 <- r9 | r0
    ldr.w   r2, [r12, #16]          // load rkey word of rkey from prev round
    str.w   r9, [r12, #84]          // store new rkey word in 'rkeys'
    eor     r8, r2, r8, ror #2      // r8 <- r2 ^ (r8 >>> 2)
    and     r8, r4, r8              // r8 <- r8 & 0xc0c0c0c0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r8, r8, r0              // r8 <- r8 | r0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r8, r8, r0              // r8 <- r8 | r0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r8, r8, r0              // r8 <- r8 | r0
    ldr.w   r2, [r12, #12]          // load rkey word of rkey from prev round
    str.w   r8, [r12, #80]          // store new rkey word in 'rkeys'
    eor     r7, r2, r7, ror #2      // r7 <- r2 ^ (r7 >>> 2)
    and     r7, r4, r7              // r7 <- r7 & 0xc0c0c0c0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r7, r7, r0              // r7 <- r7 | r0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r7, r7, r0              // r7 <- r7 | r0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r7, r7, r0              // r7 <- r7 | r0
    ldr.w   r2, [r12, #8]           // load rkey word of rkey from prev round
    str.w   r7, [r12, #76]          // store new rkey word in 'rkeys'
    eor     r6, r2, r6, ror #2      // r6 <- r2 ^ (r6 >>> 2)
    bic     r6, r4, r6              // r6 <- ~r6 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r6, r6, r0              // r6 <- r6 | r0
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r6, r6, r0              // r6 <- r6 | r0
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r6, r6, r0              // r6 <- r6 | r0
    mvn     r0, r2                  // NOT omitted in sbox
    ldr.w   r2, [r12, #4]           // load rkey word of rkey from prev round
    str.w   r0, [r12, #8]           // store new rkey word after NOT
    str.w   r6, [r12, #72]          // store new rkey word in 'rkeys'
    eor     r5, r2, r3, ror #2      // r5 <- r2 ^ (r3 >>> 2)
    bic     r5, r4, r5              // r5 <- ~r5 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r5, r5, r0              // r5 <- r5 | r0
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r5, r5, r0              // r5 <- r5 | r0
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r5, r5, r0              // r5 <- r5 | r0
    mvn     r0, r2                  // NOT omitted in sbox
    ldr.w   r2, [r12], #32          // load rkey word of rkey from prev round
    str.w   r0, [r12, #-28]         // store new rkey word after NOT
    str.w   r5, [r12, #36]          // store new rkey word in 'rkeys'
    eor     r3, r2, r1, ror #2      // r3 <- r2 ^ (r1 >>> 2)
    and     r3, r4, r3              // r3 <- r3 & 0xc0c0c0c0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r3, r3, r0              // r3 <- r3 | r0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r3, r3, r0              // r3 <- r3 | r0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r4, r3, r0              // r4 <- r3 | r0
    str.w   r4, [r12, #32]
    str.w   r12, [sp, #56]          // store the new rkeys address on the stack
    bx      lr

/******************************************************************************
* Subroutine that XORs the columns after the S-box during the AES-256 key
* schedule round function, for rounds i such that (i % 4) == 0.
* It differs from 'aes256_xorcolumns_rotword' by the omission of the rotword
* operation (i.e. 'ror #26' instead of 'ror #2').
******************************************************************************/
.align 2
aes256_xorcolumns:
    ldr     r12, [sp, #56]          // restore 'rkeys' address
    ldr.w   r5, [r12, #28]          // load rkey word of rkey from prev round
    movw    r4, #0xc0c0
    movt    r4, #0xc0c0             // r4 <- 0xc0c0c0c0
    eor     r11, r5, r11, ror #26   // r11<- r5 ^ (r11 >>> 26)
    bic     r11, r4, r11            // r11<- ~r11 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #2      // r9 <- r9 & 0x30303030
    orr     r11, r11, r9            // r11<- r11 | r9
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #4      // r9 <- r9 & 0x0c0c0c0c
    orr     r11, r11, r9            // r11<- r11 | r9
    eor     r9, r5, r11, ror #2     // r9 <- r5 ^ (r11 >>> 2)
    and     r9, r9, r4, ror #6      // r9 <- r9 & 0x03030303
    orr     r11, r11, r9            // r11<- r11 | r9
    mvn     r9, r5                  // NOT omitted in sbox
    ldr.w   r5, [r12, #24]          // load rkey word of rkey from prev round
    str     r9, [r12, #28]          // store new rkey word after NOT
    str     r11, [r12, #92]         // store new rkey word in 'rkeys'
    eor     r10, r5, r2, ror #26    // r10<- r5 ^ (r2 >>> 2)
    bic     r10, r4, r10            // r10<- ~r10 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #2      // r9 <- r9 & 0x30303030
    orr     r10, r10, r9            // r10<- r10 | r9
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #4      // r9 <- r9 & 0x0c0c0c0c
    orr     r10, r10, r9            // r10<- r10 | r9
    eor     r9, r5, r10, ror #2     // r9 <- r5 ^ (r10 >>> 2)
    and     r9, r9, r4, ror #6      // r9 <- r9 & 0x03030303
    orr     r10, r10, r9            // r10<- r10 | r9
    mvn     r9, r5                  // NOT omitted in sbox
    ldr.w   r2, [r12, #20]          // load rkey word of rkey from prev round
    str     r9, [r12, #24]          // store new rkey word after NOT
    str     r10, [r12, #88]         // store new rkey word in 'rkeys'
    eor     r9, r2, r0, ror #26     // r9 <- r2 ^ (r9 >>> 26)
    and     r9, r4, r9              // r9 <- r9 & 0xc0c0c0c0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r9, r9, r0              // r9 <- r9 | r0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r9, r9, r0              // r9 <- r9 | r0
    eor     r0, r2, r9, ror #2      // r0 <- r2 ^ (r9 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r9, r9, r0              // r9 <- r9 | r0
    ldr.w   r2, [r12, #16]          // load rkey word of rkey from prev round
    str.w   r9, [r12, #84]          // store new rkey word in 'rkeys'
    eor     r8, r2, r8, ror #26     // r8 <- r2 ^ (r8 >>> 26)
    and     r8, r4, r8              // r8 <- r8 & 0xc0c0c0c0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r8, r8, r0              // r8 <- r8 | r0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r8, r8, r0              // r8 <- r8 | r0
    eor     r0, r2, r8, ror #2      // r0 <- r2 ^ (r8 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r8, r8, r0              // r8 <- r8 | r0
    ldr.w   r2, [r12, #12]          // load rkey word of rkey from prev round
    str.w   r8, [r12, #80]          // store new rkey word in 'rkeys'
    eor     r7, r2, r7, ror #26     // r7 <- r2 ^ (r7 >>> 26)
    and     r7, r4, r7              // r7 <- r7 & 0xc0c0c0c0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r7, r7, r0              // r7 <- r7 | r0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r7, r7, r0              // r7 <- r7 | r0
    eor     r0, r2, r7, ror #2      // r0 <- r2 ^ (r7 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r7, r7, r0              // r7 <- r7 | r0
    ldr.w   r2, [r12, #8]           // load rkey word of rkey from prev round
    str.w   r7, [r12, #76]          // store new rkey word in 'rkeys'
    eor     r6, r2, r6, ror #26     // r6 <- r2 ^ (r6 >>> 26)
    bic     r6, r4, r6              // r6 <- ~r6 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r6, r6, r0              // r6 <- r6 | r0
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r6, r6, r0              // r6 <- r6 | r0
    eor     r0, r2, r6, ror #2      // r0 <- r2 ^ (r6 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r6, r6, r0              // r6 <- r6 | r0
    mvn     r0, r2                  // NOT omitted in sbox
    ldr.w   r2, [r12, #4]           // load rkey word of rkey from prev round
    str.w   r0, [r12, #8]           // store new rkey word after NOT
    str.w   r6, [r12, #72]          // store new rkey word in 'rkeys'
    eor     r5, r2, r3, ror #26     // r5 <- r2 ^ (r3 >>> 26)
    bic     r5, r4, r5              // r5 <- ~r5 & 0xc0c0c0c0 (NOT omitted in sbox)
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r5, r5, r0              // r5 <- r5 | r0
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r5, r5, r0              // r5 <- r5 | r0
    eor     r0, r2, r5, ror #2      // r0 <- r2 ^ (r5 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r5, r5, r0              // r5 <- r5 | r0
    mvn     r0, r2                  // NOT omitted in sbox
    ldr.w   r2, [r12], #32          // load rkey word of rkey from prev round
    str.w   r0, [r12, #-28]         // store new rkey word after NOT
    str.w   r5, [r12, #36]          // store new rkey word in 'rkeys'
    eor     r3, r2, r1, ror #26     // r3 <- r2 ^ (r1 >>> 26)
    and     r3, r4, r3              // r3 <- r3 & 0xc0c0c0c0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #2      // r0 <- r0 & 0x30303030
    orr     r3, r3, r0              // r3 <- r3 | r0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #4      // r0 <- r0 & 0x0c0c0c0c
    orr     r3, r3, r0              // r3 <- r3 | r0
    eor     r0, r2, r3, ror #2      // r0 <- r2 ^ (r3 >>> 2)
    and     r0, r0, r4, ror #6      // r0 <- r0 & 0x03030303
    orr     r4, r3, r0              // r4 <- r3 | r0
    str.w   r4, [r12, #32]
    str.w   r12, [sp, #56]          // store the new rkeys address on the stack
    bx      lr

/******************************************************************************
* Applies ShiftRows^(-1) on a round key to match the fixsliced representation.
******************************************************************************/
.align 2
inv_shiftrows_1:
    ldr.w   r2, [r12, #-32]!
    str     r14, [sp, #52]          // store link register
    movw    r1, #8
    movw    r14, #0x0300
    movt    r14, #0x0c0f            // r14<- 0x0c0f0300 for ShiftRows^[-1]
loop_inv_sr_1:
    movw    r3, #0x3300
    movt    r3, #0x3300             // r3 <- 0x33003300 for ShiftRows^[-1]
    swpmv   r2, r2, r2, r2, r14, 4, r0
    eor     r0, r2, r2, lsr #2
    and     r0, r3
    eor     r2, r2, r0
    eor     r3, r2, r0, lsl #2
    ldr.w   r2, [r12, #4]!
    str.w   r3, [r12, #-4]
    subs    r1, #1
    bne     loop_inv_sr_1
    ldr     r14, [sp, #52]          // restore link register
    bx      lr

/******************************************************************************
* Applies ShiftRows^(-2) on a round key to match the fixsliced representation.
* Only needed for the fully-fixsliced (ffs) representation.
******************************************************************************/
.align 2
inv_shiftrows_2:
    ldr.w   r2, [r12, #-32]!
    str     r14, [sp, #52]          // store link register
    movw    r1, #8
    movw    r14, #0x0f00
    movt    r14, #0x0f00            // r14<- 0x0f000f00 for ShiftRows^[-2]
loop_inv_sr_2:
    eor     r0, r2, r2, lsr #4
    and     r0, r14
    eor     r2, r2, r0
    eor     r3, r2, r0, lsl #4
    ldr.w   r2, [r12, #4]!
    str.w   r3, [r12, #-4]
    subs    r1, #1
    bne     loop_inv_sr_2
    ldr     r14, [sp, #52]          // restore link register
    bx      lr

/******************************************************************************
* Applies ShiftRows^(-3) on a round key to match the fixsliced representation.
* Only needed for the fully-fixsliced (ffs) representation.
******************************************************************************/
.align 2
inv_shiftrows_3:
    ldr.w   r2, [r12, #-32]!
    str     r14, [sp, #52]          // store link register
    movw    r1, #8
    movw    r14, #0x0c00
    movt    r14, #0x030f            // r14<- 0x030f0c00 for ShiftRows^[-3]
loop_inv_sr_3:
    movw    r3, #0x3300
    movt    r3, #0x3300             // r3 <- 0x33003300 for ShiftRows^[-3]
    swpmv   r2, r2, r2, r2, r14, 4, r0
    eor     r0, r2, r2, lsr #2
    and     r0, r3
    eor     r2, r2, r0
    eor     r3, r2, r0, lsl #2
    ldr.w   r2, [r12, #4]!
    str.w   r3, [r12, #-4]
    subs    r1, #1
    bne     loop_inv_sr_3
    ldr     r14, [sp, #52]          // restore link register
    bx      lr

/******************************************************************************
* Fully bitsliced AES-128 key schedule to match the fully-fixsliced (ffs)
* representation. Note that it is possible to pass two different keys as input
* parameters if one wants to encrypt 2 blocks in with two different keys.
******************************************************************************/
@ void aes128_keyschedule_ffs(u32* rkeys, const u8* key);
.global aes128_keyschedule_ffs
.type   aes128_keyschedule_ffs,%function
.align 2
aes128_keyschedule_ffs:
    push    {r0-r12,r14}
    sub.w   sp, #56                 // allow space on the stack for tmp var
    ldr.w   r4, [r1]                // load the 128-bit key in r4-r7
    ldr     r5, [r1, #4]
    ldr     r6, [r1, #8]
    ldr     r7, [r1, #12]
    ldr.w   r8, [r1]                // load the 128-bit key in r8-r11
    ldr     r9, [r1, #4]
    ldr     r10,[r1, #8]
    ldr     r11,[r1, #12]
    bl      packing                 // pack the master key
    ldr.w   r0, [sp, #56]           // restore 'rkeys' address
    stm     r0, {r4-r11}            // store the packed master key in 'rkeys'
    bl      sbox                    // apply the sbox to the master key
    eor     r11, r11, #0x00000300   // add the 1st rconst
    bl      aes128_xorcolumns_rotword
    bl      sbox                    // apply the sbox to the master key
    eor     r2, r2, #0x00000300     // add the 2nd rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_1
    bl      sbox                    // apply the sbox to the master key
    eor     r0, r0, #0x00000300     // add the 3rd rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_2
    bl      sbox                    // apply the sbox to the master key
    eor     r8, r8, #0x00000300     // add the 4th rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_3
    bl      sbox                    // apply the sbox to the master key
    eor     r7, r7, #0x00000300     // add the 5th rconst
    bl      aes128_xorcolumns_rotword
    bl      sbox                    // apply the sbox to the master key
    eor     r6, r6, #0x00000300     // add the 6th rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_1
    bl      sbox                    // apply the sbox to the master key
    eor     r3, r3, #0x00000300     // add the 7th rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_2
    bl      sbox                    // apply the sbox to the master key
    eor     r1, r1, #0x00000300     // add the 8th rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_3
    bl      sbox                    // apply the sbox to the master key
    eor     r11, r11, #0x00000300   // add the 9th rconst
    eor     r2, r2, #0x00000300     // add the 9th rconst
    eor     r8, r8, #0x00000300     // add the 9th rconst
    eor     r7, r7, #0x00000300     // add the 9th rconst
    bl      aes128_xorcolumns_rotword
    bl      sbox                    // apply the sbox to the master key
    eor     r2, r2, #0x00000300     // add the 10th rconst
    eor     r0, r0, #0x00000300     // add the 10th rconst
    eor     r7, r7, #0x00000300     // add the 10th rconst
    eor     r6, r6, #0x00000300     // add the 10th rconst
    bl      aes128_xorcolumns_rotword
    bl      inv_shiftrows_1
    mvn     r5, r5                  // add the NOT for the last rkey
    mvn     r6, r6                  // add the NOT for the last rkey
    mvn     r10, r10                // add the NOT for the last rkey
    mvn     r11, r11                // add the NOT for the last rkey
    strd    r5, r6, [r12, #4]
    strd    r10, r11, [r12, #24]
    ldrd    r0, r1, [r12, #-316]
    ldrd    r2, r3, [r12, #-296]
    mvn     r0, r0                  // remove the NOT for the key whitening
    mvn     r1, r1                  // remove the NOT for the key whitening
    mvn     r2, r2                  // remove the NOT for the key whitening
    mvn     r3, r3                  // remove the NOT for the key whitening
    strd    r0, r1, [r12, #-316]
    strd    r2, r3, [r12, #-296]
    add.w   sp, #56                 // restore stack
    pop     {r0-r12, r14}           // restore context
    bx      lr

/******************************************************************************
* Fully bitsliced AES-256 key schedule to match the fully-fixsliced (ffs)
* representation. Note that it is possible to pass 2 different keys as input
* parameters if one wants to encrypt 2 blocks in with 2 different keys.
******************************************************************************/
@ void aes256_keyschedule_ffs(u32* rkeys, const u8* key);
.global aes256_keyschedule_ffs
.type   aes256_keyschedule_ffs,%function
.align 2
aes256_keyschedule_ffs:
    push    {r0-r12,r14}
    sub.w   sp, #56                 // allow space on the stack for tmp var
    ldr.w   r4, [r1]                // load the 128 first key bits in r4-r7
    ldr     r5, [r1, #4]
    ldr     r6, [r1, #8]
    ldr     r7, [r1, #12]
    ldr.w   r8, [r1]                // load the 128 first key bits in r8-r11
    ldr     r9, [r1, #4]
    ldr     r10,[r1, #8]
    ldr     r11,[r1, #12]
    bl      packing                 // pack the master key
    ldrd    r0,r1, [sp, #56]        // restore 'rkeys' and 'key' addresses
    stm     r0, {r4-r11}            // store the packed master key in 'rkeys'
    add.w   r1, #16                 // points to the 128 last bits of the key
    ldr.w   r4, [r1]                // load the 128 first key bits in r4-r7
    ldr     r5, [r1, #4]
    ldr     r6, [r1, #8]
    ldr     r7, [r1, #12]
    ldr.w   r8, [r1]                // load the 128 first key bits in r8-r11
    ldr     r9, [r1, #4]
    ldr     r10,[r1, #8]
    ldr     r11,[r1, #12]
    bl      packing                 // pack the master key
    ldr.w   r0, [sp, #56]           // restore 'rkeys' address
    add.w   r0, #32                 // points to the 128 last bits of the key
    stm     r0, {r4-r11}            // store the packed master key in 'rkeys'
    bl      sbox                    // apply the sbox to the master key
    eor     r11, r11, #0x00000300   // add the 1st rconst
    bl      aes256_xorcolumns_rotword
    bl      sbox                    // apply the sbox to the master key
    bl      aes256_xorcolumns
    bl      inv_shiftrows_1
    bl      sbox                    // apply the sbox to the master key
    eor     r2, r2, #0x00000300     // add the 2nd rconst
    bl      aes256_xorcolumns_rotword
    bl      inv_shiftrows_2
    bl      sbox                    // apply the sbox to the master key
    bl      aes256_xorcolumns
    bl      inv_shiftrows_3
    bl      sbox                    // apply the sbox to the master key
    eor     r0, r0, #0x00000300     // add the 3rd rconst
    bl      aes256_xorcolumns_rotword
    bl      sbox                    // apply the sbox to the master key
    bl      aes256_xorcolumns
    bl      inv_shiftrows_1
    bl      sbox                    // apply the sbox to the master key
    eor     r8, r8, #0x00000300     // add the 4th rconst
    bl      aes256_xorcolumns_rotword
    bl      inv_shiftrows_2
    bl      sbox                    // apply the sbox to the master key
    bl      aes256_xorcolumns
    bl      inv_shiftrows_3
    bl      sbox                    // apply the sbox to the master key
    eor     r7, r7, #0x00000300     // add the 5th rconst
    bl      aes256_xorcolumns_rotword
    bl      sbox                    // apply the sbox to the master key
    bl      aes256_xorcolumns
    bl      inv_shiftrows_1
    bl      sbox                    // apply the sbox to the master key
    eor     r6, r6, #0x00000300     // add the 6th rconst
    bl      aes256_xorcolumns_rotword
    bl      inv_shiftrows_2
    bl      sbox                    // apply the sbox to the master key
    bl      aes256_xorcolumns
    bl      inv_shiftrows_3
    bl      sbox                    // apply the sbox to the master key
    eor     r3, r3, #0x00000300     // add the 6th rconst
    bl      aes256_xorcolumns_rotword
    add     r12, #32
    bl      inv_shiftrows_1
    mvn     r5, r5                  // add the NOT for the last rkey
    mvn     r6, r6                  // add the NOT for the last rkey
    mvn     r10, r10                // add the NOT for the last rkey
    mvn     r11, r11                // add the NOT for the last rkey
    ldrd    r0, r1, [r12, #-28]
    ldrd    r2, r3, [r12, #-8]
    strd    r5, r6, [r12, #4]
    strd    r10, r11, [r12, #24]
    mvn     r0, r0                  // add the NOT for the penultimate rkey
    mvn     r1, r1                  // add the NOT for the penultimate rkey
    mvn     r2, r2                  // add the NOT for the penultimate rkey
    mvn     r3, r3                  // add the NOT for the penultimate rkey
    ldrd    r5, r6, [r12, #-444]
    ldrd    r10, r11, [r12, #-424]
    strd    r0, r1, [r12, #-28]
    strd    r2, r3, [r12, #-8]
    mvn     r5, r5                  // remove the NOT for the key whitening
    mvn     r6, r6                  // remove the NOT for the key whitening
    mvn     r10, r10                // remove the NOT for the key whitening
    mvn     r11, r11                // remove the NOT for the key whitening
    strd    r5, r6, [r12, #-444]
    strd    r10, r11, [r12, #-424]
    add.w   sp, #56                 // restore stack
    pop     {r0-r12, r14}           // restore context
    bx      lr
The diff you're trying to view is too large. Only the first 1000 changed files have been loaded.
Showing with 0 additions and 0 deletions (0 / 0 diffs computed)
swh spinner

Computing file changes ...

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Contact— JavaScript license information— Web API

back to top