6ae17fddb79c4fae1be7c935cb682b2868adb543
[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.1"
47 .file  "des_enc-sparc.S"
48
49 #include <openssl/opensslconf.h>
50
51 #ifdef OPENSSL_FIPSCANISTER
52 #include <openssl/fipssyms.h>
53 #endif
54
55 #if defined(__SUNPRO_C) && defined(__sparcv9)
56 # define ABI64  /* They've said -xarch=v9 at command line */
57 #elif defined(__GNUC__) && defined(__arch64__)
58 # define ABI64  /* They've said -m64 at command line */
59 #endif
60
61 #ifdef ABI64
62   .register     %g2,#scratch
63   .register     %g3,#scratch
64 # define        FRAME   -192
65 # define        BIAS    2047
66 # define        LDPTR   ldx
67 # define        STPTR   stx
68 # define        ARG0    128
69 # define        ARGSZ   8
70 #else
71 # define        FRAME   -96
72 # define        BIAS    0
73 # define        LDPTR   ld
74 # define        STPTR   st
75 # define        ARG0    68
76 # define        ARGSZ   4
77 #endif
78
79 #define LOOPS 7
80
81 #define global0 %g0
82 #define global1 %g1
83 #define global2 %g2
84 #define global3 %g3
85 #define global4 %g4
86 #define global5 %g5
87
88 #define local0 %l0
89 #define local1 %l1
90 #define local2 %l2
91 #define local3 %l3
92 #define local4 %l4
93 #define local5 %l5
94 #define local7 %l6
95 #define local6 %l7
96
97 #define in0 %i0
98 #define in1 %i1
99 #define in2 %i2
100 #define in3 %i3
101 #define in4 %i4
102 #define in5 %i5
103 #define in6 %i6
104 #define in7 %i7
105
106 #define out0 %o0
107 #define out1 %o1
108 #define out2 %o2
109 #define out3 %o3
110 #define out4 %o4
111 #define out5 %o5
112 #define out6 %o6
113 #define out7 %o7
114
115 #define stub stb
116
117 changequote({,})
118
119
120 ! Macro definitions:
121
122
123 ! {ip_macro}
124 !
125 ! The logic used in initial and final permutations is the same as in
126 ! the C code. The permutations are done with a clever shift, xor, and
127 ! technique.
128 !
129 ! The macro also loads address sbox 1 to 5 to global 1 to 5, address
130 ! sbox 6 to local6, and addres sbox 8 to out3.
131 !
132 ! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
133 !
134 ! Loads key first round from address in parameter 5 to out0, out1.
135 !
136 ! After the the original LibDES initial permutation, the resulting left
137 ! is in the variable initially used for right and vice versa. The macro
138 ! implements the possibility to keep the halfs in the original registers.
139 !
140 ! parameter 1  left
141 ! parameter 2  right
142 ! parameter 3  result left (modify in first round)
143 ! parameter 4  result right (use in first round)
144 ! parameter 5  key address
145 ! parameter 6  1/2 for include encryption/decryption
146 ! parameter 7  1 for move in1 to in3
147 ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
148 ! parameter 9  1 for load ks3 and ks2 to in4 and in3
149
150 define(ip_macro, {
151
152 ! {ip_macro}
153 ! $1 $2 $4 $3 $5 $6 $7 $8 $9
154
155         ld      [out2+256], local1
156         srl     $2, 4, local4
157
158         xor     local4, $1, local4
159         ifelse($7,1,{mov in1, in3},{nop})
160
161         ld      [out2+260], local2
162         and     local4, local1, local4
163         ifelse($8,1,{mov in3, in4},{})
164         ifelse($8,2,{mov in4, in3},{})
165
166         ld      [out2+280], out4          ! loop counter
167         sll     local4, 4, local1
168         xor     $1, local4, $1
169
170         ld      [out2+264], local3
171         srl     $1, 16, local4
172         xor     $2, local1, $2
173
174         ifelse($9,1,{LDPTR      KS3, in4},{})
175         xor     local4, $2, local4
176         nop     !sethi  %hi(DES_SPtrans), global1 ! sbox addr
177
178         ifelse($9,1,{LDPTR      KS2, in3},{})
179         and     local4, local2, local4
180         nop     !or     global1, %lo(DES_SPtrans), global1   ! sbox addr
181
182         sll     local4, 16, local1
183         xor     $2, local4, $2
184
185         srl     $2, 2, local4
186         xor     $1, local1, $1
187
188         sethi   %hi(16711680), local5
189         xor     local4, $1, local4
190
191         and     local4, local3, local4
192         or      local5, 255, local5
193
194         sll     local4, 2, local2
195         xor     $1, local4, $1
196
197         srl     $1, 8, local4
198         xor     $2, local2, $2
199
200         xor     local4, $2, local4
201         add     global1, 768, global4
202
203         and     local4, local5, local4
204         add     global1, 1024, global5
205
206         ld      [out2+272], local7
207         sll     local4, 8, local1
208         xor     $2, local4, $2
209
210         srl     $2, 1, local4
211         xor     $1, local1, $1
212
213         ld      [$5], out0                ! key 7531
214         xor     local4, $1, local4
215         add     global1, 256, global2
216
217         ld      [$5+4], out1              ! key 8642
218         and     local4, local7, local4
219         add     global1, 512, global3
220
221         sll     local4, 1, local1
222         xor     $1, local4, $1
223
224         sll     $1, 3, local3
225         xor     $2, local1, $2
226
227         sll     $2, 3, local2
228         add     global1, 1280, local6     ! address sbox 8
229
230         srl     $1, 29, local4
231         add     global1, 1792, out3       ! address sbox 8
232
233         srl     $2, 29, local1
234         or      local4, local3, $4
235
236         or      local2, local1, $3
237
238         ifelse($6, 1, {
239
240                 ld      [out2+284], local5     ! 0x0000FC00 used in the rounds
241                 or      local2, local1, $3
242                 xor     $4, out0, local1
243
244                 call .des_enc.1
245                 and     local1, 252, local1
246
247         },{})
248
249         ifelse($6, 2, {
250
251                 ld      [out2+284], local5     ! 0x0000FC00 used in the rounds
252                 or      local2, local1, $3
253                 xor     $4, out0, local1
254
255                 call .des_dec.1
256                 and     local1, 252, local1
257
258         },{})
259 })
260
261
262 ! {rounds_macro}
263 !
264 ! The logic used in the DES rounds is the same as in the C code,
265 ! except that calculations for sbox 1 and sbox 5 begin before
266 ! the previous round is finished.
267 !
268 ! In each round one half (work) is modified based on key and the
269 ! other half (use).
270 !
271 ! In this version we do two rounds in a loop repeated 7 times
272 ! and two rounds separately.
273 !
274 ! One half has the bits for the sboxes in the following positions:
275 !
276 !       777777xx555555xx333333xx111111xx
277 !
278 !       88xx666666xx444444xx222222xx8888
279 !
280 ! The bits for each sbox are xor-ed with the key bits for that box.
281 ! The above xx bits are cleared, and the result used for lookup in
282 ! the sbox table. Each sbox entry contains the 4 output bits permuted
283 ! into 32 bits according to the P permutation.
284 !
285 ! In the description of DES, left and right are switched after
286 ! each round, except after last round. In this code the original
287 ! left and right are kept in the same register in all rounds, meaning
288 ! that after the 16 rounds the result for right is in the register
289 ! originally used for left.
290 !
291 ! parameter 1  first work (left in first round)
292 ! parameter 2  first use (right in first round)
293 ! parameter 3  enc/dec  1/-1
294 ! parameter 4  loop label
295 ! parameter 5  key address register
296 ! parameter 6  optional address for key next encryption/decryption
297 ! parameter 7  not empty for include retl
298 !
299 ! also compares in2 to 8
300
301 define(rounds_macro, {
302
303 ! {rounds_macro}
304 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
305
306         xor     $2, out0, local1
307
308         ld      [out2+284], local5        ! 0x0000FC00
309         ba      $4
310         and     local1, 252, local1
311
312         .align 32
313
314 $4:
315         ! local6 is address sbox 6
316         ! out3   is address sbox 8
317         ! out4   is loop counter
318
319         ld      [global1+local1], local1
320         xor     $2, out1, out1            ! 8642
321         xor     $2, out0, out0            ! 7531
322         ! fmovs %f0, %f0                  ! fxor used for alignment
323
324         srl     out1, 4, local0           ! rotate 4 right
325         and     out0, local5, local3      ! 3
326         ! fmovs %f0, %f0
327
328         ld      [$5+$3*8], local7         ! key 7531 next round
329         srl     local3, 8, local3         ! 3
330         and     local0, 252, local2       ! 2
331         ! fmovs %f0, %f0
332
333         ld      [global3+local3],local3   ! 3
334         sll     out1, 28, out1            ! rotate
335         xor     $1, local1, $1            ! 1 finished, local1 now sbox 7
336
337         ld      [global2+local2], local2  ! 2 
338         srl     out0, 24, local1          ! 7
339         or      out1, local0, out1        ! rotate
340
341         ldub    [out2+local1], local1     ! 7 (and 0xFC)
342         srl     out1, 24, local0          ! 8
343         and     out1, local5, local4      ! 4
344
345         ldub    [out2+local0], local0     ! 8 (and 0xFC)
346         srl     local4, 8, local4         ! 4
347         xor     $1, local2, $1            ! 2 finished local2 now sbox 6
348
349         ld      [global4+local4],local4   ! 4
350         srl     out1, 16, local2          ! 6
351         xor     $1, local3, $1            ! 3 finished local3 now sbox 5
352
353         ld      [out3+local0],local0      ! 8
354         and     local2, 252, local2       ! 6
355         add     global1, 1536, local5     ! address sbox 7
356
357         ld      [local6+local2], local2   ! 6
358         srl     out0, 16, local3          ! 5
359         xor     $1, local4, $1            ! 4 finished
360
361         ld      [local5+local1],local1    ! 7
362         and     local3, 252, local3       ! 5
363         xor     $1, local0, $1            ! 8 finished
364
365         ld      [global5+local3],local3   ! 5
366         xor     $1, local2, $1            ! 6 finished
367         subcc   out4, 1, out4
368
369         ld      [$5+$3*8+4], out0         ! key 8642 next round
370         xor     $1, local7, local2        ! sbox 5 next round
371         xor     $1, local1, $1            ! 7 finished
372
373         srl     local2, 16, local2        ! sbox 5 next round
374         xor     $1, local3, $1            ! 5 finished
375
376         ld      [$5+$3*16+4], out1        ! key 8642 next round again
377         and     local2, 252, local2       ! sbox5 next round
378 ! next round
379         xor     $1, local7, local7        ! 7531
380
381         ld      [global5+local2], local2  ! 5
382         srl     local7, 24, local3        ! 7
383         xor     $1, out0, out0            ! 8642
384
385         ldub    [out2+local3], local3     ! 7 (and 0xFC)
386         srl     out0, 4, local0           ! rotate 4 right
387         and     local7, 252, local1       ! 1
388
389         sll     out0, 28, out0            ! rotate
390         xor     $2, local2, $2            ! 5 finished local2 used
391
392         srl     local0, 8, local4         ! 4
393         and     local0, 252, local2       ! 2
394         ld      [local5+local3], local3   ! 7
395
396         srl     local0, 16, local5        ! 6
397         or      out0, local0, out0        ! rotate
398         ld      [global2+local2], local2  ! 2
399
400         srl     out0, 24, local0
401         ld      [$5+$3*16], out0          ! key 7531 next round
402         and     local4, 252, local4       ! 4
403
404         and     local5, 252, local5       ! 6
405         ld      [global4+local4], local4  ! 4
406         xor     $2, local3, $2            ! 7 finished local3 used
407
408         and     local0, 252, local0       ! 8
409         ld      [local6+local5], local5   ! 6
410         xor     $2, local2, $2            ! 2 finished local2 now sbox 3
411
412         srl     local7, 8, local2         ! 3 start
413         ld      [out3+local0], local0     ! 8
414         xor     $2, local4, $2            ! 4 finished
415
416         and     local2, 252, local2       ! 3
417         ld      [global1+local1], local1  ! 1
418         xor     $2, local5, $2            ! 6 finished local5 used
419
420         ld      [global3+local2], local2  ! 3
421         xor     $2, local0, $2            ! 8 finished
422         add     $5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
423
424         ld      [out2+284], local5        ! 0x0000FC00
425         xor     $2, out0, local4          ! sbox 1 next round
426         xor     $2, local1, $2            ! 1 finished
427
428         xor     $2, local2, $2            ! 3 finished
429         bne     $4
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 $5:
788         ldub    [$1+3], $2
789
790         ldub    [$1+2], $4
791         sll     $2, 8, $2
792         or      $2, $4, $2
793
794         ldub    [$1+1], $4
795         sll     $2, 8, $2
796         or      $2, $4, $2
797
798         ldub    [$1+0], $4
799         sll     $2, 8, $2
800         or      $2, $4, $2
801
802
803         ldub    [$1+3+4], $3
804
805         ldub    [$1+2+4], $4
806         sll     $3, 8, $3
807         or      $3, $4, $3
808
809         ldub    [$1+1+4], $4
810         sll     $3, 8, $3
811         or      $3, $4, $3
812
813         ldub    [$1+0+4], $4
814         sll     $3, 8, $3
815         or      $3, $4, $3
816 $5a:
817
818 })
819
820
821 ! {load_little_endian_inc}
822 !
823 ! parameter 1  address
824 ! parameter 2  destination left
825 ! parameter 3  destination right
826 ! parameter 4  temporar
827 ! parameter 4  label
828 !
829 ! adds 8 to address
830
831 define(load_little_endian_inc, {
832
833 ! {load_little_endian_inc}
834 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
835
836         ! first in memory to rightmost in register
837
838 $5:
839         ldub    [$1+3], $2
840
841         ldub    [$1+2], $4
842         sll     $2, 8, $2
843         or      $2, $4, $2
844
845         ldub    [$1+1], $4
846         sll     $2, 8, $2
847         or      $2, $4, $2
848
849         ldub    [$1+0], $4
850         sll     $2, 8, $2
851         or      $2, $4, $2
852
853         ldub    [$1+3+4], $3
854         add     $1, 8, $1
855
856         ldub    [$1+2+4-8], $4
857         sll     $3, 8, $3
858         or      $3, $4, $3
859
860         ldub    [$1+1+4-8], $4
861         sll     $3, 8, $3
862         or      $3, $4, $3
863
864         ldub    [$1+0+4-8], $4
865         sll     $3, 8, $3
866         or      $3, $4, $3
867 $5a:
868
869 })
870
871
872 ! {load_n_bytes}
873 !
874 ! Loads 1 to 7 bytes little endian
875 ! Remaining bytes are zeroed.
876 !
877 ! parameter 1  address
878 ! parameter 2  length
879 ! parameter 3  destination register left
880 ! parameter 4  destination register right
881 ! parameter 5  temp
882 ! parameter 6  temp2
883 ! parameter 7  label
884 ! parameter 8  return label
885
886 define(load_n_bytes, {
887
888 ! {load_n_bytes}
889 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
890
891 $7.0:   call    .+8
892         sll     $2, 2, $6
893
894         add     %o7,$7.jmp.table-$7.0,$5
895
896         add     $5, $6, $5
897         mov     0, $4
898
899         ld      [$5], $5
900
901         jmp     %o7+$5
902         mov     0, $3
903
904 $7.7:
905         ldub    [$1+6], $5
906         sll     $5, 16, $5
907         or      $3, $5, $3
908 $7.6:
909         ldub    [$1+5], $5
910         sll     $5, 8, $5
911         or      $3, $5, $3
912 $7.5:
913         ldub    [$1+4], $5
914         or      $3, $5, $3
915 $7.4:
916         ldub    [$1+3], $5
917         sll     $5, 24, $5
918         or      $4, $5, $4
919 $7.3:
920         ldub    [$1+2], $5
921         sll     $5, 16, $5
922         or      $4, $5, $4
923 $7.2:
924         ldub    [$1+1], $5
925         sll     $5, 8, $5
926         or      $4, $5, $4
927 $7.1:
928         ldub    [$1+0], $5
929         ba      $8
930         or      $4, $5, $4
931
932         .align 4
933
934 $7.jmp.table:
935         .word   0
936         .word   $7.1-$7.0
937         .word   $7.2-$7.0
938         .word   $7.3-$7.0
939         .word   $7.4-$7.0
940         .word   $7.5-$7.0
941         .word   $7.6-$7.0
942         .word   $7.7-$7.0
943 })
944
945
946 ! {store_little_endian}
947 !
948 ! parameter 1  address
949 ! parameter 2  source left
950 ! parameter 3  source right
951 ! parameter 4  temporar
952
953 define(store_little_endian, {
954
955 ! {store_little_endian}
956 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
957
958         ! rightmost in register to first in memory
959
960 $5:
961         and     $2, 255, $4
962         stub    $4, [$1+0]
963
964         srl     $2, 8, $4
965         and     $4, 255, $4
966         stub    $4, [$1+1]
967
968         srl     $2, 16, $4
969         and     $4, 255, $4
970         stub    $4, [$1+2]
971
972         srl     $2, 24, $4
973         stub    $4, [$1+3]
974
975
976         and     $3, 255, $4
977         stub    $4, [$1+0+4]
978
979         srl     $3, 8, $4
980         and     $4, 255, $4
981         stub    $4, [$1+1+4]
982
983         srl     $3, 16, $4
984         and     $4, 255, $4
985         stub    $4, [$1+2+4]
986
987         srl     $3, 24, $4
988         stub    $4, [$1+3+4]
989
990 $5a:
991
992 })
993
994
995 ! {store_n_bytes}
996 !
997 ! Stores 1 to 7 bytes little endian
998 !
999 ! parameter 1  address
1000 ! parameter 2  length
1001 ! parameter 3  source register left
1002 ! parameter 4  source register right
1003 ! parameter 5  temp
1004 ! parameter 6  temp2
1005 ! parameter 7  label
1006 ! parameter 8  return label
1007
1008 define(store_n_bytes, {
1009
1010 ! {store_n_bytes}
1011 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
1012
1013 $7.0:   call    .+8
1014         sll     $2, 2, $6
1015
1016         add     %o7,$7.jmp.table-$7.0,$5
1017
1018         add     $5, $6, $5
1019
1020         ld      [$5], $5
1021
1022         jmp     %o7+$5
1023         nop
1024
1025 $7.7:
1026         srl     $3, 16, $5
1027         and     $5, 0xff, $5
1028         stub    $5, [$1+6]
1029 $7.6:
1030         srl     $3, 8, $5
1031         and     $5, 0xff, $5
1032         stub    $5, [$1+5]
1033 $7.5:
1034         and     $3, 0xff, $5
1035         stub    $5, [$1+4]
1036 $7.4:
1037         srl     $4, 24, $5
1038         stub    $5, [$1+3]
1039 $7.3:
1040         srl     $4, 16, $5
1041         and     $5, 0xff, $5
1042         stub    $5, [$1+2]
1043 $7.2:
1044         srl     $4, 8, $5
1045         and     $5, 0xff, $5
1046         stub    $5, [$1+1]
1047 $7.1:
1048         and     $4, 0xff, $5
1049
1050
1051         ba      $8
1052         stub    $5, [$1]
1053
1054         .align 4
1055
1056 $7.jmp.table:
1057
1058         .word   0
1059         .word   $7.1-$7.0
1060         .word   $7.2-$7.0
1061         .word   $7.3-$7.0
1062         .word   $7.4-$7.0
1063         .word   $7.5-$7.0
1064         .word   $7.6-$7.0
1065         .word   $7.7-$7.0
1066 })
1067
1068
1069 define(testvalue,{1})
1070
1071 define(register_init, {
1072
1073 ! For test purposes:
1074
1075         sethi   %hi(testvalue), local0
1076         or      local0, %lo(testvalue), local0
1077
1078         ifelse($1,{},{}, {mov   local0, $1})
1079         ifelse($2,{},{}, {mov   local0, $2})
1080         ifelse($3,{},{}, {mov   local0, $3})
1081         ifelse($4,{},{}, {mov   local0, $4})
1082         ifelse($5,{},{}, {mov   local0, $5})
1083         ifelse($6,{},{}, {mov   local0, $6})
1084         ifelse($7,{},{}, {mov   local0, $7})
1085         ifelse($8,{},{}, {mov   local0, $8})
1086
1087         mov     local0, local1
1088         mov     local0, local2
1089         mov     local0, local3
1090         mov     local0, local4
1091         mov     local0, local5
1092         mov     local0, local7
1093         mov     local0, local6
1094         mov     local0, out0
1095         mov     local0, out1
1096         mov     local0, out2
1097         mov     local0, out3
1098         mov     local0, out4
1099         mov     local0, out5
1100         mov     local0, global1
1101         mov     local0, global2
1102         mov     local0, global3
1103         mov     local0, global4
1104         mov     local0, global5
1105
1106 })
1107
1108 .section        ".text"
1109
1110         .align 32
1111
1112 .des_enc:
1113
1114         ! key address in3
1115         ! loads key next encryption/decryption first round from [in4]
1116
1117         rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
1118
1119
1120         .align 32
1121
1122 .des_dec:
1123
1124         ! implemented with out5 as first parameter to avoid
1125         ! register exchange in ede modes
1126
1127         ! key address in4
1128         ! loads key next encryption/decryption first round from [in3]
1129
1130         rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
1131
1132
1133
1134 ! void DES_encrypt1(data, ks, enc)
1135 ! *******************************
1136
1137         .align 32
1138         .global DES_encrypt1
1139         .type    DES_encrypt1,#function
1140
1141 DES_encrypt1:
1142
1143         save    %sp, FRAME, %sp
1144
1145         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1146         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1147 1:      call    .+8
1148         add     %o7,global1,global1
1149         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1150
1151         ld      [in0], in5                ! left
1152         cmp     in2, 0                    ! enc
1153
1154         be      .encrypt.dec
1155         ld      [in0+4], out5             ! right
1156
1157         ! parameter 6  1/2 for include encryption/decryption
1158         ! parameter 7  1 for move in1 to in3
1159         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1160
1161         ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
1162
1163         rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
1164
1165         fp_macro(in5, out5, 1)            ! 1 for store to [in0]
1166
1167         ret
1168         restore
1169
1170 .encrypt.dec:
1171
1172         add     in1, 120, in3             ! use last subkey for first round
1173
1174         ! parameter 6  1/2 for include encryption/decryption
1175         ! parameter 7  1 for move in1 to in3
1176         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1177
1178         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
1179
1180         fp_macro(out5, in5, 1)            ! 1 for store to [in0]
1181
1182         ret
1183         restore
1184
1185 .DES_encrypt1.end:
1186         .size    DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
1187
1188
1189 ! void DES_encrypt2(data, ks, enc)
1190 !*********************************
1191
1192         ! encrypts/decrypts without initial/final permutation
1193
1194         .align 32
1195         .global DES_encrypt2
1196         .type    DES_encrypt2,#function
1197
1198 DES_encrypt2:
1199
1200         save    %sp, FRAME, %sp
1201
1202         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1203         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1204 1:      call    .+8
1205         add     %o7,global1,global1
1206         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1207
1208         ! Set sbox address 1 to 6 and rotate halfs 3 left
1209         ! Errors caught by destest? Yes. Still? *NO*
1210
1211         !sethi  %hi(DES_SPtrans), global1 ! address sbox 1
1212
1213         !or     global1, %lo(DES_SPtrans), global1  ! sbox 1
1214
1215         add     global1, 256, global2     ! sbox 2
1216         add     global1, 512, global3     ! sbox 3
1217
1218         ld      [in0], out5               ! right
1219         add     global1, 768, global4     ! sbox 4
1220         add     global1, 1024, global5    ! sbox 5
1221
1222         ld      [in0+4], in5              ! left
1223         add     global1, 1280, local6     ! sbox 6
1224         add     global1, 1792, out3       ! sbox 8
1225
1226         ! rotate
1227
1228         sll     in5, 3, local5
1229         mov     in1, in3                  ! key address to in3
1230
1231         sll     out5, 3, local7
1232         srl     in5, 29, in5
1233
1234         srl     out5, 29, out5
1235         add     in5, local5, in5
1236
1237         add     out5, local7, out5
1238         cmp     in2, 0
1239
1240         ! we use our own stackframe
1241
1242         be      .encrypt2.dec
1243         STPTR   in0, [%sp+BIAS+ARG0+0*ARGSZ]
1244
1245         ld      [in3], out0               ! key 7531 first round
1246         mov     LOOPS, out4               ! loop counter
1247
1248         ld      [in3+4], out1             ! key 8642 first round
1249         sethi   %hi(0x0000FC00), local5
1250
1251         call .des_enc
1252         mov     in3, in4
1253
1254         ! rotate
1255         sll     in5, 29, in0
1256         srl     in5, 3, in5
1257         sll     out5, 29, in1
1258         add     in5, in0, in5
1259         srl     out5, 3, out5
1260         LDPTR   [%sp+BIAS+ARG0+0*ARGSZ], in0
1261         add     out5, in1, out5
1262         st      in5, [in0]
1263         st      out5, [in0+4]
1264
1265         ret
1266         restore
1267
1268
1269 .encrypt2.dec:
1270
1271         add in3, 120, in4
1272
1273         ld      [in4], out0               ! key 7531 first round
1274         mov     LOOPS, out4               ! loop counter
1275
1276         ld      [in4+4], out1             ! key 8642 first round
1277         sethi   %hi(0x0000FC00), local5
1278
1279         mov     in5, local1               ! left expected in out5
1280         mov     out5, in5
1281
1282         call .des_dec
1283         mov     local1, out5
1284
1285 .encrypt2.finish:
1286
1287         ! rotate
1288         sll     in5, 29, in0
1289         srl     in5, 3, in5
1290         sll     out5, 29, in1
1291         add     in5, in0, in5
1292         srl     out5, 3, out5
1293         LDPTR   [%sp+BIAS+ARG0+0*ARGSZ], in0
1294         add     out5, in1, out5
1295         st      out5, [in0]
1296         st      in5, [in0+4]
1297
1298         ret
1299         restore
1300
1301 .DES_encrypt2.end:
1302         .size    DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
1303
1304
1305 ! void DES_encrypt3(data, ks1, ks2, ks3)
1306 ! **************************************
1307
1308         .align 32
1309         .global DES_encrypt3
1310         .type    DES_encrypt3,#function
1311
1312 DES_encrypt3:
1313
1314         save    %sp, FRAME, %sp
1315         
1316         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1317         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1318 1:      call    .+8
1319         add     %o7,global1,global1
1320         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1321
1322         ld      [in0], in5                ! left
1323         add     in2, 120, in4             ! ks2
1324
1325         ld      [in0+4], out5             ! right
1326         mov     in3, in2                  ! save ks3
1327
1328         ! parameter 6  1/2 for include encryption/decryption
1329         ! parameter 7  1 for mov in1 to in3
1330         ! parameter 8  1 for mov in3 to in4
1331         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1332
1333         ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
1334
1335         call    .des_dec
1336         mov     in2, in3                  ! preload ks3
1337
1338         call    .des_enc
1339         nop
1340
1341         fp_macro(in5, out5, 1)
1342
1343         ret
1344         restore
1345
1346 .DES_encrypt3.end:
1347         .size    DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
1348
1349
1350 ! void DES_decrypt3(data, ks1, ks2, ks3)
1351 ! **************************************
1352
1353         .align 32
1354         .global DES_decrypt3
1355         .type    DES_decrypt3,#function
1356
1357 DES_decrypt3:
1358
1359         save    %sp, FRAME, %sp
1360         
1361         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1362         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1363 1:      call    .+8
1364         add     %o7,global1,global1
1365         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1366
1367         ld      [in0], in5                ! left
1368         add     in3, 120, in4             ! ks3
1369
1370         ld      [in0+4], out5             ! right
1371         mov     in2, in3                  ! ks2
1372
1373         ! parameter 6  1/2 for include encryption/decryption
1374         ! parameter 7  1 for mov in1 to in3
1375         ! parameter 8  1 for mov in3 to in4
1376         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1377
1378         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
1379
1380         call    .des_enc
1381         add     in1, 120, in4             ! preload ks1
1382
1383         call    .des_dec
1384         nop
1385
1386         fp_macro(out5, in5, 1)
1387
1388         ret
1389         restore
1390
1391 .DES_decrypt3.end:
1392         .size    DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
1393
1394 ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
1395 ! *****************************************************************
1396
1397
1398         .align 32
1399         .global DES_ncbc_encrypt
1400         .type    DES_ncbc_encrypt,#function
1401
1402 DES_ncbc_encrypt:
1403
1404         save    %sp, FRAME, %sp
1405         
1406         define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
1407         define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
1408         define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
1409
1410         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1411         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1412 1:      call    .+8
1413         add     %o7,global1,global1
1414         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1415
1416         cmp     in5, 0                    ! enc   
1417
1418         be      .ncbc.dec
1419         STPTR   in4, IVEC
1420
1421         ! addr  left  right  temp  label
1422         load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
1423
1424         addcc   in2, -8, in2              ! bytes missing when first block done
1425
1426         bl      .ncbc.enc.seven.or.less
1427         mov     in3, in4                  ! schedule
1428
1429 .ncbc.enc.next.block:
1430
1431         load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
1432
1433 .ncbc.enc.next.block_1:
1434
1435         xor     in5, out4, in5            ! iv xor
1436         xor     out5, global4, out5       ! iv xor
1437
1438         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1439         ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
1440
1441 .ncbc.enc.next.block_2:
1442
1443 !//     call .des_enc                     ! compares in2 to 8
1444 !       rounds inlined for alignment purposes
1445
1446         add     global1, 768, global4     ! address sbox 4 since register used below
1447
1448         rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
1449
1450         bl      .ncbc.enc.next.block_fp
1451         add     in0, 8, in0               ! input address
1452
1453         ! If 8 or more bytes are to be encrypted after this block,
1454         ! we combine final permutation for this block with initial
1455         ! permutation for next block. Load next block:
1456
1457         load_little_endian(in0, global3, global4, local5, .LLE12)
1458
1459         !  parameter 1   original left
1460         !  parameter 2   original right
1461         !  parameter 3   left ip
1462         !  parameter 4   right ip
1463         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1464         !                2: mov in4 to in3
1465         !
1466         ! also adds -8 to length in2 and loads loop counter to out4
1467
1468         fp_ip_macro(out0, out1, global3, global4, 2)
1469
1470         store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
1471
1472         ld      [in3], out0               ! key 7531 first round next block
1473         mov     in5, local1
1474         xor     global3, out5, in5        ! iv xor next block
1475
1476         ld      [in3+4], out1             ! key 8642
1477         add     global1, 512, global3     ! address sbox 3 since register used
1478         xor     global4, local1, out5     ! iv xor next block
1479
1480         ba      .ncbc.enc.next.block_2
1481         add     in1, 8, in1               ! output address
1482
1483 .ncbc.enc.next.block_fp:
1484
1485         fp_macro(in5, out5)
1486
1487         store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
1488
1489         addcc   in2, -8, in2              ! bytes missing when next block done
1490
1491         bpos    .ncbc.enc.next.block
1492         add     in1, 8, in1
1493
1494 .ncbc.enc.seven.or.less:
1495
1496         cmp     in2, -8
1497
1498         ble     .ncbc.enc.finish
1499         nop
1500
1501         add     in2, 8, local1            ! bytes to load
1502
1503         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1504         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
1505
1506         ! Loads 1 to 7 bytes little endian to global4, out4
1507
1508
1509 .ncbc.enc.finish:
1510
1511         LDPTR   IVEC, local4
1512         store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
1513
1514         ret
1515         restore
1516
1517
1518 .ncbc.dec:
1519
1520         STPTR   in0, INPUT
1521         cmp     in2, 0                    ! length
1522         add     in3, 120, in3
1523
1524         LDPTR   IVEC, local7              ! ivec
1525         ble     .ncbc.dec.finish
1526         mov     in3, in4                  ! schedule
1527
1528         STPTR   in1, OUTPUT
1529         mov     in0, local5               ! input
1530
1531         load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
1532
1533 .ncbc.dec.next.block:
1534
1535         load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
1536
1537         ! parameter 6  1/2 for include encryption/decryption
1538         ! parameter 7  1 for mov in1 to in3
1539         ! parameter 8  1 for mov in3 to in4
1540
1541         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
1542
1543         fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
1544
1545         ! in2 is bytes left to be stored
1546         ! in2 is compared to 8 in the rounds
1547
1548         xor     out5, in0, out4           ! iv xor
1549         bl      .ncbc.dec.seven.or.less
1550         xor     in5, in1, global4         ! iv xor
1551
1552         ! Load ivec next block now, since input and output address might be the same.
1553
1554         load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
1555
1556         store_little_endian(local7, out4, global4, local3, .SLE3)
1557
1558         STPTR   local5, INPUT
1559         add     local7, 8, local7
1560         addcc   in2, -8, in2
1561
1562         bg      .ncbc.dec.next.block
1563         STPTR   local7, OUTPUT
1564
1565
1566 .ncbc.dec.store.iv:
1567
1568         LDPTR   IVEC, local4              ! ivec
1569         store_little_endian(local4, in0, in1, local5, .SLE4)
1570
1571 .ncbc.dec.finish:
1572
1573         ret
1574         restore
1575
1576 .ncbc.dec.seven.or.less:
1577
1578         load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
1579
1580         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
1581
1582
1583 .DES_ncbc_encrypt.end:
1584         .size    DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
1585
1586
1587 ! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
1588 ! **************************************************************************
1589
1590
1591         .align 32
1592         .global DES_ede3_cbc_encrypt
1593         .type    DES_ede3_cbc_encrypt,#function
1594
1595 DES_ede3_cbc_encrypt:
1596
1597         save    %sp, FRAME, %sp
1598
1599         define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
1600         define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1601         define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
1602
1603         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1604         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1605 1:      call    .+8
1606         add     %o7,global1,global1
1607         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1608
1609         LDPTR   [%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
1610         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1611         cmp     local3, 0                 ! enc
1612
1613         STPTR   in4, KS2
1614
1615         STPTR   in5, KS3
1616
1617         load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
1618
1619         addcc   in2, -8, in2              ! bytes missing after next block
1620
1621         bl      .ede3.enc.seven.or.less
1622         STPTR   in3, KS1
1623
1624 .ede3.enc.next.block:
1625
1626         load_little_endian(in0, out4, global4, local3, .LLE7)
1627
1628 .ede3.enc.next.block_1:
1629
1630         LDPTR   KS2, in4
1631         xor     in5, out4, in5            ! iv xor
1632         xor     out5, global4, out5       ! iv xor
1633
1634         LDPTR   KS1, in3
1635         add     in4, 120, in4             ! for decryption we use last subkey first
1636         nop
1637
1638         ip_macro(in5, out5, in5, out5, in3)
1639
1640 .ede3.enc.next.block_2:
1641
1642         call .des_enc                     ! ks1 in3
1643         nop
1644
1645         call .des_dec                     ! ks2 in4
1646         LDPTR   KS3, in3
1647
1648         call .des_enc                     ! ks3 in3  compares in2 to 8
1649         nop
1650
1651         bl      .ede3.enc.next.block_fp
1652         add     in0, 8, in0
1653
1654         ! If 8 or more bytes are to be encrypted after this block,
1655         ! we combine final permutation for this block with initial
1656         ! permutation for next block. Load next block:
1657
1658         load_little_endian(in0, global3, global4, local5, .LLE11)
1659
1660         !  parameter 1   original left
1661         !  parameter 2   original right
1662         !  parameter 3   left ip
1663         !  parameter 4   right ip
1664         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1665         !                2: mov in4 to in3
1666         !
1667         ! also adds -8 to length in2 and loads loop counter to out4
1668
1669         fp_ip_macro(out0, out1, global3, global4, 1)
1670
1671         store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
1672
1673         mov     in5, local1
1674         xor     global3, out5, in5        ! iv xor next block
1675
1676         ld      [in3], out0               ! key 7531
1677         add     global1, 512, global3     ! address sbox 3
1678         xor     global4, local1, out5     ! iv xor next block
1679
1680         ld      [in3+4], out1             ! key 8642
1681         add     global1, 768, global4     ! address sbox 4
1682         ba      .ede3.enc.next.block_2
1683         add     in1, 8, in1
1684
1685 .ede3.enc.next.block_fp:
1686
1687         fp_macro(in5, out5)
1688
1689         store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
1690
1691         addcc   in2, -8, in2              ! bytes missing when next block done
1692
1693         bpos    .ede3.enc.next.block
1694         add     in1, 8, in1
1695
1696 .ede3.enc.seven.or.less:
1697
1698         cmp     in2, -8
1699
1700         ble     .ede3.enc.finish
1701         nop
1702
1703         add     in2, 8, local1            ! bytes to load
1704
1705         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1706         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
1707
1708 .ede3.enc.finish:
1709
1710         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1711         store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
1712
1713         ret
1714         restore
1715
1716 .ede3.dec:
1717
1718         STPTR   in0, INPUT
1719         add     in5, 120, in5
1720
1721         STPTR   in1, OUTPUT
1722         mov     in0, local5
1723         add     in3, 120, in3
1724
1725         STPTR   in3, KS1
1726         cmp     in2, 0
1727
1728         ble     .ede3.dec.finish
1729         STPTR   in5, KS3
1730
1731         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
1732         load_little_endian(local7, in0, in1, local3, .LLE8)
1733
1734 .ede3.dec.next.block:
1735
1736         load_little_endian(local5, in5, out5, local3, .LLE9)
1737
1738         ! parameter 6  1/2 for include encryption/decryption
1739         ! parameter 7  1 for mov in1 to in3
1740         ! parameter 8  1 for mov in3 to in4
1741         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1742
1743         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
1744
1745         call .des_enc                     ! ks2 in3
1746         LDPTR   KS1, in4
1747
1748         call .des_dec                     ! ks1 in4
1749         nop
1750
1751         fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
1752
1753         ! in2 is bytes left to be stored
1754         ! in2 is compared to 8 in the rounds
1755
1756         xor     out5, in0, out4
1757         bl      .ede3.dec.seven.or.less
1758         xor     in5, in1, global4
1759
1760         load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
1761
1762         store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
1763
1764         STPTR   local5, INPUT
1765         addcc   in2, -8, in2
1766         add     local7, 8, local7
1767
1768         bg      .ede3.dec.next.block
1769         STPTR   local7, OUTPUT
1770
1771 .ede3.dec.store.iv:
1772
1773         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1774         store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
1775
1776 .ede3.dec.finish:
1777
1778         ret
1779         restore
1780
1781 .ede3.dec.seven.or.less:
1782
1783         load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
1784
1785         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
1786
1787
1788 .DES_ede3_cbc_encrypt.end:
1789         .size    DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
1790
1791         .align  256
1792         .type    .des_and,#object
1793         .size    .des_and,284
1794
1795 .des_and:
1796
1797 ! This table is used for AND 0xFC when it is known that register
1798 ! bits 8-31 are zero. Makes it possible to do three arithmetic
1799 ! operations in one cycle.
1800
1801         .byte  0, 0, 0, 0, 4, 4, 4, 4
1802         .byte  8, 8, 8, 8, 12, 12, 12, 12
1803         .byte  16, 16, 16, 16, 20, 20, 20, 20
1804         .byte  24, 24, 24, 24, 28, 28, 28, 28
1805         .byte  32, 32, 32, 32, 36, 36, 36, 36
1806         .byte  40, 40, 40, 40, 44, 44, 44, 44
1807         .byte  48, 48, 48, 48, 52, 52, 52, 52
1808         .byte  56, 56, 56, 56, 60, 60, 60, 60
1809         .byte  64, 64, 64, 64, 68, 68, 68, 68
1810         .byte  72, 72, 72, 72, 76, 76, 76, 76
1811         .byte  80, 80, 80, 80, 84, 84, 84, 84
1812         .byte  88, 88, 88, 88, 92, 92, 92, 92
1813         .byte  96, 96, 96, 96, 100, 100, 100, 100
1814         .byte  104, 104, 104, 104, 108, 108, 108, 108
1815         .byte  112, 112, 112, 112, 116, 116, 116, 116
1816         .byte  120, 120, 120, 120, 124, 124, 124, 124
1817         .byte  128, 128, 128, 128, 132, 132, 132, 132
1818         .byte  136, 136, 136, 136, 140, 140, 140, 140
1819         .byte  144, 144, 144, 144, 148, 148, 148, 148
1820         .byte  152, 152, 152, 152, 156, 156, 156, 156
1821         .byte  160, 160, 160, 160, 164, 164, 164, 164
1822         .byte  168, 168, 168, 168, 172, 172, 172, 172
1823         .byte  176, 176, 176, 176, 180, 180, 180, 180
1824         .byte  184, 184, 184, 184, 188, 188, 188, 188
1825         .byte  192, 192, 192, 192, 196, 196, 196, 196
1826         .byte  200, 200, 200, 200, 204, 204, 204, 204
1827         .byte  208, 208, 208, 208, 212, 212, 212, 212
1828         .byte  216, 216, 216, 216, 220, 220, 220, 220
1829         .byte  224, 224, 224, 224, 228, 228, 228, 228
1830         .byte  232, 232, 232, 232, 236, 236, 236, 236
1831         .byte  240, 240, 240, 240, 244, 244, 244, 244
1832         .byte  248, 248, 248, 248, 252, 252, 252, 252
1833
1834         ! 5 numbers for initil/final permutation
1835
1836         .word   0x0f0f0f0f                ! offset 256
1837         .word   0x0000ffff                ! 260
1838         .word   0x33333333                ! 264
1839         .word   0x00ff00ff                ! 268
1840         .word   0x55555555                ! 272
1841
1842         .word   0                         ! 276
1843         .word   LOOPS                     ! 280
1844         .word   0x0000FC00                ! 284
1845
1846         .global DES_SPtrans
1847         .type   DES_SPtrans,#object
1848         .size   DES_SPtrans,2048
1849 .align  64
1850 DES_SPtrans:
1851 .PIC.DES_SPtrans:
1852         ! nibble 0
1853         .word   0x02080800, 0x00080000, 0x02000002, 0x02080802
1854         .word   0x02000000, 0x00080802, 0x00080002, 0x02000002
1855         .word   0x00080802, 0x02080800, 0x02080000, 0x00000802
1856         .word   0x02000802, 0x02000000, 0x00000000, 0x00080002
1857         .word   0x00080000, 0x00000002, 0x02000800, 0x00080800
1858         .word   0x02080802, 0x02080000, 0x00000802, 0x02000800
1859         .word   0x00000002, 0x00000800, 0x00080800, 0x02080002
1860         .word   0x00000800, 0x02000802, 0x02080002, 0x00000000
1861         .word   0x00000000, 0x02080802, 0x02000800, 0x00080002
1862         .word   0x02080800, 0x00080000, 0x00000802, 0x02000800
1863         .word   0x02080002, 0x00000800, 0x00080800, 0x02000002
1864         .word   0x00080802, 0x00000002, 0x02000002, 0x02080000
1865         .word   0x02080802, 0x00080800, 0x02080000, 0x02000802
1866         .word   0x02000000, 0x00000802, 0x00080002, 0x00000000
1867         .word   0x00080000, 0x02000000, 0x02000802, 0x02080800
1868         .word   0x00000002, 0x02080002, 0x00000800, 0x00080802
1869         ! nibble 1
1870         .word   0x40108010, 0x00000000, 0x00108000, 0x40100000
1871         .word   0x40000010, 0x00008010, 0x40008000, 0x00108000
1872         .word   0x00008000, 0x40100010, 0x00000010, 0x40008000
1873         .word   0x00100010, 0x40108000, 0x40100000, 0x00000010
1874         .word   0x00100000, 0x40008010, 0x40100010, 0x00008000
1875         .word   0x00108010, 0x40000000, 0x00000000, 0x00100010
1876         .word   0x40008010, 0x00108010, 0x40108000, 0x40000010
1877         .word   0x40000000, 0x00100000, 0x00008010, 0x40108010
1878         .word   0x00100010, 0x40108000, 0x40008000, 0x00108010
1879         .word   0x40108010, 0x00100010, 0x40000010, 0x00000000
1880         .word   0x40000000, 0x00008010, 0x00100000, 0x40100010
1881         .word   0x00008000, 0x40000000, 0x00108010, 0x40008010
1882         .word   0x40108000, 0x00008000, 0x00000000, 0x40000010
1883         .word   0x00000010, 0x40108010, 0x00108000, 0x40100000
1884         .word   0x40100010, 0x00100000, 0x00008010, 0x40008000
1885         .word   0x40008010, 0x00000010, 0x40100000, 0x00108000
1886         ! nibble 2
1887         .word   0x04000001, 0x04040100, 0x00000100, 0x04000101
1888         .word   0x00040001, 0x04000000, 0x04000101, 0x00040100
1889         .word   0x04000100, 0x00040000, 0x04040000, 0x00000001
1890         .word   0x04040101, 0x00000101, 0x00000001, 0x04040001
1891         .word   0x00000000, 0x00040001, 0x04040100, 0x00000100
1892         .word   0x00000101, 0x04040101, 0x00040000, 0x04000001
1893         .word   0x04040001, 0x04000100, 0x00040101, 0x04040000
1894         .word   0x00040100, 0x00000000, 0x04000000, 0x00040101
1895         .word   0x04040100, 0x00000100, 0x00000001, 0x00040000
1896         .word   0x00000101, 0x00040001, 0x04040000, 0x04000101
1897         .word   0x00000000, 0x04040100, 0x00040100, 0x04040001
1898         .word   0x00040001, 0x04000000, 0x04040101, 0x00000001
1899         .word   0x00040101, 0x04000001, 0x04000000, 0x04040101
1900         .word   0x00040000, 0x04000100, 0x04000101, 0x00040100
1901         .word   0x04000100, 0x00000000, 0x04040001, 0x00000101
1902         .word   0x04000001, 0x00040101, 0x00000100, 0x04040000
1903         ! nibble 3
1904         .word   0x00401008, 0x10001000, 0x00000008, 0x10401008
1905         .word   0x00000000, 0x10400000, 0x10001008, 0x00400008
1906         .word   0x10401000, 0x10000008, 0x10000000, 0x00001008
1907         .word   0x10000008, 0x00401008, 0x00400000, 0x10000000
1908         .word   0x10400008, 0x00401000, 0x00001000, 0x00000008
1909         .word   0x00401000, 0x10001008, 0x10400000, 0x00001000
1910         .word   0x00001008, 0x00000000, 0x00400008, 0x10401000
1911         .word   0x10001000, 0x10400008, 0x10401008, 0x00400000
1912         .word   0x10400008, 0x00001008, 0x00400000, 0x10000008
1913         .word   0x00401000, 0x10001000, 0x00000008, 0x10400000
1914         .word   0x10001008, 0x00000000, 0x00001000, 0x00400008
1915         .word   0x00000000, 0x10400008, 0x10401000, 0x00001000
1916         .word   0x10000000, 0x10401008, 0x00401008, 0x00400000
1917         .word   0x10401008, 0x00000008, 0x10001000, 0x00401008
1918         .word   0x00400008, 0x00401000, 0x10400000, 0x10001008
1919         .word   0x00001008, 0x10000000, 0x10000008, 0x10401000
1920         ! nibble 4
1921         .word   0x08000000, 0x00010000, 0x00000400, 0x08010420
1922         .word   0x08010020, 0x08000400, 0x00010420, 0x08010000
1923         .word   0x00010000, 0x00000020, 0x08000020, 0x00010400
1924         .word   0x08000420, 0x08010020, 0x08010400, 0x00000000
1925         .word   0x00010400, 0x08000000, 0x00010020, 0x00000420
1926         .word   0x08000400, 0x00010420, 0x00000000, 0x08000020
1927         .word   0x00000020, 0x08000420, 0x08010420, 0x00010020
1928         .word   0x08010000, 0x00000400, 0x00000420, 0x08010400
1929         .word   0x08010400, 0x08000420, 0x00010020, 0x08010000
1930         .word   0x00010000, 0x00000020, 0x08000020, 0x08000400
1931         .word   0x08000000, 0x00010400, 0x08010420, 0x00000000
1932         .word   0x00010420, 0x08000000, 0x00000400, 0x00010020
1933         .word   0x08000420, 0x00000400, 0x00000000, 0x08010420
1934         .word   0x08010020, 0x08010400, 0x00000420, 0x00010000
1935         .word   0x00010400, 0x08010020, 0x08000400, 0x00000420
1936         .word   0x00000020, 0x00010420, 0x08010000, 0x08000020
1937         ! nibble 5
1938         .word   0x80000040, 0x00200040, 0x00000000, 0x80202000
1939         .word   0x00200040, 0x00002000, 0x80002040, 0x00200000
1940         .word   0x00002040, 0x80202040, 0x00202000, 0x80000000
1941         .word   0x80002000, 0x80000040, 0x80200000, 0x00202040
1942         .word   0x00200000, 0x80002040, 0x80200040, 0x00000000
1943         .word   0x00002000, 0x00000040, 0x80202000, 0x80200040
1944         .word   0x80202040, 0x80200000, 0x80000000, 0x00002040
1945         .word   0x00000040, 0x00202000, 0x00202040, 0x80002000
1946         .word   0x00002040, 0x80000000, 0x80002000, 0x00202040
1947         .word   0x80202000, 0x00200040, 0x00000000, 0x80002000
1948         .word   0x80000000, 0x00002000, 0x80200040, 0x00200000
1949         .word   0x00200040, 0x80202040, 0x00202000, 0x00000040
1950         .word   0x80202040, 0x00202000, 0x00200000, 0x80002040
1951         .word   0x80000040, 0x80200000, 0x00202040, 0x00000000
1952         .word   0x00002000, 0x80000040, 0x80002040, 0x80202000
1953         .word   0x80200000, 0x00002040, 0x00000040, 0x80200040
1954         ! nibble 6
1955         .word   0x00004000, 0x00000200, 0x01000200, 0x01000004
1956         .word   0x01004204, 0x00004004, 0x00004200, 0x00000000
1957         .word   0x01000000, 0x01000204, 0x00000204, 0x01004000
1958         .word   0x00000004, 0x01004200, 0x01004000, 0x00000204
1959         .word   0x01000204, 0x00004000, 0x00004004, 0x01004204
1960         .word   0x00000000, 0x01000200, 0x01000004, 0x00004200
1961         .word   0x01004004, 0x00004204, 0x01004200, 0x00000004
1962         .word   0x00004204, 0x01004004, 0x00000200, 0x01000000
1963         .word   0x00004204, 0x01004000, 0x01004004, 0x00000204
1964         .word   0x00004000, 0x00000200, 0x01000000, 0x01004004
1965         .word   0x01000204, 0x00004204, 0x00004200, 0x00000000
1966         .word   0x00000200, 0x01000004, 0x00000004, 0x01000200
1967         .word   0x00000000, 0x01000204, 0x01000200, 0x00004200
1968         .word   0x00000204, 0x00004000, 0x01004204, 0x01000000
1969         .word   0x01004200, 0x00000004, 0x00004004, 0x01004204
1970         .word   0x01000004, 0x01004200, 0x01004000, 0x00004004
1971         ! nibble 7
1972         .word   0x20800080, 0x20820000, 0x00020080, 0x00000000
1973         .word   0x20020000, 0x00800080, 0x20800000, 0x20820080
1974         .word   0x00000080, 0x20000000, 0x00820000, 0x00020080
1975         .word   0x00820080, 0x20020080, 0x20000080, 0x20800000
1976         .word   0x00020000, 0x00820080, 0x00800080, 0x20020000
1977         .word   0x20820080, 0x20000080, 0x00000000, 0x00820000
1978         .word   0x20000000, 0x00800000, 0x20020080, 0x20800080
1979         .word   0x00800000, 0x00020000, 0x20820000, 0x00000080
1980         .word   0x00800000, 0x00020000, 0x20000080, 0x20820080
1981         .word   0x00020080, 0x20000000, 0x00000000, 0x00820000
1982         .word   0x20800080, 0x20020080, 0x20020000, 0x00800080
1983         .word   0x20820000, 0x00000080, 0x00800080, 0x20020000
1984         .word   0x20820080, 0x00800000, 0x20800000, 0x20000080
1985         .word   0x00820000, 0x00020080, 0x20020080, 0x20800000
1986         .word   0x00000080, 0x20820000, 0x00820080, 0x00000000
1987         .word   0x20000000, 0x20800080, 0x00020000, 0x00820080
1988