OLD | NEW |
---|---|
1 /* arcfour.c - the arc four algorithm. | 1 /* arcfour.c - the arc four algorithm. |
2 * | 2 * |
3 * This Source Code Form is subject to the terms of the Mozilla Public | 3 * This Source Code Form is subject to the terms of the Mozilla Public |
4 * License, v. 2.0. If a copy of the MPL was not distributed with this | 4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | 6 |
7 /* See NOTES ON UMRs, Unititialized Memory Reads, below. */ | |
8 | |
9 #ifdef FREEBL_NO_DEPEND | 7 #ifdef FREEBL_NO_DEPEND |
10 #include "stubs.h" | 8 #include "stubs.h" |
11 #endif | 9 #endif |
12 | 10 |
13 #include "prerr.h" | 11 #include "prerr.h" |
14 #include "secerr.h" | 12 #include "secerr.h" |
15 | 13 |
16 #include "prtypes.h" | 14 #include "prtypes.h" |
17 #include "blapi.h" | 15 #include "blapi.h" |
18 | 16 |
19 /* Architecture-dependent defines */ | 17 /* Architecture-dependent defines */ |
20 | 18 |
21 #if defined(SOLARIS) || defined(HPUX) || defined(i386) || defined(IRIX) || \ | 19 #if defined(SOLARIS) || defined(HPUX) || defined(NSS_X86) || \ |
PaulePantert
2013/02/09 09:23:49
Separate change?
| |
22 defined(_WIN64) | 20 defined(_WIN64) |
23 /* Convert the byte-stream to a word-stream */ | 21 /* Convert the byte-stream to a word-stream */ |
24 #define CONVERT_TO_WORDS | 22 #define CONVERT_TO_WORDS |
25 #endif | 23 #endif |
26 | 24 |
27 #if defined(AIX) || defined(OSF1) || defined(NSS_BEVAND_ARCFOUR) | 25 #if defined(AIX) || defined(OSF1) || defined(NSS_BEVAND_ARCFOUR) |
28 /* Treat array variables as words, not bytes, on CPUs that take | 26 /* Treat array variables as words, not bytes, on CPUs that take |
29 * much longer to write bytes than to write words, or when using | 27 * much longer to write bytes than to write words, or when using |
30 * assembler code that required it. | 28 * assembler code that required it. |
31 */ | 29 */ |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 RC4_AllocateContext(void) | 110 RC4_AllocateContext(void) |
113 { | 111 { |
114 return PORT_ZNew(RC4Context); | 112 return PORT_ZNew(RC4Context); |
115 } | 113 } |
116 | 114 |
117 SECStatus | 115 SECStatus |
118 RC4_InitContext(RC4Context *cx, const unsigned char *key, unsigned int len, | 116 RC4_InitContext(RC4Context *cx, const unsigned char *key, unsigned int len, |
119 const unsigned char * unused1, int unused2, | 117 const unsigned char * unused1, int unused2, |
120 unsigned int unused3, unsigned int unused4) | 118 unsigned int unused3, unsigned int unused4) |
121 { | 119 { |
122 » int i; | 120 » unsigned int i; |
PaulePantert
2013/02/09 09:23:49
Also separate change.
| |
123 PRUint8 j, tmp; | 121 PRUint8 j, tmp; |
124 PRUint8 K[256]; | 122 PRUint8 K[256]; |
125 PRUint8 *L; | 123 PRUint8 *L; |
126 | 124 |
127 /* verify the key length. */ | 125 /* verify the key length. */ |
128 PORT_Assert(len > 0 && len < ARCFOUR_STATE_SIZE); | 126 PORT_Assert(len > 0 && len < ARCFOUR_STATE_SIZE); |
129 if (len == 0 || len >= ARCFOUR_STATE_SIZE) { | 127 if (len == 0 || len >= ARCFOUR_STATE_SIZE) { |
130 » » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 128 » » PORT_SetError(SEC_ERROR_BAD_KEY); |
PaulePantert
2013/02/09 09:23:49
Is that change required for the rewrite?
If not c
| |
131 return SECFailure; | 129 return SECFailure; |
132 } | 130 } |
133 if (cx == NULL) { | 131 if (cx == NULL) { |
134 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 132 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
135 return SECFailure; | 133 return SECFailure; |
136 } | 134 } |
137 /* Initialize the state using array indices. */ | 135 /* Initialize the state using array indices. */ |
138 memcpy(cx->S, Kinit, sizeof cx->S); | 136 memcpy(cx->S, Kinit, sizeof cx->S); |
139 /* Fill in K repeatedly with values from key. */ | 137 /* Fill in K repeatedly with values from key. */ |
140 L = K; | 138 L = K; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 unsigned int *outputLen, unsigned int maxOutputLen, | 206 unsigned int *outputLen, unsigned int maxOutputLen, |
209 const unsigned char *input, unsigned int inputLen) | 207 const unsigned char *input, unsigned int inputLen) |
210 { | 208 { |
211 PRUint8 t; | 209 PRUint8 t; |
212 Stype tmpSi, tmpSj; | 210 Stype tmpSi, tmpSj; |
213 register PRUint8 tmpi = cx->i; | 211 register PRUint8 tmpi = cx->i; |
214 register PRUint8 tmpj = cx->j; | 212 register PRUint8 tmpj = cx->j; |
215 unsigned int index; | 213 unsigned int index; |
216 PORT_Assert(maxOutputLen >= inputLen); | 214 PORT_Assert(maxOutputLen >= inputLen); |
217 if (maxOutputLen < inputLen) { | 215 if (maxOutputLen < inputLen) { |
218 » » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 216 » » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
219 return SECFailure; | 217 return SECFailure; |
220 } | 218 } |
221 for (index=0; index < inputLen; index++) { | 219 for (index=0; index < inputLen; index++) { |
222 /* Generate next byte from stream. */ | 220 /* Generate next byte from stream. */ |
223 ARCFOUR_NEXT_BYTE(); | 221 ARCFOUR_NEXT_BYTE(); |
224 /* output = next stream byte XOR next input byte */ | 222 /* output = next stream byte XOR next input byte */ |
225 output[index] = cx->S[t] ^ input[index]; | 223 output[index] = cx->S[t] ^ input[index]; |
226 } | 224 } |
227 *outputLen = inputLen; | 225 *outputLen = inputLen; |
228 cx->i = tmpi; | 226 cx->i = tmpi; |
(...skipping 12 matching lines...) Expand all Loading... | |
241 unsigned int *outputLen, unsigned int maxOutputLen, | 239 unsigned int *outputLen, unsigned int maxOutputLen, |
242 const unsigned char *input, unsigned int inputLen) | 240 const unsigned char *input, unsigned int inputLen) |
243 { | 241 { |
244 PRUint8 t; | 242 PRUint8 t; |
245 Stype tmpSi, tmpSj; | 243 Stype tmpSi, tmpSj; |
246 register PRUint8 tmpi = cx->i; | 244 register PRUint8 tmpi = cx->i; |
247 register PRUint8 tmpj = cx->j; | 245 register PRUint8 tmpj = cx->j; |
248 int index; | 246 int index; |
249 PORT_Assert(maxOutputLen >= inputLen); | 247 PORT_Assert(maxOutputLen >= inputLen); |
250 if (maxOutputLen < inputLen) { | 248 if (maxOutputLen < inputLen) { |
251 » » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 249 » » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
252 return SECFailure; | 250 return SECFailure; |
253 } | 251 } |
254 for (index = inputLen / 8; index-- > 0; input += 8, output += 8) { | 252 for (index = inputLen / 8; index-- > 0; input += 8, output += 8) { |
255 ARCFOUR_NEXT_BYTE(); | 253 ARCFOUR_NEXT_BYTE(); |
256 output[0] = cx->S[t] ^ input[0]; | 254 output[0] = cx->S[t] ^ input[0]; |
257 ARCFOUR_NEXT_BYTE(); | 255 ARCFOUR_NEXT_BYTE(); |
258 output[1] = cx->S[t] ^ input[1]; | 256 output[1] = cx->S[t] ^ input[1]; |
259 ARCFOUR_NEXT_BYTE(); | 257 ARCFOUR_NEXT_BYTE(); |
260 output[2] = cx->S[t] ^ input[2]; | 258 output[2] = cx->S[t] ^ input[2]; |
261 ARCFOUR_NEXT_BYTE(); | 259 ARCFOUR_NEXT_BYTE(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 #endif | 340 #endif |
343 | 341 |
344 #ifdef IS_LITTLE_ENDIAN | 342 #ifdef IS_LITTLE_ENDIAN |
345 #define RSH << | 343 #define RSH << |
346 #define LSH >> | 344 #define LSH >> |
347 #else | 345 #else |
348 #define RSH >> | 346 #define RSH >> |
349 #define LSH << | 347 #define LSH << |
350 #endif | 348 #endif |
351 | 349 |
350 #ifdef IS_LITTLE_ENDIAN | |
351 #define LEFTMOST_BYTE_SHIFT 0 | |
352 #define NEXT_BYTE_SHIFT(shift) shift + 8 | |
353 #else | |
354 #define LEFTMOST_BYTE_SHIFT 8*(WORDSIZE - 1) | |
355 #define NEXT_BYTE_SHIFT(shift) shift - 8 | |
356 #endif | |
357 | |
352 #ifdef CONVERT_TO_WORDS | 358 #ifdef CONVERT_TO_WORDS |
353 /* NOTE about UMRs, Uninitialized Memory Reads. | |
354 * | |
355 * This code reads all input data a WORD at a time, rather than byte at | |
356 * a time, and writes all output data a WORD at a time. Shifting and | |
357 * masking is used to remove unwanted data and realign bytes when | |
358 * needed. The first and last words of output are read, modified, and | |
359 * written when needed to preserve any unchanged bytes. This is a huge | |
360 * win on machines with high memory latency. | |
361 * | |
362 * However, when the input and output buffers do not begin and end on WORD | |
363 * boundaries, and the WORDS in memory that contain the first and last | |
364 * bytes of those buffers contain uninitialized data, then this code will | |
365 * read those uninitialized bytes, causing a UMR error to be reported by | |
366 * some tools. | |
367 * | |
368 * These UMRs are NOT a problem, NOT errors, and do NOT need to be "fixed". | |
369 * | |
370 * All the words read and written contain at least one byte that is | |
371 * part of the input data or output data. No words are read or written | |
372 * that do not contain data that is part of the buffer. Therefore, | |
373 * these UMRs cannot cause page faults or other problems unless the | |
374 * buffers have been assigned to improper addresses that would cause | |
375 * page faults with or without UMRs. | |
376 */ | |
377 static SECStatus | 359 static SECStatus |
378 rc4_wordconv(RC4Context *cx, unsigned char *output, | 360 rc4_wordconv(RC4Context *cx, unsigned char *output, |
379 unsigned int *outputLen, unsigned int maxOutputLen, | 361 unsigned int *outputLen, unsigned int maxOutputLen, |
380 const unsigned char *input, unsigned int inputLen) | 362 const unsigned char *input, unsigned int inputLen) |
381 { | 363 { |
382 » ptrdiff_t inOffset = (ptrdiff_t)input % WORDSIZE; | 364 » PR_STATIC_ASSERT(sizeof(PRUword) == sizeof(ptrdiff_t)); |
383 » ptrdiff_t outOffset = (ptrdiff_t)output % WORDSIZE; | 365 » unsigned int inOffset = (PRUword)input % WORDSIZE; |
384 » register WORD streamWord, mask; | 366 » unsigned int outOffset = (PRUword)output % WORDSIZE; |
Ryan Sleevi
2013/02/11 18:50:35
I'm not sure I understand the motivation here for
wtc
2013/02/11 19:14:05
Certainly. This change is necessary to fix the sig
| |
385 » register WORD *pInWord, *pOutWord; | 367 » register WORD streamWord; |
368 » register const WORD *pInWord; | |
369 » register WORD *pOutWord; | |
386 register WORD inWord, nextInWord; | 370 register WORD inWord, nextInWord; |
387 PRUint8 t; | 371 PRUint8 t; |
388 register Stype tmpSi, tmpSj; | 372 register Stype tmpSi, tmpSj; |
389 register PRUint8 tmpi = cx->i; | 373 register PRUint8 tmpi = cx->i; |
390 register PRUint8 tmpj = cx->j; | 374 register PRUint8 tmpj = cx->j; |
391 unsigned int byteCount; | 375 unsigned int byteCount; |
392 unsigned int bufShift, invBufShift; | 376 unsigned int bufShift, invBufShift; |
393 » int i; | 377 » unsigned int i; |
378 » const unsigned char *finalIn; | |
379 » unsigned char *finalOut; | |
394 | 380 |
395 PORT_Assert(maxOutputLen >= inputLen); | 381 PORT_Assert(maxOutputLen >= inputLen); |
396 if (maxOutputLen < inputLen) { | 382 if (maxOutputLen < inputLen) { |
397 » » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 383 » » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
398 return SECFailure; | 384 return SECFailure; |
399 } | 385 } |
400 if (inputLen < 2*WORDSIZE) { | 386 if (inputLen < 2*WORDSIZE) { |
401 /* Ignore word conversion, do byte-at-a-time */ | 387 /* Ignore word conversion, do byte-at-a-time */ |
402 return rc4_no_opt(cx, output, outputLen, maxOutputLen, input, in putLen); | 388 return rc4_no_opt(cx, output, outputLen, maxOutputLen, input, in putLen); |
403 } | 389 } |
404 *outputLen = inputLen; | 390 *outputLen = inputLen; |
405 » pInWord = (WORD *)(input - inOffset); | 391 » pInWord = (const WORD *)(input - inOffset); |
392 » pOutWord = (WORD *)(output - outOffset); | |
406 if (inOffset < outOffset) { | 393 if (inOffset < outOffset) { |
407 bufShift = 8*(outOffset - inOffset); | 394 bufShift = 8*(outOffset - inOffset); |
408 invBufShift = 8*WORDSIZE - bufShift; | 395 invBufShift = 8*WORDSIZE - bufShift; |
409 } else { | 396 } else { |
410 invBufShift = 8*(inOffset - outOffset); | 397 invBufShift = 8*(inOffset - outOffset); |
411 bufShift = 8*WORDSIZE - invBufShift; | 398 bufShift = 8*WORDSIZE - invBufShift; |
412 } | 399 } |
413 /*****************************************************************/ | 400 /*****************************************************************/ |
414 /* Step 1: */ | 401 /* Step 1: */ |
415 /* If the first output word is partial, consume the bytes in the */ | 402 /* If the first output word is partial, consume the bytes in the */ |
416 /* first partial output word by loading one or two words of */ | 403 /* first partial output word by loading one or two words of */ |
417 /* input and shifting them accordingly. Otherwise, just load */ | 404 /* input and shifting them accordingly. Otherwise, just load */ |
418 /* in the first word of input. At the end of this block, at */ | 405 /* in the first word of input. At the end of this block, at */ |
419 /* least one partial word of input should ALWAYS be loaded. */ | 406 /* least one partial word of input should ALWAYS be loaded. */ |
420 /*****************************************************************/ | 407 /*****************************************************************/ |
421 if (outOffset) { | 408 if (outOffset) { |
422 /* Generate input and stream words aligned relative to the | |
423 * partial output buffer. | |
424 */ | |
425 byteCount = WORDSIZE - outOffset; | 409 byteCount = WORDSIZE - outOffset; |
426 » » pOutWord = (WORD *)(output - outOffset); | 410 » » for (i = 0; i < byteCount; i++) { |
427 » » mask = streamWord = 0; | |
428 #ifdef IS_LITTLE_ENDIAN | |
429 » » for (i = WORDSIZE - byteCount; i < WORDSIZE; i++) { | |
430 #else | |
431 » » for (i = byteCount - 1; i >= 0; --i) { | |
432 #endif | |
433 ARCFOUR_NEXT_BYTE(); | 411 ARCFOUR_NEXT_BYTE(); |
434 » » » streamWord |= (WORD)(cx->S[t]) << 8*i; | 412 » » » output[i] = cx->S[t] ^ input[i]; |
435 » » » mask |= MASK1BYTE << 8*i; | 413 » » } |
436 » » } /* } */ | 414 » » /* Consumed byteCount bytes of input */ |
437 » » inWord = *pInWord++; /* UMR? see comments above. */ | 415 » » inputLen -= byteCount; |
416 » » pInWord++; | |
417 | |
418 » » /* move to next word of output */ | |
419 » » pOutWord++; | |
420 | |
438 /* If buffers are relatively misaligned, shift the bytes in inWo rd | 421 /* If buffers are relatively misaligned, shift the bytes in inWo rd |
439 * to be aligned to the output buffer. | 422 * to be aligned to the output buffer. |
440 */ | 423 */ |
441 nextInWord = 0; | |
442 if (inOffset < outOffset) { | 424 if (inOffset < outOffset) { |
443 » » » /* Have more bytes than needed, shift remainder into nex tInWord */ | 425 » » » /* The first input word (which may be partial) has more bytes |
444 » » » nextInWord = inWord LSH 8*(inOffset + byteCount); | 426 » » » * than needed. Copy the remainder to inWord. |
445 » » » inWord = inWord RSH bufShift; | 427 » » » */ |
428 » » » unsigned int shift = LEFTMOST_BYTE_SHIFT; | |
429 » » » inWord = 0; | |
430 » » » for (i = 0; i < outOffset - inOffset; i++) { | |
431 » » » » inWord |= (WORD)input[byteCount + i] << shift; | |
432 » » » » shift = NEXT_BYTE_SHIFT(shift); | |
433 » » » } | |
446 } else if (inOffset > outOffset) { | 434 } else if (inOffset > outOffset) { |
447 » » » /* Didn't get enough bytes from current input word, load another | 435 » » » /* Consumed some bytes in the second input word. Copy t he |
448 » » » * word and then shift remainder into nextInWord. | 436 » » » * remainder to inWord. |
449 */ | 437 */ |
450 » » » nextInWord = *pInWord++; | 438 » » » inWord = *pInWord++; |
451 » » » inWord = (inWord LSH invBufShift) | | 439 » » » inWord = inWord LSH invBufShift; |
452 » » » (nextInWord RSH bufShift); | 440 » » } else { |
453 » » » nextInWord = nextInWord LSH invBufShift; | 441 » » » inWord = 0; |
454 } | 442 } |
455 /* Store output of first partial word */ | |
456 *pOutWord = (*pOutWord & ~mask) | ((inWord ^ streamWord) & mask) ; | |
457 /* UMR? See comments above. */ | |
458 | |
459 /* Consumed byteCount bytes of input */ | |
460 inputLen -= byteCount; | |
461 /* move to next word of output */ | |
462 pOutWord++; | |
463 /* inWord has been consumed, but there may be bytes in nextInWor d */ | |
464 inWord = nextInWord; | |
465 } else { | 443 } else { |
466 /* output is word-aligned */ | 444 /* output is word-aligned */ |
467 pOutWord = (WORD *)output; | |
468 if (inOffset) { | 445 if (inOffset) { |
469 /* Input is not word-aligned. The first word load of in put | 446 /* Input is not word-aligned. The first word load of in put |
470 * will not produce a full word of input bytes, so one w ord | 447 * will not produce a full word of input bytes, so one w ord |
471 * must be pre-loaded. The main loop below will load in the | 448 * must be pre-loaded. The main loop below will load in the |
472 * next input word and shift some of its bytes into inWo rd | 449 * next input word and shift some of its bytes into inWo rd |
473 * in order to create a full input word. Note that the main | 450 * in order to create a full input word. Note that the main |
474 * loop must execute at least once because the input mus t | 451 * loop must execute at least once because the input mus t |
475 * be at least two words. | 452 * be at least two words. |
476 */ | 453 */ |
477 » » » inWord = *pInWord++; /* UMR? see comments above. */ | 454 » » » unsigned int shift = LEFTMOST_BYTE_SHIFT; |
478 » » » inWord = inWord LSH invBufShift; | 455 » » » inWord = 0; |
456 » » » for (i = 0; i < WORDSIZE - inOffset; i++) { | |
457 » » » » inWord |= (WORD)input[i] << shift; | |
458 » » » » shift = NEXT_BYTE_SHIFT(shift); | |
459 » » » } | |
460 » » » pInWord++; | |
479 } else { | 461 } else { |
480 /* Input is word-aligned. The first word load of input | 462 /* Input is word-aligned. The first word load of input |
481 * will produce a full word of input bytes, so nothing | 463 * will produce a full word of input bytes, so nothing |
482 * needs to be loaded here. | 464 * needs to be loaded here. |
483 */ | 465 */ |
484 inWord = 0; | 466 inWord = 0; |
485 } | 467 } |
486 } | 468 } |
487 /* Output buffer is aligned, inOffset is now measured relative to | 469 /* Output buffer is aligned, inOffset is now measured relative to |
488 * outOffset (and not a word boundary). | 470 * outOffset (and not a word boundary). |
(...skipping 14 matching lines...) Expand all Loading... | |
503 ARCFOUR_NEXT_WORD(); | 485 ARCFOUR_NEXT_WORD(); |
504 *pOutWord++ = inWord ^ streamWord; | 486 *pOutWord++ = inWord ^ streamWord; |
505 inWord = nextInWord; | 487 inWord = nextInWord; |
506 } | 488 } |
507 if (inputLen == 0) { | 489 if (inputLen == 0) { |
508 /* Nothing left to do. */ | 490 /* Nothing left to do. */ |
509 cx->i = tmpi; | 491 cx->i = tmpi; |
510 cx->j = tmpj; | 492 cx->j = tmpj; |
511 return SECSuccess; | 493 return SECSuccess; |
512 } | 494 } |
513 » » /* If the amount of remaining input is greater than the amount | 495 » » finalIn = (const unsigned char *)pInWord - WORDSIZE + inOffset; |
514 » » * bytes pulled from the current input word, need to do another | |
515 » » * word load. What's left in inWord will be consumed in step 3. | |
516 » » */ | |
517 » » if (inputLen > WORDSIZE - inOffset) | |
518 » » » inWord |= *pInWord RSH bufShift; /* UMR? See above. */ | |
519 } else { | 496 } else { |
520 for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { | 497 for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { |
521 inWord = *pInWord++; | 498 inWord = *pInWord++; |
522 ARCFOUR_NEXT_WORD(); | 499 ARCFOUR_NEXT_WORD(); |
523 *pOutWord++ = inWord ^ streamWord; | 500 *pOutWord++ = inWord ^ streamWord; |
524 } | 501 } |
525 if (inputLen == 0) { | 502 if (inputLen == 0) { |
526 /* Nothing left to do. */ | 503 /* Nothing left to do. */ |
527 cx->i = tmpi; | 504 cx->i = tmpi; |
528 cx->j = tmpj; | 505 cx->j = tmpj; |
529 return SECSuccess; | 506 return SECSuccess; |
530 } else { | |
531 /* A partial input word remains at the tail. Load it. | |
532 * The relevant bytes will be consumed in step 3. | |
533 */ | |
534 inWord = *pInWord; /* UMR? See comments above */ | |
535 } | 507 } |
508 finalIn = (const unsigned char *)pInWord; | |
536 } | 509 } |
537 /*****************************************************************/ | 510 /*****************************************************************/ |
538 /* Step 3: */ | 511 /* Step 3: */ |
539 » /* A partial word of input remains, and it is already loaded */ | 512 » /* Do the remaining partial word of input one byte at a time. */ |
540 » /* into nextInWord. Shift appropriately and consume the bytes */ | |
541 » /* used in the partial word. */ | |
542 /*****************************************************************/ | 513 /*****************************************************************/ |
543 » mask = streamWord = 0; | 514 » finalOut = (unsigned char *)pOutWord; |
544 #ifdef IS_LITTLE_ENDIAN | 515 » for (i = 0; i < inputLen; i++) { |
545 » for (i = 0; i < inputLen; ++i) { | |
546 #else | |
547 » for (i = WORDSIZE - 1; i >= WORDSIZE - inputLen; --i) { | |
548 #endif | |
549 ARCFOUR_NEXT_BYTE(); | 516 ARCFOUR_NEXT_BYTE(); |
550 » » streamWord |= (WORD)(cx->S[t]) << 8*i; | 517 » » finalOut[i] = cx->S[t] ^ finalIn[i]; |
551 » » mask |= MASK1BYTE << 8*i; | 518 » } |
552 » } /* } */ | |
553 » /* UMR? See comments above. */ | |
554 » *pOutWord = (*pOutWord & ~mask) | ((inWord ^ streamWord) & mask); | |
555 cx->i = tmpi; | 519 cx->i = tmpi; |
556 cx->j = tmpj; | 520 cx->j = tmpj; |
557 return SECSuccess; | 521 return SECSuccess; |
558 } | 522 } |
559 #endif | 523 #endif |
560 #endif /* NSS_BEVAND_ARCFOUR */ | 524 #endif /* NSS_BEVAND_ARCFOUR */ |
561 | 525 |
562 SECStatus | 526 SECStatus |
563 RC4_Encrypt(RC4Context *cx, unsigned char *output, | 527 RC4_Encrypt(RC4Context *cx, unsigned char *output, |
564 unsigned int *outputLen, unsigned int maxOutputLen, | 528 unsigned int *outputLen, unsigned int maxOutputLen, |
565 const unsigned char *input, unsigned int inputLen) | 529 const unsigned char *input, unsigned int inputLen) |
566 { | 530 { |
567 PORT_Assert(maxOutputLen >= inputLen); | 531 PORT_Assert(maxOutputLen >= inputLen); |
568 if (maxOutputLen < inputLen) { | 532 if (maxOutputLen < inputLen) { |
569 » » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 533 » » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
570 return SECFailure; | 534 return SECFailure; |
571 } | 535 } |
572 #if defined(NSS_BEVAND_ARCFOUR) | 536 #if defined(NSS_BEVAND_ARCFOUR) |
573 ARCFOUR(cx, inputLen, input, output); | 537 ARCFOUR(cx, inputLen, input, output); |
574 *outputLen = inputLen; | 538 *outputLen = inputLen; |
575 return SECSuccess; | 539 return SECSuccess; |
576 #elif defined( CONVERT_TO_WORDS ) | 540 #elif defined( CONVERT_TO_WORDS ) |
577 /* Convert the byte-stream to a word-stream */ | 541 /* Convert the byte-stream to a word-stream */ |
578 return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen ); | 542 return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen ); |
579 #else | 543 #else |
580 /* Operate on bytes, but unroll the main loop */ | 544 /* Operate on bytes, but unroll the main loop */ |
581 return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen ); | 545 return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen ); |
582 #endif | 546 #endif |
583 } | 547 } |
584 | 548 |
585 SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output, | 549 SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output, |
586 unsigned int *outputLen, unsigned int maxOutputLen, | 550 unsigned int *outputLen, unsigned int maxOutputLen, |
587 const unsigned char *input, unsigned int inputLen) | 551 const unsigned char *input, unsigned int inputLen) |
588 { | 552 { |
589 PORT_Assert(maxOutputLen >= inputLen); | 553 PORT_Assert(maxOutputLen >= inputLen); |
590 if (maxOutputLen < inputLen) { | 554 if (maxOutputLen < inputLen) { |
591 » » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 555 » » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
592 return SECFailure; | 556 return SECFailure; |
593 } | 557 } |
594 /* decrypt and encrypt are same operation. */ | 558 /* decrypt and encrypt are same operation. */ |
595 #if defined(NSS_BEVAND_ARCFOUR) | 559 #if defined(NSS_BEVAND_ARCFOUR) |
596 ARCFOUR(cx, inputLen, input, output); | 560 ARCFOUR(cx, inputLen, input, output); |
597 *outputLen = inputLen; | 561 *outputLen = inputLen; |
598 return SECSuccess; | 562 return SECSuccess; |
599 #elif defined( CONVERT_TO_WORDS ) | 563 #elif defined( CONVERT_TO_WORDS ) |
600 /* Convert the byte-stream to a word-stream */ | 564 /* Convert the byte-stream to a word-stream */ |
601 return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen ); | 565 return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen ); |
602 #else | 566 #else |
603 /* Operate on bytes, but unroll the main loop */ | 567 /* Operate on bytes, but unroll the main loop */ |
604 return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen ); | 568 return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen ); |
605 #endif | 569 #endif |
606 } | 570 } |
607 | 571 |
608 #undef CONVERT_TO_WORDS | 572 #undef CONVERT_TO_WORDS |
609 #undef USE_WORD | 573 #undef USE_WORD |
OLD | NEW |