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