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