vgetrandom-chacha.S 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2024 Christophe Leroy <christophe.leroy@csgroup.eu>, CS GROUP France
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/ppc_asm.h>
  7. #define dst_bytes r3
  8. #define key r4
  9. #define counter r5
  10. #define nblocks r6
  11. #define idx_r0 r0
  12. #define val4 r4
  13. #define const0 0x61707865
  14. #define const1 0x3320646e
  15. #define const2 0x79622d32
  16. #define const3 0x6b206574
  17. #define key0 r5
  18. #define key1 r6
  19. #define key2 r7
  20. #define key3 r8
  21. #define key4 r9
  22. #define key5 r10
  23. #define key6 r11
  24. #define key7 r12
  25. #define counter0 r14
  26. #define counter1 r15
  27. #define state0 r16
  28. #define state1 r17
  29. #define state2 r18
  30. #define state3 r19
  31. #define state4 r20
  32. #define state5 r21
  33. #define state6 r22
  34. #define state7 r23
  35. #define state8 r24
  36. #define state9 r25
  37. #define state10 r26
  38. #define state11 r27
  39. #define state12 r28
  40. #define state13 r29
  41. #define state14 r30
  42. #define state15 r31
  43. .macro quarterround4 a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3 a4 b4 c4 d4
  44. add \a1, \a1, \b1
  45. add \a2, \a2, \b2
  46. add \a3, \a3, \b3
  47. add \a4, \a4, \b4
  48. xor \d1, \d1, \a1
  49. xor \d2, \d2, \a2
  50. xor \d3, \d3, \a3
  51. xor \d4, \d4, \a4
  52. rotlwi \d1, \d1, 16
  53. rotlwi \d2, \d2, 16
  54. rotlwi \d3, \d3, 16
  55. rotlwi \d4, \d4, 16
  56. add \c1, \c1, \d1
  57. add \c2, \c2, \d2
  58. add \c3, \c3, \d3
  59. add \c4, \c4, \d4
  60. xor \b1, \b1, \c1
  61. xor \b2, \b2, \c2
  62. xor \b3, \b3, \c3
  63. xor \b4, \b4, \c4
  64. rotlwi \b1, \b1, 12
  65. rotlwi \b2, \b2, 12
  66. rotlwi \b3, \b3, 12
  67. rotlwi \b4, \b4, 12
  68. add \a1, \a1, \b1
  69. add \a2, \a2, \b2
  70. add \a3, \a3, \b3
  71. add \a4, \a4, \b4
  72. xor \d1, \d1, \a1
  73. xor \d2, \d2, \a2
  74. xor \d3, \d3, \a3
  75. xor \d4, \d4, \a4
  76. rotlwi \d1, \d1, 8
  77. rotlwi \d2, \d2, 8
  78. rotlwi \d3, \d3, 8
  79. rotlwi \d4, \d4, 8
  80. add \c1, \c1, \d1
  81. add \c2, \c2, \d2
  82. add \c3, \c3, \d3
  83. add \c4, \c4, \d4
  84. xor \b1, \b1, \c1
  85. xor \b2, \b2, \c2
  86. xor \b3, \b3, \c3
  87. xor \b4, \b4, \c4
  88. rotlwi \b1, \b1, 7
  89. rotlwi \b2, \b2, 7
  90. rotlwi \b3, \b3, 7
  91. rotlwi \b4, \b4, 7
  92. .endm
  93. #define QUARTERROUND4(a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,a4,b4,c4,d4) \
  94. quarterround4 state##a1 state##b1 state##c1 state##d1 \
  95. state##a2 state##b2 state##c2 state##d2 \
  96. state##a3 state##b3 state##c3 state##d3 \
  97. state##a4 state##b4 state##c4 state##d4
  98. /*
  99. * Very basic 32 bits implementation of ChaCha20. Produces a given positive number
  100. * of blocks of output with a nonce of 0, taking an input key and 8-byte
  101. * counter. Importantly does not spill to the stack. Its arguments are:
  102. *
  103. * r3: output bytes
  104. * r4: 32-byte key input
  105. * r5: 8-byte counter input/output (saved on stack)
  106. * r6: number of 64-byte blocks to write to output
  107. *
  108. * r0: counter of blocks (initialised with r6)
  109. * r4: Value '4' after key has been read.
  110. * r5-r12: key
  111. * r14-r15: counter
  112. * r16-r31: state
  113. */
  114. SYM_FUNC_START(__arch_chacha20_blocks_nostack)
  115. #ifdef __powerpc64__
  116. std counter, -216(r1)
  117. std r14, -144(r1)
  118. std r15, -136(r1)
  119. std r16, -128(r1)
  120. std r17, -120(r1)
  121. std r18, -112(r1)
  122. std r19, -104(r1)
  123. std r20, -96(r1)
  124. std r21, -88(r1)
  125. std r22, -80(r1)
  126. std r23, -72(r1)
  127. std r24, -64(r1)
  128. std r25, -56(r1)
  129. std r26, -48(r1)
  130. std r27, -40(r1)
  131. std r28, -32(r1)
  132. std r29, -24(r1)
  133. std r30, -16(r1)
  134. std r31, -8(r1)
  135. #else
  136. stwu r1, -96(r1)
  137. stw counter, 20(r1)
  138. #ifdef __BIG_ENDIAN__
  139. stmw r14, 24(r1)
  140. #else
  141. stw r14, 24(r1)
  142. stw r15, 28(r1)
  143. stw r16, 32(r1)
  144. stw r17, 36(r1)
  145. stw r18, 40(r1)
  146. stw r19, 44(r1)
  147. stw r20, 48(r1)
  148. stw r21, 52(r1)
  149. stw r22, 56(r1)
  150. stw r23, 60(r1)
  151. stw r24, 64(r1)
  152. stw r25, 68(r1)
  153. stw r26, 72(r1)
  154. stw r27, 76(r1)
  155. stw r28, 80(r1)
  156. stw r29, 84(r1)
  157. stw r30, 88(r1)
  158. stw r31, 92(r1)
  159. #endif
  160. #endif /* __powerpc64__ */
  161. lwz counter0, 0(counter)
  162. lwz counter1, 4(counter)
  163. #ifdef __powerpc64__
  164. rldimi counter0, counter1, 32, 0
  165. #endif
  166. mr idx_r0, nblocks
  167. subi dst_bytes, dst_bytes, 4
  168. lwz key0, 0(key)
  169. lwz key1, 4(key)
  170. lwz key2, 8(key)
  171. lwz key3, 12(key)
  172. lwz key4, 16(key)
  173. lwz key5, 20(key)
  174. lwz key6, 24(key)
  175. lwz key7, 28(key)
  176. li val4, 4
  177. .Lblock:
  178. li r31, 10
  179. lis state0, const0@ha
  180. lis state1, const1@ha
  181. lis state2, const2@ha
  182. lis state3, const3@ha
  183. addi state0, state0, const0@l
  184. addi state1, state1, const1@l
  185. addi state2, state2, const2@l
  186. addi state3, state3, const3@l
  187. mtctr r31
  188. mr state4, key0
  189. mr state5, key1
  190. mr state6, key2
  191. mr state7, key3
  192. mr state8, key4
  193. mr state9, key5
  194. mr state10, key6
  195. mr state11, key7
  196. mr state12, counter0
  197. mr state13, counter1
  198. li state14, 0
  199. li state15, 0
  200. .Lpermute:
  201. QUARTERROUND4( 0, 4, 8,12, 1, 5, 9,13, 2, 6,10,14, 3, 7,11,15)
  202. QUARTERROUND4( 0, 5,10,15, 1, 6,11,12, 2, 7, 8,13, 3, 4, 9,14)
  203. bdnz .Lpermute
  204. addis state0, state0, const0@ha
  205. addis state1, state1, const1@ha
  206. addis state2, state2, const2@ha
  207. addis state3, state3, const3@ha
  208. addi state0, state0, const0@l
  209. addi state1, state1, const1@l
  210. addi state2, state2, const2@l
  211. addi state3, state3, const3@l
  212. add state4, state4, key0
  213. add state5, state5, key1
  214. add state6, state6, key2
  215. add state7, state7, key3
  216. add state8, state8, key4
  217. add state9, state9, key5
  218. add state10, state10, key6
  219. add state11, state11, key7
  220. add state12, state12, counter0
  221. add state13, state13, counter1
  222. #ifdef __BIG_ENDIAN__
  223. stwbrx state0, val4, dst_bytes
  224. addi dst_bytes, dst_bytes, 8
  225. stwbrx state1, 0, dst_bytes
  226. stwbrx state2, val4, dst_bytes
  227. addi dst_bytes, dst_bytes, 8
  228. stwbrx state3, 0, dst_bytes
  229. stwbrx state4, val4, dst_bytes
  230. addi dst_bytes, dst_bytes, 8
  231. stwbrx state5, 0, dst_bytes
  232. stwbrx state6, val4, dst_bytes
  233. addi dst_bytes, dst_bytes, 8
  234. stwbrx state7, 0, dst_bytes
  235. stwbrx state8, val4, dst_bytes
  236. addi dst_bytes, dst_bytes, 8
  237. stwbrx state9, 0, dst_bytes
  238. stwbrx state10, val4, dst_bytes
  239. addi dst_bytes, dst_bytes, 8
  240. stwbrx state11, 0, dst_bytes
  241. stwbrx state12, val4, dst_bytes
  242. addi dst_bytes, dst_bytes, 8
  243. stwbrx state13, 0, dst_bytes
  244. stwbrx state14, val4, dst_bytes
  245. addi dst_bytes, dst_bytes, 8
  246. stwbrx state15, 0, dst_bytes
  247. #else
  248. stw state0, 4(dst_bytes)
  249. stw state1, 8(dst_bytes)
  250. stw state2, 12(dst_bytes)
  251. stw state3, 16(dst_bytes)
  252. stw state4, 20(dst_bytes)
  253. stw state5, 24(dst_bytes)
  254. stw state6, 28(dst_bytes)
  255. stw state7, 32(dst_bytes)
  256. stw state8, 36(dst_bytes)
  257. stw state9, 40(dst_bytes)
  258. stw state10, 44(dst_bytes)
  259. stw state11, 48(dst_bytes)
  260. stw state12, 52(dst_bytes)
  261. stw state13, 56(dst_bytes)
  262. stw state14, 60(dst_bytes)
  263. stwu state15, 64(dst_bytes)
  264. #endif
  265. subic. idx_r0, idx_r0, 1 /* subi. can't use r0 as source */
  266. #ifdef __powerpc64__
  267. addi counter0, counter0, 1
  268. srdi counter1, counter0, 32
  269. #else
  270. addic counter0, counter0, 1
  271. addze counter1, counter1
  272. #endif
  273. bne .Lblock
  274. #ifdef __powerpc64__
  275. ld counter, -216(r1)
  276. #else
  277. lwz counter, 20(r1)
  278. #endif
  279. stw counter0, 0(counter)
  280. stw counter1, 4(counter)
  281. li r6, 0
  282. li r7, 0
  283. li r8, 0
  284. li r9, 0
  285. li r10, 0
  286. li r11, 0
  287. li r12, 0
  288. #ifdef __powerpc64__
  289. ld r14, -144(r1)
  290. ld r15, -136(r1)
  291. ld r16, -128(r1)
  292. ld r17, -120(r1)
  293. ld r18, -112(r1)
  294. ld r19, -104(r1)
  295. ld r20, -96(r1)
  296. ld r21, -88(r1)
  297. ld r22, -80(r1)
  298. ld r23, -72(r1)
  299. ld r24, -64(r1)
  300. ld r25, -56(r1)
  301. ld r26, -48(r1)
  302. ld r27, -40(r1)
  303. ld r28, -32(r1)
  304. ld r29, -24(r1)
  305. ld r30, -16(r1)
  306. ld r31, -8(r1)
  307. #else
  308. #ifdef __BIG_ENDIAN__
  309. lmw r14, 24(r1)
  310. #else
  311. lwz r14, 24(r1)
  312. lwz r15, 28(r1)
  313. lwz r16, 32(r1)
  314. lwz r17, 36(r1)
  315. lwz r18, 40(r1)
  316. lwz r19, 44(r1)
  317. lwz r20, 48(r1)
  318. lwz r21, 52(r1)
  319. lwz r22, 56(r1)
  320. lwz r23, 60(r1)
  321. lwz r24, 64(r1)
  322. lwz r25, 68(r1)
  323. lwz r26, 72(r1)
  324. lwz r27, 76(r1)
  325. lwz r28, 80(r1)
  326. lwz r29, 84(r1)
  327. lwz r30, 88(r1)
  328. lwz r31, 92(r1)
  329. #endif
  330. addi r1, r1, 96
  331. #endif /* __powerpc64__ */
  332. blr
  333. SYM_FUNC_END(__arch_chacha20_blocks_nostack)