aes-cipher-core.S 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Scalar AES core transform
  3. *
  4. * Copyright (C) 2017 Linaro Ltd.
  5. * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/linkage.h>
  12. #include <asm/cache.h>
  13. .text
  14. .align 5
  15. rk .req r0
  16. rounds .req r1
  17. in .req r2
  18. out .req r3
  19. ttab .req ip
  20. t0 .req lr
  21. t1 .req r2
  22. t2 .req r3
  23. .macro __select, out, in, idx
  24. .if __LINUX_ARM_ARCH__ < 7
  25. and \out, \in, #0xff << (8 * \idx)
  26. .else
  27. ubfx \out, \in, #(8 * \idx), #8
  28. .endif
  29. .endm
  30. .macro __load, out, in, idx, sz, op
  31. .if __LINUX_ARM_ARCH__ < 7 && \idx > 0
  32. ldr\op \out, [ttab, \in, lsr #(8 * \idx) - \sz]
  33. .else
  34. ldr\op \out, [ttab, \in, lsl #\sz]
  35. .endif
  36. .endm
  37. .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op
  38. __select \out0, \in0, 0
  39. __select t0, \in1, 1
  40. __load \out0, \out0, 0, \sz, \op
  41. __load t0, t0, 1, \sz, \op
  42. .if \enc
  43. __select \out1, \in1, 0
  44. __select t1, \in2, 1
  45. .else
  46. __select \out1, \in3, 0
  47. __select t1, \in0, 1
  48. .endif
  49. __load \out1, \out1, 0, \sz, \op
  50. __select t2, \in2, 2
  51. __load t1, t1, 1, \sz, \op
  52. __load t2, t2, 2, \sz, \op
  53. eor \out0, \out0, t0, ror #24
  54. __select t0, \in3, 3
  55. .if \enc
  56. __select \t3, \in3, 2
  57. __select \t4, \in0, 3
  58. .else
  59. __select \t3, \in1, 2
  60. __select \t4, \in2, 3
  61. .endif
  62. __load \t3, \t3, 2, \sz, \op
  63. __load t0, t0, 3, \sz, \op
  64. __load \t4, \t4, 3, \sz, \op
  65. eor \out1, \out1, t1, ror #24
  66. eor \out0, \out0, t2, ror #16
  67. ldm rk!, {t1, t2}
  68. eor \out1, \out1, \t3, ror #16
  69. eor \out0, \out0, t0, ror #8
  70. eor \out1, \out1, \t4, ror #8
  71. eor \out0, \out0, t1
  72. eor \out1, \out1, t2
  73. .endm
  74. .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op
  75. __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op
  76. __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op
  77. .endm
  78. .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op
  79. __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op
  80. __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op
  81. .endm
  82. .macro __rev, out, in
  83. .if __LINUX_ARM_ARCH__ < 6
  84. lsl t0, \in, #24
  85. and t1, \in, #0xff00
  86. and t2, \in, #0xff0000
  87. orr \out, t0, \in, lsr #24
  88. orr \out, \out, t1, lsl #8
  89. orr \out, \out, t2, lsr #8
  90. .else
  91. rev \out, \in
  92. .endif
  93. .endm
  94. .macro __adrl, out, sym, c
  95. .if __LINUX_ARM_ARCH__ < 7
  96. ldr\c \out, =\sym
  97. .else
  98. movw\c \out, #:lower16:\sym
  99. movt\c \out, #:upper16:\sym
  100. .endif
  101. .endm
  102. .macro do_crypt, round, ttab, ltab, bsz
  103. push {r3-r11, lr}
  104. ldr r4, [in]
  105. ldr r5, [in, #4]
  106. ldr r6, [in, #8]
  107. ldr r7, [in, #12]
  108. ldm rk!, {r8-r11}
  109. #ifdef CONFIG_CPU_BIG_ENDIAN
  110. __rev r4, r4
  111. __rev r5, r5
  112. __rev r6, r6
  113. __rev r7, r7
  114. #endif
  115. eor r4, r4, r8
  116. eor r5, r5, r9
  117. eor r6, r6, r10
  118. eor r7, r7, r11
  119. __adrl ttab, \ttab
  120. tst rounds, #2
  121. bne 1f
  122. 0: \round r8, r9, r10, r11, r4, r5, r6, r7
  123. \round r4, r5, r6, r7, r8, r9, r10, r11
  124. 1: subs rounds, rounds, #4
  125. \round r8, r9, r10, r11, r4, r5, r6, r7
  126. bls 2f
  127. \round r4, r5, r6, r7, r8, r9, r10, r11
  128. b 0b
  129. 2: __adrl ttab, \ltab
  130. \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b
  131. #ifdef CONFIG_CPU_BIG_ENDIAN
  132. __rev r4, r4
  133. __rev r5, r5
  134. __rev r6, r6
  135. __rev r7, r7
  136. #endif
  137. ldr out, [sp]
  138. str r4, [out]
  139. str r5, [out, #4]
  140. str r6, [out, #8]
  141. str r7, [out, #12]
  142. pop {r3-r11, pc}
  143. .align 3
  144. .ltorg
  145. .endm
  146. ENTRY(__aes_arm_encrypt)
  147. do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2
  148. ENDPROC(__aes_arm_encrypt)
  149. .align 5
  150. ENTRY(__aes_arm_decrypt)
  151. do_crypt iround, crypto_it_tab, __aes_arm_inverse_sbox, 0
  152. ENDPROC(__aes_arm_decrypt)
  153. .section ".rodata", "a"
  154. .align L1_CACHE_SHIFT
  155. .type __aes_arm_inverse_sbox, %object
  156. __aes_arm_inverse_sbox:
  157. .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
  158. .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
  159. .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
  160. .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
  161. .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
  162. .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
  163. .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
  164. .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
  165. .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
  166. .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
  167. .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
  168. .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
  169. .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
  170. .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
  171. .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
  172. .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
  173. .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
  174. .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
  175. .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
  176. .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
  177. .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
  178. .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
  179. .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
  180. .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
  181. .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
  182. .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
  183. .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
  184. .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
  185. .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
  186. .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
  187. .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
  188. .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
  189. .size __aes_arm_inverse_sbox, . - __aes_arm_inverse_sbox