1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci#
4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci
9e1051a39Sopenharmony_ci#
10e1051a39Sopenharmony_ci# ====================================================================
11e1051a39Sopenharmony_ci# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
12e1051a39Sopenharmony_ci# project. The module is, however, dual licensed under OpenSSL and
13e1051a39Sopenharmony_ci# CRYPTOGAMS licenses depending on where you obtain it. For further
14e1051a39Sopenharmony_ci# details see http://www.openssl.org/~appro/cryptogams/.
15e1051a39Sopenharmony_ci# ====================================================================
16e1051a39Sopenharmony_ci#
17e1051a39Sopenharmony_ci# RC4 for C64x+.
18e1051a39Sopenharmony_ci#
19e1051a39Sopenharmony_ci# April 2014
20e1051a39Sopenharmony_ci#
21e1051a39Sopenharmony_ci# RC4 subroutine processes one byte in 7.0 cycles, which is 3x faster
22e1051a39Sopenharmony_ci# than TI CGT-generated code. Loop is scheduled in such way that
23e1051a39Sopenharmony_ci# there is only one reference to memory in each cycle. This is done
24e1051a39Sopenharmony_ci# to avoid L1D memory banking conflicts, see SPRU871 TI publication
25e1051a39Sopenharmony_ci# for further details. Otherwise it should be possible to schedule
26e1051a39Sopenharmony_ci# the loop for iteration interval of 6...
27e1051a39Sopenharmony_ci
28e1051a39Sopenharmony_ci($KEY,$LEN,$INP,$OUT)=("A4","B4","A6","B6");
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_ci($KEYA,$XX,$TY,$xx,$ONE,$ret)=map("A$_",(5,7,8,9,1,2));
31e1051a39Sopenharmony_ci($KEYB,$YY,$TX,$tx,$SUM,$dat)=map("B$_",(5,7,8,9,1,2));
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_ci$code.=<<___;
34e1051a39Sopenharmony_ci	.text
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_ci	.if	.ASSEMBLER_VERSION<7000000
37e1051a39Sopenharmony_ci	.asg	0,__TI_EABI__
38e1051a39Sopenharmony_ci	.endif
39e1051a39Sopenharmony_ci	.if	__TI_EABI__
40e1051a39Sopenharmony_ci	.nocmp
41e1051a39Sopenharmony_ci	.asg	RC4,_RC4
42e1051a39Sopenharmony_ci	.asg	RC4_set_key,_RC4_set_key
43e1051a39Sopenharmony_ci	.asg	RC4_options,_RC4_options
44e1051a39Sopenharmony_ci	.endif
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ci	.global	_RC4
47e1051a39Sopenharmony_ci	.align	16
48e1051a39Sopenharmony_ci_RC4:
49e1051a39Sopenharmony_ci	.asmfunc
50e1051a39Sopenharmony_ci	MV	$LEN,B0
51e1051a39Sopenharmony_ci  [!B0]	BNOP	B3			; if (len==0) return;
52e1051a39Sopenharmony_ci||[B0]	ADD	$KEY,2,$KEYA
53e1051a39Sopenharmony_ci||[B0]	ADD	$KEY,2,$KEYB
54e1051a39Sopenharmony_ci  [B0]	MVK	1,$ONE
55e1051a39Sopenharmony_ci||[B0]	LDBU	*${KEYA}[-2],$XX	; key->x
56e1051a39Sopenharmony_ci  [B0]	LDBU	*${KEYB}[-1],$YY	; key->y
57e1051a39Sopenharmony_ci||	NOP	4
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci	ADD4	$ONE,$XX,$XX
60e1051a39Sopenharmony_ci	LDBU	*${KEYA}[$XX],$TX
61e1051a39Sopenharmony_ci||	MVC	$LEN,ILC
62e1051a39Sopenharmony_ci	NOP	4
63e1051a39Sopenharmony_ci;;==================================================
64e1051a39Sopenharmony_ci	SPLOOP	7
65e1051a39Sopenharmony_ci||	ADD4	$TX,$YY,$YY
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ci	LDBU	*${KEYB}[$YY],$TY
68e1051a39Sopenharmony_ci||	MVD	$XX,$xx
69e1051a39Sopenharmony_ci||	ADD4	$ONE,$XX,$XX
70e1051a39Sopenharmony_ci	LDBU	*${KEYA}[$XX],$tx
71e1051a39Sopenharmony_ci	CMPEQ	$YY,$XX,B0
72e1051a39Sopenharmony_ci||	NOP	3
73e1051a39Sopenharmony_ci	STB	$TX,*${KEYB}[$YY]
74e1051a39Sopenharmony_ci||[B0]	ADD4	$TX,$YY,$YY
75e1051a39Sopenharmony_ci	STB	$TY,*${KEYA}[$xx]
76e1051a39Sopenharmony_ci||[!B0]	ADD4	$tx,$YY,$YY
77e1051a39Sopenharmony_ci||[!B0]	MVD	$tx,$TX
78e1051a39Sopenharmony_ci	ADD4	$TY,$TX,$SUM		; [0,0] $TX is not replaced by $tx yet!
79e1051a39Sopenharmony_ci||	NOP	2
80e1051a39Sopenharmony_ci	LDBU	*$INP++,$dat
81e1051a39Sopenharmony_ci||	NOP	2
82e1051a39Sopenharmony_ci	LDBU	*${KEYB}[$SUM],$ret
83e1051a39Sopenharmony_ci||	NOP	5
84e1051a39Sopenharmony_ci	XOR.L	$dat,$ret,$ret
85e1051a39Sopenharmony_ci	SPKERNEL
86e1051a39Sopenharmony_ci||	STB	$ret,*$OUT++
87e1051a39Sopenharmony_ci;;==================================================
88e1051a39Sopenharmony_ci	SUB4	$XX,$ONE,$XX
89e1051a39Sopenharmony_ci||	NOP	5
90e1051a39Sopenharmony_ci	STB	$XX,*${KEYA}[-2]	; key->x
91e1051a39Sopenharmony_ci||	SUB4	$YY,$TX,$YY
92e1051a39Sopenharmony_ci||	BNOP	B3
93e1051a39Sopenharmony_ci	STB	$YY,*${KEYB}[-1]	; key->y
94e1051a39Sopenharmony_ci||	NOP	5
95e1051a39Sopenharmony_ci	.endasmfunc
96e1051a39Sopenharmony_ci
97e1051a39Sopenharmony_ci	.global	_RC4_set_key
98e1051a39Sopenharmony_ci	.align	16
99e1051a39Sopenharmony_ci_RC4_set_key:
100e1051a39Sopenharmony_ci	.asmfunc
101e1051a39Sopenharmony_ci	.if	.BIG_ENDIAN
102e1051a39Sopenharmony_ci	MVK	0x00000404,$ONE
103e1051a39Sopenharmony_ci||	MVK	0x00000203,B0
104e1051a39Sopenharmony_ci	MVKH	0x04040000,$ONE
105e1051a39Sopenharmony_ci||	MVKH	0x00010000,B0
106e1051a39Sopenharmony_ci	.else
107e1051a39Sopenharmony_ci	MVK	0x00000404,$ONE
108e1051a39Sopenharmony_ci||	MVK	0x00000100,B0
109e1051a39Sopenharmony_ci	MVKH	0x04040000,$ONE
110e1051a39Sopenharmony_ci||	MVKH	0x03020000,B0
111e1051a39Sopenharmony_ci	.endif
112e1051a39Sopenharmony_ci	ADD	$KEY,2,$KEYA
113e1051a39Sopenharmony_ci||	ADD	$KEY,2,$KEYB
114e1051a39Sopenharmony_ci||	ADD	$INP,$LEN,$ret		; end of input
115e1051a39Sopenharmony_ci	LDBU	*${INP}++,$dat
116e1051a39Sopenharmony_ci||	MVK	0,$TX
117e1051a39Sopenharmony_ci	STH	$TX,*${KEY}++		; key->x=key->y=0
118e1051a39Sopenharmony_ci||	MV	B0,A0
119e1051a39Sopenharmony_ci||	MVK	64-4,B0
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci;;==================================================
122e1051a39Sopenharmony_ci	SPLOOPD	1
123e1051a39Sopenharmony_ci||	MVC	B0,ILC
124e1051a39Sopenharmony_ci
125e1051a39Sopenharmony_ci	STNW	A0,*${KEY}++
126e1051a39Sopenharmony_ci||	ADD4	$ONE,A0,A0
127e1051a39Sopenharmony_ci	SPKERNEL
128e1051a39Sopenharmony_ci;;==================================================
129e1051a39Sopenharmony_ci
130e1051a39Sopenharmony_ci	MVK	0,$YY
131e1051a39Sopenharmony_ci||	MVK	0,$XX
132e1051a39Sopenharmony_ci	MVK	1,$ONE
133e1051a39Sopenharmony_ci||	MVK	256-1,B0
134e1051a39Sopenharmony_ci
135e1051a39Sopenharmony_ci;;==================================================
136e1051a39Sopenharmony_ci	SPLOOPD	8
137e1051a39Sopenharmony_ci||	MVC	B0,ILC
138e1051a39Sopenharmony_ci
139e1051a39Sopenharmony_ci	ADD4	$dat,$YY,$YY
140e1051a39Sopenharmony_ci||	CMPEQ	$INP,$ret,A0		; end of input?
141e1051a39Sopenharmony_ci	LDBU	*${KEYB}[$YY],$TY
142e1051a39Sopenharmony_ci||	MVD	$XX,$xx
143e1051a39Sopenharmony_ci||	ADD4	$ONE,$XX,$XX
144e1051a39Sopenharmony_ci	LDBU	*${KEYA}[$XX],$tx
145e1051a39Sopenharmony_ci||[A0]	SUB	$INP,$LEN,$INP		; rewind
146e1051a39Sopenharmony_ci	LDBU	*${INP}++,$dat
147e1051a39Sopenharmony_ci||	CMPEQ	$YY,$XX,B0
148e1051a39Sopenharmony_ci||	NOP	3
149e1051a39Sopenharmony_ci	STB	$TX,*${KEYB}[$YY]
150e1051a39Sopenharmony_ci||[B0]	ADD4	$TX,$YY,$YY
151e1051a39Sopenharmony_ci	STB	$TY,*${KEYA}[$xx]
152e1051a39Sopenharmony_ci||[!B0]	ADD4	$tx,$YY,$YY
153e1051a39Sopenharmony_ci||[!B0]	MV	$tx,$TX
154e1051a39Sopenharmony_ci	SPKERNEL
155e1051a39Sopenharmony_ci;;==================================================
156e1051a39Sopenharmony_ci
157e1051a39Sopenharmony_ci	BNOP	B3,5
158e1051a39Sopenharmony_ci	.endasmfunc
159e1051a39Sopenharmony_ci
160e1051a39Sopenharmony_ci	.global	_RC4_options
161e1051a39Sopenharmony_ci	.align	16
162e1051a39Sopenharmony_ci_RC4_options:
163e1051a39Sopenharmony_ci_rc4_options:
164e1051a39Sopenharmony_ci	.asmfunc
165e1051a39Sopenharmony_ci	BNOP	B3,1
166e1051a39Sopenharmony_ci	ADDKPC	_rc4_options,B4
167e1051a39Sopenharmony_ci	.if	__TI_EABI__
168e1051a39Sopenharmony_ci	MVKL	\$PCR_OFFSET(rc4_options,_rc4_options),A4
169e1051a39Sopenharmony_ci	MVKH	\$PCR_OFFSET(rc4_options,_rc4_options),A4
170e1051a39Sopenharmony_ci	.else
171e1051a39Sopenharmony_ci	MVKL	(rc4_options-_rc4_options),A4
172e1051a39Sopenharmony_ci	MVKH	(rc4_options-_rc4_options),A4
173e1051a39Sopenharmony_ci	.endif
174e1051a39Sopenharmony_ci	ADD	B4,A4,A4
175e1051a39Sopenharmony_ci	.endasmfunc
176e1051a39Sopenharmony_ci
177e1051a39Sopenharmony_ci	.if	__TI_EABI__
178e1051a39Sopenharmony_ci	.sect	".text:rc4_options.const"
179e1051a39Sopenharmony_ci	.else
180e1051a39Sopenharmony_ci	.sect	".const:rc4_options"
181e1051a39Sopenharmony_ci	.endif
182e1051a39Sopenharmony_ci	.align	4
183e1051a39Sopenharmony_circ4_options:
184e1051a39Sopenharmony_ci	.cstring "rc4(sploop,char)"
185e1051a39Sopenharmony_ci	.cstring "RC4 for C64+, CRYPTOGAMS by <appro\@openssl.org>"
186e1051a39Sopenharmony_ci	.align	4
187e1051a39Sopenharmony_ci___
188e1051a39Sopenharmony_ci
189e1051a39Sopenharmony_ci$output = pop and open STDOUT,">$output";
190e1051a39Sopenharmony_ciprint $code;
191e1051a39Sopenharmony_ciclose STDOUT or die "error closing STDOUT: $!";
192