1OPTION	DOTNAME
2.text$	SEGMENT ALIGN(256) 'CODE'
3EXTERN	OPENSSL_ia32cap_P:NEAR
4
5PUBLIC	asm_RC4
6
7ALIGN	16
8asm_RC4	PROC PUBLIC
9	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
10	mov	QWORD PTR[16+rsp],rsi
11	mov	rax,rsp
12$L$SEH_begin_asm_RC4::
13	mov	rdi,rcx
14	mov	rsi,rdx
15	mov	rdx,r8
16	mov	rcx,r9
17
18
19	or	rsi,rsi
20	jne	$L$entry
21	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
22	mov	rsi,QWORD PTR[16+rsp]
23	DB	0F3h,0C3h		;repret
24$L$entry::
25	push	rbx
26	push	r12
27	push	r13
28$L$prologue::
29	mov	r11,rsi
30	mov	r12,rdx
31	mov	r13,rcx
32	xor	r10,r10
33	xor	rcx,rcx
34
35	lea	rdi,QWORD PTR[8+rdi]
36	mov	r10b,BYTE PTR[((-8))+rdi]
37	mov	cl,BYTE PTR[((-4))+rdi]
38	cmp	DWORD PTR[256+rdi],-1
39	je	$L$RC4_CHAR
40	lea	r8,QWORD PTR[OPENSSL_ia32cap_P]
41	mov	r8d,DWORD PTR[r8]
42	xor	rbx,rbx
43	inc	r10b
44	sub	rbx,r10
45	sub	r13,r12
46	mov	eax,DWORD PTR[r10*4+rdi]
47	test	r11,-16
48	jz	$L$loop1
49	bt	r8d,30
50	jc	$L$intel
51	and	rbx,7
52	lea	rsi,QWORD PTR[1+r10]
53	jz	$L$oop8
54	sub	r11,rbx
55$L$oop8_warmup::
56	add	cl,al
57	mov	edx,DWORD PTR[rcx*4+rdi]
58	mov	DWORD PTR[rcx*4+rdi],eax
59	mov	DWORD PTR[r10*4+rdi],edx
60	add	al,dl
61	inc	r10b
62	mov	edx,DWORD PTR[rax*4+rdi]
63	mov	eax,DWORD PTR[r10*4+rdi]
64	xor	dl,BYTE PTR[r12]
65	mov	BYTE PTR[r13*1+r12],dl
66	lea	r12,QWORD PTR[1+r12]
67	dec	rbx
68	jnz	$L$oop8_warmup
69
70	lea	rsi,QWORD PTR[1+r10]
71	jmp	$L$oop8
72ALIGN	16
73$L$oop8::
74	add	cl,al
75	mov	edx,DWORD PTR[rcx*4+rdi]
76	mov	DWORD PTR[rcx*4+rdi],eax
77	mov	ebx,DWORD PTR[rsi*4+rdi]
78	ror	r8,8
79	mov	DWORD PTR[r10*4+rdi],edx
80	add	dl,al
81	mov	r8b,BYTE PTR[rdx*4+rdi]
82	add	cl,bl
83	mov	edx,DWORD PTR[rcx*4+rdi]
84	mov	DWORD PTR[rcx*4+rdi],ebx
85	mov	eax,DWORD PTR[4+rsi*4+rdi]
86	ror	r8,8
87	mov	DWORD PTR[4+r10*4+rdi],edx
88	add	dl,bl
89	mov	r8b,BYTE PTR[rdx*4+rdi]
90	add	cl,al
91	mov	edx,DWORD PTR[rcx*4+rdi]
92	mov	DWORD PTR[rcx*4+rdi],eax
93	mov	ebx,DWORD PTR[8+rsi*4+rdi]
94	ror	r8,8
95	mov	DWORD PTR[8+r10*4+rdi],edx
96	add	dl,al
97	mov	r8b,BYTE PTR[rdx*4+rdi]
98	add	cl,bl
99	mov	edx,DWORD PTR[rcx*4+rdi]
100	mov	DWORD PTR[rcx*4+rdi],ebx
101	mov	eax,DWORD PTR[12+rsi*4+rdi]
102	ror	r8,8
103	mov	DWORD PTR[12+r10*4+rdi],edx
104	add	dl,bl
105	mov	r8b,BYTE PTR[rdx*4+rdi]
106	add	cl,al
107	mov	edx,DWORD PTR[rcx*4+rdi]
108	mov	DWORD PTR[rcx*4+rdi],eax
109	mov	ebx,DWORD PTR[16+rsi*4+rdi]
110	ror	r8,8
111	mov	DWORD PTR[16+r10*4+rdi],edx
112	add	dl,al
113	mov	r8b,BYTE PTR[rdx*4+rdi]
114	add	cl,bl
115	mov	edx,DWORD PTR[rcx*4+rdi]
116	mov	DWORD PTR[rcx*4+rdi],ebx
117	mov	eax,DWORD PTR[20+rsi*4+rdi]
118	ror	r8,8
119	mov	DWORD PTR[20+r10*4+rdi],edx
120	add	dl,bl
121	mov	r8b,BYTE PTR[rdx*4+rdi]
122	add	cl,al
123	mov	edx,DWORD PTR[rcx*4+rdi]
124	mov	DWORD PTR[rcx*4+rdi],eax
125	mov	ebx,DWORD PTR[24+rsi*4+rdi]
126	ror	r8,8
127	mov	DWORD PTR[24+r10*4+rdi],edx
128	add	dl,al
129	mov	r8b,BYTE PTR[rdx*4+rdi]
130	add	sil,8
131	add	cl,bl
132	mov	edx,DWORD PTR[rcx*4+rdi]
133	mov	DWORD PTR[rcx*4+rdi],ebx
134	mov	eax,DWORD PTR[((-4))+rsi*4+rdi]
135	ror	r8,8
136	mov	DWORD PTR[28+r10*4+rdi],edx
137	add	dl,bl
138	mov	r8b,BYTE PTR[rdx*4+rdi]
139	add	r10b,8
140	ror	r8,8
141	sub	r11,8
142
143	xor	r8,QWORD PTR[r12]
144	mov	QWORD PTR[r13*1+r12],r8
145	lea	r12,QWORD PTR[8+r12]
146
147	test	r11,-8
148	jnz	$L$oop8
149	cmp	r11,0
150	jne	$L$loop1
151	jmp	$L$exit
152
153ALIGN	16
154$L$intel::
155	test	r11,-32
156	jz	$L$loop1
157	and	rbx,15
158	jz	$L$oop16_is_hot
159	sub	r11,rbx
160$L$oop16_warmup::
161	add	cl,al
162	mov	edx,DWORD PTR[rcx*4+rdi]
163	mov	DWORD PTR[rcx*4+rdi],eax
164	mov	DWORD PTR[r10*4+rdi],edx
165	add	al,dl
166	inc	r10b
167	mov	edx,DWORD PTR[rax*4+rdi]
168	mov	eax,DWORD PTR[r10*4+rdi]
169	xor	dl,BYTE PTR[r12]
170	mov	BYTE PTR[r13*1+r12],dl
171	lea	r12,QWORD PTR[1+r12]
172	dec	rbx
173	jnz	$L$oop16_warmup
174
175	mov	rbx,rcx
176	xor	rcx,rcx
177	mov	cl,bl
178
179$L$oop16_is_hot::
180	lea	rsi,QWORD PTR[r10*4+rdi]
181	add	cl,al
182	mov	edx,DWORD PTR[rcx*4+rdi]
183	pxor	xmm0,xmm0
184	mov	DWORD PTR[rcx*4+rdi],eax
185	add	al,dl
186	mov	ebx,DWORD PTR[4+rsi]
187	movzx	eax,al
188	mov	DWORD PTR[rsi],edx
189	add	cl,bl
190	pinsrw	xmm0,WORD PTR[rax*4+rdi],0
191	jmp	$L$oop16_enter
192ALIGN	16
193$L$oop16::
194	add	cl,al
195	mov	edx,DWORD PTR[rcx*4+rdi]
196	pxor	xmm2,xmm0
197	psllq	xmm1,8
198	pxor	xmm0,xmm0
199	mov	DWORD PTR[rcx*4+rdi],eax
200	add	al,dl
201	mov	ebx,DWORD PTR[4+rsi]
202	movzx	eax,al
203	mov	DWORD PTR[rsi],edx
204	pxor	xmm2,xmm1
205	add	cl,bl
206	pinsrw	xmm0,WORD PTR[rax*4+rdi],0
207	movdqu	XMMWORD PTR[r13*1+r12],xmm2
208	lea	r12,QWORD PTR[16+r12]
209$L$oop16_enter::
210	mov	edx,DWORD PTR[rcx*4+rdi]
211	pxor	xmm1,xmm1
212	mov	DWORD PTR[rcx*4+rdi],ebx
213	add	bl,dl
214	mov	eax,DWORD PTR[8+rsi]
215	movzx	ebx,bl
216	mov	DWORD PTR[4+rsi],edx
217	add	cl,al
218	pinsrw	xmm1,WORD PTR[rbx*4+rdi],0
219	mov	edx,DWORD PTR[rcx*4+rdi]
220	mov	DWORD PTR[rcx*4+rdi],eax
221	add	al,dl
222	mov	ebx,DWORD PTR[12+rsi]
223	movzx	eax,al
224	mov	DWORD PTR[8+rsi],edx
225	add	cl,bl
226	pinsrw	xmm0,WORD PTR[rax*4+rdi],1
227	mov	edx,DWORD PTR[rcx*4+rdi]
228	mov	DWORD PTR[rcx*4+rdi],ebx
229	add	bl,dl
230	mov	eax,DWORD PTR[16+rsi]
231	movzx	ebx,bl
232	mov	DWORD PTR[12+rsi],edx
233	add	cl,al
234	pinsrw	xmm1,WORD PTR[rbx*4+rdi],1
235	mov	edx,DWORD PTR[rcx*4+rdi]
236	mov	DWORD PTR[rcx*4+rdi],eax
237	add	al,dl
238	mov	ebx,DWORD PTR[20+rsi]
239	movzx	eax,al
240	mov	DWORD PTR[16+rsi],edx
241	add	cl,bl
242	pinsrw	xmm0,WORD PTR[rax*4+rdi],2
243	mov	edx,DWORD PTR[rcx*4+rdi]
244	mov	DWORD PTR[rcx*4+rdi],ebx
245	add	bl,dl
246	mov	eax,DWORD PTR[24+rsi]
247	movzx	ebx,bl
248	mov	DWORD PTR[20+rsi],edx
249	add	cl,al
250	pinsrw	xmm1,WORD PTR[rbx*4+rdi],2
251	mov	edx,DWORD PTR[rcx*4+rdi]
252	mov	DWORD PTR[rcx*4+rdi],eax
253	add	al,dl
254	mov	ebx,DWORD PTR[28+rsi]
255	movzx	eax,al
256	mov	DWORD PTR[24+rsi],edx
257	add	cl,bl
258	pinsrw	xmm0,WORD PTR[rax*4+rdi],3
259	mov	edx,DWORD PTR[rcx*4+rdi]
260	mov	DWORD PTR[rcx*4+rdi],ebx
261	add	bl,dl
262	mov	eax,DWORD PTR[32+rsi]
263	movzx	ebx,bl
264	mov	DWORD PTR[28+rsi],edx
265	add	cl,al
266	pinsrw	xmm1,WORD PTR[rbx*4+rdi],3
267	mov	edx,DWORD PTR[rcx*4+rdi]
268	mov	DWORD PTR[rcx*4+rdi],eax
269	add	al,dl
270	mov	ebx,DWORD PTR[36+rsi]
271	movzx	eax,al
272	mov	DWORD PTR[32+rsi],edx
273	add	cl,bl
274	pinsrw	xmm0,WORD PTR[rax*4+rdi],4
275	mov	edx,DWORD PTR[rcx*4+rdi]
276	mov	DWORD PTR[rcx*4+rdi],ebx
277	add	bl,dl
278	mov	eax,DWORD PTR[40+rsi]
279	movzx	ebx,bl
280	mov	DWORD PTR[36+rsi],edx
281	add	cl,al
282	pinsrw	xmm1,WORD PTR[rbx*4+rdi],4
283	mov	edx,DWORD PTR[rcx*4+rdi]
284	mov	DWORD PTR[rcx*4+rdi],eax
285	add	al,dl
286	mov	ebx,DWORD PTR[44+rsi]
287	movzx	eax,al
288	mov	DWORD PTR[40+rsi],edx
289	add	cl,bl
290	pinsrw	xmm0,WORD PTR[rax*4+rdi],5
291	mov	edx,DWORD PTR[rcx*4+rdi]
292	mov	DWORD PTR[rcx*4+rdi],ebx
293	add	bl,dl
294	mov	eax,DWORD PTR[48+rsi]
295	movzx	ebx,bl
296	mov	DWORD PTR[44+rsi],edx
297	add	cl,al
298	pinsrw	xmm1,WORD PTR[rbx*4+rdi],5
299	mov	edx,DWORD PTR[rcx*4+rdi]
300	mov	DWORD PTR[rcx*4+rdi],eax
301	add	al,dl
302	mov	ebx,DWORD PTR[52+rsi]
303	movzx	eax,al
304	mov	DWORD PTR[48+rsi],edx
305	add	cl,bl
306	pinsrw	xmm0,WORD PTR[rax*4+rdi],6
307	mov	edx,DWORD PTR[rcx*4+rdi]
308	mov	DWORD PTR[rcx*4+rdi],ebx
309	add	bl,dl
310	mov	eax,DWORD PTR[56+rsi]
311	movzx	ebx,bl
312	mov	DWORD PTR[52+rsi],edx
313	add	cl,al
314	pinsrw	xmm1,WORD PTR[rbx*4+rdi],6
315	mov	edx,DWORD PTR[rcx*4+rdi]
316	mov	DWORD PTR[rcx*4+rdi],eax
317	add	al,dl
318	mov	ebx,DWORD PTR[60+rsi]
319	movzx	eax,al
320	mov	DWORD PTR[56+rsi],edx
321	add	cl,bl
322	pinsrw	xmm0,WORD PTR[rax*4+rdi],7
323	add	r10b,16
324	movdqu	xmm2,XMMWORD PTR[r12]
325	mov	edx,DWORD PTR[rcx*4+rdi]
326	mov	DWORD PTR[rcx*4+rdi],ebx
327	add	bl,dl
328	movzx	ebx,bl
329	mov	DWORD PTR[60+rsi],edx
330	lea	rsi,QWORD PTR[r10*4+rdi]
331	pinsrw	xmm1,WORD PTR[rbx*4+rdi],7
332	mov	eax,DWORD PTR[rsi]
333	mov	rbx,rcx
334	xor	rcx,rcx
335	sub	r11,16
336	mov	cl,bl
337	test	r11,-16
338	jnz	$L$oop16
339
340	psllq	xmm1,8
341	pxor	xmm2,xmm0
342	pxor	xmm2,xmm1
343	movdqu	XMMWORD PTR[r13*1+r12],xmm2
344	lea	r12,QWORD PTR[16+r12]
345
346	cmp	r11,0
347	jne	$L$loop1
348	jmp	$L$exit
349
350ALIGN	16
351$L$loop1::
352	add	cl,al
353	mov	edx,DWORD PTR[rcx*4+rdi]
354	mov	DWORD PTR[rcx*4+rdi],eax
355	mov	DWORD PTR[r10*4+rdi],edx
356	add	al,dl
357	inc	r10b
358	mov	edx,DWORD PTR[rax*4+rdi]
359	mov	eax,DWORD PTR[r10*4+rdi]
360	xor	dl,BYTE PTR[r12]
361	mov	BYTE PTR[r13*1+r12],dl
362	lea	r12,QWORD PTR[1+r12]
363	dec	r11
364	jnz	$L$loop1
365	jmp	$L$exit
366
367ALIGN	16
368$L$RC4_CHAR::
369	add	r10b,1
370	movzx	eax,BYTE PTR[r10*1+rdi]
371	test	r11,-8
372	jz	$L$cloop1
373	jmp	$L$cloop8
374ALIGN	16
375$L$cloop8::
376	mov	r8d,DWORD PTR[r12]
377	mov	r9d,DWORD PTR[4+r12]
378	add	cl,al
379	lea	rsi,QWORD PTR[1+r10]
380	movzx	edx,BYTE PTR[rcx*1+rdi]
381	movzx	esi,sil
382	movzx	ebx,BYTE PTR[rsi*1+rdi]
383	mov	BYTE PTR[rcx*1+rdi],al
384	cmp	rcx,rsi
385	mov	BYTE PTR[r10*1+rdi],dl
386	jne	$L$cmov0
387	mov	rbx,rax
388$L$cmov0::
389	add	dl,al
390	xor	r8b,BYTE PTR[rdx*1+rdi]
391	ror	r8d,8
392	add	cl,bl
393	lea	r10,QWORD PTR[1+rsi]
394	movzx	edx,BYTE PTR[rcx*1+rdi]
395	movzx	r10d,r10b
396	movzx	eax,BYTE PTR[r10*1+rdi]
397	mov	BYTE PTR[rcx*1+rdi],bl
398	cmp	rcx,r10
399	mov	BYTE PTR[rsi*1+rdi],dl
400	jne	$L$cmov1
401	mov	rax,rbx
402$L$cmov1::
403	add	dl,bl
404	xor	r8b,BYTE PTR[rdx*1+rdi]
405	ror	r8d,8
406	add	cl,al
407	lea	rsi,QWORD PTR[1+r10]
408	movzx	edx,BYTE PTR[rcx*1+rdi]
409	movzx	esi,sil
410	movzx	ebx,BYTE PTR[rsi*1+rdi]
411	mov	BYTE PTR[rcx*1+rdi],al
412	cmp	rcx,rsi
413	mov	BYTE PTR[r10*1+rdi],dl
414	jne	$L$cmov2
415	mov	rbx,rax
416$L$cmov2::
417	add	dl,al
418	xor	r8b,BYTE PTR[rdx*1+rdi]
419	ror	r8d,8
420	add	cl,bl
421	lea	r10,QWORD PTR[1+rsi]
422	movzx	edx,BYTE PTR[rcx*1+rdi]
423	movzx	r10d,r10b
424	movzx	eax,BYTE PTR[r10*1+rdi]
425	mov	BYTE PTR[rcx*1+rdi],bl
426	cmp	rcx,r10
427	mov	BYTE PTR[rsi*1+rdi],dl
428	jne	$L$cmov3
429	mov	rax,rbx
430$L$cmov3::
431	add	dl,bl
432	xor	r8b,BYTE PTR[rdx*1+rdi]
433	ror	r8d,8
434	add	cl,al
435	lea	rsi,QWORD PTR[1+r10]
436	movzx	edx,BYTE PTR[rcx*1+rdi]
437	movzx	esi,sil
438	movzx	ebx,BYTE PTR[rsi*1+rdi]
439	mov	BYTE PTR[rcx*1+rdi],al
440	cmp	rcx,rsi
441	mov	BYTE PTR[r10*1+rdi],dl
442	jne	$L$cmov4
443	mov	rbx,rax
444$L$cmov4::
445	add	dl,al
446	xor	r9b,BYTE PTR[rdx*1+rdi]
447	ror	r9d,8
448	add	cl,bl
449	lea	r10,QWORD PTR[1+rsi]
450	movzx	edx,BYTE PTR[rcx*1+rdi]
451	movzx	r10d,r10b
452	movzx	eax,BYTE PTR[r10*1+rdi]
453	mov	BYTE PTR[rcx*1+rdi],bl
454	cmp	rcx,r10
455	mov	BYTE PTR[rsi*1+rdi],dl
456	jne	$L$cmov5
457	mov	rax,rbx
458$L$cmov5::
459	add	dl,bl
460	xor	r9b,BYTE PTR[rdx*1+rdi]
461	ror	r9d,8
462	add	cl,al
463	lea	rsi,QWORD PTR[1+r10]
464	movzx	edx,BYTE PTR[rcx*1+rdi]
465	movzx	esi,sil
466	movzx	ebx,BYTE PTR[rsi*1+rdi]
467	mov	BYTE PTR[rcx*1+rdi],al
468	cmp	rcx,rsi
469	mov	BYTE PTR[r10*1+rdi],dl
470	jne	$L$cmov6
471	mov	rbx,rax
472$L$cmov6::
473	add	dl,al
474	xor	r9b,BYTE PTR[rdx*1+rdi]
475	ror	r9d,8
476	add	cl,bl
477	lea	r10,QWORD PTR[1+rsi]
478	movzx	edx,BYTE PTR[rcx*1+rdi]
479	movzx	r10d,r10b
480	movzx	eax,BYTE PTR[r10*1+rdi]
481	mov	BYTE PTR[rcx*1+rdi],bl
482	cmp	rcx,r10
483	mov	BYTE PTR[rsi*1+rdi],dl
484	jne	$L$cmov7
485	mov	rax,rbx
486$L$cmov7::
487	add	dl,bl
488	xor	r9b,BYTE PTR[rdx*1+rdi]
489	ror	r9d,8
490	lea	r11,QWORD PTR[((-8))+r11]
491	mov	DWORD PTR[r13],r8d
492	lea	r12,QWORD PTR[8+r12]
493	mov	DWORD PTR[4+r13],r9d
494	lea	r13,QWORD PTR[8+r13]
495
496	test	r11,-8
497	jnz	$L$cloop8
498	cmp	r11,0
499	jne	$L$cloop1
500	jmp	$L$exit
501ALIGN	16
502$L$cloop1::
503	add	cl,al
504	movzx	ecx,cl
505	movzx	edx,BYTE PTR[rcx*1+rdi]
506	mov	BYTE PTR[rcx*1+rdi],al
507	mov	BYTE PTR[r10*1+rdi],dl
508	add	dl,al
509	add	r10b,1
510	movzx	edx,dl
511	movzx	r10d,r10b
512	movzx	edx,BYTE PTR[rdx*1+rdi]
513	movzx	eax,BYTE PTR[r10*1+rdi]
514	xor	dl,BYTE PTR[r12]
515	lea	r12,QWORD PTR[1+r12]
516	mov	BYTE PTR[r13],dl
517	lea	r13,QWORD PTR[1+r13]
518	sub	r11,1
519	jnz	$L$cloop1
520	jmp	$L$exit
521
522ALIGN	16
523$L$exit::
524	sub	r10b,1
525	mov	DWORD PTR[((-8))+rdi],r10d
526	mov	DWORD PTR[((-4))+rdi],ecx
527
528	mov	r13,QWORD PTR[rsp]
529	mov	r12,QWORD PTR[8+rsp]
530	mov	rbx,QWORD PTR[16+rsp]
531	add	rsp,24
532$L$epilogue::
533	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
534	mov	rsi,QWORD PTR[16+rsp]
535	DB	0F3h,0C3h		;repret
536$L$SEH_end_asm_RC4::
537asm_RC4	ENDP
538PUBLIC	asm_RC4_set_key
539
540ALIGN	16
541asm_RC4_set_key	PROC PUBLIC
542	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
543	mov	QWORD PTR[16+rsp],rsi
544	mov	rax,rsp
545$L$SEH_begin_asm_RC4_set_key::
546	mov	rdi,rcx
547	mov	rsi,rdx
548	mov	rdx,r8
549
550
551	lea	rdi,QWORD PTR[8+rdi]
552	lea	rdx,QWORD PTR[rsi*1+rdx]
553	neg	rsi
554	mov	rcx,rsi
555	xor	eax,eax
556	xor	r9,r9
557	xor	r10,r10
558	xor	r11,r11
559
560	lea	r8,QWORD PTR[OPENSSL_ia32cap_P]
561	mov	r8d,DWORD PTR[r8]
562	bt	r8d,20
563	jc	$L$c1stloop
564	jmp	$L$w1stloop
565
566ALIGN	16
567$L$w1stloop::
568	mov	DWORD PTR[rax*4+rdi],eax
569	add	al,1
570	jnc	$L$w1stloop
571
572	xor	r9,r9
573	xor	r8,r8
574ALIGN	16
575$L$w2ndloop::
576	mov	r10d,DWORD PTR[r9*4+rdi]
577	add	r8b,BYTE PTR[rsi*1+rdx]
578	add	r8b,r10b
579	add	rsi,1
580	mov	r11d,DWORD PTR[r8*4+rdi]
581	cmovz	rsi,rcx
582	mov	DWORD PTR[r8*4+rdi],r10d
583	mov	DWORD PTR[r9*4+rdi],r11d
584	add	r9b,1
585	jnc	$L$w2ndloop
586	jmp	$L$exit_key
587
588ALIGN	16
589$L$c1stloop::
590	mov	BYTE PTR[rax*1+rdi],al
591	add	al,1
592	jnc	$L$c1stloop
593
594	xor	r9,r9
595	xor	r8,r8
596ALIGN	16
597$L$c2ndloop::
598	mov	r10b,BYTE PTR[r9*1+rdi]
599	add	r8b,BYTE PTR[rsi*1+rdx]
600	add	r8b,r10b
601	add	rsi,1
602	mov	r11b,BYTE PTR[r8*1+rdi]
603	jnz	$L$cnowrap
604	mov	rsi,rcx
605$L$cnowrap::
606	mov	BYTE PTR[r8*1+rdi],r10b
607	mov	BYTE PTR[r9*1+rdi],r11b
608	add	r9b,1
609	jnc	$L$c2ndloop
610	mov	DWORD PTR[256+rdi],-1
611
612ALIGN	16
613$L$exit_key::
614	xor	eax,eax
615	mov	DWORD PTR[((-8))+rdi],eax
616	mov	DWORD PTR[((-4))+rdi],eax
617	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
618	mov	rsi,QWORD PTR[16+rsp]
619	DB	0F3h,0C3h		;repret
620$L$SEH_end_asm_RC4_set_key::
621asm_RC4_set_key	ENDP
622
623PUBLIC	RC4_options
624
625ALIGN	16
626RC4_options	PROC PUBLIC
627	lea	rax,QWORD PTR[$L$opts]
628	mov	rdx,QWORD PTR[OPENSSL_ia32cap_P]
629	mov	edx,DWORD PTR[rdx]
630	bt	edx,20
631	jc	$L$8xchar
632	bt	edx,30
633	jnc	$L$done
634	add	rax,25
635	DB	0F3h,0C3h		;repret
636$L$8xchar::
637	add	rax,12
638$L$done::
639	DB	0F3h,0C3h		;repret
640ALIGN	64
641$L$opts::
642DB	114,99,52,40,56,120,44,105,110,116,41,0
643DB	114,99,52,40,56,120,44,99,104,97,114,41,0
644DB	114,99,52,40,49,54,120,44,105,110,116,41,0
645DB	82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32
646DB	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
647DB	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
648DB	62,0
649ALIGN	64
650RC4_options	ENDP
651EXTERN	__imp_RtlVirtualUnwind:NEAR
652
653ALIGN	16
654stream_se_handler	PROC PRIVATE
655	push	rsi
656	push	rdi
657	push	rbx
658	push	rbp
659	push	r12
660	push	r13
661	push	r14
662	push	r15
663	pushfq
664	sub	rsp,64
665
666	mov	rax,QWORD PTR[120+r8]
667	mov	rbx,QWORD PTR[248+r8]
668
669	lea	r10,QWORD PTR[$L$prologue]
670	cmp	rbx,r10
671	jb	$L$in_prologue
672
673	mov	rax,QWORD PTR[152+r8]
674
675	lea	r10,QWORD PTR[$L$epilogue]
676	cmp	rbx,r10
677	jae	$L$in_prologue
678
679	lea	rax,QWORD PTR[24+rax]
680
681	mov	rbx,QWORD PTR[((-8))+rax]
682	mov	r12,QWORD PTR[((-16))+rax]
683	mov	r13,QWORD PTR[((-24))+rax]
684	mov	QWORD PTR[144+r8],rbx
685	mov	QWORD PTR[216+r8],r12
686	mov	QWORD PTR[224+r8],r13
687
688$L$in_prologue::
689	mov	rdi,QWORD PTR[8+rax]
690	mov	rsi,QWORD PTR[16+rax]
691	mov	QWORD PTR[152+r8],rax
692	mov	QWORD PTR[168+r8],rsi
693	mov	QWORD PTR[176+r8],rdi
694
695	jmp	$L$common_seh_exit
696stream_se_handler	ENDP
697
698
699ALIGN	16
700key_se_handler	PROC PRIVATE
701	push	rsi
702	push	rdi
703	push	rbx
704	push	rbp
705	push	r12
706	push	r13
707	push	r14
708	push	r15
709	pushfq
710	sub	rsp,64
711
712	mov	rax,QWORD PTR[152+r8]
713	mov	rdi,QWORD PTR[8+rax]
714	mov	rsi,QWORD PTR[16+rax]
715	mov	QWORD PTR[168+r8],rsi
716	mov	QWORD PTR[176+r8],rdi
717
718$L$common_seh_exit::
719
720	mov	rdi,QWORD PTR[40+r9]
721	mov	rsi,r8
722	mov	ecx,154
723	DD	0a548f3fch
724
725	mov	rsi,r9
726	xor	rcx,rcx
727	mov	rdx,QWORD PTR[8+rsi]
728	mov	r8,QWORD PTR[rsi]
729	mov	r9,QWORD PTR[16+rsi]
730	mov	r10,QWORD PTR[40+rsi]
731	lea	r11,QWORD PTR[56+rsi]
732	lea	r12,QWORD PTR[24+rsi]
733	mov	QWORD PTR[32+rsp],r10
734	mov	QWORD PTR[40+rsp],r11
735	mov	QWORD PTR[48+rsp],r12
736	mov	QWORD PTR[56+rsp],rcx
737	call	QWORD PTR[__imp_RtlVirtualUnwind]
738
739	mov	eax,1
740	add	rsp,64
741	popfq
742	pop	r15
743	pop	r14
744	pop	r13
745	pop	r12
746	pop	rbp
747	pop	rbx
748	pop	rdi
749	pop	rsi
750	DB	0F3h,0C3h		;repret
751key_se_handler	ENDP
752
753.text$	ENDS
754.pdata	SEGMENT READONLY ALIGN(4)
755ALIGN	4
756	DD	imagerel $L$SEH_begin_asm_RC4
757	DD	imagerel $L$SEH_end_asm_RC4
758	DD	imagerel $L$SEH_info_asm_RC4
759
760	DD	imagerel $L$SEH_begin_asm_RC4_set_key
761	DD	imagerel $L$SEH_end_asm_RC4_set_key
762	DD	imagerel $L$SEH_info_asm_RC4_set_key
763
764.pdata	ENDS
765.xdata	SEGMENT READONLY ALIGN(8)
766ALIGN	8
767$L$SEH_info_asm_RC4::
768DB	9,0,0,0
769	DD	imagerel stream_se_handler
770$L$SEH_info_asm_RC4_set_key::
771DB	9,0,0,0
772	DD	imagerel key_se_handler
773
774.xdata	ENDS
775END
776