sm4-ce-ccm-core.S 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * SM4-CCM AEAD Algorithm using ARMv8 Crypto Extensions
  4. * as specified in rfc8998
  5. * https://datatracker.ietf.org/doc/html/rfc8998
  6. *
  7. * Copyright (C) 2022 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
  8. */
  9. #include <linux/linkage.h>
  10. #include <linux/cfi_types.h>
  11. #include <asm/assembler.h>
  12. #include "sm4-ce-asm.h"
  13. .arch armv8-a+crypto
  14. .irp b, 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 25, 26, 27, 28, 29, 30, 31
  15. .set .Lv\b\().4s, \b
  16. .endr
  17. .macro sm4e, vd, vn
  18. .inst 0xcec08400 | (.L\vn << 5) | .L\vd
  19. .endm
  20. /* Register macros */
  21. #define RMAC v16
  22. /* Helper macros. */
  23. #define inc_le128(vctr) \
  24. mov vctr.d[1], x8; \
  25. mov vctr.d[0], x7; \
  26. adds x8, x8, #1; \
  27. rev64 vctr.16b, vctr.16b; \
  28. adc x7, x7, xzr;
  29. .align 3
  30. SYM_FUNC_START(sm4_ce_cbcmac_update)
  31. /* input:
  32. * x0: round key array, CTX
  33. * x1: mac
  34. * x2: src
  35. * w3: nblocks
  36. */
  37. SM4_PREPARE(x0)
  38. ld1 {RMAC.16b}, [x1]
  39. .Lcbcmac_loop_4x:
  40. cmp w3, #4
  41. blt .Lcbcmac_loop_1x
  42. sub w3, w3, #4
  43. ld1 {v0.16b-v3.16b}, [x2], #64
  44. SM4_CRYPT_BLK(RMAC)
  45. eor RMAC.16b, RMAC.16b, v0.16b
  46. SM4_CRYPT_BLK(RMAC)
  47. eor RMAC.16b, RMAC.16b, v1.16b
  48. SM4_CRYPT_BLK(RMAC)
  49. eor RMAC.16b, RMAC.16b, v2.16b
  50. SM4_CRYPT_BLK(RMAC)
  51. eor RMAC.16b, RMAC.16b, v3.16b
  52. cbz w3, .Lcbcmac_end
  53. b .Lcbcmac_loop_4x
  54. .Lcbcmac_loop_1x:
  55. sub w3, w3, #1
  56. ld1 {v0.16b}, [x2], #16
  57. SM4_CRYPT_BLK(RMAC)
  58. eor RMAC.16b, RMAC.16b, v0.16b
  59. cbnz w3, .Lcbcmac_loop_1x
  60. .Lcbcmac_end:
  61. st1 {RMAC.16b}, [x1]
  62. ret
  63. SYM_FUNC_END(sm4_ce_cbcmac_update)
  64. .align 3
  65. SYM_FUNC_START(sm4_ce_ccm_final)
  66. /* input:
  67. * x0: round key array, CTX
  68. * x1: ctr0 (big endian, 128 bit)
  69. * x2: mac
  70. */
  71. SM4_PREPARE(x0)
  72. ld1 {RMAC.16b}, [x2]
  73. ld1 {v0.16b}, [x1]
  74. SM4_CRYPT_BLK2(RMAC, v0)
  75. /* en-/decrypt the mac with ctr0 */
  76. eor RMAC.16b, RMAC.16b, v0.16b
  77. st1 {RMAC.16b}, [x2]
  78. ret
  79. SYM_FUNC_END(sm4_ce_ccm_final)
  80. .align 3
  81. SYM_TYPED_FUNC_START(sm4_ce_ccm_enc)
  82. /* input:
  83. * x0: round key array, CTX
  84. * x1: dst
  85. * x2: src
  86. * x3: ctr (big endian, 128 bit)
  87. * w4: nbytes
  88. * x5: mac
  89. */
  90. SM4_PREPARE(x0)
  91. ldp x7, x8, [x3]
  92. rev x7, x7
  93. rev x8, x8
  94. ld1 {RMAC.16b}, [x5]
  95. .Lccm_enc_loop_4x:
  96. cmp w4, #(4 * 16)
  97. blt .Lccm_enc_loop_1x
  98. sub w4, w4, #(4 * 16)
  99. /* construct CTRs */
  100. inc_le128(v8) /* +0 */
  101. inc_le128(v9) /* +1 */
  102. inc_le128(v10) /* +2 */
  103. inc_le128(v11) /* +3 */
  104. ld1 {v0.16b-v3.16b}, [x2], #64
  105. SM4_CRYPT_BLK2(v8, RMAC)
  106. eor v8.16b, v8.16b, v0.16b
  107. eor RMAC.16b, RMAC.16b, v0.16b
  108. SM4_CRYPT_BLK2(v9, RMAC)
  109. eor v9.16b, v9.16b, v1.16b
  110. eor RMAC.16b, RMAC.16b, v1.16b
  111. SM4_CRYPT_BLK2(v10, RMAC)
  112. eor v10.16b, v10.16b, v2.16b
  113. eor RMAC.16b, RMAC.16b, v2.16b
  114. SM4_CRYPT_BLK2(v11, RMAC)
  115. eor v11.16b, v11.16b, v3.16b
  116. eor RMAC.16b, RMAC.16b, v3.16b
  117. st1 {v8.16b-v11.16b}, [x1], #64
  118. cbz w4, .Lccm_enc_end
  119. b .Lccm_enc_loop_4x
  120. .Lccm_enc_loop_1x:
  121. cmp w4, #16
  122. blt .Lccm_enc_tail
  123. sub w4, w4, #16
  124. /* construct CTRs */
  125. inc_le128(v8)
  126. ld1 {v0.16b}, [x2], #16
  127. SM4_CRYPT_BLK2(v8, RMAC)
  128. eor v8.16b, v8.16b, v0.16b
  129. eor RMAC.16b, RMAC.16b, v0.16b
  130. st1 {v8.16b}, [x1], #16
  131. cbz w4, .Lccm_enc_end
  132. b .Lccm_enc_loop_1x
  133. .Lccm_enc_tail:
  134. /* construct CTRs */
  135. inc_le128(v8)
  136. SM4_CRYPT_BLK2(RMAC, v8)
  137. /* store new MAC */
  138. st1 {RMAC.16b}, [x5]
  139. .Lccm_enc_tail_loop:
  140. ldrb w0, [x2], #1 /* get 1 byte from input */
  141. umov w9, v8.b[0] /* get top crypted CTR byte */
  142. umov w6, RMAC.b[0] /* get top MAC byte */
  143. eor w9, w9, w0 /* w9 = CTR ^ input */
  144. eor w6, w6, w0 /* w6 = MAC ^ input */
  145. strb w9, [x1], #1 /* store out byte */
  146. strb w6, [x5], #1 /* store MAC byte */
  147. subs w4, w4, #1
  148. beq .Lccm_enc_ret
  149. /* shift out one byte */
  150. ext RMAC.16b, RMAC.16b, RMAC.16b, #1
  151. ext v8.16b, v8.16b, v8.16b, #1
  152. b .Lccm_enc_tail_loop
  153. .Lccm_enc_end:
  154. /* store new MAC */
  155. st1 {RMAC.16b}, [x5]
  156. /* store new CTR */
  157. rev x7, x7
  158. rev x8, x8
  159. stp x7, x8, [x3]
  160. .Lccm_enc_ret:
  161. ret
  162. SYM_FUNC_END(sm4_ce_ccm_enc)
  163. .align 3
  164. SYM_TYPED_FUNC_START(sm4_ce_ccm_dec)
  165. /* input:
  166. * x0: round key array, CTX
  167. * x1: dst
  168. * x2: src
  169. * x3: ctr (big endian, 128 bit)
  170. * w4: nbytes
  171. * x5: mac
  172. */
  173. SM4_PREPARE(x0)
  174. ldp x7, x8, [x3]
  175. rev x7, x7
  176. rev x8, x8
  177. ld1 {RMAC.16b}, [x5]
  178. .Lccm_dec_loop_4x:
  179. cmp w4, #(4 * 16)
  180. blt .Lccm_dec_loop_1x
  181. sub w4, w4, #(4 * 16)
  182. /* construct CTRs */
  183. inc_le128(v8) /* +0 */
  184. inc_le128(v9) /* +1 */
  185. inc_le128(v10) /* +2 */
  186. inc_le128(v11) /* +3 */
  187. ld1 {v0.16b-v3.16b}, [x2], #64
  188. SM4_CRYPT_BLK2(v8, RMAC)
  189. eor v8.16b, v8.16b, v0.16b
  190. eor RMAC.16b, RMAC.16b, v8.16b
  191. SM4_CRYPT_BLK2(v9, RMAC)
  192. eor v9.16b, v9.16b, v1.16b
  193. eor RMAC.16b, RMAC.16b, v9.16b
  194. SM4_CRYPT_BLK2(v10, RMAC)
  195. eor v10.16b, v10.16b, v2.16b
  196. eor RMAC.16b, RMAC.16b, v10.16b
  197. SM4_CRYPT_BLK2(v11, RMAC)
  198. eor v11.16b, v11.16b, v3.16b
  199. eor RMAC.16b, RMAC.16b, v11.16b
  200. st1 {v8.16b-v11.16b}, [x1], #64
  201. cbz w4, .Lccm_dec_end
  202. b .Lccm_dec_loop_4x
  203. .Lccm_dec_loop_1x:
  204. cmp w4, #16
  205. blt .Lccm_dec_tail
  206. sub w4, w4, #16
  207. /* construct CTRs */
  208. inc_le128(v8)
  209. ld1 {v0.16b}, [x2], #16
  210. SM4_CRYPT_BLK2(v8, RMAC)
  211. eor v8.16b, v8.16b, v0.16b
  212. eor RMAC.16b, RMAC.16b, v8.16b
  213. st1 {v8.16b}, [x1], #16
  214. cbz w4, .Lccm_dec_end
  215. b .Lccm_dec_loop_1x
  216. .Lccm_dec_tail:
  217. /* construct CTRs */
  218. inc_le128(v8)
  219. SM4_CRYPT_BLK2(RMAC, v8)
  220. /* store new MAC */
  221. st1 {RMAC.16b}, [x5]
  222. .Lccm_dec_tail_loop:
  223. ldrb w0, [x2], #1 /* get 1 byte from input */
  224. umov w9, v8.b[0] /* get top crypted CTR byte */
  225. umov w6, RMAC.b[0] /* get top MAC byte */
  226. eor w9, w9, w0 /* w9 = CTR ^ input */
  227. eor w6, w6, w9 /* w6 = MAC ^ output */
  228. strb w9, [x1], #1 /* store out byte */
  229. strb w6, [x5], #1 /* store MAC byte */
  230. subs w4, w4, #1
  231. beq .Lccm_dec_ret
  232. /* shift out one byte */
  233. ext RMAC.16b, RMAC.16b, RMAC.16b, #1
  234. ext v8.16b, v8.16b, v8.16b, #1
  235. b .Lccm_dec_tail_loop
  236. .Lccm_dec_end:
  237. /* store new MAC */
  238. st1 {RMAC.16b}, [x5]
  239. /* store new CTR */
  240. rev x7, x7
  241. rev x8, x8
  242. stp x7, x8, [x3]
  243. .Lccm_dec_ret:
  244. ret
  245. SYM_FUNC_END(sm4_ce_ccm_dec)