554ff184129088135ad2643c1c9832174a17be88kais/*
554ff184129088135ad2643c1c9832174a17be88kais * CDDL HEADER START
554ff184129088135ad2643c1c9832174a17be88kais *
554ff184129088135ad2643c1c9832174a17be88kais * The contents of this file are subject to the terms of the
b6c3f7863936abeae522e48a13887dddeb691a45bubbva * Common Development and Distribution License (the "License").
b6c3f7863936abeae522e48a13887dddeb691a45bubbva * You may not use this file except in compliance with the License.
554ff184129088135ad2643c1c9832174a17be88kais *
554ff184129088135ad2643c1c9832174a17be88kais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
554ff184129088135ad2643c1c9832174a17be88kais * or http://www.opensolaris.org/os/licensing.
554ff184129088135ad2643c1c9832174a17be88kais * See the License for the specific language governing permissions
554ff184129088135ad2643c1c9832174a17be88kais * and limitations under the License.
554ff184129088135ad2643c1c9832174a17be88kais *
554ff184129088135ad2643c1c9832174a17be88kais * When distributing Covered Code, include this CDDL HEADER in each
554ff184129088135ad2643c1c9832174a17be88kais * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
554ff184129088135ad2643c1c9832174a17be88kais * If applicable, add the following below this CDDL HEADER, with the
554ff184129088135ad2643c1c9832174a17be88kais * fields enclosed by brackets "[]" replaced with your own identifying
554ff184129088135ad2643c1c9832174a17be88kais * information: Portions Copyright [yyyy] [name of copyright owner]
554ff184129088135ad2643c1c9832174a17be88kais *
554ff184129088135ad2643c1c9832174a17be88kais * CDDL HEADER END
554ff184129088135ad2643c1c9832174a17be88kais */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
554ff184129088135ad2643c1c9832174a17be88kais/*
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais#include "../arcfour.h"
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais/* Initialize the key stream 'key' using the key value */
554ff184129088135ad2643c1c9832174a17be88kaisvoid
554ff184129088135ad2643c1c9832174a17be88kaisarcfour_key_init(ARCFour_key *key, uchar_t *keyval, int keyvallen)
554ff184129088135ad2643c1c9832174a17be88kais{
554ff184129088135ad2643c1c9832174a17be88kais uchar_t ext_keyval[256];
554ff184129088135ad2643c1c9832174a17be88kais uchar_t tmp;
554ff184129088135ad2643c1c9832174a17be88kais int i, j;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais for (i = j = 0; i < 256; i++, j++) {
554ff184129088135ad2643c1c9832174a17be88kais if (j == keyvallen)
554ff184129088135ad2643c1c9832174a17be88kais j = 0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais ext_keyval[i] = keyval[j];
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais for (i = 0; i < 256; i++)
554ff184129088135ad2643c1c9832174a17be88kais key->arr[i] = (uchar_t)i;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais j = 0;
554ff184129088135ad2643c1c9832174a17be88kais for (i = 0; i < 256; i++) {
554ff184129088135ad2643c1c9832174a17be88kais j = (j + key->arr[i] + ext_keyval[i]) % 256;
554ff184129088135ad2643c1c9832174a17be88kais tmp = key->arr[i];
554ff184129088135ad2643c1c9832174a17be88kais key->arr[i] = key->arr[j];
554ff184129088135ad2643c1c9832174a17be88kais key->arr[j] = tmp;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais key->i = 0;
554ff184129088135ad2643c1c9832174a17be88kais key->j = 0;
554ff184129088135ad2643c1c9832174a17be88kais}
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais/*
554ff184129088135ad2643c1c9832174a17be88kais * Encipher 'in' using 'key.
554ff184129088135ad2643c1c9832174a17be88kais * in and out can point to the same location
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kaisvoid
554ff184129088135ad2643c1c9832174a17be88kaisarcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
554ff184129088135ad2643c1c9832174a17be88kais{
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino size_t ii;
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino unsigned long long in0, merge = 0, merge0 = 0, merge1, mask = 0;
554ff184129088135ad2643c1c9832174a17be88kais uchar_t i, j, *base, jj, *base1, tmp;
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino unsigned int tmp0, tmp1, i_accum, shift = 0, i1;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais int index;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais base = key->arr;
554ff184129088135ad2643c1c9832174a17be88kais
b6c3f7863936abeae522e48a13887dddeb691a45bubbva index = (((uintptr_t)in) & 0x7);
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* Get the 'in' on an 8-byte alignment */
554ff184129088135ad2643c1c9832174a17be88kais if (index > 0) {
554ff184129088135ad2643c1c9832174a17be88kais i = key->i;
554ff184129088135ad2643c1c9832174a17be88kais j = key->j;
b6c3f7863936abeae522e48a13887dddeb691a45bubbva
b6c3f7863936abeae522e48a13887dddeb691a45bubbva for (index = 8 - index; (index-- > 0) && len > 0;
554ff184129088135ad2643c1c9832174a17be88kais len--, in++, out++) {
b6c3f7863936abeae522e48a13887dddeb691a45bubbva
554ff184129088135ad2643c1c9832174a17be88kais i = i + 1;
554ff184129088135ad2643c1c9832174a17be88kais j = j + key->arr[i];
554ff184129088135ad2643c1c9832174a17be88kais tmp = key->arr[i];
554ff184129088135ad2643c1c9832174a17be88kais key->arr[i] = key->arr[j];
554ff184129088135ad2643c1c9832174a17be88kais key->arr[j] = tmp;
554ff184129088135ad2643c1c9832174a17be88kais tmp = key->arr[i] + key->arr[j];
554ff184129088135ad2643c1c9832174a17be88kais *out = *in ^ key->arr[tmp];
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais key->i = i;
554ff184129088135ad2643c1c9832174a17be88kais key->j = j;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais if (len == 0)
554ff184129088135ad2643c1c9832174a17be88kais return;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* See if we're fortunate and 'out' got aligned as well */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Niagara optimized version for
554ff184129088135ad2643c1c9832174a17be88kais * the cases where the input and output buffers are aligned on
554ff184129088135ad2643c1c9832174a17be88kais * a multiple of 8-byte boundary.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais#ifdef sun4v
b6c3f7863936abeae522e48a13887dddeb691a45bubbva if ((((uintptr_t)out) & 7) != 0) {
554ff184129088135ad2643c1c9832174a17be88kais#endif /* sun4v */
554ff184129088135ad2643c1c9832174a17be88kais i = key->i;
554ff184129088135ad2643c1c9832174a17be88kais j = key->j;
554ff184129088135ad2643c1c9832174a17be88kais for (ii = 0; ii < len; ii++) {
554ff184129088135ad2643c1c9832174a17be88kais i = i + 1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais out[ii] = in[ii] ^ base[tmp0];
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais key->i = i;
554ff184129088135ad2643c1c9832174a17be88kais key->j = j;
554ff184129088135ad2643c1c9832174a17be88kais#ifdef sun4v
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais i = key->i;
554ff184129088135ad2643c1c9832174a17be88kais j = key->j;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Want to align base[i] on a 2B boundary -- allows updates
554ff184129088135ad2643c1c9832174a17be88kais * via [i] to be performed in 2B chunks (reducing # of stores).
554ff184129088135ad2643c1c9832174a17be88kais * Requires appropriate alias detection.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais if (((i+1) % 2) != 0) {
554ff184129088135ad2643c1c9832174a17be88kais i = i + 1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge0 = (unsigned long long)(base[tmp0]) << 56;
554ff184129088135ad2643c1c9832174a17be88kais shift = 8; mask = 0xff;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Note - in and out may now be misaligned -
554ff184129088135ad2643c1c9832174a17be88kais * as updating [out] in 8B chunks need to handle this
554ff184129088135ad2643c1c9832174a17be88kais * possibility. Also could have a 1B overrun.
554ff184129088135ad2643c1c9832174a17be88kais * Need to drop out of loop early as a result.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais for (ii = 0, i1 = i; ii < ((len-1) & (~7));
554ff184129088135ad2643c1c9832174a17be88kais ii += 8, i1 = i1&0xff) {
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * If i < less than 248, know wont wrap around
554ff184129088135ad2643c1c9832174a17be88kais * (i % 256), so don't need to bother with masking i
554ff184129088135ad2643c1c9832174a17be88kais * after each increment
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais if (i1 < 248) {
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 0 */
554ff184129088135ad2643c1c9832174a17be88kais i1 = (i1 + 1);
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Creating this base pointer reduces subsequent
554ff184129088135ad2643c1c9832174a17be88kais * arihmetic ops required to load [i]
554ff184129088135ad2643c1c9832174a17be88kais *
554ff184129088135ad2643c1c9832174a17be88kais * N.B. don't need to check if [j] aliases.
554ff184129088135ad2643c1c9832174a17be88kais * [i] and [j] end up with the same values
554ff184129088135ad2643c1c9832174a17be88kais * anyway.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais base1 = &base[i1];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[0];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Don't store [i] yet
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais i_accum = tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Check [tmp0] doesn't alias with [i]
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Updating [out] in 8B chunks
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais if (i1 == tmp0) {
554ff184129088135ad2643c1c9832174a17be88kais merge =
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(i_accum) << 56;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais merge =
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 56;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 1 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[1];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * [j] can now alias with [i] and [i-1]
554ff184129088135ad2643c1c9832174a17be88kais * If alias abort speculation
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais if ((i1 ^ j) < 2) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[0] = (uchar_t)i_accum;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)
554ff184129088135ad2643c1c9832174a17be88kais (base[tmp0]) << 48;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais i_accum = i_accum << 8;
554ff184129088135ad2643c1c9832174a17be88kais i_accum |= tmp1;
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Speculation suceeded! Update [i]
554ff184129088135ad2643c1c9832174a17be88kais * in 2B chunk
554ff184129088135ad2643c1c9832174a17be88kais */
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554ff184129088135ad2643c1c9832174a17be88kais *((unsigned short *) &base[i1]) =
554ff184129088135ad2643c1c9832174a17be88kais i_accum;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 48;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Too expensive to perform [i] speculation for
554ff184129088135ad2643c1c9832174a17be88kais * every byte. Just need to reduce frequency
554ff184129088135ad2643c1c9832174a17be88kais * of stores until store buffer full stalls
554ff184129088135ad2643c1c9832174a17be88kais * are not the bottleneck.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 2 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[2];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[2] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 += tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = tmp1 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp1]) << 40;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 3 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[3];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[3] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 32;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 4 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[4];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[4] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 24;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 5 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[5];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[5] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 16;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 6 */
554ff184129088135ad2643c1c9832174a17be88kais i1 = (i1+6);
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[6];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais i_accum = tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais if (i1 == tmp0) {
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(i_accum) << 8;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 8;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 7 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base1[7];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Perform [i] speculation again. Indentical
554ff184129088135ad2643c1c9832174a17be88kais * to that performed for BYTE0 and BYTE1.
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais if ((i1 ^ j) < 2) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[6] = (uchar_t)i_accum;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base1[7] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]);
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais i_accum = i_accum << 8;
554ff184129088135ad2643c1c9832174a17be88kais i_accum |= tmp1;
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554ff184129088135ad2643c1c9832174a17be88kais *((unsigned short *) &base[i1]) =
554ff184129088135ad2643c1c9832174a17be88kais i_accum;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]);
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais i1++;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * i is too close to wrap-around to allow
554ff184129088135ad2643c1c9832174a17be88kais * masking to be disregarded
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Same old speculation for BYTE 0 and BYTE 1
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 0 */
554ff184129088135ad2643c1c9832174a17be88kais i1 = (i1 + 1) & 0xff;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh jj = (uchar_t)i1;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais i_accum = tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais if (i1 == tmp0) {
554ff184129088135ad2643c1c9832174a17be88kais merge =
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(i_accum) << 56;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais merge =
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 56;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 1 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1+1];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais if ((jj ^ j) < 2) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[jj] = (uchar_t)i_accum;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i1+1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 48;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais i_accum = i_accum << 8;
554ff184129088135ad2643c1c9832174a17be88kais i_accum |= tmp1;
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554ff184129088135ad2643c1c9832174a17be88kais *((unsigned short *) &base[jj]) =
554ff184129088135ad2643c1c9832174a17be88kais i_accum;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 48;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 2 */
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * As know i must be even when enter loop (to
554ff184129088135ad2643c1c9832174a17be88kais * satisfy alignment), can only wrap around
554ff184129088135ad2643c1c9832174a17be88kais * on the even bytes. So just need to perform
554ff184129088135ad2643c1c9832174a17be88kais * mask every 2nd byte
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais i1 = (i1 + 2) & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 40;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 3 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1+1];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i1+1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 32;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 4 */
554ff184129088135ad2643c1c9832174a17be88kais i1 = (i1 + 2) & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 24;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 5 */
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1+1];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i1+1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais merge |= (unsigned long long)(base[tmp0]) << 16;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 6 */
554ff184129088135ad2643c1c9832174a17be88kais i1 = (i1+2) &0xff;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh jj = (uchar_t)i1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais i_accum = tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais if (i1 == tmp0) {
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(i_accum) << 8;
554ff184129088135ad2643c1c9832174a17be88kais } else {
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]) <<
554ff184129088135ad2643c1c9832174a17be88kais 8;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /* BYTE 7 */
554ff184129088135ad2643c1c9832174a17be88kais i1++;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i1];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais if ((jj ^ j) < 2) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[jj] = (uchar_t)i_accum;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i1] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]);
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais } else {
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais i_accum = i_accum << 8;
554ff184129088135ad2643c1c9832174a17be88kais i_accum |= tmp1;
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554ff184129088135ad2643c1c9832174a17be88kais *((unsigned short *) &base[jj]) =
554ff184129088135ad2643c1c9832174a17be88kais i_accum;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge |=
554ff184129088135ad2643c1c9832174a17be88kais (unsigned long long)(base[tmp0]);
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Perform update to [out]
554ff184129088135ad2643c1c9832174a17be88kais * Remember could be alignment issues
554ff184129088135ad2643c1c9832174a17be88kais */
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554ff184129088135ad2643c1c9832174a17be88kais in0 = *((unsigned long long *) (&in[ii]));
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge1 = merge0 | (merge >> shift);
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais merge0 = (merge & mask) << 56;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais in0 = in0 ^ merge1;
554ff184129088135ad2643c1c9832174a17be88kais
71269a2275bf5a143dad6461eee2710a344e7261Anthony Scarpino /* LINTED E_BAD_PTR_CAST_ALIGN */
554ff184129088135ad2643c1c9832174a17be88kais *((unsigned long long *) (&out[ii])) = in0;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh i = (uchar_t)i1;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Handle any overrun
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais if (shift) {
554ff184129088135ad2643c1c9832174a17be88kais out[ii] = in[ii] ^ (merge0 >> 56);
554ff184129088135ad2643c1c9832174a17be88kais ii++;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais /*
554ff184129088135ad2643c1c9832174a17be88kais * Handle final few bytes
554ff184129088135ad2643c1c9832174a17be88kais */
554ff184129088135ad2643c1c9832174a17be88kais for (; ii < len; ii++) {
554ff184129088135ad2643c1c9832174a17be88kais i = i + 1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = base[i];
554ff184129088135ad2643c1c9832174a17be88kais j = j + tmp0;
554ff184129088135ad2643c1c9832174a17be88kais tmp1 = base[j];
554ff184129088135ad2643c1c9832174a17be88kais
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[i] = (uchar_t)tmp1;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh base[j] = (uchar_t)tmp0;
554ff184129088135ad2643c1c9832174a17be88kais
554ff184129088135ad2643c1c9832174a17be88kais tmp0 += tmp1;
554ff184129088135ad2643c1c9832174a17be88kais tmp0 = tmp0 & 0xff;
554ff184129088135ad2643c1c9832174a17be88kais out[ii] = in[ii] ^ base[tmp0];
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais key->i = i;
554ff184129088135ad2643c1c9832174a17be88kais key->j = j;
554ff184129088135ad2643c1c9832174a17be88kais }
554ff184129088135ad2643c1c9832174a17be88kais#endif /* sun4v */
554ff184129088135ad2643c1c9832174a17be88kais}