aes-neonbs-core.S 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /*
  2. * Bit sliced AES using NEON instructions
  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. /*
  12. * The algorithm implemented here is described in detail by the paper
  13. * 'Faster and Timing-Attack Resistant AES-GCM' by Emilia Kaesper and
  14. * Peter Schwabe (https://eprint.iacr.org/2009/129.pdf)
  15. *
  16. * This implementation is based primarily on the OpenSSL implementation
  17. * for 32-bit ARM written by Andy Polyakov <appro@openssl.org>
  18. */
  19. #include <linux/linkage.h>
  20. #include <asm/assembler.h>
  21. .text
  22. .fpu neon
  23. rounds .req ip
  24. bskey .req r4
  25. q0l .req d0
  26. q0h .req d1
  27. q1l .req d2
  28. q1h .req d3
  29. q2l .req d4
  30. q2h .req d5
  31. q3l .req d6
  32. q3h .req d7
  33. q4l .req d8
  34. q4h .req d9
  35. q5l .req d10
  36. q5h .req d11
  37. q6l .req d12
  38. q6h .req d13
  39. q7l .req d14
  40. q7h .req d15
  41. q8l .req d16
  42. q8h .req d17
  43. q9l .req d18
  44. q9h .req d19
  45. q10l .req d20
  46. q10h .req d21
  47. q11l .req d22
  48. q11h .req d23
  49. q12l .req d24
  50. q12h .req d25
  51. q13l .req d26
  52. q13h .req d27
  53. q14l .req d28
  54. q14h .req d29
  55. q15l .req d30
  56. q15h .req d31
  57. .macro __tbl, out, tbl, in, tmp
  58. .ifc \out, \tbl
  59. .ifb \tmp
  60. .error __tbl needs temp register if out == tbl
  61. .endif
  62. vmov \tmp, \out
  63. .endif
  64. vtbl.8 \out\()l, {\tbl}, \in\()l
  65. .ifc \out, \tbl
  66. vtbl.8 \out\()h, {\tmp}, \in\()h
  67. .else
  68. vtbl.8 \out\()h, {\tbl}, \in\()h
  69. .endif
  70. .endm
  71. .macro __ldr, out, sym
  72. vldr \out\()l, \sym
  73. vldr \out\()h, \sym + 8
  74. .endm
  75. .macro __adr, reg, lbl
  76. adr \reg, \lbl
  77. THUMB( orr \reg, \reg, #1 )
  78. .endm
  79. .macro in_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
  80. veor \b2, \b2, \b1
  81. veor \b5, \b5, \b6
  82. veor \b3, \b3, \b0
  83. veor \b6, \b6, \b2
  84. veor \b5, \b5, \b0
  85. veor \b6, \b6, \b3
  86. veor \b3, \b3, \b7
  87. veor \b7, \b7, \b5
  88. veor \b3, \b3, \b4
  89. veor \b4, \b4, \b5
  90. veor \b2, \b2, \b7
  91. veor \b3, \b3, \b1
  92. veor \b1, \b1, \b5
  93. .endm
  94. .macro out_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
  95. veor \b0, \b0, \b6
  96. veor \b1, \b1, \b4
  97. veor \b4, \b4, \b6
  98. veor \b2, \b2, \b0
  99. veor \b6, \b6, \b1
  100. veor \b1, \b1, \b5
  101. veor \b5, \b5, \b3
  102. veor \b3, \b3, \b7
  103. veor \b7, \b7, \b5
  104. veor \b2, \b2, \b5
  105. veor \b4, \b4, \b7
  106. .endm
  107. .macro inv_in_bs_ch, b6, b1, b2, b4, b7, b0, b3, b5
  108. veor \b1, \b1, \b7
  109. veor \b4, \b4, \b7
  110. veor \b7, \b7, \b5
  111. veor \b1, \b1, \b3
  112. veor \b2, \b2, \b5
  113. veor \b3, \b3, \b7
  114. veor \b6, \b6, \b1
  115. veor \b2, \b2, \b0
  116. veor \b5, \b5, \b3
  117. veor \b4, \b4, \b6
  118. veor \b0, \b0, \b6
  119. veor \b1, \b1, \b4
  120. .endm
  121. .macro inv_out_bs_ch, b6, b5, b0, b3, b7, b1, b4, b2
  122. veor \b1, \b1, \b5
  123. veor \b2, \b2, \b7
  124. veor \b3, \b3, \b1
  125. veor \b4, \b4, \b5
  126. veor \b7, \b7, \b5
  127. veor \b3, \b3, \b4
  128. veor \b5, \b5, \b0
  129. veor \b3, \b3, \b7
  130. veor \b6, \b6, \b2
  131. veor \b2, \b2, \b1
  132. veor \b6, \b6, \b3
  133. veor \b3, \b3, \b0
  134. veor \b5, \b5, \b6
  135. .endm
  136. .macro mul_gf4, x0, x1, y0, y1, t0, t1
  137. veor \t0, \y0, \y1
  138. vand \t0, \t0, \x0
  139. veor \x0, \x0, \x1
  140. vand \t1, \x1, \y0
  141. vand \x0, \x0, \y1
  142. veor \x1, \t1, \t0
  143. veor \x0, \x0, \t1
  144. .endm
  145. .macro mul_gf4_n_gf4, x0, x1, y0, y1, t0, x2, x3, y2, y3, t1
  146. veor \t0, \y0, \y1
  147. veor \t1, \y2, \y3
  148. vand \t0, \t0, \x0
  149. vand \t1, \t1, \x2
  150. veor \x0, \x0, \x1
  151. veor \x2, \x2, \x3
  152. vand \x1, \x1, \y0
  153. vand \x3, \x3, \y2
  154. vand \x0, \x0, \y1
  155. vand \x2, \x2, \y3
  156. veor \x1, \x1, \x0
  157. veor \x2, \x2, \x3
  158. veor \x0, \x0, \t0
  159. veor \x3, \x3, \t1
  160. .endm
  161. .macro mul_gf16_2, x0, x1, x2, x3, x4, x5, x6, x7, \
  162. y0, y1, y2, y3, t0, t1, t2, t3
  163. veor \t0, \x0, \x2
  164. veor \t1, \x1, \x3
  165. mul_gf4 \x0, \x1, \y0, \y1, \t2, \t3
  166. veor \y0, \y0, \y2
  167. veor \y1, \y1, \y3
  168. mul_gf4_n_gf4 \t0, \t1, \y0, \y1, \t3, \x2, \x3, \y2, \y3, \t2
  169. veor \x0, \x0, \t0
  170. veor \x2, \x2, \t0
  171. veor \x1, \x1, \t1
  172. veor \x3, \x3, \t1
  173. veor \t0, \x4, \x6
  174. veor \t1, \x5, \x7
  175. mul_gf4_n_gf4 \t0, \t1, \y0, \y1, \t3, \x6, \x7, \y2, \y3, \t2
  176. veor \y0, \y0, \y2
  177. veor \y1, \y1, \y3
  178. mul_gf4 \x4, \x5, \y0, \y1, \t2, \t3
  179. veor \x4, \x4, \t0
  180. veor \x6, \x6, \t0
  181. veor \x5, \x5, \t1
  182. veor \x7, \x7, \t1
  183. .endm
  184. .macro inv_gf256, x0, x1, x2, x3, x4, x5, x6, x7, \
  185. t0, t1, t2, t3, s0, s1, s2, s3
  186. veor \t3, \x4, \x6
  187. veor \t0, \x5, \x7
  188. veor \t1, \x1, \x3
  189. veor \s1, \x7, \x6
  190. veor \s0, \x0, \x2
  191. veor \s3, \t3, \t0
  192. vorr \t2, \t0, \t1
  193. vand \s2, \t3, \s0
  194. vorr \t3, \t3, \s0
  195. veor \s0, \s0, \t1
  196. vand \t0, \t0, \t1
  197. veor \t1, \x3, \x2
  198. vand \s3, \s3, \s0
  199. vand \s1, \s1, \t1
  200. veor \t1, \x4, \x5
  201. veor \s0, \x1, \x0
  202. veor \t3, \t3, \s1
  203. veor \t2, \t2, \s1
  204. vand \s1, \t1, \s0
  205. vorr \t1, \t1, \s0
  206. veor \t3, \t3, \s3
  207. veor \t0, \t0, \s1
  208. veor \t2, \t2, \s2
  209. veor \t1, \t1, \s3
  210. veor \t0, \t0, \s2
  211. vand \s0, \x7, \x3
  212. veor \t1, \t1, \s2
  213. vand \s1, \x6, \x2
  214. vand \s2, \x5, \x1
  215. vorr \s3, \x4, \x0
  216. veor \t3, \t3, \s0
  217. veor \t1, \t1, \s2
  218. veor \s0, \t0, \s3
  219. veor \t2, \t2, \s1
  220. vand \s2, \t3, \t1
  221. veor \s1, \t2, \s2
  222. veor \s3, \s0, \s2
  223. vbsl \s1, \t1, \s0
  224. vmvn \t0, \s0
  225. vbsl \s0, \s1, \s3
  226. vbsl \t0, \s1, \s3
  227. vbsl \s3, \t3, \t2
  228. veor \t3, \t3, \t2
  229. vand \s2, \s0, \s3
  230. veor \t1, \t1, \t0
  231. veor \s2, \s2, \t3
  232. mul_gf16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
  233. \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
  234. .endm
  235. .macro sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
  236. t0, t1, t2, t3, s0, s1, s2, s3
  237. in_bs_ch \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
  238. inv_gf256 \b6, \b5, \b0, \b3, \b7, \b1, \b4, \b2, \
  239. \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
  240. out_bs_ch \b7, \b1, \b4, \b2, \b6, \b5, \b0, \b3
  241. .endm
  242. .macro inv_sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
  243. t0, t1, t2, t3, s0, s1, s2, s3
  244. inv_in_bs_ch \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
  245. inv_gf256 \b5, \b1, \b2, \b6, \b3, \b7, \b0, \b4, \
  246. \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
  247. inv_out_bs_ch \b3, \b7, \b0, \b4, \b5, \b1, \b2, \b6
  248. .endm
  249. .macro shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
  250. t0, t1, t2, t3, mask
  251. vld1.8 {\t0-\t1}, [bskey, :256]!
  252. veor \t0, \t0, \x0
  253. vld1.8 {\t2-\t3}, [bskey, :256]!
  254. veor \t1, \t1, \x1
  255. __tbl \x0, \t0, \mask
  256. veor \t2, \t2, \x2
  257. __tbl \x1, \t1, \mask
  258. vld1.8 {\t0-\t1}, [bskey, :256]!
  259. veor \t3, \t3, \x3
  260. __tbl \x2, \t2, \mask
  261. __tbl \x3, \t3, \mask
  262. vld1.8 {\t2-\t3}, [bskey, :256]!
  263. veor \t0, \t0, \x4
  264. veor \t1, \t1, \x5
  265. __tbl \x4, \t0, \mask
  266. veor \t2, \t2, \x6
  267. __tbl \x5, \t1, \mask
  268. veor \t3, \t3, \x7
  269. __tbl \x6, \t2, \mask
  270. __tbl \x7, \t3, \mask
  271. .endm
  272. .macro inv_shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
  273. t0, t1, t2, t3, mask
  274. __tbl \x0, \x0, \mask, \t0
  275. __tbl \x1, \x1, \mask, \t1
  276. __tbl \x2, \x2, \mask, \t2
  277. __tbl \x3, \x3, \mask, \t3
  278. __tbl \x4, \x4, \mask, \t0
  279. __tbl \x5, \x5, \mask, \t1
  280. __tbl \x6, \x6, \mask, \t2
  281. __tbl \x7, \x7, \mask, \t3
  282. .endm
  283. .macro mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
  284. t0, t1, t2, t3, t4, t5, t6, t7, inv
  285. vext.8 \t0, \x0, \x0, #12
  286. vext.8 \t1, \x1, \x1, #12
  287. veor \x0, \x0, \t0
  288. vext.8 \t2, \x2, \x2, #12
  289. veor \x1, \x1, \t1
  290. vext.8 \t3, \x3, \x3, #12
  291. veor \x2, \x2, \t2
  292. vext.8 \t4, \x4, \x4, #12
  293. veor \x3, \x3, \t3
  294. vext.8 \t5, \x5, \x5, #12
  295. veor \x4, \x4, \t4
  296. vext.8 \t6, \x6, \x6, #12
  297. veor \x5, \x5, \t5
  298. vext.8 \t7, \x7, \x7, #12
  299. veor \x6, \x6, \t6
  300. veor \t1, \t1, \x0
  301. veor.8 \x7, \x7, \t7
  302. vext.8 \x0, \x0, \x0, #8
  303. veor \t2, \t2, \x1
  304. veor \t0, \t0, \x7
  305. veor \t1, \t1, \x7
  306. vext.8 \x1, \x1, \x1, #8
  307. veor \t5, \t5, \x4
  308. veor \x0, \x0, \t0
  309. veor \t6, \t6, \x5
  310. veor \x1, \x1, \t1
  311. vext.8 \t0, \x4, \x4, #8
  312. veor \t4, \t4, \x3
  313. vext.8 \t1, \x5, \x5, #8
  314. veor \t7, \t7, \x6
  315. vext.8 \x4, \x3, \x3, #8
  316. veor \t3, \t3, \x2
  317. vext.8 \x5, \x7, \x7, #8
  318. veor \t4, \t4, \x7
  319. vext.8 \x3, \x6, \x6, #8
  320. veor \t3, \t3, \x7
  321. vext.8 \x6, \x2, \x2, #8
  322. veor \x7, \t1, \t5
  323. .ifb \inv
  324. veor \x2, \t0, \t4
  325. veor \x4, \x4, \t3
  326. veor \x5, \x5, \t7
  327. veor \x3, \x3, \t6
  328. veor \x6, \x6, \t2
  329. .else
  330. veor \t3, \t3, \x4
  331. veor \x5, \x5, \t7
  332. veor \x2, \x3, \t6
  333. veor \x3, \t0, \t4
  334. veor \x4, \x6, \t2
  335. vmov \x6, \t3
  336. .endif
  337. .endm
  338. .macro inv_mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
  339. t0, t1, t2, t3, t4, t5, t6, t7
  340. vld1.8 {\t0-\t1}, [bskey, :256]!
  341. veor \x0, \x0, \t0
  342. vld1.8 {\t2-\t3}, [bskey, :256]!
  343. veor \x1, \x1, \t1
  344. vld1.8 {\t4-\t5}, [bskey, :256]!
  345. veor \x2, \x2, \t2
  346. vld1.8 {\t6-\t7}, [bskey, :256]
  347. sub bskey, bskey, #224
  348. veor \x3, \x3, \t3
  349. veor \x4, \x4, \t4
  350. veor \x5, \x5, \t5
  351. veor \x6, \x6, \t6
  352. veor \x7, \x7, \t7
  353. vext.8 \t0, \x0, \x0, #8
  354. vext.8 \t6, \x6, \x6, #8
  355. vext.8 \t7, \x7, \x7, #8
  356. veor \t0, \t0, \x0
  357. vext.8 \t1, \x1, \x1, #8
  358. veor \t6, \t6, \x6
  359. vext.8 \t2, \x2, \x2, #8
  360. veor \t7, \t7, \x7
  361. vext.8 \t3, \x3, \x3, #8
  362. veor \t1, \t1, \x1
  363. vext.8 \t4, \x4, \x4, #8
  364. veor \t2, \t2, \x2
  365. vext.8 \t5, \x5, \x5, #8
  366. veor \t3, \t3, \x3
  367. veor \t4, \t4, \x4
  368. veor \t5, \t5, \x5
  369. veor \x0, \x0, \t6
  370. veor \x1, \x1, \t6
  371. veor \x2, \x2, \t0
  372. veor \x4, \x4, \t2
  373. veor \x3, \x3, \t1
  374. veor \x1, \x1, \t7
  375. veor \x2, \x2, \t7
  376. veor \x4, \x4, \t6
  377. veor \x5, \x5, \t3
  378. veor \x3, \x3, \t6
  379. veor \x6, \x6, \t4
  380. veor \x4, \x4, \t7
  381. veor \x5, \x5, \t7
  382. veor \x7, \x7, \t5
  383. mix_cols \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
  384. \t0, \t1, \t2, \t3, \t4, \t5, \t6, \t7, 1
  385. .endm
  386. .macro swapmove_2x, a0, b0, a1, b1, n, mask, t0, t1
  387. vshr.u64 \t0, \b0, #\n
  388. vshr.u64 \t1, \b1, #\n
  389. veor \t0, \t0, \a0
  390. veor \t1, \t1, \a1
  391. vand \t0, \t0, \mask
  392. vand \t1, \t1, \mask
  393. veor \a0, \a0, \t0
  394. vshl.s64 \t0, \t0, #\n
  395. veor \a1, \a1, \t1
  396. vshl.s64 \t1, \t1, #\n
  397. veor \b0, \b0, \t0
  398. veor \b1, \b1, \t1
  399. .endm
  400. .macro bitslice, x7, x6, x5, x4, x3, x2, x1, x0, t0, t1, t2, t3
  401. vmov.i8 \t0, #0x55
  402. vmov.i8 \t1, #0x33
  403. swapmove_2x \x0, \x1, \x2, \x3, 1, \t0, \t2, \t3
  404. swapmove_2x \x4, \x5, \x6, \x7, 1, \t0, \t2, \t3
  405. vmov.i8 \t0, #0x0f
  406. swapmove_2x \x0, \x2, \x1, \x3, 2, \t1, \t2, \t3
  407. swapmove_2x \x4, \x6, \x5, \x7, 2, \t1, \t2, \t3
  408. swapmove_2x \x0, \x4, \x1, \x5, 4, \t0, \t2, \t3
  409. swapmove_2x \x2, \x6, \x3, \x7, 4, \t0, \t2, \t3
  410. .endm
  411. .align 4
  412. M0: .quad 0x02060a0e03070b0f, 0x0004080c0105090d
  413. /*
  414. * void aesbs_convert_key(u8 out[], u32 const rk[], int rounds)
  415. */
  416. ENTRY(aesbs_convert_key)
  417. vld1.32 {q7}, [r1]! // load round 0 key
  418. vld1.32 {q15}, [r1]! // load round 1 key
  419. vmov.i8 q8, #0x01 // bit masks
  420. vmov.i8 q9, #0x02
  421. vmov.i8 q10, #0x04
  422. vmov.i8 q11, #0x08
  423. vmov.i8 q12, #0x10
  424. vmov.i8 q13, #0x20
  425. __ldr q14, M0
  426. sub r2, r2, #1
  427. vst1.8 {q7}, [r0, :128]! // save round 0 key
  428. .Lkey_loop:
  429. __tbl q7, q15, q14
  430. vmov.i8 q6, #0x40
  431. vmov.i8 q15, #0x80
  432. vtst.8 q0, q7, q8
  433. vtst.8 q1, q7, q9
  434. vtst.8 q2, q7, q10
  435. vtst.8 q3, q7, q11
  436. vtst.8 q4, q7, q12
  437. vtst.8 q5, q7, q13
  438. vtst.8 q6, q7, q6
  439. vtst.8 q7, q7, q15
  440. vld1.32 {q15}, [r1]! // load next round key
  441. vmvn q0, q0
  442. vmvn q1, q1
  443. vmvn q5, q5
  444. vmvn q6, q6
  445. subs r2, r2, #1
  446. vst1.8 {q0-q1}, [r0, :256]!
  447. vst1.8 {q2-q3}, [r0, :256]!
  448. vst1.8 {q4-q5}, [r0, :256]!
  449. vst1.8 {q6-q7}, [r0, :256]!
  450. bne .Lkey_loop
  451. vmov.i8 q7, #0x63 // compose .L63
  452. veor q15, q15, q7
  453. vst1.8 {q15}, [r0, :128]
  454. bx lr
  455. ENDPROC(aesbs_convert_key)
  456. .align 4
  457. M0SR: .quad 0x0a0e02060f03070b, 0x0004080c05090d01
  458. aesbs_encrypt8:
  459. vld1.8 {q9}, [bskey, :128]! // round 0 key
  460. __ldr q8, M0SR
  461. veor q10, q0, q9 // xor with round0 key
  462. veor q11, q1, q9
  463. __tbl q0, q10, q8
  464. veor q12, q2, q9
  465. __tbl q1, q11, q8
  466. veor q13, q3, q9
  467. __tbl q2, q12, q8
  468. veor q14, q4, q9
  469. __tbl q3, q13, q8
  470. veor q15, q5, q9
  471. __tbl q4, q14, q8
  472. veor q10, q6, q9
  473. __tbl q5, q15, q8
  474. veor q11, q7, q9
  475. __tbl q6, q10, q8
  476. __tbl q7, q11, q8
  477. bitslice q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
  478. sub rounds, rounds, #1
  479. b .Lenc_sbox
  480. .align 5
  481. SR: .quad 0x0504070600030201, 0x0f0e0d0c0a09080b
  482. SRM0: .quad 0x0304090e00050a0f, 0x01060b0c0207080d
  483. .Lenc_last:
  484. __ldr q12, SRM0
  485. .Lenc_loop:
  486. shift_rows q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
  487. .Lenc_sbox:
  488. sbox q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
  489. q13, q14, q15
  490. subs rounds, rounds, #1
  491. bcc .Lenc_done
  492. mix_cols q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11, q12, \
  493. q13, q14, q15
  494. beq .Lenc_last
  495. __ldr q12, SR
  496. b .Lenc_loop
  497. .Lenc_done:
  498. vld1.8 {q12}, [bskey, :128] // last round key
  499. bitslice q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11
  500. veor q0, q0, q12
  501. veor q1, q1, q12
  502. veor q4, q4, q12
  503. veor q6, q6, q12
  504. veor q3, q3, q12
  505. veor q7, q7, q12
  506. veor q2, q2, q12
  507. veor q5, q5, q12
  508. bx lr
  509. ENDPROC(aesbs_encrypt8)
  510. .align 4
  511. M0ISR: .quad 0x0a0e0206070b0f03, 0x0004080c0d010509
  512. aesbs_decrypt8:
  513. add bskey, bskey, rounds, lsl #7
  514. sub bskey, bskey, #112
  515. vld1.8 {q9}, [bskey, :128] // round 0 key
  516. sub bskey, bskey, #128
  517. __ldr q8, M0ISR
  518. veor q10, q0, q9 // xor with round0 key
  519. veor q11, q1, q9
  520. __tbl q0, q10, q8
  521. veor q12, q2, q9
  522. __tbl q1, q11, q8
  523. veor q13, q3, q9
  524. __tbl q2, q12, q8
  525. veor q14, q4, q9
  526. __tbl q3, q13, q8
  527. veor q15, q5, q9
  528. __tbl q4, q14, q8
  529. veor q10, q6, q9
  530. __tbl q5, q15, q8
  531. veor q11, q7, q9
  532. __tbl q6, q10, q8
  533. __tbl q7, q11, q8
  534. bitslice q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
  535. sub rounds, rounds, #1
  536. b .Ldec_sbox
  537. .align 5
  538. ISR: .quad 0x0504070602010003, 0x0f0e0d0c080b0a09
  539. ISRM0: .quad 0x01040b0e0205080f, 0x0306090c00070a0d
  540. .Ldec_last:
  541. __ldr q12, ISRM0
  542. .Ldec_loop:
  543. inv_shift_rows q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
  544. .Ldec_sbox:
  545. inv_sbox q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
  546. q13, q14, q15
  547. subs rounds, rounds, #1
  548. bcc .Ldec_done
  549. inv_mix_cols q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11, q12, \
  550. q13, q14, q15
  551. beq .Ldec_last
  552. __ldr q12, ISR
  553. b .Ldec_loop
  554. .Ldec_done:
  555. add bskey, bskey, #112
  556. vld1.8 {q12}, [bskey, :128] // last round key
  557. bitslice q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11
  558. veor q0, q0, q12
  559. veor q1, q1, q12
  560. veor q6, q6, q12
  561. veor q4, q4, q12
  562. veor q2, q2, q12
  563. veor q7, q7, q12
  564. veor q3, q3, q12
  565. veor q5, q5, q12
  566. bx lr
  567. ENDPROC(aesbs_decrypt8)
  568. /*
  569. * aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  570. * int blocks)
  571. * aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  572. * int blocks)
  573. */
  574. .macro __ecb_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
  575. push {r4-r6, lr}
  576. ldr r5, [sp, #16] // number of blocks
  577. 99: __adr ip, 0f
  578. and lr, r5, #7
  579. cmp r5, #8
  580. sub ip, ip, lr, lsl #2
  581. bxlt ip // computed goto if blocks < 8
  582. vld1.8 {q0}, [r1]!
  583. vld1.8 {q1}, [r1]!
  584. vld1.8 {q2}, [r1]!
  585. vld1.8 {q3}, [r1]!
  586. vld1.8 {q4}, [r1]!
  587. vld1.8 {q5}, [r1]!
  588. vld1.8 {q6}, [r1]!
  589. vld1.8 {q7}, [r1]!
  590. 0: mov bskey, r2
  591. mov rounds, r3
  592. bl \do8
  593. __adr ip, 1f
  594. and lr, r5, #7
  595. cmp r5, #8
  596. sub ip, ip, lr, lsl #2
  597. bxlt ip // computed goto if blocks < 8
  598. vst1.8 {\o0}, [r0]!
  599. vst1.8 {\o1}, [r0]!
  600. vst1.8 {\o2}, [r0]!
  601. vst1.8 {\o3}, [r0]!
  602. vst1.8 {\o4}, [r0]!
  603. vst1.8 {\o5}, [r0]!
  604. vst1.8 {\o6}, [r0]!
  605. vst1.8 {\o7}, [r0]!
  606. 1: subs r5, r5, #8
  607. bgt 99b
  608. pop {r4-r6, pc}
  609. .endm
  610. .align 4
  611. ENTRY(aesbs_ecb_encrypt)
  612. __ecb_crypt aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
  613. ENDPROC(aesbs_ecb_encrypt)
  614. .align 4
  615. ENTRY(aesbs_ecb_decrypt)
  616. __ecb_crypt aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
  617. ENDPROC(aesbs_ecb_decrypt)
  618. /*
  619. * aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
  620. * int rounds, int blocks, u8 iv[])
  621. */
  622. .align 4
  623. ENTRY(aesbs_cbc_decrypt)
  624. mov ip, sp
  625. push {r4-r6, lr}
  626. ldm ip, {r5-r6} // load args 4-5
  627. 99: __adr ip, 0f
  628. and lr, r5, #7
  629. cmp r5, #8
  630. sub ip, ip, lr, lsl #2
  631. mov lr, r1
  632. bxlt ip // computed goto if blocks < 8
  633. vld1.8 {q0}, [lr]!
  634. vld1.8 {q1}, [lr]!
  635. vld1.8 {q2}, [lr]!
  636. vld1.8 {q3}, [lr]!
  637. vld1.8 {q4}, [lr]!
  638. vld1.8 {q5}, [lr]!
  639. vld1.8 {q6}, [lr]!
  640. vld1.8 {q7}, [lr]
  641. 0: mov bskey, r2
  642. mov rounds, r3
  643. bl aesbs_decrypt8
  644. vld1.8 {q8}, [r6]
  645. vmov q9, q8
  646. vmov q10, q8
  647. vmov q11, q8
  648. vmov q12, q8
  649. vmov q13, q8
  650. vmov q14, q8
  651. vmov q15, q8
  652. __adr ip, 1f
  653. and lr, r5, #7
  654. cmp r5, #8
  655. sub ip, ip, lr, lsl #2
  656. bxlt ip // computed goto if blocks < 8
  657. vld1.8 {q9}, [r1]!
  658. vld1.8 {q10}, [r1]!
  659. vld1.8 {q11}, [r1]!
  660. vld1.8 {q12}, [r1]!
  661. vld1.8 {q13}, [r1]!
  662. vld1.8 {q14}, [r1]!
  663. vld1.8 {q15}, [r1]!
  664. W(nop)
  665. 1: __adr ip, 2f
  666. sub ip, ip, lr, lsl #3
  667. bxlt ip // computed goto if blocks < 8
  668. veor q0, q0, q8
  669. vst1.8 {q0}, [r0]!
  670. veor q1, q1, q9
  671. vst1.8 {q1}, [r0]!
  672. veor q6, q6, q10
  673. vst1.8 {q6}, [r0]!
  674. veor q4, q4, q11
  675. vst1.8 {q4}, [r0]!
  676. veor q2, q2, q12
  677. vst1.8 {q2}, [r0]!
  678. veor q7, q7, q13
  679. vst1.8 {q7}, [r0]!
  680. veor q3, q3, q14
  681. vst1.8 {q3}, [r0]!
  682. veor q5, q5, q15
  683. vld1.8 {q8}, [r1]! // load next round's iv
  684. 2: vst1.8 {q5}, [r0]!
  685. subs r5, r5, #8
  686. vst1.8 {q8}, [r6] // store next round's iv
  687. bgt 99b
  688. pop {r4-r6, pc}
  689. ENDPROC(aesbs_cbc_decrypt)
  690. .macro next_ctr, q
  691. vmov.32 \q\()h[1], r10
  692. adds r10, r10, #1
  693. vmov.32 \q\()h[0], r9
  694. adcs r9, r9, #0
  695. vmov.32 \q\()l[1], r8
  696. adcs r8, r8, #0
  697. vmov.32 \q\()l[0], r7
  698. adc r7, r7, #0
  699. vrev32.8 \q, \q
  700. .endm
  701. /*
  702. * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
  703. * int rounds, int blocks, u8 ctr[], u8 final[])
  704. */
  705. ENTRY(aesbs_ctr_encrypt)
  706. mov ip, sp
  707. push {r4-r10, lr}
  708. ldm ip, {r5-r7} // load args 4-6
  709. teq r7, #0
  710. addne r5, r5, #1 // one extra block if final != 0
  711. vld1.8 {q0}, [r6] // load counter
  712. vrev32.8 q1, q0
  713. vmov r9, r10, d3
  714. vmov r7, r8, d2
  715. adds r10, r10, #1
  716. adcs r9, r9, #0
  717. adcs r8, r8, #0
  718. adc r7, r7, #0
  719. 99: vmov q1, q0
  720. vmov q2, q0
  721. vmov q3, q0
  722. vmov q4, q0
  723. vmov q5, q0
  724. vmov q6, q0
  725. vmov q7, q0
  726. __adr ip, 0f
  727. sub lr, r5, #1
  728. and lr, lr, #7
  729. cmp r5, #8
  730. sub ip, ip, lr, lsl #5
  731. sub ip, ip, lr, lsl #2
  732. bxlt ip // computed goto if blocks < 8
  733. next_ctr q1
  734. next_ctr q2
  735. next_ctr q3
  736. next_ctr q4
  737. next_ctr q5
  738. next_ctr q6
  739. next_ctr q7
  740. 0: mov bskey, r2
  741. mov rounds, r3
  742. bl aesbs_encrypt8
  743. __adr ip, 1f
  744. and lr, r5, #7
  745. cmp r5, #8
  746. movgt r4, #0
  747. ldrle r4, [sp, #40] // load final in the last round
  748. sub ip, ip, lr, lsl #2
  749. bxlt ip // computed goto if blocks < 8
  750. vld1.8 {q8}, [r1]!
  751. vld1.8 {q9}, [r1]!
  752. vld1.8 {q10}, [r1]!
  753. vld1.8 {q11}, [r1]!
  754. vld1.8 {q12}, [r1]!
  755. vld1.8 {q13}, [r1]!
  756. vld1.8 {q14}, [r1]!
  757. teq r4, #0 // skip last block if 'final'
  758. 1: bne 2f
  759. vld1.8 {q15}, [r1]!
  760. 2: __adr ip, 3f
  761. cmp r5, #8
  762. sub ip, ip, lr, lsl #3
  763. bxlt ip // computed goto if blocks < 8
  764. veor q0, q0, q8
  765. vst1.8 {q0}, [r0]!
  766. veor q1, q1, q9
  767. vst1.8 {q1}, [r0]!
  768. veor q4, q4, q10
  769. vst1.8 {q4}, [r0]!
  770. veor q6, q6, q11
  771. vst1.8 {q6}, [r0]!
  772. veor q3, q3, q12
  773. vst1.8 {q3}, [r0]!
  774. veor q7, q7, q13
  775. vst1.8 {q7}, [r0]!
  776. veor q2, q2, q14
  777. vst1.8 {q2}, [r0]!
  778. teq r4, #0 // skip last block if 'final'
  779. W(bne) 5f
  780. 3: veor q5, q5, q15
  781. vst1.8 {q5}, [r0]!
  782. 4: next_ctr q0
  783. subs r5, r5, #8
  784. bgt 99b
  785. vst1.8 {q0}, [r6]
  786. pop {r4-r10, pc}
  787. 5: vst1.8 {q5}, [r4]
  788. b 4b
  789. ENDPROC(aesbs_ctr_encrypt)
  790. .macro next_tweak, out, in, const, tmp
  791. vshr.s64 \tmp, \in, #63
  792. vand \tmp, \tmp, \const
  793. vadd.u64 \out, \in, \in
  794. vext.8 \tmp, \tmp, \tmp, #8
  795. veor \out, \out, \tmp
  796. .endm
  797. .align 4
  798. .Lxts_mul_x:
  799. .quad 1, 0x87
  800. /*
  801. * aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  802. * int blocks, u8 iv[])
  803. * aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  804. * int blocks, u8 iv[])
  805. */
  806. __xts_prepare8:
  807. vld1.8 {q14}, [r7] // load iv
  808. __ldr q15, .Lxts_mul_x // load tweak mask
  809. vmov q12, q14
  810. __adr ip, 0f
  811. and r4, r6, #7
  812. cmp r6, #8
  813. sub ip, ip, r4, lsl #5
  814. mov r4, sp
  815. bxlt ip // computed goto if blocks < 8
  816. vld1.8 {q0}, [r1]!
  817. next_tweak q12, q14, q15, q13
  818. veor q0, q0, q14
  819. vst1.8 {q14}, [r4, :128]!
  820. vld1.8 {q1}, [r1]!
  821. next_tweak q14, q12, q15, q13
  822. veor q1, q1, q12
  823. vst1.8 {q12}, [r4, :128]!
  824. vld1.8 {q2}, [r1]!
  825. next_tweak q12, q14, q15, q13
  826. veor q2, q2, q14
  827. vst1.8 {q14}, [r4, :128]!
  828. vld1.8 {q3}, [r1]!
  829. next_tweak q14, q12, q15, q13
  830. veor q3, q3, q12
  831. vst1.8 {q12}, [r4, :128]!
  832. vld1.8 {q4}, [r1]!
  833. next_tweak q12, q14, q15, q13
  834. veor q4, q4, q14
  835. vst1.8 {q14}, [r4, :128]!
  836. vld1.8 {q5}, [r1]!
  837. next_tweak q14, q12, q15, q13
  838. veor q5, q5, q12
  839. vst1.8 {q12}, [r4, :128]!
  840. vld1.8 {q6}, [r1]!
  841. next_tweak q12, q14, q15, q13
  842. veor q6, q6, q14
  843. vst1.8 {q14}, [r4, :128]!
  844. vld1.8 {q7}, [r1]!
  845. next_tweak q14, q12, q15, q13
  846. veor q7, q7, q12
  847. vst1.8 {q12}, [r4, :128]
  848. 0: vst1.8 {q14}, [r7] // store next iv
  849. bx lr
  850. ENDPROC(__xts_prepare8)
  851. .macro __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
  852. push {r4-r8, lr}
  853. mov r5, sp // preserve sp
  854. ldrd r6, r7, [sp, #24] // get blocks and iv args
  855. sub ip, sp, #128 // make room for 8x tweak
  856. bic ip, ip, #0xf // align sp to 16 bytes
  857. mov sp, ip
  858. 99: bl __xts_prepare8
  859. mov bskey, r2
  860. mov rounds, r3
  861. bl \do8
  862. __adr ip, 0f
  863. and lr, r6, #7
  864. cmp r6, #8
  865. sub ip, ip, lr, lsl #2
  866. mov r4, sp
  867. bxlt ip // computed goto if blocks < 8
  868. vld1.8 {q8}, [r4, :128]!
  869. vld1.8 {q9}, [r4, :128]!
  870. vld1.8 {q10}, [r4, :128]!
  871. vld1.8 {q11}, [r4, :128]!
  872. vld1.8 {q12}, [r4, :128]!
  873. vld1.8 {q13}, [r4, :128]!
  874. vld1.8 {q14}, [r4, :128]!
  875. vld1.8 {q15}, [r4, :128]
  876. 0: __adr ip, 1f
  877. sub ip, ip, lr, lsl #3
  878. bxlt ip // computed goto if blocks < 8
  879. veor \o0, \o0, q8
  880. vst1.8 {\o0}, [r0]!
  881. veor \o1, \o1, q9
  882. vst1.8 {\o1}, [r0]!
  883. veor \o2, \o2, q10
  884. vst1.8 {\o2}, [r0]!
  885. veor \o3, \o3, q11
  886. vst1.8 {\o3}, [r0]!
  887. veor \o4, \o4, q12
  888. vst1.8 {\o4}, [r0]!
  889. veor \o5, \o5, q13
  890. vst1.8 {\o5}, [r0]!
  891. veor \o6, \o6, q14
  892. vst1.8 {\o6}, [r0]!
  893. veor \o7, \o7, q15
  894. vst1.8 {\o7}, [r0]!
  895. 1: subs r6, r6, #8
  896. bgt 99b
  897. mov sp, r5
  898. pop {r4-r8, pc}
  899. .endm
  900. ENTRY(aesbs_xts_encrypt)
  901. __xts_crypt aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
  902. ENDPROC(aesbs_xts_encrypt)
  903. ENTRY(aesbs_xts_decrypt)
  904. __xts_crypt aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
  905. ENDPROC(aesbs_xts_decrypt)