aes-cipher-core.S 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. .text
  13. .align 5
  14. rk .req r0
  15. rounds .req r1
  16. in .req r2
  17. out .req r3
  18. ttab .req ip
  19. t0 .req lr
  20. t1 .req r2
  21. t2 .req r3
  22. .macro __select, out, in, idx
  23. .if __LINUX_ARM_ARCH__ < 7
  24. and \out, \in, #0xff << (8 * \idx)
  25. .else
  26. ubfx \out, \in, #(8 * \idx), #8
  27. .endif
  28. .endm
  29. .macro __load, out, in, idx
  30. .if __LINUX_ARM_ARCH__ < 7 && \idx > 0
  31. ldr \out, [ttab, \in, lsr #(8 * \idx) - 2]
  32. .else
  33. ldr \out, [ttab, \in, lsl #2]
  34. .endif
  35. .endm
  36. .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc
  37. __select \out0, \in0, 0
  38. __select t0, \in1, 1
  39. __load \out0, \out0, 0
  40. __load t0, t0, 1
  41. .if \enc
  42. __select \out1, \in1, 0
  43. __select t1, \in2, 1
  44. .else
  45. __select \out1, \in3, 0
  46. __select t1, \in0, 1
  47. .endif
  48. __load \out1, \out1, 0
  49. __select t2, \in2, 2
  50. __load t1, t1, 1
  51. __load t2, t2, 2
  52. eor \out0, \out0, t0, ror #24
  53. __select t0, \in3, 3
  54. .if \enc
  55. __select \t3, \in3, 2
  56. __select \t4, \in0, 3
  57. .else
  58. __select \t3, \in1, 2
  59. __select \t4, \in2, 3
  60. .endif
  61. __load \t3, \t3, 2
  62. __load t0, t0, 3
  63. __load \t4, \t4, 3
  64. eor \out1, \out1, t1, ror #24
  65. eor \out0, \out0, t2, ror #16
  66. ldm rk!, {t1, t2}
  67. eor \out1, \out1, \t3, ror #16
  68. eor \out0, \out0, t0, ror #8
  69. eor \out1, \out1, \t4, ror #8
  70. eor \out0, \out0, t1
  71. eor \out1, \out1, t2
  72. .endm
  73. .macro fround, out0, out1, out2, out3, in0, in1, in2, in3
  74. __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1
  75. __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1
  76. .endm
  77. .macro iround, out0, out1, out2, out3, in0, in1, in2, in3
  78. __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0
  79. __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0
  80. .endm
  81. .macro __rev, out, in
  82. .if __LINUX_ARM_ARCH__ < 6
  83. lsl t0, \in, #24
  84. and t1, \in, #0xff00
  85. and t2, \in, #0xff0000
  86. orr \out, t0, \in, lsr #24
  87. orr \out, \out, t1, lsl #8
  88. orr \out, \out, t2, lsr #8
  89. .else
  90. rev \out, \in
  91. .endif
  92. .endm
  93. .macro __adrl, out, sym, c
  94. .if __LINUX_ARM_ARCH__ < 7
  95. ldr\c \out, =\sym
  96. .else
  97. movw\c \out, #:lower16:\sym
  98. movt\c \out, #:upper16:\sym
  99. .endif
  100. .endm
  101. .macro do_crypt, round, ttab, ltab
  102. push {r3-r11, lr}
  103. ldr r4, [in]
  104. ldr r5, [in, #4]
  105. ldr r6, [in, #8]
  106. ldr r7, [in, #12]
  107. ldm rk!, {r8-r11}
  108. #ifdef CONFIG_CPU_BIG_ENDIAN
  109. __rev r4, r4
  110. __rev r5, r5
  111. __rev r6, r6
  112. __rev r7, r7
  113. #endif
  114. eor r4, r4, r8
  115. eor r5, r5, r9
  116. eor r6, r6, r10
  117. eor r7, r7, r11
  118. __adrl ttab, \ttab
  119. tst rounds, #2
  120. bne 1f
  121. 0: \round r8, r9, r10, r11, r4, r5, r6, r7
  122. \round r4, r5, r6, r7, r8, r9, r10, r11
  123. 1: subs rounds, rounds, #4
  124. \round r8, r9, r10, r11, r4, r5, r6, r7
  125. __adrl ttab, \ltab, ls
  126. \round r4, r5, r6, r7, r8, r9, r10, r11
  127. bhi 0b
  128. #ifdef CONFIG_CPU_BIG_ENDIAN
  129. __rev r4, r4
  130. __rev r5, r5
  131. __rev r6, r6
  132. __rev r7, r7
  133. #endif
  134. ldr out, [sp]
  135. str r4, [out]
  136. str r5, [out, #4]
  137. str r6, [out, #8]
  138. str r7, [out, #12]
  139. pop {r3-r11, pc}
  140. .align 3
  141. .ltorg
  142. .endm
  143. ENTRY(__aes_arm_encrypt)
  144. do_crypt fround, crypto_ft_tab, crypto_fl_tab
  145. ENDPROC(__aes_arm_encrypt)
  146. ENTRY(__aes_arm_decrypt)
  147. do_crypt iround, crypto_it_tab, crypto_il_tab
  148. ENDPROC(__aes_arm_decrypt)