1554ff184Skais /*
2554ff184Skais * CDDL HEADER START
3554ff184Skais *
4554ff184Skais * The contents of this file are subject to the terms of the
5b6c3f786Sbubbva * Common Development and Distribution License (the "License").
6b6c3f786Sbubbva * You may not use this file except in compliance with the License.
7554ff184Skais *
8554ff184Skais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9554ff184Skais * or http://www.opensolaris.org/os/licensing.
10554ff184Skais * See the License for the specific language governing permissions
11554ff184Skais * and limitations under the License.
12554ff184Skais *
13554ff184Skais * When distributing Covered Code, include this CDDL HEADER in each
14554ff184Skais * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15554ff184Skais * If applicable, add the following below this CDDL HEADER, with the
16554ff184Skais * fields enclosed by brackets "[]" replaced with your own identifying
17554ff184Skais * information: Portions Copyright [yyyy] [name of copyright owner]
18554ff184Skais *
19554ff184Skais * CDDL HEADER END
20554ff184Skais */
21*726fad2aSDina K Nimeh
22554ff184Skais /*
23*726fad2aSDina K Nimeh * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24554ff184Skais */
25554ff184Skais
26554ff184Skais #include "../arcfour.h"
27554ff184Skais
28554ff184Skais /* Initialize the key stream 'key' using the key value */
29554ff184Skais void
arcfour_key_init(ARCFour_key * key,uchar_t * keyval,int keyvallen)30554ff184Skais arcfour_key_init(ARCFour_key *key, uchar_t *keyval, int keyvallen)
31554ff184Skais {
32554ff184Skais uchar_t ext_keyval[256];
33554ff184Skais uchar_t tmp;
34554ff184Skais int i, j;
35554ff184Skais
36554ff184Skais for (i = j = 0; i < 256; i++, j++) {
37554ff184Skais if (j == keyvallen)
38554ff184Skais j = 0;
39554ff184Skais
40554ff184Skais ext_keyval[i] = keyval[j];
41554ff184Skais }
42554ff184Skais for (i = 0; i < 256; i++)
43554ff184Skais key->arr[i] = (uchar_t)i;
44554ff184Skais
45554ff184Skais j = 0;
46554ff184Skais for (i = 0; i < 256; i++) {
47554ff184Skais j = (j + key->arr[i] + ext_keyval[i]) % 256;
48554ff184Skais tmp = key->arr[i];
49554ff184Skais key->arr[i] = key->arr[j];
50554ff184Skais key->arr[j] = tmp;
51554ff184Skais }
52554ff184Skais key->i = 0;
53554ff184Skais key->j = 0;
54554ff184Skais }
55554ff184Skais
56554ff184Skais
57554ff184Skais /*
58554ff184Skais * Encipher 'in' using 'key.
59554ff184Skais * in and out can point to the same location
60554ff184Skais */
61554ff184Skais void
arcfour_crypt(ARCFour_key * key,uchar_t * in,uchar_t * out,size_t len)62554ff184Skais arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
63554ff184Skais {
6471269a22SAnthony Scarpino size_t ii;
6571269a22SAnthony Scarpino unsigned long long in0, merge = 0, merge0 = 0, merge1, mask = 0;
66554ff184Skais uchar_t i, j, *base, jj, *base1, tmp;
6771269a22SAnthony Scarpino unsigned int tmp0, tmp1, i_accum, shift = 0, i1;
68554ff184Skais
69554ff184Skais int index;
70554ff184Skais
71554ff184Skais base = key->arr;
72554ff184Skais
73b6c3f786Sbubbva index = (((uintptr_t)in) & 0x7);
74554ff184Skais
75554ff184Skais /* Get the 'in' on an 8-byte alignment */
76554ff184Skais if (index > 0) {
77554ff184Skais i = key->i;
78554ff184Skais j = key->j;
79b6c3f786Sbubbva
80b6c3f786Sbubbva for (index = 8 - index; (index-- > 0) && len > 0;
81554ff184Skais len--, in++, out++) {
82b6c3f786Sbubbva
83554ff184Skais i = i + 1;
84554ff184Skais j = j + key->arr[i];
85554ff184Skais tmp = key->arr[i];
86554ff184Skais key->arr[i] = key->arr[j];
87554ff184Skais key->arr[j] = tmp;
88554ff184Skais tmp = key->arr[i] + key->arr[j];
89554ff184Skais *out = *in ^ key->arr[tmp];
90554ff184Skais }
91554ff184Skais key->i = i;
92554ff184Skais key->j = j;
93554ff184Skais
94554ff184Skais }
95554ff184Skais if (len == 0)
96554ff184Skais return;
97554ff184Skais
98554ff184Skais /* See if we're fortunate and 'out' got aligned as well */
99554ff184Skais
100554ff184Skais
101554ff184Skais /*
102554ff184Skais * Niagara optimized version for
103554ff184Skais * the cases where the input and output buffers are aligned on
104554ff184Skais * a multiple of 8-byte boundary.
105554ff184Skais */
106554ff184Skais #ifdef sun4v
107b6c3f786Sbubbva if ((((uintptr_t)out) & 7) != 0) {
108554ff184Skais #endif /* sun4v */
109554ff184Skais i = key->i;
110554ff184Skais j = key->j;
111554ff184Skais for (ii = 0; ii < len; ii++) {
112554ff184Skais i = i + 1;
113554ff184Skais tmp0 = base[i];
114554ff184Skais j = j + tmp0;
115554ff184Skais tmp1 = base[j];
116*726fad2aSDina K Nimeh base[i] = (uchar_t)tmp1;
117*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
118554ff184Skais tmp0 += tmp1;
119554ff184Skais tmp0 = tmp0 & 0xff;
120554ff184Skais out[ii] = in[ii] ^ base[tmp0];
121554ff184Skais }
122554ff184Skais key->i = i;
123554ff184Skais key->j = j;
124554ff184Skais #ifdef sun4v
125554ff184Skais } else {
126554ff184Skais i = key->i;
127554ff184Skais j = key->j;
128554ff184Skais
129554ff184Skais /*
130554ff184Skais * Want to align base[i] on a 2B boundary -- allows updates
131554ff184Skais * via [i] to be performed in 2B chunks (reducing # of stores).
132554ff184Skais * Requires appropriate alias detection.
133554ff184Skais */
134554ff184Skais
135554ff184Skais if (((i+1) % 2) != 0) {
136554ff184Skais i = i + 1;
137554ff184Skais tmp0 = base[i];
138554ff184Skais j = j + tmp0;
139554ff184Skais tmp1 = base[j];
140554ff184Skais
141*726fad2aSDina K Nimeh base[i] = (uchar_t)tmp1;
142*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
143554ff184Skais
144554ff184Skais tmp0 += tmp1;
145554ff184Skais tmp0 = tmp0 & 0xff;
146554ff184Skais
147554ff184Skais merge0 = (unsigned long long)(base[tmp0]) << 56;
148554ff184Skais shift = 8; mask = 0xff;
149554ff184Skais }
150554ff184Skais
151554ff184Skais /*
152554ff184Skais * Note - in and out may now be misaligned -
153554ff184Skais * as updating [out] in 8B chunks need to handle this
154554ff184Skais * possibility. Also could have a 1B overrun.
155554ff184Skais * Need to drop out of loop early as a result.
156554ff184Skais */
157554ff184Skais
158554ff184Skais for (ii = 0, i1 = i; ii < ((len-1) & (~7));
159554ff184Skais ii += 8, i1 = i1&0xff) {
160554ff184Skais
161554ff184Skais /*
162554ff184Skais * If i < less than 248, know wont wrap around
163554ff184Skais * (i % 256), so don't need to bother with masking i
164554ff184Skais * after each increment
165554ff184Skais */
166554ff184Skais if (i1 < 248) {
167554ff184Skais
168554ff184Skais /* BYTE 0 */
169554ff184Skais i1 = (i1 + 1);
170554ff184Skais
171554ff184Skais /*
172554ff184Skais * Creating this base pointer reduces subsequent
173554ff184Skais * arihmetic ops required to load [i]
174554ff184Skais *
175554ff184Skais * N.B. don't need to check if [j] aliases.
176554ff184Skais * [i] and [j] end up with the same values
177554ff184Skais * anyway.
178554ff184Skais */
179554ff184Skais base1 = &base[i1];
180554ff184Skais
181554ff184Skais tmp0 = base1[0];
182554ff184Skais j = j + tmp0;
183554ff184Skais
184554ff184Skais tmp1 = base[j];
185554ff184Skais /*
186554ff184Skais * Don't store [i] yet
187554ff184Skais */
188554ff184Skais i_accum = tmp1;
189*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
190554ff184Skais
191554ff184Skais tmp0 += tmp1;
192554ff184Skais tmp0 = tmp0 & 0xff;
193554ff184Skais
194554ff184Skais /*
195554ff184Skais * Check [tmp0] doesn't alias with [i]
196554ff184Skais */
197554ff184Skais
198554ff184Skais /*
199554ff184Skais * Updating [out] in 8B chunks
200554ff184Skais */
201554ff184Skais if (i1 == tmp0) {
202554ff184Skais merge =
203554ff184Skais (unsigned long long)(i_accum) << 56;
204554ff184Skais } else {
205554ff184Skais merge =
206554ff184Skais (unsigned long long)(base[tmp0]) <<
207554ff184Skais 56;
208554ff184Skais }
209554ff184Skais
210554ff184Skais /* BYTE 1 */
211554ff184Skais tmp0 = base1[1];
212554ff184Skais
213554ff184Skais j = j + tmp0;
214554ff184Skais
215554ff184Skais /*
216554ff184Skais * [j] can now alias with [i] and [i-1]
217554ff184Skais * If alias abort speculation
218554ff184Skais */
219554ff184Skais if ((i1 ^ j) < 2) {
220*726fad2aSDina K Nimeh base1[0] = (uchar_t)i_accum;
221554ff184Skais
222554ff184Skais tmp1 = base[j];
223554ff184Skais
224*726fad2aSDina K Nimeh base1[1] = (uchar_t)tmp1;
225*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
226554ff184Skais
227554ff184Skais tmp0 += tmp1;
228554ff184Skais tmp0 = tmp0 & 0xff;
229554ff184Skais
230554ff184Skais merge |= (unsigned long long)
231554ff184Skais (base[tmp0]) << 48;
232554ff184Skais } else {
233554ff184Skais
234554ff184Skais tmp1 = base[j];
235554ff184Skais
236554ff184Skais i_accum = i_accum << 8;
237554ff184Skais i_accum |= tmp1;
238554ff184Skais
239*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
240554ff184Skais
241554ff184Skais tmp0 += tmp1;
242554ff184Skais tmp0 = tmp0 & 0xff;
243554ff184Skais
244554ff184Skais /*
245554ff184Skais * Speculation suceeded! Update [i]
246554ff184Skais * in 2B chunk
247554ff184Skais */
24871269a22SAnthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
249554ff184Skais *((unsigned short *) &base[i1]) =
250554ff184Skais i_accum;
251554ff184Skais
252554ff184Skais merge |=
253554ff184Skais (unsigned long long)(base[tmp0]) <<
254554ff184Skais 48;
255554ff184Skais }
256554ff184Skais
257554ff184Skais
258554ff184Skais /*
259554ff184Skais * Too expensive to perform [i] speculation for
260554ff184Skais * every byte. Just need to reduce frequency
261554ff184Skais * of stores until store buffer full stalls
262554ff184Skais * are not the bottleneck.
263554ff184Skais */
264554ff184Skais
265554ff184Skais /* BYTE 2 */
266554ff184Skais tmp0 = base1[2];
267554ff184Skais j = j + tmp0;
268554ff184Skais tmp1 = base[j];
269*726fad2aSDina K Nimeh base1[2] = (uchar_t)tmp1;
270*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
271554ff184Skais tmp1 += tmp0;
272554ff184Skais tmp1 = tmp1 & 0xff;
273554ff184Skais merge |= (unsigned long long)(base[tmp1]) << 40;
274554ff184Skais
275554ff184Skais /* BYTE 3 */
276554ff184Skais tmp0 = base1[3];
277554ff184Skais j = j + tmp0;
278554ff184Skais tmp1 = base[j];
279*726fad2aSDina K Nimeh base1[3] = (uchar_t)tmp1;
280*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
281554ff184Skais tmp0 += tmp1;
282554ff184Skais tmp0 = tmp0 & 0xff;
283554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 32;
284554ff184Skais
285554ff184Skais /* BYTE 4 */
286554ff184Skais tmp0 = base1[4];
287554ff184Skais j = j + tmp0;
288554ff184Skais tmp1 = base[j];
289*726fad2aSDina K Nimeh base1[4] = (uchar_t)tmp1;
290*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
291554ff184Skais tmp0 += tmp1;
292554ff184Skais tmp0 = tmp0 & 0xff;
293554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 24;
294554ff184Skais
295554ff184Skais /* BYTE 5 */
296554ff184Skais tmp0 = base1[5];
297554ff184Skais j = j + tmp0;
298554ff184Skais tmp1 = base[j];
299*726fad2aSDina K Nimeh base1[5] = (uchar_t)tmp1;
300*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
301554ff184Skais tmp0 += tmp1;
302554ff184Skais tmp0 = tmp0 & 0xff;
303554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 16;
304554ff184Skais
305554ff184Skais /* BYTE 6 */
306554ff184Skais i1 = (i1+6);
307554ff184Skais tmp0 = base1[6];
308554ff184Skais j = j + tmp0;
309554ff184Skais tmp1 = base[j];
310554ff184Skais i_accum = tmp1;
311*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
312554ff184Skais
313554ff184Skais tmp0 += tmp1;
314554ff184Skais tmp0 = tmp0 & 0xff;
315554ff184Skais
316554ff184Skais if (i1 == tmp0) {
317554ff184Skais merge |=
318554ff184Skais (unsigned long long)(i_accum) << 8;
319554ff184Skais } else {
320554ff184Skais merge |=
321554ff184Skais (unsigned long long)(base[tmp0]) <<
322554ff184Skais 8;
323554ff184Skais }
324554ff184Skais
325554ff184Skais /* BYTE 7 */
326554ff184Skais tmp0 = base1[7];
327554ff184Skais
328554ff184Skais /*
329554ff184Skais * Perform [i] speculation again. Indentical
330554ff184Skais * to that performed for BYTE0 and BYTE1.
331554ff184Skais */
332554ff184Skais j = j + tmp0;
333554ff184Skais if ((i1 ^ j) < 2) {
334*726fad2aSDina K Nimeh base1[6] = (uchar_t)i_accum;
335554ff184Skais tmp1 = base[j];
336554ff184Skais
337*726fad2aSDina K Nimeh base1[7] = (uchar_t)tmp1;
338*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
339554ff184Skais
340554ff184Skais tmp0 += tmp1;
341554ff184Skais tmp0 = tmp0 & 0xff;
342554ff184Skais
343554ff184Skais merge |=
344554ff184Skais (unsigned long long)(base[tmp0]);
345554ff184Skais
346554ff184Skais } else {
347554ff184Skais tmp1 = base[j];
348554ff184Skais
349554ff184Skais i_accum = i_accum << 8;
350554ff184Skais i_accum |= tmp1;
351554ff184Skais
352*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
353554ff184Skais
354554ff184Skais tmp0 += tmp1;
355554ff184Skais tmp0 = tmp0 & 0xff;
356554ff184Skais
35771269a22SAnthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
358554ff184Skais *((unsigned short *) &base[i1]) =
359554ff184Skais i_accum;
360554ff184Skais
361554ff184Skais merge |=
362554ff184Skais (unsigned long long)(base[tmp0]);
363554ff184Skais }
364554ff184Skais i1++;
365554ff184Skais } else {
366554ff184Skais /*
367554ff184Skais * i is too close to wrap-around to allow
368554ff184Skais * masking to be disregarded
369554ff184Skais */
370554ff184Skais
371554ff184Skais /*
372554ff184Skais * Same old speculation for BYTE 0 and BYTE 1
373554ff184Skais */
374554ff184Skais
375554ff184Skais /* BYTE 0 */
376554ff184Skais i1 = (i1 + 1) & 0xff;
377*726fad2aSDina K Nimeh jj = (uchar_t)i1;
378554ff184Skais
379554ff184Skais tmp0 = base[i1];
380554ff184Skais j = j + tmp0;
381554ff184Skais
382554ff184Skais tmp1 = base[j];
383554ff184Skais i_accum = tmp1;
384*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
385554ff184Skais
386554ff184Skais tmp0 += tmp1;
387554ff184Skais tmp0 = tmp0 & 0xff;
388554ff184Skais
389554ff184Skais if (i1 == tmp0) {
390554ff184Skais merge =
391554ff184Skais (unsigned long long)(i_accum) << 56;
392554ff184Skais } else {
393554ff184Skais merge =
394554ff184Skais (unsigned long long)(base[tmp0]) <<
395554ff184Skais 56;
396554ff184Skais }
397554ff184Skais
398554ff184Skais /* BYTE 1 */
399554ff184Skais tmp0 = base[i1+1];
400554ff184Skais
401554ff184Skais j = j + tmp0;
402554ff184Skais
403554ff184Skais if ((jj ^ j) < 2) {
404*726fad2aSDina K Nimeh base[jj] = (uchar_t)i_accum;
405554ff184Skais
406554ff184Skais tmp1 = base[j];
407554ff184Skais
408*726fad2aSDina K Nimeh base[i1+1] = (uchar_t)tmp1;
409*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
410554ff184Skais
411554ff184Skais tmp0 += tmp1;
412554ff184Skais tmp0 = tmp0 & 0xff;
413554ff184Skais
414554ff184Skais merge |=
415554ff184Skais (unsigned long long)(base[tmp0]) <<
416554ff184Skais 48;
417554ff184Skais } else {
418554ff184Skais
419554ff184Skais tmp1 = base[j];
420554ff184Skais
421554ff184Skais i_accum = i_accum << 8;
422554ff184Skais i_accum |= tmp1;
423554ff184Skais
424*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
425554ff184Skais
426554ff184Skais tmp0 += tmp1;
427554ff184Skais tmp0 = tmp0 & 0xff;
428554ff184Skais
42971269a22SAnthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
430554ff184Skais *((unsigned short *) &base[jj]) =
431554ff184Skais i_accum;
432554ff184Skais
433554ff184Skais merge |=
434554ff184Skais (unsigned long long)(base[tmp0]) <<
435554ff184Skais 48;
436554ff184Skais }
437554ff184Skais
438554ff184Skais /* BYTE 2 */
439554ff184Skais /*
440554ff184Skais * As know i must be even when enter loop (to
441554ff184Skais * satisfy alignment), can only wrap around
442554ff184Skais * on the even bytes. So just need to perform
443554ff184Skais * mask every 2nd byte
444554ff184Skais */
445554ff184Skais i1 = (i1 + 2) & 0xff;
446554ff184Skais tmp0 = base[i1];
447554ff184Skais j = j + tmp0;
448554ff184Skais tmp1 = base[j];
449*726fad2aSDina K Nimeh base[i1] = (uchar_t)tmp1;
450*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
451554ff184Skais tmp0 += tmp1;
452554ff184Skais tmp0 = tmp0 & 0xff;
453554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 40;
454554ff184Skais
455554ff184Skais /* BYTE 3 */
456554ff184Skais tmp0 = base[i1+1];
457554ff184Skais j = j + tmp0;
458554ff184Skais tmp1 = base[j];
459*726fad2aSDina K Nimeh base[i1+1] = (uchar_t)tmp1;
460*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
461554ff184Skais tmp0 += tmp1;
462554ff184Skais tmp0 = tmp0 & 0xff;
463554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 32;
464554ff184Skais
465554ff184Skais /* BYTE 4 */
466554ff184Skais i1 = (i1 + 2) & 0xff;
467554ff184Skais tmp0 = base[i1];
468554ff184Skais j = j + tmp0;
469554ff184Skais tmp1 = base[j];
470*726fad2aSDina K Nimeh base[i1] = (uchar_t)tmp1;
471*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
472554ff184Skais tmp0 += tmp1;
473554ff184Skais tmp0 = tmp0 & 0xff;
474554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 24;
475554ff184Skais
476554ff184Skais /* BYTE 5 */
477554ff184Skais tmp0 = base[i1+1];
478554ff184Skais j = j + tmp0;
479554ff184Skais tmp1 = base[j];
480*726fad2aSDina K Nimeh base[i1+1] = (uchar_t)tmp1;
481*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
482554ff184Skais tmp0 += tmp1;
483554ff184Skais tmp0 = tmp0 & 0xff;
484554ff184Skais merge |= (unsigned long long)(base[tmp0]) << 16;
485554ff184Skais
486554ff184Skais /* BYTE 6 */
487554ff184Skais i1 = (i1+2) &0xff;
488*726fad2aSDina K Nimeh jj = (uchar_t)i1;
489554ff184Skais tmp0 = base[i1];
490554ff184Skais
491554ff184Skais j = j + tmp0;
492554ff184Skais
493554ff184Skais tmp1 = base[j];
494554ff184Skais i_accum = tmp1;
495*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
496554ff184Skais
497554ff184Skais
498554ff184Skais tmp0 += tmp1;
499554ff184Skais tmp0 = tmp0 & 0xff;
500554ff184Skais
501554ff184Skais if (i1 == tmp0) {
502554ff184Skais merge |=
503554ff184Skais (unsigned long long)(i_accum) << 8;
504554ff184Skais } else {
505554ff184Skais merge |=
506554ff184Skais (unsigned long long)(base[tmp0]) <<
507554ff184Skais 8;
508554ff184Skais }
509554ff184Skais
510554ff184Skais /* BYTE 7 */
511554ff184Skais i1++;
512554ff184Skais tmp0 = base[i1];
513554ff184Skais
514554ff184Skais j = j + tmp0;
515554ff184Skais if ((jj ^ j) < 2) {
516*726fad2aSDina K Nimeh base[jj] = (uchar_t)i_accum;
517554ff184Skais tmp1 = base[j];
518554ff184Skais
519*726fad2aSDina K Nimeh base[i1] = (uchar_t)tmp1;
520*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
521554ff184Skais
522554ff184Skais tmp0 += tmp1;
523554ff184Skais tmp0 = tmp0 & 0xff;
524554ff184Skais
525554ff184Skais merge |=
526554ff184Skais (unsigned long long)(base[tmp0]);
527554ff184Skais
528554ff184Skais } else {
52971269a22SAnthony Scarpino
530554ff184Skais tmp1 = base[j];
531554ff184Skais
532554ff184Skais i_accum = i_accum << 8;
533554ff184Skais i_accum |= tmp1;
534554ff184Skais
535*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
536554ff184Skais
537554ff184Skais tmp0 += tmp1;
538554ff184Skais tmp0 = tmp0 & 0xff;
539554ff184Skais
54071269a22SAnthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
541554ff184Skais *((unsigned short *) &base[jj]) =
542554ff184Skais i_accum;
543554ff184Skais
544554ff184Skais merge |=
545554ff184Skais (unsigned long long)(base[tmp0]);
546554ff184Skais }
547554ff184Skais }
548554ff184Skais
549554ff184Skais /*
550554ff184Skais * Perform update to [out]
551554ff184Skais * Remember could be alignment issues
552554ff184Skais */
55371269a22SAnthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554554ff184Skais in0 = *((unsigned long long *) (&in[ii]));
555554ff184Skais
556554ff184Skais merge1 = merge0 | (merge >> shift);
557554ff184Skais
558554ff184Skais merge0 = (merge & mask) << 56;
559554ff184Skais
560554ff184Skais in0 = in0 ^ merge1;
561554ff184Skais
56271269a22SAnthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
563554ff184Skais *((unsigned long long *) (&out[ii])) = in0;
564554ff184Skais }
565554ff184Skais
566*726fad2aSDina K Nimeh i = (uchar_t)i1;
567554ff184Skais
568554ff184Skais /*
569554ff184Skais * Handle any overrun
570554ff184Skais */
571554ff184Skais if (shift) {
572554ff184Skais out[ii] = in[ii] ^ (merge0 >> 56);
573554ff184Skais ii++;
574554ff184Skais }
575554ff184Skais
576554ff184Skais /*
577554ff184Skais * Handle final few bytes
578554ff184Skais */
579554ff184Skais for (; ii < len; ii++) {
580554ff184Skais i = i + 1;
581554ff184Skais tmp0 = base[i];
582554ff184Skais j = j + tmp0;
583554ff184Skais tmp1 = base[j];
584554ff184Skais
585*726fad2aSDina K Nimeh base[i] = (uchar_t)tmp1;
586*726fad2aSDina K Nimeh base[j] = (uchar_t)tmp0;
587554ff184Skais
588554ff184Skais tmp0 += tmp1;
589554ff184Skais tmp0 = tmp0 & 0xff;
590554ff184Skais out[ii] = in[ii] ^ base[tmp0];
591554ff184Skais }
592554ff184Skais key->i = i;
593554ff184Skais key->j = j;
594554ff184Skais }
595554ff184Skais #endif /* sun4v */
596554ff184Skais }
597