aes-modes.S 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*
  2. * linux/arch/arm64/crypto/aes-modes.S - chaining mode wrappers for AES
  3. *
  4. * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. /* included by aes-ce.S and aes-neon.S */
  11. .text
  12. .align 4
  13. aes_encrypt_block4x:
  14. encrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
  15. ret
  16. ENDPROC(aes_encrypt_block4x)
  17. aes_decrypt_block4x:
  18. decrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
  19. ret
  20. ENDPROC(aes_decrypt_block4x)
  21. /*
  22. * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  23. * int blocks)
  24. * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  25. * int blocks)
  26. */
  27. AES_ENTRY(aes_ecb_encrypt)
  28. stp x29, x30, [sp, #-16]!
  29. mov x29, sp
  30. enc_prepare w3, x2, x5
  31. .LecbencloopNx:
  32. subs w4, w4, #4
  33. bmi .Lecbenc1x
  34. ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35. bl aes_encrypt_block4x
  36. st1 {v0.16b-v3.16b}, [x0], #64
  37. b .LecbencloopNx
  38. .Lecbenc1x:
  39. adds w4, w4, #4
  40. beq .Lecbencout
  41. .Lecbencloop:
  42. ld1 {v0.16b}, [x1], #16 /* get next pt block */
  43. encrypt_block v0, w3, x2, x5, w6
  44. st1 {v0.16b}, [x0], #16
  45. subs w4, w4, #1
  46. bne .Lecbencloop
  47. .Lecbencout:
  48. ldp x29, x30, [sp], #16
  49. ret
  50. AES_ENDPROC(aes_ecb_encrypt)
  51. AES_ENTRY(aes_ecb_decrypt)
  52. stp x29, x30, [sp, #-16]!
  53. mov x29, sp
  54. dec_prepare w3, x2, x5
  55. .LecbdecloopNx:
  56. subs w4, w4, #4
  57. bmi .Lecbdec1x
  58. ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  59. bl aes_decrypt_block4x
  60. st1 {v0.16b-v3.16b}, [x0], #64
  61. b .LecbdecloopNx
  62. .Lecbdec1x:
  63. adds w4, w4, #4
  64. beq .Lecbdecout
  65. .Lecbdecloop:
  66. ld1 {v0.16b}, [x1], #16 /* get next ct block */
  67. decrypt_block v0, w3, x2, x5, w6
  68. st1 {v0.16b}, [x0], #16
  69. subs w4, w4, #1
  70. bne .Lecbdecloop
  71. .Lecbdecout:
  72. ldp x29, x30, [sp], #16
  73. ret
  74. AES_ENDPROC(aes_ecb_decrypt)
  75. /*
  76. * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  77. * int blocks, u8 iv[])
  78. * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  79. * int blocks, u8 iv[])
  80. */
  81. AES_ENTRY(aes_cbc_encrypt)
  82. ld1 {v4.16b}, [x5] /* get iv */
  83. enc_prepare w3, x2, x6
  84. .Lcbcencloop4x:
  85. subs w4, w4, #4
  86. bmi .Lcbcenc1x
  87. ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  88. eor v0.16b, v0.16b, v4.16b /* ..and xor with iv */
  89. encrypt_block v0, w3, x2, x6, w7
  90. eor v1.16b, v1.16b, v0.16b
  91. encrypt_block v1, w3, x2, x6, w7
  92. eor v2.16b, v2.16b, v1.16b
  93. encrypt_block v2, w3, x2, x6, w7
  94. eor v3.16b, v3.16b, v2.16b
  95. encrypt_block v3, w3, x2, x6, w7
  96. st1 {v0.16b-v3.16b}, [x0], #64
  97. mov v4.16b, v3.16b
  98. b .Lcbcencloop4x
  99. .Lcbcenc1x:
  100. adds w4, w4, #4
  101. beq .Lcbcencout
  102. .Lcbcencloop:
  103. ld1 {v0.16b}, [x1], #16 /* get next pt block */
  104. eor v4.16b, v4.16b, v0.16b /* ..and xor with iv */
  105. encrypt_block v4, w3, x2, x6, w7
  106. st1 {v4.16b}, [x0], #16
  107. subs w4, w4, #1
  108. bne .Lcbcencloop
  109. .Lcbcencout:
  110. st1 {v4.16b}, [x5] /* return iv */
  111. ret
  112. AES_ENDPROC(aes_cbc_encrypt)
  113. AES_ENTRY(aes_cbc_decrypt)
  114. stp x29, x30, [sp, #-16]!
  115. mov x29, sp
  116. ld1 {v7.16b}, [x5] /* get iv */
  117. dec_prepare w3, x2, x6
  118. .LcbcdecloopNx:
  119. subs w4, w4, #4
  120. bmi .Lcbcdec1x
  121. ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  122. mov v4.16b, v0.16b
  123. mov v5.16b, v1.16b
  124. mov v6.16b, v2.16b
  125. bl aes_decrypt_block4x
  126. sub x1, x1, #16
  127. eor v0.16b, v0.16b, v7.16b
  128. eor v1.16b, v1.16b, v4.16b
  129. ld1 {v7.16b}, [x1], #16 /* reload 1 ct block */
  130. eor v2.16b, v2.16b, v5.16b
  131. eor v3.16b, v3.16b, v6.16b
  132. st1 {v0.16b-v3.16b}, [x0], #64
  133. b .LcbcdecloopNx
  134. .Lcbcdec1x:
  135. adds w4, w4, #4
  136. beq .Lcbcdecout
  137. .Lcbcdecloop:
  138. ld1 {v1.16b}, [x1], #16 /* get next ct block */
  139. mov v0.16b, v1.16b /* ...and copy to v0 */
  140. decrypt_block v0, w3, x2, x6, w7
  141. eor v0.16b, v0.16b, v7.16b /* xor with iv => pt */
  142. mov v7.16b, v1.16b /* ct is next iv */
  143. st1 {v0.16b}, [x0], #16
  144. subs w4, w4, #1
  145. bne .Lcbcdecloop
  146. .Lcbcdecout:
  147. st1 {v7.16b}, [x5] /* return iv */
  148. ldp x29, x30, [sp], #16
  149. ret
  150. AES_ENDPROC(aes_cbc_decrypt)
  151. /*
  152. * aes_cbc_cts_encrypt(u8 out[], u8 const in[], u32 const rk[],
  153. * int rounds, int bytes, u8 const iv[])
  154. * aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
  155. * int rounds, int bytes, u8 const iv[])
  156. */
  157. AES_ENTRY(aes_cbc_cts_encrypt)
  158. adr_l x8, .Lcts_permute_table
  159. sub x4, x4, #16
  160. add x9, x8, #32
  161. add x8, x8, x4
  162. sub x9, x9, x4
  163. ld1 {v3.16b}, [x8]
  164. ld1 {v4.16b}, [x9]
  165. ld1 {v0.16b}, [x1], x4 /* overlapping loads */
  166. ld1 {v1.16b}, [x1]
  167. ld1 {v5.16b}, [x5] /* get iv */
  168. enc_prepare w3, x2, x6
  169. eor v0.16b, v0.16b, v5.16b /* xor with iv */
  170. tbl v1.16b, {v1.16b}, v4.16b
  171. encrypt_block v0, w3, x2, x6, w7
  172. eor v1.16b, v1.16b, v0.16b
  173. tbl v0.16b, {v0.16b}, v3.16b
  174. encrypt_block v1, w3, x2, x6, w7
  175. add x4, x0, x4
  176. st1 {v0.16b}, [x4] /* overlapping stores */
  177. st1 {v1.16b}, [x0]
  178. ret
  179. AES_ENDPROC(aes_cbc_cts_encrypt)
  180. AES_ENTRY(aes_cbc_cts_decrypt)
  181. adr_l x8, .Lcts_permute_table
  182. sub x4, x4, #16
  183. add x9, x8, #32
  184. add x8, x8, x4
  185. sub x9, x9, x4
  186. ld1 {v3.16b}, [x8]
  187. ld1 {v4.16b}, [x9]
  188. ld1 {v0.16b}, [x1], x4 /* overlapping loads */
  189. ld1 {v1.16b}, [x1]
  190. ld1 {v5.16b}, [x5] /* get iv */
  191. dec_prepare w3, x2, x6
  192. tbl v2.16b, {v1.16b}, v4.16b
  193. decrypt_block v0, w3, x2, x6, w7
  194. eor v2.16b, v2.16b, v0.16b
  195. tbx v0.16b, {v1.16b}, v4.16b
  196. tbl v2.16b, {v2.16b}, v3.16b
  197. decrypt_block v0, w3, x2, x6, w7
  198. eor v0.16b, v0.16b, v5.16b /* xor with iv */
  199. add x4, x0, x4
  200. st1 {v2.16b}, [x4] /* overlapping stores */
  201. st1 {v0.16b}, [x0]
  202. ret
  203. AES_ENDPROC(aes_cbc_cts_decrypt)
  204. .section ".rodata", "a"
  205. .align 6
  206. .Lcts_permute_table:
  207. .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  208. .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  209. .byte 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
  210. .byte 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
  211. .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  212. .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  213. .previous
  214. /*
  215. * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  216. * int blocks, u8 ctr[])
  217. */
  218. AES_ENTRY(aes_ctr_encrypt)
  219. stp x29, x30, [sp, #-16]!
  220. mov x29, sp
  221. enc_prepare w3, x2, x6
  222. ld1 {v4.16b}, [x5]
  223. umov x6, v4.d[1] /* keep swabbed ctr in reg */
  224. rev x6, x6
  225. cmn w6, w4 /* 32 bit overflow? */
  226. bcs .Lctrloop
  227. .LctrloopNx:
  228. subs w4, w4, #4
  229. bmi .Lctr1x
  230. add w7, w6, #1
  231. mov v0.16b, v4.16b
  232. add w8, w6, #2
  233. mov v1.16b, v4.16b
  234. add w9, w6, #3
  235. mov v2.16b, v4.16b
  236. rev w7, w7
  237. mov v3.16b, v4.16b
  238. rev w8, w8
  239. mov v1.s[3], w7
  240. rev w9, w9
  241. mov v2.s[3], w8
  242. mov v3.s[3], w9
  243. ld1 {v5.16b-v7.16b}, [x1], #48 /* get 3 input blocks */
  244. bl aes_encrypt_block4x
  245. eor v0.16b, v5.16b, v0.16b
  246. ld1 {v5.16b}, [x1], #16 /* get 1 input block */
  247. eor v1.16b, v6.16b, v1.16b
  248. eor v2.16b, v7.16b, v2.16b
  249. eor v3.16b, v5.16b, v3.16b
  250. st1 {v0.16b-v3.16b}, [x0], #64
  251. add x6, x6, #4
  252. rev x7, x6
  253. ins v4.d[1], x7
  254. cbz w4, .Lctrout
  255. b .LctrloopNx
  256. .Lctr1x:
  257. adds w4, w4, #4
  258. beq .Lctrout
  259. .Lctrloop:
  260. mov v0.16b, v4.16b
  261. encrypt_block v0, w3, x2, x8, w7
  262. adds x6, x6, #1 /* increment BE ctr */
  263. rev x7, x6
  264. ins v4.d[1], x7
  265. bcs .Lctrcarry /* overflow? */
  266. .Lctrcarrydone:
  267. subs w4, w4, #1
  268. bmi .Lctrtailblock /* blocks <0 means tail block */
  269. ld1 {v3.16b}, [x1], #16
  270. eor v3.16b, v0.16b, v3.16b
  271. st1 {v3.16b}, [x0], #16
  272. bne .Lctrloop
  273. .Lctrout:
  274. st1 {v4.16b}, [x5] /* return next CTR value */
  275. ldp x29, x30, [sp], #16
  276. ret
  277. .Lctrtailblock:
  278. st1 {v0.16b}, [x0]
  279. ldp x29, x30, [sp], #16
  280. ret
  281. .Lctrcarry:
  282. umov x7, v4.d[0] /* load upper word of ctr */
  283. rev x7, x7 /* ... to handle the carry */
  284. add x7, x7, #1
  285. rev x7, x7
  286. ins v4.d[0], x7
  287. b .Lctrcarrydone
  288. AES_ENDPROC(aes_ctr_encrypt)
  289. /*
  290. * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  291. * int blocks, u8 const rk2[], u8 iv[], int first)
  292. * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  293. * int blocks, u8 const rk2[], u8 iv[], int first)
  294. */
  295. .macro next_tweak, out, in, tmp
  296. sshr \tmp\().2d, \in\().2d, #63
  297. and \tmp\().16b, \tmp\().16b, xtsmask.16b
  298. add \out\().2d, \in\().2d, \in\().2d
  299. ext \tmp\().16b, \tmp\().16b, \tmp\().16b, #8
  300. eor \out\().16b, \out\().16b, \tmp\().16b
  301. .endm
  302. .macro xts_load_mask, tmp
  303. movi xtsmask.2s, #0x1
  304. movi \tmp\().2s, #0x87
  305. uzp1 xtsmask.4s, xtsmask.4s, \tmp\().4s
  306. .endm
  307. AES_ENTRY(aes_xts_encrypt)
  308. stp x29, x30, [sp, #-16]!
  309. mov x29, sp
  310. ld1 {v4.16b}, [x6]
  311. cbz w7, .Lxtsencnotfirst
  312. enc_prepare w3, x5, x8
  313. encrypt_block v4, w3, x5, x8, w7 /* first tweak */
  314. enc_switch_key w3, x2, x8
  315. xts_load_mask v8
  316. b .LxtsencNx
  317. .Lxtsencnotfirst:
  318. enc_prepare w3, x2, x8
  319. .LxtsencloopNx:
  320. xts_reload_mask v8
  321. next_tweak v4, v4, v8
  322. .LxtsencNx:
  323. subs w4, w4, #4
  324. bmi .Lxtsenc1x
  325. ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  326. next_tweak v5, v4, v8
  327. eor v0.16b, v0.16b, v4.16b
  328. next_tweak v6, v5, v8
  329. eor v1.16b, v1.16b, v5.16b
  330. eor v2.16b, v2.16b, v6.16b
  331. next_tweak v7, v6, v8
  332. eor v3.16b, v3.16b, v7.16b
  333. bl aes_encrypt_block4x
  334. eor v3.16b, v3.16b, v7.16b
  335. eor v0.16b, v0.16b, v4.16b
  336. eor v1.16b, v1.16b, v5.16b
  337. eor v2.16b, v2.16b, v6.16b
  338. st1 {v0.16b-v3.16b}, [x0], #64
  339. mov v4.16b, v7.16b
  340. cbz w4, .Lxtsencout
  341. b .LxtsencloopNx
  342. .Lxtsenc1x:
  343. adds w4, w4, #4
  344. beq .Lxtsencout
  345. .Lxtsencloop:
  346. ld1 {v1.16b}, [x1], #16
  347. eor v0.16b, v1.16b, v4.16b
  348. encrypt_block v0, w3, x2, x8, w7
  349. eor v0.16b, v0.16b, v4.16b
  350. st1 {v0.16b}, [x0], #16
  351. subs w4, w4, #1
  352. beq .Lxtsencout
  353. next_tweak v4, v4, v8
  354. b .Lxtsencloop
  355. .Lxtsencout:
  356. st1 {v4.16b}, [x6]
  357. ldp x29, x30, [sp], #16
  358. ret
  359. AES_ENDPROC(aes_xts_encrypt)
  360. AES_ENTRY(aes_xts_decrypt)
  361. stp x29, x30, [sp, #-16]!
  362. mov x29, sp
  363. ld1 {v4.16b}, [x6]
  364. cbz w7, .Lxtsdecnotfirst
  365. enc_prepare w3, x5, x8
  366. encrypt_block v4, w3, x5, x8, w7 /* first tweak */
  367. dec_prepare w3, x2, x8
  368. xts_load_mask v8
  369. b .LxtsdecNx
  370. .Lxtsdecnotfirst:
  371. dec_prepare w3, x2, x8
  372. .LxtsdecloopNx:
  373. xts_reload_mask v8
  374. next_tweak v4, v4, v8
  375. .LxtsdecNx:
  376. subs w4, w4, #4
  377. bmi .Lxtsdec1x
  378. ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  379. next_tweak v5, v4, v8
  380. eor v0.16b, v0.16b, v4.16b
  381. next_tweak v6, v5, v8
  382. eor v1.16b, v1.16b, v5.16b
  383. eor v2.16b, v2.16b, v6.16b
  384. next_tweak v7, v6, v8
  385. eor v3.16b, v3.16b, v7.16b
  386. bl aes_decrypt_block4x
  387. eor v3.16b, v3.16b, v7.16b
  388. eor v0.16b, v0.16b, v4.16b
  389. eor v1.16b, v1.16b, v5.16b
  390. eor v2.16b, v2.16b, v6.16b
  391. st1 {v0.16b-v3.16b}, [x0], #64
  392. mov v4.16b, v7.16b
  393. cbz w4, .Lxtsdecout
  394. b .LxtsdecloopNx
  395. .Lxtsdec1x:
  396. adds w4, w4, #4
  397. beq .Lxtsdecout
  398. .Lxtsdecloop:
  399. ld1 {v1.16b}, [x1], #16
  400. eor v0.16b, v1.16b, v4.16b
  401. decrypt_block v0, w3, x2, x8, w7
  402. eor v0.16b, v0.16b, v4.16b
  403. st1 {v0.16b}, [x0], #16
  404. subs w4, w4, #1
  405. beq .Lxtsdecout
  406. next_tweak v4, v4, v8
  407. b .Lxtsdecloop
  408. .Lxtsdecout:
  409. st1 {v4.16b}, [x6]
  410. ldp x29, x30, [sp], #16
  411. ret
  412. AES_ENDPROC(aes_xts_decrypt)
  413. /*
  414. * aes_mac_update(u8 const in[], u32 const rk[], int rounds,
  415. * int blocks, u8 dg[], int enc_before, int enc_after)
  416. */
  417. AES_ENTRY(aes_mac_update)
  418. frame_push 6
  419. mov x19, x0
  420. mov x20, x1
  421. mov x21, x2
  422. mov x22, x3
  423. mov x23, x4
  424. mov x24, x6
  425. ld1 {v0.16b}, [x23] /* get dg */
  426. enc_prepare w2, x1, x7
  427. cbz w5, .Lmacloop4x
  428. encrypt_block v0, w2, x1, x7, w8
  429. .Lmacloop4x:
  430. subs w22, w22, #4
  431. bmi .Lmac1x
  432. ld1 {v1.16b-v4.16b}, [x19], #64 /* get next pt block */
  433. eor v0.16b, v0.16b, v1.16b /* ..and xor with dg */
  434. encrypt_block v0, w21, x20, x7, w8
  435. eor v0.16b, v0.16b, v2.16b
  436. encrypt_block v0, w21, x20, x7, w8
  437. eor v0.16b, v0.16b, v3.16b
  438. encrypt_block v0, w21, x20, x7, w8
  439. eor v0.16b, v0.16b, v4.16b
  440. cmp w22, wzr
  441. csinv x5, x24, xzr, eq
  442. cbz w5, .Lmacout
  443. encrypt_block v0, w21, x20, x7, w8
  444. st1 {v0.16b}, [x23] /* return dg */
  445. cond_yield_neon .Lmacrestart
  446. b .Lmacloop4x
  447. .Lmac1x:
  448. add w22, w22, #4
  449. .Lmacloop:
  450. cbz w22, .Lmacout
  451. ld1 {v1.16b}, [x19], #16 /* get next pt block */
  452. eor v0.16b, v0.16b, v1.16b /* ..and xor with dg */
  453. subs w22, w22, #1
  454. csinv x5, x24, xzr, eq
  455. cbz w5, .Lmacout
  456. .Lmacenc:
  457. encrypt_block v0, w21, x20, x7, w8
  458. b .Lmacloop
  459. .Lmacout:
  460. st1 {v0.16b}, [x23] /* return dg */
  461. frame_pop
  462. ret
  463. .Lmacrestart:
  464. ld1 {v0.16b}, [x23] /* get dg */
  465. enc_prepare w21, x20, x0
  466. b .Lmacloop4x
  467. AES_ENDPROC(aes_mac_update)