GAS can't stand stub, which is stb's synonym.
[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         sethi   %hi(DES_SPtrans),global1
1437         or      global1,%lo(DES_SPtrans),global1
1438         sethi   %hi(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2
1439         add     global1,out0,global1
1440         add     out2,%lo(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2
1441         LDPTR   [out2+global1],global1
1442 #else
1443         setn    DES_SPtrans,out2,global1        ! synthetic instruction !
1444 #endif
1445
1446         retl
1447         add     out0,.des_and-.PIC.me.up,out2
1448
1449         .align  256
1450         .type    .des_and,#object
1451         .size    .des_and,284
1452
1453 .des_and:
1454
1455 ! This table is used for AND 0xFC when it is known that register
1456 ! bits 8-31 are zero. Makes it possible to do three arithmetic
1457 ! operations in one cycle.
1458
1459         .byte  0, 0, 0, 0, 4, 4, 4, 4
1460         .byte  8, 8, 8, 8, 12, 12, 12, 12
1461         .byte  16, 16, 16, 16, 20, 20, 20, 20
1462         .byte  24, 24, 24, 24, 28, 28, 28, 28
1463         .byte  32, 32, 32, 32, 36, 36, 36, 36
1464         .byte  40, 40, 40, 40, 44, 44, 44, 44
1465         .byte  48, 48, 48, 48, 52, 52, 52, 52
1466         .byte  56, 56, 56, 56, 60, 60, 60, 60
1467         .byte  64, 64, 64, 64, 68, 68, 68, 68
1468         .byte  72, 72, 72, 72, 76, 76, 76, 76
1469         .byte  80, 80, 80, 80, 84, 84, 84, 84
1470         .byte  88, 88, 88, 88, 92, 92, 92, 92
1471         .byte  96, 96, 96, 96, 100, 100, 100, 100
1472         .byte  104, 104, 104, 104, 108, 108, 108, 108
1473         .byte  112, 112, 112, 112, 116, 116, 116, 116
1474         .byte  120, 120, 120, 120, 124, 124, 124, 124
1475         .byte  128, 128, 128, 128, 132, 132, 132, 132
1476         .byte  136, 136, 136, 136, 140, 140, 140, 140
1477         .byte  144, 144, 144, 144, 148, 148, 148, 148
1478         .byte  152, 152, 152, 152, 156, 156, 156, 156
1479         .byte  160, 160, 160, 160, 164, 164, 164, 164
1480         .byte  168, 168, 168, 168, 172, 172, 172, 172
1481         .byte  176, 176, 176, 176, 180, 180, 180, 180
1482         .byte  184, 184, 184, 184, 188, 188, 188, 188
1483         .byte  192, 192, 192, 192, 196, 196, 196, 196
1484         .byte  200, 200, 200, 200, 204, 204, 204, 204
1485         .byte  208, 208, 208, 208, 212, 212, 212, 212
1486         .byte  216, 216, 216, 216, 220, 220, 220, 220
1487         .byte  224, 224, 224, 224, 228, 228, 228, 228
1488         .byte  232, 232, 232, 232, 236, 236, 236, 236
1489         .byte  240, 240, 240, 240, 244, 244, 244, 244
1490         .byte  248, 248, 248, 248, 252, 252, 252, 252
1491
1492         ! 5 numbers for initil/final permutation
1493
1494         .word   0x0f0f0f0f                ! offset 256
1495         .word   0x0000ffff                ! 260
1496         .word   0x33333333                ! 264
1497         .word   0x00ff00ff                ! 268
1498         .word   0x55555555                ! 272
1499
1500         .word   0                         ! 276
1501         .word   LOOPS                     ! 280
1502         .word   0x0000FC00                ! 284
1503
1504 ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
1505 ! *****************************************************************
1506
1507
1508         .align 32
1509         .global DES_ncbc_encrypt
1510         .type    DES_ncbc_encrypt,#function
1511
1512 DES_ncbc_encrypt:
1513
1514         save    %sp, FRAME, %sp
1515         
1516         define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
1517         define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
1518         define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
1519
1520         call    .PIC.me.up
1521         mov     .PIC.me.up-(.-4),out0
1522
1523         cmp     in5, 0                    ! enc   
1524
1525 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1526         be,pn   %icc, .ncbc.dec
1527 #else
1528         be      .ncbc.dec
1529 #endif
1530         STPTR   in4, IVEC
1531
1532         ! addr  left  right  temp  label
1533         load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
1534
1535         addcc   in2, -8, in2              ! bytes missing when first block done
1536
1537 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1538         bl,pn   %icc, .ncbc.enc.seven.or.less
1539 #else
1540         bl      .ncbc.enc.seven.or.less
1541 #endif
1542         mov     in3, in4                  ! schedule
1543
1544 .ncbc.enc.next.block:
1545
1546         load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
1547
1548 .ncbc.enc.next.block_1:
1549
1550         xor     in5, out4, in5            ! iv xor
1551         xor     out5, global4, out5       ! iv xor
1552
1553         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1554         ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
1555
1556 .ncbc.enc.next.block_2:
1557
1558 !//     call .des_enc                     ! compares in2 to 8
1559 !       rounds inlined for alignment purposes
1560
1561         add     global1, 768, global4     ! address sbox 4 since register used below
1562
1563         rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
1564
1565 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1566         bl,pn   %icc, .ncbc.enc.next.block_fp
1567 #else
1568         bl      .ncbc.enc.next.block_fp
1569 #endif
1570         add     in0, 8, in0               ! input address
1571
1572         ! If 8 or more bytes are to be encrypted after this block,
1573         ! we combine final permutation for this block with initial
1574         ! permutation for next block. Load next block:
1575
1576         load_little_endian(in0, global3, global4, local5, .LLE12)
1577
1578         !  parameter 1   original left
1579         !  parameter 2   original right
1580         !  parameter 3   left ip
1581         !  parameter 4   right ip
1582         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1583         !                2: mov in4 to in3
1584         !
1585         ! also adds -8 to length in2 and loads loop counter to out4
1586
1587         fp_ip_macro(out0, out1, global3, global4, 2)
1588
1589         store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
1590
1591         ld      [in3], out0               ! key 7531 first round next block
1592         mov     in5, local1
1593         xor     global3, out5, in5        ! iv xor next block
1594
1595         ld      [in3+4], out1             ! key 8642
1596         add     global1, 512, global3     ! address sbox 3 since register used
1597         xor     global4, local1, out5     ! iv xor next block
1598
1599         ba      .ncbc.enc.next.block_2
1600         add     in1, 8, in1               ! output adress
1601
1602 .ncbc.enc.next.block_fp:
1603
1604         fp_macro(in5, out5)
1605
1606         store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
1607
1608         addcc   in2, -8, in2              ! bytes missing when next block done
1609
1610 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1611         bpos,pt %icc, .ncbc.enc.next.block  ! also jumps if 0
1612 #else
1613         bpos    .ncbc.enc.next.block
1614 #endif
1615         add     in1, 8, in1
1616
1617 .ncbc.enc.seven.or.less:
1618
1619         cmp     in2, -8
1620
1621 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1622         ble,pt  %icc, .ncbc.enc.finish
1623 #else
1624         ble     .ncbc.enc.finish
1625 #endif
1626         nop
1627
1628         add     in2, 8, local1            ! bytes to load
1629
1630         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1631         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
1632
1633         ! Loads 1 to 7 bytes little endian to global4, out4
1634
1635
1636 .ncbc.enc.finish:
1637
1638         LDPTR   IVEC, local4
1639         store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
1640
1641         ret
1642         restore
1643
1644
1645 .ncbc.dec:
1646
1647         STPTR   in0, INPUT
1648         cmp     in2, 0                    ! length
1649         add     in3, 120, in3
1650
1651         LDPTR   IVEC, local7              ! ivec
1652 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1653         ble,pn  %icc, .ncbc.dec.finish
1654 #else
1655         ble     .ncbc.dec.finish
1656 #endif
1657         mov     in3, in4                  ! schedule
1658
1659         STPTR   in1, OUTPUT
1660         mov     in0, local5               ! input
1661
1662         load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
1663
1664 .ncbc.dec.next.block:
1665
1666         load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
1667
1668         ! parameter 6  1/2 for include encryption/decryption
1669         ! parameter 7  1 for mov in1 to in3
1670         ! parameter 8  1 for mov in3 to in4
1671
1672         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
1673
1674         fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
1675
1676         ! in2 is bytes left to be stored
1677         ! in2 is compared to 8 in the rounds
1678
1679         xor     out5, in0, out4           ! iv xor
1680 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1681         bl,pn   %icc, .ncbc.dec.seven.or.less
1682 #else
1683         bl      .ncbc.dec.seven.or.less
1684 #endif
1685         xor     in5, in1, global4         ! iv xor
1686
1687         ! Load ivec next block now, since input and output address might be the same.
1688
1689         load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
1690
1691         store_little_endian(local7, out4, global4, local3, .SLE3)
1692
1693         STPTR   local5, INPUT
1694         add     local7, 8, local7
1695         addcc   in2, -8, in2
1696
1697 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1698         bg,pt   %icc, .ncbc.dec.next.block
1699 #else
1700         bg      .ncbc.dec.next.block
1701 #endif
1702         STPTR   local7, OUTPUT
1703
1704
1705 .ncbc.dec.store.iv:
1706
1707         LDPTR   IVEC, local4              ! ivec
1708         store_little_endian(local4, in0, in1, local5, .SLE4)
1709
1710 .ncbc.dec.finish:
1711
1712         ret
1713         restore
1714
1715 .ncbc.dec.seven.or.less:
1716
1717         load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
1718
1719         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
1720
1721
1722 .DES_ncbc_encrypt.end:
1723         .size    DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
1724
1725
1726 ! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
1727 ! **************************************************************************
1728
1729
1730         .align 32
1731         .global DES_ede3_cbc_encrypt
1732         .type    DES_ede3_cbc_encrypt,#function
1733
1734 DES_ede3_cbc_encrypt:
1735
1736         save    %sp, FRAME, %sp
1737
1738         define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
1739         define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1740         define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
1741
1742         call    .PIC.me.up
1743         mov     .PIC.me.up-(.-4),out0
1744
1745         LDPTR   [%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
1746         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1747         cmp     local3, 0                 ! enc
1748
1749 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1750         be,pn   %icc, .ede3.dec
1751 #else
1752         be      .ede3.dec
1753 #endif
1754         STPTR   in4, KS2
1755
1756         STPTR   in5, KS3
1757
1758         load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
1759
1760         addcc   in2, -8, in2              ! bytes missing after next block
1761
1762 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1763         bl,pn   %icc,  .ede3.enc.seven.or.less
1764 #else
1765         bl      .ede3.enc.seven.or.less
1766 #endif
1767         STPTR   in3, KS1
1768
1769 .ede3.enc.next.block:
1770
1771         load_little_endian(in0, out4, global4, local3, .LLE7)
1772
1773 .ede3.enc.next.block_1:
1774
1775         LDPTR   KS2, in4
1776         xor     in5, out4, in5            ! iv xor
1777         xor     out5, global4, out5       ! iv xor
1778
1779         LDPTR   KS1, in3
1780         add     in4, 120, in4             ! for decryption we use last subkey first
1781         nop
1782
1783         ip_macro(in5, out5, in5, out5, in3)
1784
1785 .ede3.enc.next.block_2:
1786
1787         call .des_enc                     ! ks1 in3
1788         nop
1789
1790         call .des_dec                     ! ks2 in4
1791         LDPTR   KS3, in3
1792
1793         call .des_enc                     ! ks3 in3  compares in2 to 8
1794         nop
1795
1796 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1797         bl,pn   %icc, .ede3.enc.next.block_fp
1798 #else
1799         bl      .ede3.enc.next.block_fp
1800 #endif
1801         add     in0, 8, in0
1802
1803         ! If 8 or more bytes are to be encrypted after this block,
1804         ! we combine final permutation for this block with initial
1805         ! permutation for next block. Load next block:
1806
1807         load_little_endian(in0, global3, global4, local5, .LLE11)
1808
1809         !  parameter 1   original left
1810         !  parameter 2   original right
1811         !  parameter 3   left ip
1812         !  parameter 4   right ip
1813         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1814         !                2: mov in4 to in3
1815         !
1816         ! also adds -8 to length in2 and loads loop counter to out4
1817
1818         fp_ip_macro(out0, out1, global3, global4, 1)
1819
1820         store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
1821
1822         mov     in5, local1
1823         xor     global3, out5, in5        ! iv xor next block
1824
1825         ld      [in3], out0               ! key 7531
1826         add     global1, 512, global3     ! address sbox 3
1827         xor     global4, local1, out5     ! iv xor next block
1828
1829         ld      [in3+4], out1             ! key 8642
1830         add     global1, 768, global4     ! address sbox 4
1831         ba      .ede3.enc.next.block_2
1832         add     in1, 8, in1
1833
1834 .ede3.enc.next.block_fp:
1835
1836         fp_macro(in5, out5)
1837
1838         store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
1839
1840         addcc   in2, -8, in2              ! bytes missing when next block done
1841
1842 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1843         bpos,pt %icc, .ede3.enc.next.block
1844 #else
1845         bpos    .ede3.enc.next.block
1846 #endif
1847         add     in1, 8, in1
1848
1849 .ede3.enc.seven.or.less:
1850
1851         cmp     in2, -8
1852
1853 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1854         ble,pt  %icc, .ede3.enc.finish
1855 #else
1856         ble     .ede3.enc.finish
1857 #endif
1858         nop
1859
1860         add     in2, 8, local1            ! bytes to load
1861
1862         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1863         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
1864
1865 .ede3.enc.finish:
1866
1867         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1868         store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
1869
1870         ret
1871         restore
1872
1873 .ede3.dec:
1874
1875         STPTR   in0, INPUT
1876         add     in5, 120, in5
1877
1878         STPTR   in1, OUTPUT
1879         mov     in0, local5
1880         add     in3, 120, in3
1881
1882         STPTR   in3, KS1
1883         cmp     in2, 0
1884
1885 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1886         ble     %icc, .ede3.dec.finish
1887 #else
1888         ble     .ede3.dec.finish
1889 #endif
1890         STPTR   in5, KS3
1891
1892         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
1893         load_little_endian(local7, in0, in1, local3, .LLE8)
1894
1895 .ede3.dec.next.block:
1896
1897         load_little_endian(local5, in5, out5, local3, .LLE9)
1898
1899         ! parameter 6  1/2 for include encryption/decryption
1900         ! parameter 7  1 for mov in1 to in3
1901         ! parameter 8  1 for mov in3 to in4
1902         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1903
1904         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
1905
1906         call .des_enc                     ! ks2 in3
1907         LDPTR   KS1, in4
1908
1909         call .des_dec                     ! ks1 in4
1910         nop
1911
1912         fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
1913
1914         ! in2 is bytes left to be stored
1915         ! in2 is compared to 8 in the rounds
1916
1917         xor     out5, in0, out4
1918 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1919         bl,pn   %icc, .ede3.dec.seven.or.less
1920 #else
1921         bl      .ede3.dec.seven.or.less
1922 #endif
1923         xor     in5, in1, global4
1924
1925         load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
1926
1927         store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
1928
1929         STPTR   local5, INPUT
1930         addcc   in2, -8, in2
1931         add     local7, 8, local7
1932
1933 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1934         bg,pt   %icc, .ede3.dec.next.block
1935 #else
1936         bg      .ede3.dec.next.block
1937 #endif
1938         STPTR   local7, OUTPUT
1939
1940 .ede3.dec.store.iv:
1941
1942         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1943         store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
1944
1945 .ede3.dec.finish:
1946
1947         ret
1948         restore
1949
1950 .ede3.dec.seven.or.less:
1951
1952         load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
1953
1954         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
1955
1956
1957 .DES_ede3_cbc_encrypt.end:
1958         .size    DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt