Another GAS fix-up and some commentary...
[openssl.git] / crypto / des / asm / des_enc.m4
1 !  des_enc.m4
2 !  des_enc.S  (generated from des_enc.m4)
3 !
4 !  UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
5 !
6 !  Version 1.0. 32-bit version.
7 !
8 !  June 8, 2000.
9 !
10 !  Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
11 !               by Andy Polyakov.
12 !
13 !  January 1, 2003.
14 !
15 !  Assembler version: Copyright Svend Olaf Mikkelsen.
16 !
17 !  Original C code: Copyright Eric A. Young.
18 !
19 !  This code can be freely used by LibDES/SSLeay/OpenSSL users.
20 !
21 !  The LibDES/SSLeay/OpenSSL copyright notices must be respected.
22 !
23 !  This version can be redistributed.
24 !
25 !  To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
26 !
27 !  Global registers 1 to 5 are used. This is the same as done by the
28 !  cc compiler. The UltraSPARC load/store little endian feature is used.
29 !
30 !  Instruction grouping often refers to one CPU cycle.
31 !
32 !  Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
33 !
34 !  Assemble through cc:  cc -c -xarch=v8plusa -o des_enc.o des_enc.S
35 !
36 !  Performance improvement according to './apps/openssl speed des'
37 !
38 !       32-bit build:
39 !               23%  faster than cc-5.2 -xarch=v8plus -xO5
40 !               115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
41 !       64-bit build:
42 !               50%  faster than cc-5.2 -xarch=v9 -xO5
43 !               100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
44 !
45
46 .ident "des_enc.m4 2.0"
47
48 #if defined(__SUNPRO_C) && defined(__sparcv9)
49 # define ABI64  /* They've said -xarch=v9 at command line */
50 #elif defined(__GNUC__) && defined(__arch64__)
51 # define ABI64  /* They've said -m64 at command line */
52 #endif
53
54 #ifdef ABI64
55   .register     %g2,#scratch
56   .register     %g3,#scratch
57 # define        FRAME   -192
58 # define        BIAS    2047
59 # define        LDPTR   ldx
60 # define        STPTR   stx
61 # define        ARG0    128
62 # define        ARGSZ   8
63 # ifndef OPENSSL_SYSNAME_ULTRASPARC
64 # define OPENSSL_SYSNAME_ULTRASPARC
65 # endif
66 #else
67 # define        FRAME   -96
68 # define        BIAS    0
69 # define        LDPTR   ld
70 # define        STPTR   st
71 # define        ARG0    68
72 # define        ARGSZ   4
73 #endif
74
75 #define LOOPS 7
76
77 #define global0 %g0
78 #define global1 %g1
79 #define global2 %g2
80 #define global3 %g3
81 #define global4 %g4
82 #define global5 %g5
83
84 #define local0 %l0
85 #define local1 %l1
86 #define local2 %l2
87 #define local3 %l3
88 #define local4 %l4
89 #define local5 %l5
90 #define local7 %l6
91 #define local6 %l7
92
93 #define in0 %i0
94 #define in1 %i1
95 #define in2 %i2
96 #define in3 %i3
97 #define in4 %i4
98 #define in5 %i5
99 #define in6 %i6
100 #define in7 %i7
101
102 #define out0 %o0
103 #define out1 %o1
104 #define out2 %o2
105 #define out3 %o3
106 #define out4 %o4
107 #define out5 %o5
108 #define out6 %o6
109 #define out7 %o7
110
111 #define stub stb
112
113 changequote({,})
114
115
116 ! Macro definitions:
117
118
119 ! {ip_macro}
120 !
121 ! The logic used in initial and final permutations is the same as in
122 ! the C code. The permutations are done with a clever shift, xor, and
123 ! technique.
124 !
125 ! The macro also loads address sbox 1 to 5 to global 1 to 5, address
126 ! sbox 6 to local6, and addres sbox 8 to out3.
127 !
128 ! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
129 !
130 ! Loads key first round from address in parameter 5 to out0, out1.
131 !
132 ! After the the original LibDES initial permutation, the resulting left
133 ! is in the variable initially used for right and vice versa. The macro
134 ! implements the possibility to keep the halfs in the original registers.
135 !
136 ! parameter 1  left
137 ! parameter 2  right
138 ! parameter 3  result left (modify in first round)
139 ! parameter 4  result right (use in first round)
140 ! parameter 5  key address
141 ! parameter 6  1/2 for include encryption/decryption
142 ! parameter 7  1 for move in1 to in3
143 ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
144 ! parameter 9  1 for load ks3 and ks2 to in4 and in3
145
146 define(ip_macro, {
147
148 ! {ip_macro}
149 ! $1 $2 $4 $3 $5 $6 $7 $8 $9
150
151         ld      [out2+256], local1
152         srl     $2, 4, local4
153
154         xor     local4, $1, local4
155         ifelse($7,1,{mov in1, in3},{nop})
156
157         ld      [out2+260], local2
158         and     local4, local1, local4
159         ifelse($8,1,{mov in3, in4},{})
160         ifelse($8,2,{mov in4, in3},{})
161
162         ld      [out2+280], out4          ! loop counter
163         sll     local4, 4, local1
164         xor     $1, local4, $1
165
166         ld      [out2+264], local3
167         srl     $1, 16, local4
168         xor     $2, local1, $2
169
170         ifelse($9,1,{LDPTR      KS3, in4},{})
171         xor     local4, $2, local4
172         nop     !sethi  %hi(DES_SPtrans), global1 ! sbox addr
173
174         ifelse($9,1,{LDPTR      KS2, in3},{})
175         and     local4, local2, local4
176         nop     !or     global1, %lo(DES_SPtrans), global1   ! sbox addr
177
178         sll     local4, 16, local1
179         xor     $2, local4, $2
180
181         srl     $2, 2, local4
182         xor     $1, local1, $1
183
184         sethi   %hi(16711680), local5
185         xor     local4, $1, local4
186
187         and     local4, local3, local4
188         or      local5, 255, local5
189
190         sll     local4, 2, local2
191         xor     $1, local4, $1
192
193         srl     $1, 8, local4
194         xor     $2, local2, $2
195
196         xor     local4, $2, local4
197         add     global1, 768, global4
198
199         and     local4, local5, local4
200         add     global1, 1024, global5
201
202         ld      [out2+272], local7
203         sll     local4, 8, local1
204         xor     $2, local4, $2
205
206         srl     $2, 1, local4
207         xor     $1, local1, $1
208
209         ld      [$5], out0                ! key 7531
210         xor     local4, $1, local4
211         add     global1, 256, global2
212
213         ld      [$5+4], out1              ! key 8642
214         and     local4, local7, local4
215         add     global1, 512, global3
216
217         sll     local4, 1, local1
218         xor     $1, local4, $1
219
220         sll     $1, 3, local3
221         xor     $2, local1, $2
222
223         sll     $2, 3, local2
224         add     global1, 1280, local6     ! address sbox 8
225
226         srl     $1, 29, local4
227         add     global1, 1792, out3       ! address sbox 8
228
229         srl     $2, 29, local1
230         or      local4, local3, $4
231
232         or      local2, local1, $3
233
234         ifelse($6, 1, {
235
236                 ld      [out2+284], local5     ! 0x0000FC00 used in the rounds
237                 or      local2, local1, $3
238                 xor     $4, out0, local1
239
240                 call .des_enc.1
241                 and     local1, 252, local1
242
243         },{})
244
245         ifelse($6, 2, {
246
247                 ld      [out2+284], local5     ! 0x0000FC00 used in the rounds
248                 or      local2, local1, $3
249                 xor     $4, out0, local1
250
251                 call .des_dec.1
252                 and     local1, 252, local1
253
254         },{})
255 })
256
257
258 ! {rounds_macro}
259 !
260 ! The logic used in the DES rounds is the same as in the C code,
261 ! except that calculations for sbox 1 and sbox 5 begin before
262 ! the previous round is finished.
263 !
264 ! In each round one half (work) is modified based on key and the
265 ! other half (use).
266 !
267 ! In this version we do two rounds in a loop repeated 7 times
268 ! and two rounds seperately.
269 !
270 ! One half has the bits for the sboxes in the following positions:
271 !
272 !       777777xx555555xx333333xx111111xx
273 !
274 !       88xx666666xx444444xx222222xx8888
275 !
276 ! The bits for each sbox are xor-ed with the key bits for that box.
277 ! The above xx bits are cleared, and the result used for lookup in
278 ! the sbox table. Each sbox entry contains the 4 output bits permuted
279 ! into 32 bits according to the P permutation.
280 !
281 ! In the description of DES, left and right are switched after
282 ! each round, except after last round. In this code the original
283 ! left and right are kept in the same register in all rounds, meaning
284 ! that after the 16 rounds the result for right is in the register
285 ! originally used for left.
286 !
287 ! parameter 1  first work (left in first round)
288 ! parameter 2  first use (right in first round)
289 ! parameter 3  enc/dec  1/-1
290 ! parameter 4  loop label
291 ! parameter 5  key address register
292 ! parameter 6  optional address for key next encryption/decryption
293 ! parameter 7  not empty for include retl
294 !
295 ! also compares in2 to 8
296
297 define(rounds_macro, {
298
299 ! {rounds_macro}
300 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
301
302         xor     $2, out0, local1
303
304         ld      [out2+284], local5        ! 0x0000FC00
305         ba      $4
306         and     local1, 252, local1
307
308         .align 32
309
310 $4:
311         ! local6 is address sbox 6
312         ! out3   is address sbox 8
313         ! out4   is loop counter
314
315         ld      [global1+local1], local1
316         xor     $2, out1, out1            ! 8642
317         xor     $2, out0, out0            ! 7531
318         fmovs   %f0, %f0                  ! fxor used for alignment
319
320         srl     out1, 4, local0           ! rotate 4 right
321         and     out0, local5, local3      ! 3
322         fmovs   %f0, %f0
323
324         ld      [$5+$3*8], local7         ! key 7531 next round
325         srl     local3, 8, local3         ! 3
326         and     local0, 252, local2       ! 2
327         fmovs   %f0, %f0
328
329         ld      [global3+local3],local3   ! 3
330         sll     out1, 28, out1            ! rotate
331         xor     $1, local1, $1            ! 1 finished, local1 now sbox 7
332
333         ld      [global2+local2], local2  ! 2 
334         srl     out0, 24, local1          ! 7
335         or      out1, local0, out1        ! rotate
336
337         ldub    [out2+local1], local1     ! 7 (and 0xFC)
338         srl     out1, 24, local0          ! 8
339         and     out1, local5, local4      ! 4
340
341         ldub    [out2+local0], local0     ! 8 (and 0xFC)
342         srl     local4, 8, local4         ! 4
343         xor     $1, local2, $1            ! 2 finished local2 now sbox 6
344
345         ld      [global4+local4],local4   ! 4
346         srl     out1, 16, local2          ! 6
347         xor     $1, local3, $1            ! 3 finished local3 now sbox 5
348
349         ld      [out3+local0],local0      ! 8
350         and     local2, 252, local2       ! 6
351         add     global1, 1536, local5     ! address sbox 7
352
353         ld      [local6+local2], local2   ! 6
354         srl     out0, 16, local3          ! 5
355         xor     $1, local4, $1            ! 4 finished
356
357         ld      [local5+local1],local1    ! 7
358         and     local3, 252, local3       ! 5
359         xor     $1, local0, $1            ! 8 finished
360
361         ld      [global5+local3],local3   ! 5
362         xor     $1, local2, $1            ! 6 finished
363         subcc   out4, 1, out4
364
365         ld      [$5+$3*8+4], out0         ! key 8642 next round
366         xor     $1, local7, local2        ! sbox 5 next round
367         xor     $1, local1, $1            ! 7 finished
368
369         srl     local2, 16, local2        ! sbox 5 next round
370         xor     $1, local3, $1            ! 5 finished
371
372         ld      [$5+$3*16+4], out1        ! key 8642 next round again
373         and     local2, 252, local2       ! sbox5 next round
374 ! next round
375         xor     $1, local7, local7        ! 7531
376
377         ld      [global5+local2], local2  ! 5
378         srl     local7, 24, local3        ! 7
379         xor     $1, out0, out0            ! 8642
380
381         ldub    [out2+local3], local3     ! 7 (and 0xFC)
382         srl     out0, 4, local0           ! rotate 4 right
383         and     local7, 252, local1       ! 1
384
385         sll     out0, 28, out0            ! rotate
386         xor     $2, local2, $2            ! 5 finished local2 used
387
388         srl     local0, 8, local4         ! 4
389         and     local0, 252, local2       ! 2
390         ld      [local5+local3], local3   ! 7
391
392         srl     local0, 16, local5        ! 6
393         or      out0, local0, out0        ! rotate
394         ld      [global2+local2], local2  ! 2
395
396         srl     out0, 24, local0
397         ld      [$5+$3*16], out0          ! key 7531 next round
398         and     local4, 252, local4       ! 4
399
400         and     local5, 252, local5       ! 6
401         ld      [global4+local4], local4  ! 4
402         xor     $2, local3, $2            ! 7 finished local3 used
403
404         and     local0, 252, local0       ! 8
405         ld      [local6+local5], local5   ! 6
406         xor     $2, local2, $2            ! 2 finished local2 now sbox 3
407
408         srl     local7, 8, local2         ! 3 start
409         ld      [out3+local0], local0     ! 8
410         xor     $2, local4, $2            ! 4 finished
411
412         and     local2, 252, local2       ! 3
413         ld      [global1+local1], local1  ! 1
414         xor     $2, local5, $2            ! 6 finished local5 used
415
416         ld      [global3+local2], local2  ! 3
417         xor     $2, local0, $2            ! 8 finished
418         add     $5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
419
420         ld      [out2+284], local5        ! 0x0000FC00
421         xor     $2, out0, local4          ! sbox 1 next round
422         xor     $2, local1, $2            ! 1 finished
423
424         xor     $2, local2, $2            ! 3 finished
425 #ifdef OPENSSL_SYSNAME_ULTRASPARC
426         bne,pt  %icc, $4
427 #else
428         bne     $4
429 #endif
430         and     local4, 252, local1       ! sbox 1 next round
431
432 ! two rounds more:
433
434         ld      [global1+local1], local1
435         xor     $2, out1, out1
436         xor     $2, out0, out0
437
438         srl     out1, 4, local0           ! rotate
439         and     out0, local5, local3
440
441         ld      [$5+$3*8], local7         ! key 7531
442         srl     local3, 8, local3
443         and     local0, 252, local2
444
445         ld      [global3+local3],local3
446         sll     out1, 28, out1            ! rotate
447         xor     $1, local1, $1            ! 1 finished, local1 now sbox 7
448
449         ld      [global2+local2], local2
450         srl     out0, 24, local1
451         or      out1, local0, out1        ! rotate
452
453         ldub    [out2+local1], local1
454         srl     out1, 24, local0
455         and     out1, local5, local4
456
457         ldub    [out2+local0], local0
458         srl     local4, 8, local4
459         xor     $1, local2, $1            ! 2 finished local2 now sbox 6
460
461         ld      [global4+local4],local4
462         srl     out1, 16, local2
463         xor     $1, local3, $1            ! 3 finished local3 now sbox 5
464
465         ld      [out3+local0],local0
466         and     local2, 252, local2
467         add     global1, 1536, local5     ! address sbox 7
468
469         ld      [local6+local2], local2
470         srl     out0, 16, local3
471         xor     $1, local4, $1            ! 4 finished
472
473         ld      [local5+local1],local1
474         and     local3, 252, local3
475         xor     $1, local0, $1
476
477         ld      [global5+local3],local3
478         xor     $1, local2, $1            ! 6 finished
479         cmp     in2, 8
480
481         ifelse($6,{}, {}, {ld   [out2+280], out4})  ! loop counter
482         xor     $1, local7, local2        ! sbox 5 next round
483         xor     $1, local1, $1            ! 7 finished
484
485         ld      [$5+$3*8+4], out0
486         srl     local2, 16, local2        ! sbox 5 next round
487         xor     $1, local3, $1            ! 5 finished
488
489         and     local2, 252, local2
490 ! next round (two rounds more)
491         xor     $1, local7, local7        ! 7531
492
493         ld      [global5+local2], local2
494         srl     local7, 24, local3
495         xor     $1, out0, out0            ! 8642
496
497         ldub    [out2+local3], local3
498         srl     out0, 4, local0           ! rotate
499         and     local7, 252, local1
500
501         sll     out0, 28, out0            ! rotate
502         xor     $2, local2, $2            ! 5 finished local2 used
503
504         srl     local0, 8, local4
505         and     local0, 252, local2
506         ld      [local5+local3], local3
507
508         srl     local0, 16, local5
509         or      out0, local0, out0        ! rotate
510         ld      [global2+local2], local2
511
512         srl     out0, 24, local0
513         ifelse($6,{}, {}, {ld   [$6], out0})   ! key next encryption/decryption
514         and     local4, 252, local4
515
516         and     local5, 252, local5
517         ld      [global4+local4], local4
518         xor     $2, local3, $2            ! 7 finished local3 used
519
520         and     local0, 252, local0
521         ld      [local6+local5], local5
522         xor     $2, local2, $2            ! 2 finished local2 now sbox 3
523
524         srl     local7, 8, local2         ! 3 start
525         ld      [out3+local0], local0
526         xor     $2, local4, $2
527
528         and     local2, 252, local2
529         ld      [global1+local1], local1
530         xor     $2, local5, $2            ! 6 finished local5 used
531
532         ld      [global3+local2], local2
533         srl     $1, 3, local3
534         xor     $2, local0, $2
535
536         ifelse($6,{}, {}, {ld   [$6+4], out1}) ! key next encryption/decryption
537         sll     $1, 29, local4
538         xor     $2, local1, $2
539
540         ifelse($7,{}, {}, {retl})
541         xor     $2, local2, $2
542 })
543
544
545 ! {fp_macro}
546 !
547 !  parameter 1   right (original left)
548 !  parameter 2   left (original right)
549 !  parameter 3   1 for optional store to [in0]
550 !  parameter 4   1 for load input/output address to local5/7
551 !
552 !  The final permutation logic switches the halfes, meaning that
553 !  left and right ends up the the registers originally used.
554
555 define(fp_macro, {
556
557 ! {fp_macro}
558 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
559
560         ! initially undo the rotate 3 left done after initial permutation
561         ! original left is received shifted 3 right and 29 left in local3/4
562
563         sll     $2, 29, local1
564         or      local3, local4, $1
565
566         srl     $2, 3, $2
567         sethi   %hi(0x55555555), local2
568
569         or      $2, local1, $2
570         or      local2, %lo(0x55555555), local2
571
572         srl     $2, 1, local3
573         sethi   %hi(0x00ff00ff), local1
574         xor     local3, $1, local3
575         or      local1, %lo(0x00ff00ff), local1
576         and     local3, local2, local3
577         sethi   %hi(0x33333333), local4
578         sll     local3, 1, local2
579
580         xor     $1, local3, $1
581
582         srl     $1, 8, local3
583         xor     $2, local2, $2
584         xor     local3, $2, local3
585         or      local4, %lo(0x33333333), local4
586         and     local3, local1, local3
587         sethi   %hi(0x0000ffff), local1
588         sll     local3, 8, local2
589
590         xor     $2, local3, $2
591
592         srl     $2, 2, local3
593         xor     $1, local2, $1
594         xor     local3, $1, local3
595         or      local1, %lo(0x0000ffff), local1
596         and     local3, local4, local3
597         sethi   %hi(0x0f0f0f0f), local4
598         sll     local3, 2, local2
599
600         ifelse($4,1, {LDPTR INPUT, local5})
601         xor     $1, local3, $1
602
603         ifelse($4,1, {LDPTR OUTPUT, local7})
604         srl     $1, 16, local3
605         xor     $2, local2, $2
606         xor     local3, $2, local3
607         or      local4, %lo(0x0f0f0f0f), local4
608         and     local3, local1, local3
609         sll     local3, 16, local2
610
611         xor     $2, local3, local1
612
613         srl     local1, 4, local3
614         xor     $1, local2, $1
615         xor     local3, $1, local3
616         and     local3, local4, local3
617         sll     local3, 4, local2
618
619         xor     $1, local3, $1
620
621         ! optional store:
622
623         ifelse($3,1, {st $1, [in0]})
624
625         xor     local1, local2, $2
626
627         ifelse($3,1, {st $2, [in0+4]})
628
629 })
630
631
632 ! {fp_ip_macro}
633 !
634 ! Does initial permutation for next block mixed with
635 ! final permutation for current block.
636 !
637 ! parameter 1   original left
638 ! parameter 2   original right
639 ! parameter 3   left ip
640 ! parameter 4   right ip
641 ! parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
642 !                2: mov in4 to in3
643 !
644 ! also adds -8 to length in2 and loads loop counter to out4
645
646 define(fp_ip_macro, {
647
648 ! {fp_ip_macro}
649 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
650
651         define({temp1},{out4})
652         define({temp2},{local3})
653
654         define({ip1},{local1})
655         define({ip2},{local2})
656         define({ip4},{local4})
657         define({ip5},{local5})
658
659         ! $1 in local3, local4
660
661         ld      [out2+256], ip1
662         sll     out5, 29, temp1
663         or      local3, local4, $1
664
665         srl     out5, 3, $2
666         ifelse($5,2,{mov in4, in3})
667
668         ld      [out2+272], ip5
669         srl     $4, 4, local0
670         or      $2, temp1, $2
671
672         srl     $2, 1, temp1
673         xor     temp1, $1, temp1
674
675         and     temp1, ip5, temp1
676         xor     local0, $3, local0
677
678         sll     temp1, 1, temp2
679         xor     $1, temp1, $1
680
681         and     local0, ip1, local0
682         add     in2, -8, in2
683
684         sll     local0, 4, local7
685         xor     $3, local0, $3
686
687         ld      [out2+268], ip4
688         srl     $1, 8, temp1
689         xor     $2, temp2, $2
690         ld      [out2+260], ip2
691         srl     $3, 16, local0
692         xor     $4, local7, $4
693         xor     temp1, $2, temp1
694         xor     local0, $4, local0
695         and     temp1, ip4, temp1
696         and     local0, ip2, local0
697         sll     temp1, 8, temp2
698         xor     $2, temp1, $2
699         sll     local0, 16, local7
700         xor     $4, local0, $4
701
702         srl     $2, 2, temp1
703         xor     $1, temp2, $1
704
705         ld      [out2+264], temp2         ! ip3
706         srl     $4, 2, local0
707         xor     $3, local7, $3
708         xor     temp1, $1, temp1
709         xor     local0, $3, local0
710         and     temp1, temp2, temp1
711         and     local0, temp2, local0
712         sll     temp1, 2, temp2
713         xor     $1, temp1, $1
714         sll     local0, 2, local7
715         xor     $3, local0, $3
716
717         srl     $1, 16, temp1
718         xor     $2, temp2, $2
719         srl     $3, 8, local0
720         xor     $4, local7, $4
721         xor     temp1, $2, temp1
722         xor     local0, $4, local0
723         and     temp1, ip2, temp1
724         and     local0, ip4, local0
725         sll     temp1, 16, temp2
726         xor     $2, temp1, local4
727         sll     local0, 8, local7
728         xor     $4, local0, $4
729
730         srl     $4, 1, local0
731         xor     $3, local7, $3
732
733         srl     local4, 4, temp1
734         xor     local0, $3, local0
735
736         xor     $1, temp2, $1
737         and     local0, ip5, local0
738
739         sll     local0, 1, local7
740         xor     temp1, $1, temp1
741
742         xor     $3, local0, $3
743         xor     $4, local7, $4
744
745         sll     $3, 3, local5
746         and     temp1, ip1, temp1
747
748         sll     temp1, 4, temp2
749         xor     $1, temp1, $1
750
751         ifelse($5,1,{LDPTR      KS2, in4})
752         sll     $4, 3, local2
753         xor     local4, temp2, $2
754
755         ! reload since used as temporar:
756
757         ld      [out2+280], out4          ! loop counter
758
759         srl     $3, 29, local0
760         ifelse($5,1,{add in4, 120, in4})
761
762         ifelse($5,1,{LDPTR      KS1, in3})
763         srl     $4, 29, local7
764
765         or      local0, local5, $4
766         or      local2, local7, $3
767
768 })
769
770
771
772 ! {load_little_endian}
773 !
774 ! parameter 1  address
775 ! parameter 2  destination left
776 ! parameter 3  destination right
777 ! parameter 4  temporar
778 ! parameter 5  label
779
780 define(load_little_endian, {
781
782 ! {load_little_endian}
783 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
784
785         ! first in memory to rightmost in register
786
787 #ifdef OPENSSL_SYSNAME_ULTRASPARC
788         andcc   $1, 3, global0
789         bne,pn  %icc, $5
790         nop
791
792         lda     [$1] 0x88, $2
793         add     $1, 4, $4
794
795         ba,pt   %icc, $5a
796         lda     [$4] 0x88, $3
797 #endif
798
799 $5:
800         ldub    [$1+3], $2
801
802         ldub    [$1+2], $4
803         sll     $2, 8, $2
804         or      $2, $4, $2
805
806         ldub    [$1+1], $4
807         sll     $2, 8, $2
808         or      $2, $4, $2
809
810         ldub    [$1+0], $4
811         sll     $2, 8, $2
812         or      $2, $4, $2
813
814
815         ldub    [$1+3+4], $3
816
817         ldub    [$1+2+4], $4
818         sll     $3, 8, $3
819         or      $3, $4, $3
820
821         ldub    [$1+1+4], $4
822         sll     $3, 8, $3
823         or      $3, $4, $3
824
825         ldub    [$1+0+4], $4
826         sll     $3, 8, $3
827         or      $3, $4, $3
828 $5a:
829
830 })
831
832
833 ! {load_little_endian_inc}
834 !
835 ! parameter 1  address
836 ! parameter 2  destination left
837 ! parameter 3  destination right
838 ! parameter 4  temporar
839 ! parameter 4  label
840 !
841 ! adds 8 to address
842
843 define(load_little_endian_inc, {
844
845 ! {load_little_endian_inc}
846 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
847
848         ! first in memory to rightmost in register
849
850 #ifdef OPENSSL_SYSNAME_ULTRASPARC
851         andcc   $1, 3, global0
852         bne,pn  %icc, $5
853         nop
854
855         lda     [$1] 0x88, $2
856         add     $1, 4, $1
857
858         lda     [$1] 0x88, $3
859         ba,pt   %icc, $5a
860         add     $1, 4, $1
861 #endif
862
863 $5:
864         ldub    [$1+3], $2
865
866         ldub    [$1+2], $4
867         sll     $2, 8, $2
868         or      $2, $4, $2
869
870         ldub    [$1+1], $4
871         sll     $2, 8, $2
872         or      $2, $4, $2
873
874         ldub    [$1+0], $4
875         sll     $2, 8, $2
876         or      $2, $4, $2
877
878         ldub    [$1+3+4], $3
879         add     $1, 8, $1
880
881         ldub    [$1+2+4-8], $4
882         sll     $3, 8, $3
883         or      $3, $4, $3
884
885         ldub    [$1+1+4-8], $4
886         sll     $3, 8, $3
887         or      $3, $4, $3
888
889         ldub    [$1+0+4-8], $4
890         sll     $3, 8, $3
891         or      $3, $4, $3
892 $5a:
893
894 })
895
896
897 ! {load_n_bytes}
898 !
899 ! Loads 1 to 7 bytes little endian
900 ! Remaining bytes are zeroed.
901 !
902 ! parameter 1  address
903 ! parameter 2  length
904 ! parameter 3  destination register left
905 ! parameter 4  destination register right
906 ! parameter 5  temp
907 ! parameter 6  temp2
908 ! parameter 7  label
909 ! parameter 8  return label
910
911 define(load_n_bytes, {
912
913 ! {load_n_bytes}
914 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
915
916 $7.0:   call    .+8
917         sll     $2, 2, $6
918
919         add     %o7,$7.jmp.table-$7.0,$5
920
921         add     $5, $6, $5
922         mov     0, $4
923
924         ld      [$5], $5
925
926         jmp     %o7+$5
927         mov     0, $3
928
929 $7.7:
930         ldub    [$1+6], $5
931         sll     $5, 16, $5
932         or      $3, $5, $3
933 $7.6:
934         ldub    [$1+5], $5
935         sll     $5, 8, $5
936         or      $3, $5, $3
937 $7.5:
938         ldub    [$1+4], $5
939         or      $3, $5, $3
940 $7.4:
941         ldub    [$1+3], $5
942         sll     $5, 24, $5
943         or      $4, $5, $4
944 $7.3:
945         ldub    [$1+2], $5
946         sll     $5, 16, $5
947         or      $4, $5, $4
948 $7.2:
949         ldub    [$1+1], $5
950         sll     $5, 8, $5
951         or      $4, $5, $4
952 $7.1:
953         ldub    [$1+0], $5
954         ba      $8
955         or      $4, $5, $4
956
957         .align 4
958
959 $7.jmp.table:
960         .word   0
961         .word   $7.1-$7.0
962         .word   $7.2-$7.0
963         .word   $7.3-$7.0
964         .word   $7.4-$7.0
965         .word   $7.5-$7.0
966         .word   $7.6-$7.0
967         .word   $7.7-$7.0
968 })
969
970
971 ! {store_little_endian}
972 !
973 ! parameter 1  address
974 ! parameter 2  source left
975 ! parameter 3  source right
976 ! parameter 4  temporar
977
978 define(store_little_endian, {
979
980 ! {store_little_endian}
981 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
982
983         ! rightmost in register to first in memory
984
985 #ifdef OPENSSL_SYSNAME_ULTRASPARC
986         andcc   $1, 3, global0
987         bne,pn  %icc, $5
988         nop
989
990         sta     $2, [$1] 0x88
991         add     $1, 4, $4
992
993         ba,pt   %icc, $5a
994         sta     $3, [$4] 0x88
995 #endif
996
997 $5:
998         and     $2, 255, $4
999         stub    $4, [$1+0]
1000
1001         srl     $2, 8, $4
1002         and     $4, 255, $4
1003         stub    $4, [$1+1]
1004
1005         srl     $2, 16, $4
1006         and     $4, 255, $4
1007         stub    $4, [$1+2]
1008
1009         srl     $2, 24, $4
1010         stub    $4, [$1+3]
1011
1012
1013         and     $3, 255, $4
1014         stub    $4, [$1+0+4]
1015
1016         srl     $3, 8, $4
1017         and     $4, 255, $4
1018         stub    $4, [$1+1+4]
1019
1020         srl     $3, 16, $4
1021         and     $4, 255, $4
1022         stub    $4, [$1+2+4]
1023
1024         srl     $3, 24, $4
1025         stub    $4, [$1+3+4]
1026
1027 $5a:
1028
1029 })
1030
1031
1032 ! {store_n_bytes}
1033 !
1034 ! Stores 1 to 7 bytes little endian
1035 !
1036 ! parameter 1  address
1037 ! parameter 2  length
1038 ! parameter 3  source register left
1039 ! parameter 4  source register right
1040 ! parameter 5  temp
1041 ! parameter 6  temp2
1042 ! parameter 7  label
1043 ! parameter 8  return label
1044
1045 define(store_n_bytes, {
1046
1047 ! {store_n_bytes}
1048 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
1049
1050 $7.0:   call    .+8
1051         sll     $2, 2, $6
1052
1053         add     %o7,$7.jmp.table-$7.0,$5
1054
1055         add     $5, $6, $5
1056
1057         ld      [$5], $5
1058
1059         jmp     %o7+$5
1060         nop
1061
1062 $7.7:
1063         srl     $3, 16, $5
1064         and     $5, 0xff, $5
1065         stub    $5, [$1+6]
1066 $7.6:
1067         srl     $3, 8, $5
1068         and     $5, 0xff, $5
1069         stub    $5, [$1+5]
1070 $7.5:
1071         and     $3, 0xff, $5
1072         stub    $5, [$1+4]
1073 $7.4:
1074         srl     $4, 24, $5
1075         stub    $5, [$1+3]
1076 $7.3:
1077         srl     $4, 16, $5
1078         and     $5, 0xff, $5
1079         stub    $5, [$1+2]
1080 $7.2:
1081         srl     $4, 8, $5
1082         and     $5, 0xff, $5
1083         stub    $5, [$1+1]
1084 $7.1:
1085         and     $4, 0xff, $5
1086
1087
1088         ba      $8
1089         stub    $5, [$1]
1090
1091         .align 4
1092
1093 $7.jmp.table:
1094
1095         .word   0
1096         .word   $7.1-$7.0
1097         .word   $7.2-$7.0
1098         .word   $7.3-$7.0
1099         .word   $7.4-$7.0
1100         .word   $7.5-$7.0
1101         .word   $7.6-$7.0
1102         .word   $7.7-$7.0
1103 })
1104
1105
1106 define(testvalue,{1})
1107
1108 define(register_init, {
1109
1110 ! For test purposes:
1111
1112         sethi   %hi(testvalue), local0
1113         or      local0, %lo(testvalue), local0
1114
1115         ifelse($1,{},{}, {mov   local0, $1})
1116         ifelse($2,{},{}, {mov   local0, $2})
1117         ifelse($3,{},{}, {mov   local0, $3})
1118         ifelse($4,{},{}, {mov   local0, $4})
1119         ifelse($5,{},{}, {mov   local0, $5})
1120         ifelse($6,{},{}, {mov   local0, $6})
1121         ifelse($7,{},{}, {mov   local0, $7})
1122         ifelse($8,{},{}, {mov   local0, $8})
1123
1124         mov     local0, local1
1125         mov     local0, local2
1126         mov     local0, local3
1127         mov     local0, local4
1128         mov     local0, local5
1129         mov     local0, local7
1130         mov     local0, local6
1131         mov     local0, out0
1132         mov     local0, out1
1133         mov     local0, out2
1134         mov     local0, out3
1135         mov     local0, out4
1136         mov     local0, out5
1137         mov     local0, global1
1138         mov     local0, global2
1139         mov     local0, global3
1140         mov     local0, global4
1141         mov     local0, global5
1142
1143 })
1144
1145 .section        ".text"
1146
1147         .align 32
1148
1149 .des_enc:
1150
1151         ! key address in3
1152         ! loads key next encryption/decryption first round from [in4]
1153
1154         rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
1155
1156
1157         .align 32
1158
1159 .des_dec:
1160
1161         ! implemented with out5 as first parameter to avoid
1162         ! register exchange in ede modes
1163
1164         ! key address in4
1165         ! loads key next encryption/decryption first round from [in3]
1166
1167         rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
1168
1169
1170
1171 ! void DES_encrypt1(data, ks, enc)
1172 ! *******************************
1173
1174         .align 32
1175         .global DES_encrypt1
1176         .type    DES_encrypt1,#function
1177
1178 DES_encrypt1:
1179
1180         save    %sp, FRAME, %sp
1181
1182         call    .PIC.me.up
1183         mov     .PIC.me.up-(.-4),out0
1184
1185         ld      [in0], in5                ! left
1186         cmp     in2, 0                    ! enc
1187
1188 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1189         be,pn   %icc, .encrypt.dec        ! enc/dec
1190 #else
1191         be      .encrypt.dec
1192 #endif
1193         ld      [in0+4], out5             ! right
1194
1195         ! parameter 6  1/2 for include encryption/decryption
1196         ! parameter 7  1 for move in1 to in3
1197         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1198
1199         ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
1200
1201         rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
1202
1203         fp_macro(in5, out5, 1)            ! 1 for store to [in0]
1204
1205         ret
1206         restore
1207
1208 .encrypt.dec:
1209
1210         add     in1, 120, in3             ! use last subkey for first round
1211
1212         ! parameter 6  1/2 for include encryption/decryption
1213         ! parameter 7  1 for move in1 to in3
1214         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1215
1216         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
1217
1218         fp_macro(out5, in5, 1)            ! 1 for store to [in0]
1219
1220         ret
1221         restore
1222
1223 .DES_encrypt1.end:
1224         .size    DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
1225
1226
1227 ! void DES_encrypt2(data, ks, enc)
1228 !*********************************
1229
1230         ! encrypts/decrypts without initial/final permutation
1231
1232         .align 32
1233         .global DES_encrypt2
1234         .type    DES_encrypt2,#function
1235
1236 DES_encrypt2:
1237
1238         save    %sp, FRAME, %sp
1239
1240         call    .PIC.me.up
1241         mov     .PIC.me.up-(.-4),out0
1242
1243         ! Set sbox address 1 to 6 and rotate halfs 3 left
1244         ! Errors caught by destest? Yes. Still? *NO*
1245
1246         !sethi  %hi(DES_SPtrans), global1 ! address sbox 1
1247
1248         !or     global1, %lo(DES_SPtrans), global1  ! sbox 1
1249
1250         add     global1, 256, global2     ! sbox 2
1251         add     global1, 512, global3     ! sbox 3
1252
1253         ld      [in0], out5               ! right
1254         add     global1, 768, global4     ! sbox 4
1255         add     global1, 1024, global5    ! sbox 5
1256
1257         ld      [in0+4], in5              ! left
1258         add     global1, 1280, local6     ! sbox 6
1259         add     global1, 1792, out3       ! sbox 8
1260
1261         ! rotate
1262
1263         sll     in5, 3, local5
1264         mov     in1, in3                  ! key address to in3
1265
1266         sll     out5, 3, local7
1267         srl     in5, 29, in5
1268
1269         srl     out5, 29, out5
1270         add     in5, local5, in5
1271
1272         add     out5, local7, out5
1273         cmp     in2, 0
1274
1275         ! we use our own stackframe
1276
1277 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1278         be,pn   %icc, .encrypt2.dec       ! decryption
1279 #else
1280         be      .encrypt2.dec
1281 #endif
1282         STPTR   in0, [%sp+BIAS+ARG0+0*ARGSZ]
1283
1284         ld      [in3], out0               ! key 7531 first round
1285         mov     LOOPS, out4               ! loop counter
1286
1287         ld      [in3+4], out1             ! key 8642 first round
1288         sethi   %hi(0x0000FC00), local5
1289
1290         call .des_enc
1291         mov     in3, in4
1292
1293         ! rotate
1294         sll     in5, 29, in0
1295         srl     in5, 3, in5
1296         sll     out5, 29, in1
1297         add     in5, in0, in5
1298         srl     out5, 3, out5
1299         LDPTR   [%sp+BIAS+ARG0+0*ARGSZ], in0
1300         add     out5, in1, out5
1301         st      in5, [in0]
1302         st      out5, [in0+4]
1303
1304         ret
1305         restore
1306
1307
1308 .encrypt2.dec:
1309
1310         add in3, 120, in4
1311
1312         ld      [in4], out0               ! key 7531 first round
1313         mov     LOOPS, out4               ! loop counter
1314
1315         ld      [in4+4], out1             ! key 8642 first round
1316         sethi   %hi(0x0000FC00), local5
1317
1318         mov     in5, local1               ! left expected in out5
1319         mov     out5, in5
1320
1321         call .des_dec
1322         mov     local1, out5
1323
1324 .encrypt2.finish:
1325
1326         ! rotate
1327         sll     in5, 29, in0
1328         srl     in5, 3, in5
1329         sll     out5, 29, in1
1330         add     in5, in0, in5
1331         srl     out5, 3, out5
1332         LDPTR   [%sp+BIAS+ARG0+0*ARGSZ], in0
1333         add     out5, in1, out5
1334         st      out5, [in0]
1335         st      in5, [in0+4]
1336
1337         ret
1338         restore
1339
1340 .DES_encrypt2.end:
1341         .size    DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
1342
1343
1344 ! void DES_encrypt3(data, ks1, ks2, ks3)
1345 ! **************************************
1346
1347         .align 32
1348         .global DES_encrypt3
1349         .type    DES_encrypt3,#function
1350
1351 DES_encrypt3:
1352
1353         save    %sp, FRAME, %sp
1354         
1355         call    .PIC.me.up
1356         mov     .PIC.me.up-(.-4),out0
1357
1358         ld      [in0], in5                ! left
1359         add     in2, 120, in4             ! ks2
1360
1361         ld      [in0+4], out5             ! right
1362         mov     in3, in2                  ! save ks3
1363
1364         ! parameter 6  1/2 for include encryption/decryption
1365         ! parameter 7  1 for mov in1 to in3
1366         ! parameter 8  1 for mov in3 to in4
1367         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1368
1369         ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
1370
1371         call    .des_dec
1372         mov     in2, in3                  ! preload ks3
1373
1374         call    .des_enc
1375         nop
1376
1377         fp_macro(in5, out5, 1)
1378
1379         ret
1380         restore
1381
1382 .DES_encrypt3.end:
1383         .size    DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
1384
1385
1386 ! void DES_decrypt3(data, ks1, ks2, ks3)
1387 ! **************************************
1388
1389         .align 32
1390         .global DES_decrypt3
1391         .type    DES_decrypt3,#function
1392
1393 DES_decrypt3:
1394
1395         save    %sp, FRAME, %sp
1396         
1397         call    .PIC.me.up
1398         mov     .PIC.me.up-(.-4),out0
1399
1400         ld      [in0], in5                ! left
1401         add     in3, 120, in4             ! ks3
1402
1403         ld      [in0+4], out5             ! right
1404         mov     in2, in3                  ! ks2
1405
1406         ! parameter 6  1/2 for include encryption/decryption
1407         ! parameter 7  1 for mov in1 to in3
1408         ! parameter 8  1 for mov in3 to in4
1409         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1410
1411         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
1412
1413         call    .des_enc
1414         add     in1, 120, in4             ! preload ks1
1415
1416         call    .des_dec
1417         nop
1418
1419         fp_macro(out5, in5, 1)
1420
1421         ret
1422         restore
1423
1424 .DES_decrypt3.end:
1425         .size    DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
1426
1427 ! input:        out0    offset between .PIC.me.up and caller
1428 ! output:       out0    pointer to .PIC.me.up
1429 !               out2    pointer to .des_and
1430 !               global1 pointer to DES_SPtrans
1431         .align  32
1432 .PIC.me.up:
1433         add     out0,%o7,out0                   ! pointer to .PIC.me.up
1434
1435 #ifdef OPENSSL_PIC
1436         ! In case anybody wonders why this code is same for both ABI.
1437         ! To start with it's not. Do note LDPTR below. But of course
1438         ! you must be wondering why the rest of it doesn't contain
1439         ! things like %hh, %hm and %lm. Well, those are needed only
1440         ! if OpenSSL library *itself* will become larger than 4GB,
1441         ! which is not going to happen any time soon. 
1442         sethi   %hi(DES_SPtrans),global1
1443         or      global1,%lo(DES_SPtrans),global1
1444         sethi   %hi(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2
1445         add     global1,out0,global1
1446         add     out2,%lo(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2
1447         LDPTR   [out2+global1],global1
1448 #elif 0
1449         setn    DES_SPtrans,out2,global1        ! synthetic instruction !
1450 #elif defined(ABI64)
1451         sethi   %hh(DES_SPtrans),out2
1452         or      out2,%hm(DES_SPtrans),out2
1453         sethi   %lm(DES_SPtrans),global1
1454         or      global1,%lo(DES_SPtrans),global1
1455         sllx    out2,32,out2
1456         or      out2,global1,global1
1457 #else
1458         sethi   %hi(DES_SPtrans),global1
1459         or      global1,%lo(DES_SPtrans),global1
1460 #endif
1461
1462         retl
1463         add     out0,.des_and-.PIC.me.up,out2
1464
1465         .align  256
1466         .type    .des_and,#object
1467         .size    .des_and,284
1468
1469 .des_and:
1470
1471 ! This table is used for AND 0xFC when it is known that register
1472 ! bits 8-31 are zero. Makes it possible to do three arithmetic
1473 ! operations in one cycle.
1474
1475         .byte  0, 0, 0, 0, 4, 4, 4, 4
1476         .byte  8, 8, 8, 8, 12, 12, 12, 12
1477         .byte  16, 16, 16, 16, 20, 20, 20, 20
1478         .byte  24, 24, 24, 24, 28, 28, 28, 28
1479         .byte  32, 32, 32, 32, 36, 36, 36, 36
1480         .byte  40, 40, 40, 40, 44, 44, 44, 44
1481         .byte  48, 48, 48, 48, 52, 52, 52, 52
1482         .byte  56, 56, 56, 56, 60, 60, 60, 60
1483         .byte  64, 64, 64, 64, 68, 68, 68, 68
1484         .byte  72, 72, 72, 72, 76, 76, 76, 76
1485         .byte  80, 80, 80, 80, 84, 84, 84, 84
1486         .byte  88, 88, 88, 88, 92, 92, 92, 92
1487         .byte  96, 96, 96, 96, 100, 100, 100, 100
1488         .byte  104, 104, 104, 104, 108, 108, 108, 108
1489         .byte  112, 112, 112, 112, 116, 116, 116, 116
1490         .byte  120, 120, 120, 120, 124, 124, 124, 124
1491         .byte  128, 128, 128, 128, 132, 132, 132, 132
1492         .byte  136, 136, 136, 136, 140, 140, 140, 140
1493         .byte  144, 144, 144, 144, 148, 148, 148, 148
1494         .byte  152, 152, 152, 152, 156, 156, 156, 156
1495         .byte  160, 160, 160, 160, 164, 164, 164, 164
1496         .byte  168, 168, 168, 168, 172, 172, 172, 172
1497         .byte  176, 176, 176, 176, 180, 180, 180, 180
1498         .byte  184, 184, 184, 184, 188, 188, 188, 188
1499         .byte  192, 192, 192, 192, 196, 196, 196, 196
1500         .byte  200, 200, 200, 200, 204, 204, 204, 204
1501         .byte  208, 208, 208, 208, 212, 212, 212, 212
1502         .byte  216, 216, 216, 216, 220, 220, 220, 220
1503         .byte  224, 224, 224, 224, 228, 228, 228, 228
1504         .byte  232, 232, 232, 232, 236, 236, 236, 236
1505         .byte  240, 240, 240, 240, 244, 244, 244, 244
1506         .byte  248, 248, 248, 248, 252, 252, 252, 252
1507
1508         ! 5 numbers for initil/final permutation
1509
1510         .word   0x0f0f0f0f                ! offset 256
1511         .word   0x0000ffff                ! 260
1512         .word   0x33333333                ! 264
1513         .word   0x00ff00ff                ! 268
1514         .word   0x55555555                ! 272
1515
1516         .word   0                         ! 276
1517         .word   LOOPS                     ! 280
1518         .word   0x0000FC00                ! 284
1519
1520 ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
1521 ! *****************************************************************
1522
1523
1524         .align 32
1525         .global DES_ncbc_encrypt
1526         .type    DES_ncbc_encrypt,#function
1527
1528 DES_ncbc_encrypt:
1529
1530         save    %sp, FRAME, %sp
1531         
1532         define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
1533         define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
1534         define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
1535
1536         call    .PIC.me.up
1537         mov     .PIC.me.up-(.-4),out0
1538
1539         cmp     in5, 0                    ! enc   
1540
1541 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1542         be,pn   %icc, .ncbc.dec
1543 #else
1544         be      .ncbc.dec
1545 #endif
1546         STPTR   in4, IVEC
1547
1548         ! addr  left  right  temp  label
1549         load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
1550
1551         addcc   in2, -8, in2              ! bytes missing when first block done
1552
1553 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1554         bl,pn   %icc, .ncbc.enc.seven.or.less
1555 #else
1556         bl      .ncbc.enc.seven.or.less
1557 #endif
1558         mov     in3, in4                  ! schedule
1559
1560 .ncbc.enc.next.block:
1561
1562         load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
1563
1564 .ncbc.enc.next.block_1:
1565
1566         xor     in5, out4, in5            ! iv xor
1567         xor     out5, global4, out5       ! iv xor
1568
1569         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1570         ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
1571
1572 .ncbc.enc.next.block_2:
1573
1574 !//     call .des_enc                     ! compares in2 to 8
1575 !       rounds inlined for alignment purposes
1576
1577         add     global1, 768, global4     ! address sbox 4 since register used below
1578
1579         rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
1580
1581 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1582         bl,pn   %icc, .ncbc.enc.next.block_fp
1583 #else
1584         bl      .ncbc.enc.next.block_fp
1585 #endif
1586         add     in0, 8, in0               ! input address
1587
1588         ! If 8 or more bytes are to be encrypted after this block,
1589         ! we combine final permutation for this block with initial
1590         ! permutation for next block. Load next block:
1591
1592         load_little_endian(in0, global3, global4, local5, .LLE12)
1593
1594         !  parameter 1   original left
1595         !  parameter 2   original right
1596         !  parameter 3   left ip
1597         !  parameter 4   right ip
1598         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1599         !                2: mov in4 to in3
1600         !
1601         ! also adds -8 to length in2 and loads loop counter to out4
1602
1603         fp_ip_macro(out0, out1, global3, global4, 2)
1604
1605         store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
1606
1607         ld      [in3], out0               ! key 7531 first round next block
1608         mov     in5, local1
1609         xor     global3, out5, in5        ! iv xor next block
1610
1611         ld      [in3+4], out1             ! key 8642
1612         add     global1, 512, global3     ! address sbox 3 since register used
1613         xor     global4, local1, out5     ! iv xor next block
1614
1615         ba      .ncbc.enc.next.block_2
1616         add     in1, 8, in1               ! output adress
1617
1618 .ncbc.enc.next.block_fp:
1619
1620         fp_macro(in5, out5)
1621
1622         store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
1623
1624         addcc   in2, -8, in2              ! bytes missing when next block done
1625
1626 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1627         bpos,pt %icc, .ncbc.enc.next.block  ! also jumps if 0
1628 #else
1629         bpos    .ncbc.enc.next.block
1630 #endif
1631         add     in1, 8, in1
1632
1633 .ncbc.enc.seven.or.less:
1634
1635         cmp     in2, -8
1636
1637 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1638         ble,pt  %icc, .ncbc.enc.finish
1639 #else
1640         ble     .ncbc.enc.finish
1641 #endif
1642         nop
1643
1644         add     in2, 8, local1            ! bytes to load
1645
1646         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1647         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
1648
1649         ! Loads 1 to 7 bytes little endian to global4, out4
1650
1651
1652 .ncbc.enc.finish:
1653
1654         LDPTR   IVEC, local4
1655         store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
1656
1657         ret
1658         restore
1659
1660
1661 .ncbc.dec:
1662
1663         STPTR   in0, INPUT
1664         cmp     in2, 0                    ! length
1665         add     in3, 120, in3
1666
1667         LDPTR   IVEC, local7              ! ivec
1668 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1669         ble,pn  %icc, .ncbc.dec.finish
1670 #else
1671         ble     .ncbc.dec.finish
1672 #endif
1673         mov     in3, in4                  ! schedule
1674
1675         STPTR   in1, OUTPUT
1676         mov     in0, local5               ! input
1677
1678         load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
1679
1680 .ncbc.dec.next.block:
1681
1682         load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
1683
1684         ! parameter 6  1/2 for include encryption/decryption
1685         ! parameter 7  1 for mov in1 to in3
1686         ! parameter 8  1 for mov in3 to in4
1687
1688         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
1689
1690         fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
1691
1692         ! in2 is bytes left to be stored
1693         ! in2 is compared to 8 in the rounds
1694
1695         xor     out5, in0, out4           ! iv xor
1696 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1697         bl,pn   %icc, .ncbc.dec.seven.or.less
1698 #else
1699         bl      .ncbc.dec.seven.or.less
1700 #endif
1701         xor     in5, in1, global4         ! iv xor
1702
1703         ! Load ivec next block now, since input and output address might be the same.
1704
1705         load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
1706
1707         store_little_endian(local7, out4, global4, local3, .SLE3)
1708
1709         STPTR   local5, INPUT
1710         add     local7, 8, local7
1711         addcc   in2, -8, in2
1712
1713 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1714         bg,pt   %icc, .ncbc.dec.next.block
1715 #else
1716         bg      .ncbc.dec.next.block
1717 #endif
1718         STPTR   local7, OUTPUT
1719
1720
1721 .ncbc.dec.store.iv:
1722
1723         LDPTR   IVEC, local4              ! ivec
1724         store_little_endian(local4, in0, in1, local5, .SLE4)
1725
1726 .ncbc.dec.finish:
1727
1728         ret
1729         restore
1730
1731 .ncbc.dec.seven.or.less:
1732
1733         load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
1734
1735         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
1736
1737
1738 .DES_ncbc_encrypt.end:
1739         .size    DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
1740
1741
1742 ! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
1743 ! **************************************************************************
1744
1745
1746         .align 32
1747         .global DES_ede3_cbc_encrypt
1748         .type    DES_ede3_cbc_encrypt,#function
1749
1750 DES_ede3_cbc_encrypt:
1751
1752         save    %sp, FRAME, %sp
1753
1754         define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
1755         define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1756         define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
1757
1758         call    .PIC.me.up
1759         mov     .PIC.me.up-(.-4),out0
1760
1761         LDPTR   [%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
1762         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1763         cmp     local3, 0                 ! enc
1764
1765 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1766         be,pn   %icc, .ede3.dec
1767 #else
1768         be      .ede3.dec
1769 #endif
1770         STPTR   in4, KS2
1771
1772         STPTR   in5, KS3
1773
1774         load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
1775
1776         addcc   in2, -8, in2              ! bytes missing after next block
1777
1778 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1779         bl,pn   %icc,  .ede3.enc.seven.or.less
1780 #else
1781         bl      .ede3.enc.seven.or.less
1782 #endif
1783         STPTR   in3, KS1
1784
1785 .ede3.enc.next.block:
1786
1787         load_little_endian(in0, out4, global4, local3, .LLE7)
1788
1789 .ede3.enc.next.block_1:
1790
1791         LDPTR   KS2, in4
1792         xor     in5, out4, in5            ! iv xor
1793         xor     out5, global4, out5       ! iv xor
1794
1795         LDPTR   KS1, in3
1796         add     in4, 120, in4             ! for decryption we use last subkey first
1797         nop
1798
1799         ip_macro(in5, out5, in5, out5, in3)
1800
1801 .ede3.enc.next.block_2:
1802
1803         call .des_enc                     ! ks1 in3
1804         nop
1805
1806         call .des_dec                     ! ks2 in4
1807         LDPTR   KS3, in3
1808
1809         call .des_enc                     ! ks3 in3  compares in2 to 8
1810         nop
1811
1812 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1813         bl,pn   %icc, .ede3.enc.next.block_fp
1814 #else
1815         bl      .ede3.enc.next.block_fp
1816 #endif
1817         add     in0, 8, in0
1818
1819         ! If 8 or more bytes are to be encrypted after this block,
1820         ! we combine final permutation for this block with initial
1821         ! permutation for next block. Load next block:
1822
1823         load_little_endian(in0, global3, global4, local5, .LLE11)
1824
1825         !  parameter 1   original left
1826         !  parameter 2   original right
1827         !  parameter 3   left ip
1828         !  parameter 4   right ip
1829         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1830         !                2: mov in4 to in3
1831         !
1832         ! also adds -8 to length in2 and loads loop counter to out4
1833
1834         fp_ip_macro(out0, out1, global3, global4, 1)
1835
1836         store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
1837
1838         mov     in5, local1
1839         xor     global3, out5, in5        ! iv xor next block
1840
1841         ld      [in3], out0               ! key 7531
1842         add     global1, 512, global3     ! address sbox 3
1843         xor     global4, local1, out5     ! iv xor next block
1844
1845         ld      [in3+4], out1             ! key 8642
1846         add     global1, 768, global4     ! address sbox 4
1847         ba      .ede3.enc.next.block_2
1848         add     in1, 8, in1
1849
1850 .ede3.enc.next.block_fp:
1851
1852         fp_macro(in5, out5)
1853
1854         store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
1855
1856         addcc   in2, -8, in2              ! bytes missing when next block done
1857
1858 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1859         bpos,pt %icc, .ede3.enc.next.block
1860 #else
1861         bpos    .ede3.enc.next.block
1862 #endif
1863         add     in1, 8, in1
1864
1865 .ede3.enc.seven.or.less:
1866
1867         cmp     in2, -8
1868
1869 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1870         ble,pt  %icc, .ede3.enc.finish
1871 #else
1872         ble     .ede3.enc.finish
1873 #endif
1874         nop
1875
1876         add     in2, 8, local1            ! bytes to load
1877
1878         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1879         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
1880
1881 .ede3.enc.finish:
1882
1883         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1884         store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
1885
1886         ret
1887         restore
1888
1889 .ede3.dec:
1890
1891         STPTR   in0, INPUT
1892         add     in5, 120, in5
1893
1894         STPTR   in1, OUTPUT
1895         mov     in0, local5
1896         add     in3, 120, in3
1897
1898         STPTR   in3, KS1
1899         cmp     in2, 0
1900
1901 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1902         ble     %icc, .ede3.dec.finish
1903 #else
1904         ble     .ede3.dec.finish
1905 #endif
1906         STPTR   in5, KS3
1907
1908         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
1909         load_little_endian(local7, in0, in1, local3, .LLE8)
1910
1911 .ede3.dec.next.block:
1912
1913         load_little_endian(local5, in5, out5, local3, .LLE9)
1914
1915         ! parameter 6  1/2 for include encryption/decryption
1916         ! parameter 7  1 for mov in1 to in3
1917         ! parameter 8  1 for mov in3 to in4
1918         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1919
1920         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
1921
1922         call .des_enc                     ! ks2 in3
1923         LDPTR   KS1, in4
1924
1925         call .des_dec                     ! ks1 in4
1926         nop
1927
1928         fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
1929
1930         ! in2 is bytes left to be stored
1931         ! in2 is compared to 8 in the rounds
1932
1933         xor     out5, in0, out4
1934 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1935         bl,pn   %icc, .ede3.dec.seven.or.less
1936 #else
1937         bl      .ede3.dec.seven.or.less
1938 #endif
1939         xor     in5, in1, global4
1940
1941         load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
1942
1943         store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
1944
1945         STPTR   local5, INPUT
1946         addcc   in2, -8, in2
1947         add     local7, 8, local7
1948
1949 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1950         bg,pt   %icc, .ede3.dec.next.block
1951 #else
1952         bg      .ede3.dec.next.block
1953 #endif
1954         STPTR   local7, OUTPUT
1955
1956 .ede3.dec.store.iv:
1957
1958         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1959         store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
1960
1961 .ede3.dec.finish:
1962
1963         ret
1964         restore
1965
1966 .ede3.dec.seven.or.less:
1967
1968         load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
1969
1970         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
1971
1972
1973 .DES_ede3_cbc_encrypt.end:
1974         .size    DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt