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 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 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