aest4-sparcv9.pl 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. #! /usr/bin/env perl
  2. # Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. #
  4. # Licensed under the OpenSSL license (the "License"). You may not use
  5. # this file except in compliance with the License. You can obtain a copy
  6. # in the file LICENSE in the source distribution or at
  7. # https://www.openssl.org/source/license.html
  8. # ====================================================================
  9. # Written by David S. Miller and Andy Polyakov.
  10. # The module is licensed under 2-clause BSD license. October 2012.
  11. # All rights reserved.
  12. # ====================================================================
  13. ######################################################################
  14. # AES for SPARC T4.
  15. #
  16. # AES round instructions complete in 3 cycles and can be issued every
  17. # cycle. It means that round calculations should take 4*rounds cycles,
  18. # because any given round instruction depends on result of *both*
  19. # previous instructions:
  20. #
  21. # |0 |1 |2 |3 |4
  22. # |01|01|01|
  23. # |23|23|23|
  24. # |01|01|...
  25. # |23|...
  26. #
  27. # Provided that fxor [with IV] takes 3 cycles to complete, critical
  28. # path length for CBC encrypt would be 3+4*rounds, or in other words
  29. # it should process one byte in at least (3+4*rounds)/16 cycles. This
  30. # estimate doesn't account for "collateral" instructions, such as
  31. # fetching input from memory, xor-ing it with zero-round key and
  32. # storing the result. Yet, *measured* performance [for data aligned
  33. # at 64-bit boundary!] deviates from this equation by less than 0.5%:
  34. #
  35. # 128-bit key 192- 256-
  36. # CBC encrypt 2.70/2.90(*) 3.20/3.40 3.70/3.90
  37. # (*) numbers after slash are for
  38. # misaligned data.
  39. #
  40. # Out-of-order execution logic managed to fully overlap "collateral"
  41. # instructions with those on critical path. Amazing!
  42. #
  43. # As with Intel AES-NI, question is if it's possible to improve
  44. # performance of parallelizable modes by interleaving round
  45. # instructions. Provided round instruction latency and throughput
  46. # optimal interleave factor is 2. But can we expect 2x performance
  47. # improvement? Well, as round instructions can be issued one per
  48. # cycle, they don't saturate the 2-way issue pipeline and therefore
  49. # there is room for "collateral" calculations... Yet, 2x speed-up
  50. # over CBC encrypt remains unattaintable:
  51. #
  52. # 128-bit key 192- 256-
  53. # CBC decrypt 1.64/2.11 1.89/2.37 2.23/2.61
  54. # CTR 1.64/2.08(*) 1.89/2.33 2.23/2.61
  55. # (*) numbers after slash are for
  56. # misaligned data.
  57. #
  58. # Estimates based on amount of instructions under assumption that
  59. # round instructions are not pairable with any other instruction
  60. # suggest that latter is the actual case and pipeline runs
  61. # underutilized. It should be noted that T4 out-of-order execution
  62. # logic is so capable that performance gain from 2x interleave is
  63. # not even impressive, ~7-13% over non-interleaved code, largest
  64. # for 256-bit keys.
  65. # To anchor to something else, software implementation processes
  66. # one byte in 29 cycles with 128-bit key on same processor. Intel
  67. # Sandy Bridge encrypts byte in 5.07 cycles in CBC mode and decrypts
  68. # in 0.93, naturally with AES-NI.
  69. $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
  70. push(@INC,"${dir}","${dir}../../perlasm");
  71. require "sparcv9_modes.pl";
  72. $output = pop;
  73. open STDOUT,">$output";
  74. $::evp=1; # if $evp is set to 0, script generates module with
  75. # AES_[en|de]crypt, AES_set_[en|de]crypt_key and AES_cbc_encrypt entry
  76. # points. These however are not fully compatible with openssl/aes.h,
  77. # because they expect AES_KEY to be aligned at 64-bit boundary. When
  78. # used through EVP, alignment is arranged at EVP layer. Second thing
  79. # that is arranged by EVP is at least 32-bit alignment of IV.
  80. ######################################################################
  81. # single-round subroutines
  82. #
  83. {
  84. my ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5));
  85. $code.=<<___;
  86. #include "sparc_arch.h"
  87. #ifdef __arch64__
  88. .register %g2,#scratch
  89. .register %g3,#scratch
  90. #endif
  91. .text
  92. .globl aes_t4_encrypt
  93. .align 32
  94. aes_t4_encrypt:
  95. andcc $inp, 7, %g1 ! is input aligned?
  96. andn $inp, 7, $inp
  97. ldx [$key + 0], %g4
  98. ldx [$key + 8], %g5
  99. ldx [$inp + 0], %o4
  100. bz,pt %icc, 1f
  101. ldx [$inp + 8], %o5
  102. ldx [$inp + 16], $inp
  103. sll %g1, 3, %g1
  104. sub %g0, %g1, %o3
  105. sllx %o4, %g1, %o4
  106. sllx %o5, %g1, %g1
  107. srlx %o5, %o3, %o5
  108. srlx $inp, %o3, %o3
  109. or %o5, %o4, %o4
  110. or %o3, %g1, %o5
  111. 1:
  112. ld [$key + 240], $rounds
  113. ldd [$key + 16], %f12
  114. ldd [$key + 24], %f14
  115. xor %g4, %o4, %o4
  116. xor %g5, %o5, %o5
  117. movxtod %o4, %f0
  118. movxtod %o5, %f2
  119. srl $rounds, 1, $rounds
  120. ldd [$key + 32], %f16
  121. sub $rounds, 1, $rounds
  122. ldd [$key + 40], %f18
  123. add $key, 48, $key
  124. .Lenc:
  125. aes_eround01 %f12, %f0, %f2, %f4
  126. aes_eround23 %f14, %f0, %f2, %f2
  127. ldd [$key + 0], %f12
  128. ldd [$key + 8], %f14
  129. sub $rounds,1,$rounds
  130. aes_eround01 %f16, %f4, %f2, %f0
  131. aes_eround23 %f18, %f4, %f2, %f2
  132. ldd [$key + 16], %f16
  133. ldd [$key + 24], %f18
  134. brnz,pt $rounds, .Lenc
  135. add $key, 32, $key
  136. andcc $out, 7, $tmp ! is output aligned?
  137. aes_eround01 %f12, %f0, %f2, %f4
  138. aes_eround23 %f14, %f0, %f2, %f2
  139. aes_eround01_l %f16, %f4, %f2, %f0
  140. aes_eround23_l %f18, %f4, %f2, %f2
  141. bnz,pn %icc, 2f
  142. nop
  143. std %f0, [$out + 0]
  144. retl
  145. std %f2, [$out + 8]
  146. 2: alignaddrl $out, %g0, $out
  147. mov 0xff, $mask
  148. srl $mask, $tmp, $mask
  149. faligndata %f0, %f0, %f4
  150. faligndata %f0, %f2, %f6
  151. faligndata %f2, %f2, %f8
  152. stda %f4, [$out + $mask]0xc0 ! partial store
  153. std %f6, [$out + 8]
  154. add $out, 16, $out
  155. orn %g0, $mask, $mask
  156. retl
  157. stda %f8, [$out + $mask]0xc0 ! partial store
  158. .type aes_t4_encrypt,#function
  159. .size aes_t4_encrypt,.-aes_t4_encrypt
  160. .globl aes_t4_decrypt
  161. .align 32
  162. aes_t4_decrypt:
  163. andcc $inp, 7, %g1 ! is input aligned?
  164. andn $inp, 7, $inp
  165. ldx [$key + 0], %g4
  166. ldx [$key + 8], %g5
  167. ldx [$inp + 0], %o4
  168. bz,pt %icc, 1f
  169. ldx [$inp + 8], %o5
  170. ldx [$inp + 16], $inp
  171. sll %g1, 3, %g1
  172. sub %g0, %g1, %o3
  173. sllx %o4, %g1, %o4
  174. sllx %o5, %g1, %g1
  175. srlx %o5, %o3, %o5
  176. srlx $inp, %o3, %o3
  177. or %o5, %o4, %o4
  178. or %o3, %g1, %o5
  179. 1:
  180. ld [$key + 240], $rounds
  181. ldd [$key + 16], %f12
  182. ldd [$key + 24], %f14
  183. xor %g4, %o4, %o4
  184. xor %g5, %o5, %o5
  185. movxtod %o4, %f0
  186. movxtod %o5, %f2
  187. srl $rounds, 1, $rounds
  188. ldd [$key + 32], %f16
  189. sub $rounds, 1, $rounds
  190. ldd [$key + 40], %f18
  191. add $key, 48, $key
  192. .Ldec:
  193. aes_dround01 %f12, %f0, %f2, %f4
  194. aes_dround23 %f14, %f0, %f2, %f2
  195. ldd [$key + 0], %f12
  196. ldd [$key + 8], %f14
  197. sub $rounds,1,$rounds
  198. aes_dround01 %f16, %f4, %f2, %f0
  199. aes_dround23 %f18, %f4, %f2, %f2
  200. ldd [$key + 16], %f16
  201. ldd [$key + 24], %f18
  202. brnz,pt $rounds, .Ldec
  203. add $key, 32, $key
  204. andcc $out, 7, $tmp ! is output aligned?
  205. aes_dround01 %f12, %f0, %f2, %f4
  206. aes_dround23 %f14, %f0, %f2, %f2
  207. aes_dround01_l %f16, %f4, %f2, %f0
  208. aes_dround23_l %f18, %f4, %f2, %f2
  209. bnz,pn %icc, 2f
  210. nop
  211. std %f0, [$out + 0]
  212. retl
  213. std %f2, [$out + 8]
  214. 2: alignaddrl $out, %g0, $out
  215. mov 0xff, $mask
  216. srl $mask, $tmp, $mask
  217. faligndata %f0, %f0, %f4
  218. faligndata %f0, %f2, %f6
  219. faligndata %f2, %f2, %f8
  220. stda %f4, [$out + $mask]0xc0 ! partial store
  221. std %f6, [$out + 8]
  222. add $out, 16, $out
  223. orn %g0, $mask, $mask
  224. retl
  225. stda %f8, [$out + $mask]0xc0 ! partial store
  226. .type aes_t4_decrypt,#function
  227. .size aes_t4_decrypt,.-aes_t4_decrypt
  228. ___
  229. }
  230. ######################################################################
  231. # key setup subroutines
  232. #
  233. {
  234. my ($inp,$bits,$out,$tmp)=map("%o$_",(0..5));
  235. $code.=<<___;
  236. .globl aes_t4_set_encrypt_key
  237. .align 32
  238. aes_t4_set_encrypt_key:
  239. .Lset_encrypt_key:
  240. and $inp, 7, $tmp
  241. alignaddr $inp, %g0, $inp
  242. cmp $bits, 192
  243. ldd [$inp + 0], %f0
  244. bl,pt %icc,.L128
  245. ldd [$inp + 8], %f2
  246. be,pt %icc,.L192
  247. ldd [$inp + 16], %f4
  248. brz,pt $tmp, .L256aligned
  249. ldd [$inp + 24], %f6
  250. ldd [$inp + 32], %f8
  251. faligndata %f0, %f2, %f0
  252. faligndata %f2, %f4, %f2
  253. faligndata %f4, %f6, %f4
  254. faligndata %f6, %f8, %f6
  255. .L256aligned:
  256. ___
  257. for ($i=0; $i<6; $i++) {
  258. $code.=<<___;
  259. std %f0, [$out + `32*$i+0`]
  260. aes_kexpand1 %f0, %f6, $i, %f0
  261. std %f2, [$out + `32*$i+8`]
  262. aes_kexpand2 %f2, %f0, %f2
  263. std %f4, [$out + `32*$i+16`]
  264. aes_kexpand0 %f4, %f2, %f4
  265. std %f6, [$out + `32*$i+24`]
  266. aes_kexpand2 %f6, %f4, %f6
  267. ___
  268. }
  269. $code.=<<___;
  270. std %f0, [$out + `32*$i+0`]
  271. aes_kexpand1 %f0, %f6, $i, %f0
  272. std %f2, [$out + `32*$i+8`]
  273. aes_kexpand2 %f2, %f0, %f2
  274. std %f4, [$out + `32*$i+16`]
  275. std %f6, [$out + `32*$i+24`]
  276. std %f0, [$out + `32*$i+32`]
  277. std %f2, [$out + `32*$i+40`]
  278. mov 14, $tmp
  279. st $tmp, [$out + 240]
  280. retl
  281. xor %o0, %o0, %o0
  282. .align 16
  283. .L192:
  284. brz,pt $tmp, .L192aligned
  285. nop
  286. ldd [$inp + 24], %f6
  287. faligndata %f0, %f2, %f0
  288. faligndata %f2, %f4, %f2
  289. faligndata %f4, %f6, %f4
  290. .L192aligned:
  291. ___
  292. for ($i=0; $i<7; $i++) {
  293. $code.=<<___;
  294. std %f0, [$out + `24*$i+0`]
  295. aes_kexpand1 %f0, %f4, $i, %f0
  296. std %f2, [$out + `24*$i+8`]
  297. aes_kexpand2 %f2, %f0, %f2
  298. std %f4, [$out + `24*$i+16`]
  299. aes_kexpand2 %f4, %f2, %f4
  300. ___
  301. }
  302. $code.=<<___;
  303. std %f0, [$out + `24*$i+0`]
  304. aes_kexpand1 %f0, %f4, $i, %f0
  305. std %f2, [$out + `24*$i+8`]
  306. aes_kexpand2 %f2, %f0, %f2
  307. std %f4, [$out + `24*$i+16`]
  308. std %f0, [$out + `24*$i+24`]
  309. std %f2, [$out + `24*$i+32`]
  310. mov 12, $tmp
  311. st $tmp, [$out + 240]
  312. retl
  313. xor %o0, %o0, %o0
  314. .align 16
  315. .L128:
  316. brz,pt $tmp, .L128aligned
  317. nop
  318. ldd [$inp + 16], %f4
  319. faligndata %f0, %f2, %f0
  320. faligndata %f2, %f4, %f2
  321. .L128aligned:
  322. ___
  323. for ($i=0; $i<10; $i++) {
  324. $code.=<<___;
  325. std %f0, [$out + `16*$i+0`]
  326. aes_kexpand1 %f0, %f2, $i, %f0
  327. std %f2, [$out + `16*$i+8`]
  328. aes_kexpand2 %f2, %f0, %f2
  329. ___
  330. }
  331. $code.=<<___;
  332. std %f0, [$out + `16*$i+0`]
  333. std %f2, [$out + `16*$i+8`]
  334. mov 10, $tmp
  335. st $tmp, [$out + 240]
  336. retl
  337. xor %o0, %o0, %o0
  338. .type aes_t4_set_encrypt_key,#function
  339. .size aes_t4_set_encrypt_key,.-aes_t4_set_encrypt_key
  340. .globl aes_t4_set_decrypt_key
  341. .align 32
  342. aes_t4_set_decrypt_key:
  343. mov %o7, %o5
  344. call .Lset_encrypt_key
  345. nop
  346. mov %o5, %o7
  347. sll $tmp, 4, $inp ! $tmp is number of rounds
  348. add $tmp, 2, $tmp
  349. add $out, $inp, $inp ! $inp=$out+16*rounds
  350. srl $tmp, 2, $tmp ! $tmp=(rounds+2)/4
  351. .Lkey_flip:
  352. ldd [$out + 0], %f0
  353. ldd [$out + 8], %f2
  354. ldd [$out + 16], %f4
  355. ldd [$out + 24], %f6
  356. ldd [$inp + 0], %f8
  357. ldd [$inp + 8], %f10
  358. ldd [$inp - 16], %f12
  359. ldd [$inp - 8], %f14
  360. sub $tmp, 1, $tmp
  361. std %f0, [$inp + 0]
  362. std %f2, [$inp + 8]
  363. std %f4, [$inp - 16]
  364. std %f6, [$inp - 8]
  365. std %f8, [$out + 0]
  366. std %f10, [$out + 8]
  367. std %f12, [$out + 16]
  368. std %f14, [$out + 24]
  369. add $out, 32, $out
  370. brnz $tmp, .Lkey_flip
  371. sub $inp, 32, $inp
  372. retl
  373. xor %o0, %o0, %o0
  374. .type aes_t4_set_decrypt_key,#function
  375. .size aes_t4_set_decrypt_key,.-aes_t4_set_decrypt_key
  376. ___
  377. }
  378. {{{
  379. my ($inp,$out,$len,$key,$ivec,$enc)=map("%i$_",(0..5));
  380. my ($ileft,$iright,$ooff,$omask,$ivoff)=map("%l$_",(1..7));
  381. $code.=<<___;
  382. .align 32
  383. _aes128_encrypt_1x:
  384. ___
  385. for ($i=0; $i<4; $i++) {
  386. $code.=<<___;
  387. aes_eround01 %f`16+8*$i+0`, %f0, %f2, %f4
  388. aes_eround23 %f`16+8*$i+2`, %f0, %f2, %f2
  389. aes_eround01 %f`16+8*$i+4`, %f4, %f2, %f0
  390. aes_eround23 %f`16+8*$i+6`, %f4, %f2, %f2
  391. ___
  392. }
  393. $code.=<<___;
  394. aes_eround01 %f48, %f0, %f2, %f4
  395. aes_eround23 %f50, %f0, %f2, %f2
  396. aes_eround01_l %f52, %f4, %f2, %f0
  397. retl
  398. aes_eround23_l %f54, %f4, %f2, %f2
  399. .type _aes128_encrypt_1x,#function
  400. .size _aes128_encrypt_1x,.-_aes128_encrypt_1x
  401. .align 32
  402. _aes128_encrypt_2x:
  403. ___
  404. for ($i=0; $i<4; $i++) {
  405. $code.=<<___;
  406. aes_eround01 %f`16+8*$i+0`, %f0, %f2, %f8
  407. aes_eround23 %f`16+8*$i+2`, %f0, %f2, %f2
  408. aes_eround01 %f`16+8*$i+0`, %f4, %f6, %f10
  409. aes_eround23 %f`16+8*$i+2`, %f4, %f6, %f6
  410. aes_eround01 %f`16+8*$i+4`, %f8, %f2, %f0
  411. aes_eround23 %f`16+8*$i+6`, %f8, %f2, %f2
  412. aes_eround01 %f`16+8*$i+4`, %f10, %f6, %f4
  413. aes_eround23 %f`16+8*$i+6`, %f10, %f6, %f6
  414. ___
  415. }
  416. $code.=<<___;
  417. aes_eround01 %f48, %f0, %f2, %f8
  418. aes_eround23 %f50, %f0, %f2, %f2
  419. aes_eround01 %f48, %f4, %f6, %f10
  420. aes_eround23 %f50, %f4, %f6, %f6
  421. aes_eround01_l %f52, %f8, %f2, %f0
  422. aes_eround23_l %f54, %f8, %f2, %f2
  423. aes_eround01_l %f52, %f10, %f6, %f4
  424. retl
  425. aes_eround23_l %f54, %f10, %f6, %f6
  426. .type _aes128_encrypt_2x,#function
  427. .size _aes128_encrypt_2x,.-_aes128_encrypt_2x
  428. .align 32
  429. _aes128_loadkey:
  430. ldx [$key + 0], %g4
  431. ldx [$key + 8], %g5
  432. ___
  433. for ($i=2; $i<22;$i++) { # load key schedule
  434. $code.=<<___;
  435. ldd [$key + `8*$i`], %f`12+2*$i`
  436. ___
  437. }
  438. $code.=<<___;
  439. retl
  440. nop
  441. .type _aes128_loadkey,#function
  442. .size _aes128_loadkey,.-_aes128_loadkey
  443. _aes128_load_enckey=_aes128_loadkey
  444. _aes128_load_deckey=_aes128_loadkey
  445. ___
  446. &alg_cbc_encrypt_implement("aes",128);
  447. if ($::evp) {
  448. &alg_ctr32_implement("aes",128);
  449. &alg_xts_implement("aes",128,"en");
  450. &alg_xts_implement("aes",128,"de");
  451. }
  452. &alg_cbc_decrypt_implement("aes",128);
  453. $code.=<<___;
  454. .align 32
  455. _aes128_decrypt_1x:
  456. ___
  457. for ($i=0; $i<4; $i++) {
  458. $code.=<<___;
  459. aes_dround01 %f`16+8*$i+0`, %f0, %f2, %f4
  460. aes_dround23 %f`16+8*$i+2`, %f0, %f2, %f2
  461. aes_dround01 %f`16+8*$i+4`, %f4, %f2, %f0
  462. aes_dround23 %f`16+8*$i+6`, %f4, %f2, %f2
  463. ___
  464. }
  465. $code.=<<___;
  466. aes_dround01 %f48, %f0, %f2, %f4
  467. aes_dround23 %f50, %f0, %f2, %f2
  468. aes_dround01_l %f52, %f4, %f2, %f0
  469. retl
  470. aes_dround23_l %f54, %f4, %f2, %f2
  471. .type _aes128_decrypt_1x,#function
  472. .size _aes128_decrypt_1x,.-_aes128_decrypt_1x
  473. .align 32
  474. _aes128_decrypt_2x:
  475. ___
  476. for ($i=0; $i<4; $i++) {
  477. $code.=<<___;
  478. aes_dround01 %f`16+8*$i+0`, %f0, %f2, %f8
  479. aes_dround23 %f`16+8*$i+2`, %f0, %f2, %f2
  480. aes_dround01 %f`16+8*$i+0`, %f4, %f6, %f10
  481. aes_dround23 %f`16+8*$i+2`, %f4, %f6, %f6
  482. aes_dround01 %f`16+8*$i+4`, %f8, %f2, %f0
  483. aes_dround23 %f`16+8*$i+6`, %f8, %f2, %f2
  484. aes_dround01 %f`16+8*$i+4`, %f10, %f6, %f4
  485. aes_dround23 %f`16+8*$i+6`, %f10, %f6, %f6
  486. ___
  487. }
  488. $code.=<<___;
  489. aes_dround01 %f48, %f0, %f2, %f8
  490. aes_dround23 %f50, %f0, %f2, %f2
  491. aes_dround01 %f48, %f4, %f6, %f10
  492. aes_dround23 %f50, %f4, %f6, %f6
  493. aes_dround01_l %f52, %f8, %f2, %f0
  494. aes_dround23_l %f54, %f8, %f2, %f2
  495. aes_dround01_l %f52, %f10, %f6, %f4
  496. retl
  497. aes_dround23_l %f54, %f10, %f6, %f6
  498. .type _aes128_decrypt_2x,#function
  499. .size _aes128_decrypt_2x,.-_aes128_decrypt_2x
  500. ___
  501. $code.=<<___;
  502. .align 32
  503. _aes192_encrypt_1x:
  504. ___
  505. for ($i=0; $i<5; $i++) {
  506. $code.=<<___;
  507. aes_eround01 %f`16+8*$i+0`, %f0, %f2, %f4
  508. aes_eround23 %f`16+8*$i+2`, %f0, %f2, %f2
  509. aes_eround01 %f`16+8*$i+4`, %f4, %f2, %f0
  510. aes_eround23 %f`16+8*$i+6`, %f4, %f2, %f2
  511. ___
  512. }
  513. $code.=<<___;
  514. aes_eround01 %f56, %f0, %f2, %f4
  515. aes_eround23 %f58, %f0, %f2, %f2
  516. aes_eround01_l %f60, %f4, %f2, %f0
  517. retl
  518. aes_eround23_l %f62, %f4, %f2, %f2
  519. .type _aes192_encrypt_1x,#function
  520. .size _aes192_encrypt_1x,.-_aes192_encrypt_1x
  521. .align 32
  522. _aes192_encrypt_2x:
  523. ___
  524. for ($i=0; $i<5; $i++) {
  525. $code.=<<___;
  526. aes_eround01 %f`16+8*$i+0`, %f0, %f2, %f8
  527. aes_eround23 %f`16+8*$i+2`, %f0, %f2, %f2
  528. aes_eround01 %f`16+8*$i+0`, %f4, %f6, %f10
  529. aes_eround23 %f`16+8*$i+2`, %f4, %f6, %f6
  530. aes_eround01 %f`16+8*$i+4`, %f8, %f2, %f0
  531. aes_eround23 %f`16+8*$i+6`, %f8, %f2, %f2
  532. aes_eround01 %f`16+8*$i+4`, %f10, %f6, %f4
  533. aes_eround23 %f`16+8*$i+6`, %f10, %f6, %f6
  534. ___
  535. }
  536. $code.=<<___;
  537. aes_eround01 %f56, %f0, %f2, %f8
  538. aes_eround23 %f58, %f0, %f2, %f2
  539. aes_eround01 %f56, %f4, %f6, %f10
  540. aes_eround23 %f58, %f4, %f6, %f6
  541. aes_eround01_l %f60, %f8, %f2, %f0
  542. aes_eround23_l %f62, %f8, %f2, %f2
  543. aes_eround01_l %f60, %f10, %f6, %f4
  544. retl
  545. aes_eround23_l %f62, %f10, %f6, %f6
  546. .type _aes192_encrypt_2x,#function
  547. .size _aes192_encrypt_2x,.-_aes192_encrypt_2x
  548. .align 32
  549. _aes256_encrypt_1x:
  550. aes_eround01 %f16, %f0, %f2, %f4
  551. aes_eround23 %f18, %f0, %f2, %f2
  552. ldd [$key + 208], %f16
  553. ldd [$key + 216], %f18
  554. aes_eround01 %f20, %f4, %f2, %f0
  555. aes_eround23 %f22, %f4, %f2, %f2
  556. ldd [$key + 224], %f20
  557. ldd [$key + 232], %f22
  558. ___
  559. for ($i=1; $i<6; $i++) {
  560. $code.=<<___;
  561. aes_eround01 %f`16+8*$i+0`, %f0, %f2, %f4
  562. aes_eround23 %f`16+8*$i+2`, %f0, %f2, %f2
  563. aes_eround01 %f`16+8*$i+4`, %f4, %f2, %f0
  564. aes_eround23 %f`16+8*$i+6`, %f4, %f2, %f2
  565. ___
  566. }
  567. $code.=<<___;
  568. aes_eround01 %f16, %f0, %f2, %f4
  569. aes_eround23 %f18, %f0, %f2, %f2
  570. ldd [$key + 16], %f16
  571. ldd [$key + 24], %f18
  572. aes_eround01_l %f20, %f4, %f2, %f0
  573. aes_eround23_l %f22, %f4, %f2, %f2
  574. ldd [$key + 32], %f20
  575. retl
  576. ldd [$key + 40], %f22
  577. .type _aes256_encrypt_1x,#function
  578. .size _aes256_encrypt_1x,.-_aes256_encrypt_1x
  579. .align 32
  580. _aes256_encrypt_2x:
  581. aes_eround01 %f16, %f0, %f2, %f8
  582. aes_eround23 %f18, %f0, %f2, %f2
  583. aes_eround01 %f16, %f4, %f6, %f10
  584. aes_eround23 %f18, %f4, %f6, %f6
  585. ldd [$key + 208], %f16
  586. ldd [$key + 216], %f18
  587. aes_eround01 %f20, %f8, %f2, %f0
  588. aes_eround23 %f22, %f8, %f2, %f2
  589. aes_eround01 %f20, %f10, %f6, %f4
  590. aes_eround23 %f22, %f10, %f6, %f6
  591. ldd [$key + 224], %f20
  592. ldd [$key + 232], %f22
  593. ___
  594. for ($i=1; $i<6; $i++) {
  595. $code.=<<___;
  596. aes_eround01 %f`16+8*$i+0`, %f0, %f2, %f8
  597. aes_eround23 %f`16+8*$i+2`, %f0, %f2, %f2
  598. aes_eround01 %f`16+8*$i+0`, %f4, %f6, %f10
  599. aes_eround23 %f`16+8*$i+2`, %f4, %f6, %f6
  600. aes_eround01 %f`16+8*$i+4`, %f8, %f2, %f0
  601. aes_eround23 %f`16+8*$i+6`, %f8, %f2, %f2
  602. aes_eround01 %f`16+8*$i+4`, %f10, %f6, %f4
  603. aes_eround23 %f`16+8*$i+6`, %f10, %f6, %f6
  604. ___
  605. }
  606. $code.=<<___;
  607. aes_eround01 %f16, %f0, %f2, %f8
  608. aes_eround23 %f18, %f0, %f2, %f2
  609. aes_eround01 %f16, %f4, %f6, %f10
  610. aes_eround23 %f18, %f4, %f6, %f6
  611. ldd [$key + 16], %f16
  612. ldd [$key + 24], %f18
  613. aes_eround01_l %f20, %f8, %f2, %f0
  614. aes_eround23_l %f22, %f8, %f2, %f2
  615. aes_eround01_l %f20, %f10, %f6, %f4
  616. aes_eround23_l %f22, %f10, %f6, %f6
  617. ldd [$key + 32], %f20
  618. retl
  619. ldd [$key + 40], %f22
  620. .type _aes256_encrypt_2x,#function
  621. .size _aes256_encrypt_2x,.-_aes256_encrypt_2x
  622. .align 32
  623. _aes192_loadkey:
  624. ldx [$key + 0], %g4
  625. ldx [$key + 8], %g5
  626. ___
  627. for ($i=2; $i<26;$i++) { # load key schedule
  628. $code.=<<___;
  629. ldd [$key + `8*$i`], %f`12+2*$i`
  630. ___
  631. }
  632. $code.=<<___;
  633. retl
  634. nop
  635. .type _aes192_loadkey,#function
  636. .size _aes192_loadkey,.-_aes192_loadkey
  637. _aes256_loadkey=_aes192_loadkey
  638. _aes192_load_enckey=_aes192_loadkey
  639. _aes192_load_deckey=_aes192_loadkey
  640. _aes256_load_enckey=_aes192_loadkey
  641. _aes256_load_deckey=_aes192_loadkey
  642. ___
  643. &alg_cbc_encrypt_implement("aes",256);
  644. &alg_cbc_encrypt_implement("aes",192);
  645. if ($::evp) {
  646. &alg_ctr32_implement("aes",256);
  647. &alg_xts_implement("aes",256,"en");
  648. &alg_xts_implement("aes",256,"de");
  649. &alg_ctr32_implement("aes",192);
  650. }
  651. &alg_cbc_decrypt_implement("aes",192);
  652. &alg_cbc_decrypt_implement("aes",256);
  653. $code.=<<___;
  654. .align 32
  655. _aes256_decrypt_1x:
  656. aes_dround01 %f16, %f0, %f2, %f4
  657. aes_dround23 %f18, %f0, %f2, %f2
  658. ldd [$key + 208], %f16
  659. ldd [$key + 216], %f18
  660. aes_dround01 %f20, %f4, %f2, %f0
  661. aes_dround23 %f22, %f4, %f2, %f2
  662. ldd [$key + 224], %f20
  663. ldd [$key + 232], %f22
  664. ___
  665. for ($i=1; $i<6; $i++) {
  666. $code.=<<___;
  667. aes_dround01 %f`16+8*$i+0`, %f0, %f2, %f4
  668. aes_dround23 %f`16+8*$i+2`, %f0, %f2, %f2
  669. aes_dround01 %f`16+8*$i+4`, %f4, %f2, %f0
  670. aes_dround23 %f`16+8*$i+6`, %f4, %f2, %f2
  671. ___
  672. }
  673. $code.=<<___;
  674. aes_dround01 %f16, %f0, %f2, %f4
  675. aes_dround23 %f18, %f0, %f2, %f2
  676. ldd [$key + 16], %f16
  677. ldd [$key + 24], %f18
  678. aes_dround01_l %f20, %f4, %f2, %f0
  679. aes_dround23_l %f22, %f4, %f2, %f2
  680. ldd [$key + 32], %f20
  681. retl
  682. ldd [$key + 40], %f22
  683. .type _aes256_decrypt_1x,#function
  684. .size _aes256_decrypt_1x,.-_aes256_decrypt_1x
  685. .align 32
  686. _aes256_decrypt_2x:
  687. aes_dround01 %f16, %f0, %f2, %f8
  688. aes_dround23 %f18, %f0, %f2, %f2
  689. aes_dround01 %f16, %f4, %f6, %f10
  690. aes_dround23 %f18, %f4, %f6, %f6
  691. ldd [$key + 208], %f16
  692. ldd [$key + 216], %f18
  693. aes_dround01 %f20, %f8, %f2, %f0
  694. aes_dround23 %f22, %f8, %f2, %f2
  695. aes_dround01 %f20, %f10, %f6, %f4
  696. aes_dround23 %f22, %f10, %f6, %f6
  697. ldd [$key + 224], %f20
  698. ldd [$key + 232], %f22
  699. ___
  700. for ($i=1; $i<6; $i++) {
  701. $code.=<<___;
  702. aes_dround01 %f`16+8*$i+0`, %f0, %f2, %f8
  703. aes_dround23 %f`16+8*$i+2`, %f0, %f2, %f2
  704. aes_dround01 %f`16+8*$i+0`, %f4, %f6, %f10
  705. aes_dround23 %f`16+8*$i+2`, %f4, %f6, %f6
  706. aes_dround01 %f`16+8*$i+4`, %f8, %f2, %f0
  707. aes_dround23 %f`16+8*$i+6`, %f8, %f2, %f2
  708. aes_dround01 %f`16+8*$i+4`, %f10, %f6, %f4
  709. aes_dround23 %f`16+8*$i+6`, %f10, %f6, %f6
  710. ___
  711. }
  712. $code.=<<___;
  713. aes_dround01 %f16, %f0, %f2, %f8
  714. aes_dround23 %f18, %f0, %f2, %f2
  715. aes_dround01 %f16, %f4, %f6, %f10
  716. aes_dround23 %f18, %f4, %f6, %f6
  717. ldd [$key + 16], %f16
  718. ldd [$key + 24], %f18
  719. aes_dround01_l %f20, %f8, %f2, %f0
  720. aes_dround23_l %f22, %f8, %f2, %f2
  721. aes_dround01_l %f20, %f10, %f6, %f4
  722. aes_dround23_l %f22, %f10, %f6, %f6
  723. ldd [$key + 32], %f20
  724. retl
  725. ldd [$key + 40], %f22
  726. .type _aes256_decrypt_2x,#function
  727. .size _aes256_decrypt_2x,.-_aes256_decrypt_2x
  728. .align 32
  729. _aes192_decrypt_1x:
  730. ___
  731. for ($i=0; $i<5; $i++) {
  732. $code.=<<___;
  733. aes_dround01 %f`16+8*$i+0`, %f0, %f2, %f4
  734. aes_dround23 %f`16+8*$i+2`, %f0, %f2, %f2
  735. aes_dround01 %f`16+8*$i+4`, %f4, %f2, %f0
  736. aes_dround23 %f`16+8*$i+6`, %f4, %f2, %f2
  737. ___
  738. }
  739. $code.=<<___;
  740. aes_dround01 %f56, %f0, %f2, %f4
  741. aes_dround23 %f58, %f0, %f2, %f2
  742. aes_dround01_l %f60, %f4, %f2, %f0
  743. retl
  744. aes_dround23_l %f62, %f4, %f2, %f2
  745. .type _aes192_decrypt_1x,#function
  746. .size _aes192_decrypt_1x,.-_aes192_decrypt_1x
  747. .align 32
  748. _aes192_decrypt_2x:
  749. ___
  750. for ($i=0; $i<5; $i++) {
  751. $code.=<<___;
  752. aes_dround01 %f`16+8*$i+0`, %f0, %f2, %f8
  753. aes_dround23 %f`16+8*$i+2`, %f0, %f2, %f2
  754. aes_dround01 %f`16+8*$i+0`, %f4, %f6, %f10
  755. aes_dround23 %f`16+8*$i+2`, %f4, %f6, %f6
  756. aes_dround01 %f`16+8*$i+4`, %f8, %f2, %f0
  757. aes_dround23 %f`16+8*$i+6`, %f8, %f2, %f2
  758. aes_dround01 %f`16+8*$i+4`, %f10, %f6, %f4
  759. aes_dround23 %f`16+8*$i+6`, %f10, %f6, %f6
  760. ___
  761. }
  762. $code.=<<___;
  763. aes_dround01 %f56, %f0, %f2, %f8
  764. aes_dround23 %f58, %f0, %f2, %f2
  765. aes_dround01 %f56, %f4, %f6, %f10
  766. aes_dround23 %f58, %f4, %f6, %f6
  767. aes_dround01_l %f60, %f8, %f2, %f0
  768. aes_dround23_l %f62, %f8, %f2, %f2
  769. aes_dround01_l %f60, %f10, %f6, %f4
  770. retl
  771. aes_dround23_l %f62, %f10, %f6, %f6
  772. .type _aes192_decrypt_2x,#function
  773. .size _aes192_decrypt_2x,.-_aes192_decrypt_2x
  774. ___
  775. }}}
  776. if (!$::evp) {
  777. $code.=<<___;
  778. .global AES_encrypt
  779. AES_encrypt=aes_t4_encrypt
  780. .global AES_decrypt
  781. AES_decrypt=aes_t4_decrypt
  782. .global AES_set_encrypt_key
  783. .align 32
  784. AES_set_encrypt_key:
  785. andcc %o2, 7, %g0 ! check alignment
  786. bnz,a,pn %icc, 1f
  787. mov -1, %o0
  788. brz,a,pn %o0, 1f
  789. mov -1, %o0
  790. brz,a,pn %o2, 1f
  791. mov -1, %o0
  792. andncc %o1, 0x1c0, %g0
  793. bnz,a,pn %icc, 1f
  794. mov -2, %o0
  795. cmp %o1, 128
  796. bl,a,pn %icc, 1f
  797. mov -2, %o0
  798. b aes_t4_set_encrypt_key
  799. nop
  800. 1: retl
  801. nop
  802. .type AES_set_encrypt_key,#function
  803. .size AES_set_encrypt_key,.-AES_set_encrypt_key
  804. .global AES_set_decrypt_key
  805. .align 32
  806. AES_set_decrypt_key:
  807. andcc %o2, 7, %g0 ! check alignment
  808. bnz,a,pn %icc, 1f
  809. mov -1, %o0
  810. brz,a,pn %o0, 1f
  811. mov -1, %o0
  812. brz,a,pn %o2, 1f
  813. mov -1, %o0
  814. andncc %o1, 0x1c0, %g0
  815. bnz,a,pn %icc, 1f
  816. mov -2, %o0
  817. cmp %o1, 128
  818. bl,a,pn %icc, 1f
  819. mov -2, %o0
  820. b aes_t4_set_decrypt_key
  821. nop
  822. 1: retl
  823. nop
  824. .type AES_set_decrypt_key,#function
  825. .size AES_set_decrypt_key,.-AES_set_decrypt_key
  826. ___
  827. my ($inp,$out,$len,$key,$ivec,$enc)=map("%o$_",(0..5));
  828. $code.=<<___;
  829. .globl AES_cbc_encrypt
  830. .align 32
  831. AES_cbc_encrypt:
  832. ld [$key + 240], %g1
  833. nop
  834. brz $enc, .Lcbc_decrypt
  835. cmp %g1, 12
  836. bl,pt %icc, aes128_t4_cbc_encrypt
  837. nop
  838. be,pn %icc, aes192_t4_cbc_encrypt
  839. nop
  840. ba aes256_t4_cbc_encrypt
  841. nop
  842. .Lcbc_decrypt:
  843. bl,pt %icc, aes128_t4_cbc_decrypt
  844. nop
  845. be,pn %icc, aes192_t4_cbc_decrypt
  846. nop
  847. ba aes256_t4_cbc_decrypt
  848. nop
  849. .type AES_cbc_encrypt,#function
  850. .size AES_cbc_encrypt,.-AES_cbc_encrypt
  851. ___
  852. }
  853. $code.=<<___;
  854. .asciz "AES for SPARC T4, David S. Miller, Andy Polyakov"
  855. .align 4
  856. ___
  857. &emit_assembler();
  858. close STDOUT;