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 #ifdef FREEBL_NO_DEPEND | 7 #ifdef FREEBL_NO_DEPEND |
8 #include "stubs.h" | 8 #include "stubs.h" |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 unsigned int inOffset = (PRUword)input % WORDSIZE; | 365 unsigned int inOffset = (PRUword)input % WORDSIZE; |
366 unsigned int outOffset = (PRUword)output % WORDSIZE; | 366 unsigned int outOffset = (PRUword)output % WORDSIZE; |
367 register WORD streamWord; | 367 register WORD streamWord; |
368 register const WORD *pInWord; | 368 register const WORD *pInWord; |
369 register WORD *pOutWord; | 369 register WORD *pOutWord; |
370 register WORD inWord, nextInWord; | 370 register WORD inWord, nextInWord; |
371 PRUint8 t; | 371 PRUint8 t; |
372 register Stype tmpSi, tmpSj; | 372 register Stype tmpSi, tmpSj; |
373 register PRUint8 tmpi = cx->i; | 373 register PRUint8 tmpi = cx->i; |
374 register PRUint8 tmpj = cx->j; | 374 register PRUint8 tmpj = cx->j; |
375 unsigned int byteCount; | |
wtc
2013/05/07 18:00:50
I moved this variable declaration to the lexical s
| |
376 unsigned int bufShift, invBufShift; | 375 unsigned int bufShift, invBufShift; |
377 unsigned int i; | 376 unsigned int i; |
378 const unsigned char *finalIn; | 377 const unsigned char *finalIn; |
379 unsigned char *finalOut; | 378 unsigned char *finalOut; |
380 | 379 |
381 PORT_Assert(maxOutputLen >= inputLen); | 380 PORT_Assert(maxOutputLen >= inputLen); |
382 if (maxOutputLen < inputLen) { | 381 if (maxOutputLen < inputLen) { |
383 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | 382 PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
384 return SECFailure; | 383 return SECFailure; |
385 } | 384 } |
386 if (inputLen < 2*WORDSIZE) { | 385 if (inputLen < 2*WORDSIZE) { |
387 /* Ignore word conversion, do byte-at-a-time */ | 386 /* Ignore word conversion, do byte-at-a-time */ |
388 return rc4_no_opt(cx, output, outputLen, maxOutputLen, input, in putLen); | 387 return rc4_no_opt(cx, output, outputLen, maxOutputLen, input, in putLen); |
389 } | 388 } |
390 *outputLen = inputLen; | 389 *outputLen = inputLen; |
391 pInWord = (const WORD *)(input - inOffset); | 390 pInWord = (const WORD *)(input - inOffset); |
392 pOutWord = (WORD *)(output - outOffset); | 391 pOutWord = (WORD *)(output - outOffset); |
393 » if (inOffset < outOffset) { | 392 » if (inOffset <= outOffset) { |
wtc
2013/05/07 18:00:50
How to review this change.
1. Verify that bufShif
| |
394 bufShift = 8*(outOffset - inOffset); | 393 bufShift = 8*(outOffset - inOffset); |
395 invBufShift = 8*WORDSIZE - bufShift; | 394 invBufShift = 8*WORDSIZE - bufShift; |
396 } else { | 395 } else { |
397 invBufShift = 8*(inOffset - outOffset); | 396 invBufShift = 8*(inOffset - outOffset); |
398 bufShift = 8*WORDSIZE - invBufShift; | 397 bufShift = 8*WORDSIZE - invBufShift; |
399 } | 398 } |
400 /*****************************************************************/ | 399 /*****************************************************************/ |
401 /* Step 1: */ | 400 /* Step 1: */ |
402 /* If the first output word is partial, consume the bytes in the */ | 401 /* If the first output word is partial, consume the bytes in the */ |
403 /* first partial output word by loading one or two words of */ | 402 /* first partial output word by loading one or two words of */ |
404 /* input and shifting them accordingly. Otherwise, just load */ | 403 /* input and shifting them accordingly. Otherwise, just load */ |
405 /* in the first word of input. At the end of this block, at */ | 404 /* in the first word of input. At the end of this block, at */ |
406 /* least one partial word of input should ALWAYS be loaded. */ | 405 /* least one partial word of input should ALWAYS be loaded. */ |
407 /*****************************************************************/ | 406 /*****************************************************************/ |
408 if (outOffset) { | 407 if (outOffset) { |
409 » » byteCount = WORDSIZE - outOffset; | 408 » » unsigned int byteCount = WORDSIZE - outOffset; |
410 for (i = 0; i < byteCount; i++) { | 409 for (i = 0; i < byteCount; i++) { |
411 ARCFOUR_NEXT_BYTE(); | 410 ARCFOUR_NEXT_BYTE(); |
412 output[i] = cx->S[t] ^ input[i]; | 411 output[i] = cx->S[t] ^ input[i]; |
413 } | 412 } |
414 /* Consumed byteCount bytes of input */ | 413 /* Consumed byteCount bytes of input */ |
415 inputLen -= byteCount; | 414 inputLen -= byteCount; |
416 pInWord++; | 415 pInWord++; |
417 | 416 |
418 /* move to next word of output */ | 417 /* move to next word of output */ |
419 pOutWord++; | 418 pOutWord++; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 } | 458 } |
460 pInWord++; | 459 pInWord++; |
461 } else { | 460 } else { |
462 /* Input is word-aligned. The first word load of input | 461 /* Input is word-aligned. The first word load of input |
463 * will produce a full word of input bytes, so nothing | 462 * will produce a full word of input bytes, so nothing |
464 * needs to be loaded here. | 463 * needs to be loaded here. |
465 */ | 464 */ |
466 inWord = 0; | 465 inWord = 0; |
467 } | 466 } |
468 } | 467 } |
469 /* Output buffer is aligned, inOffset is now measured relative to | |
470 * outOffset (and not a word boundary). | |
471 */ | |
472 inOffset = (inOffset + WORDSIZE - outOffset) % WORDSIZE; | |
wtc
2013/05/07 18:00:50
This redefinition of inOffset is very confusing. I
| |
473 /*****************************************************************/ | 468 /*****************************************************************/ |
474 /* Step 2: main loop */ | 469 /* Step 2: main loop */ |
475 /* At this point the output buffer is word-aligned. Any unused */ | 470 /* At this point the output buffer is word-aligned. Any unused */ |
476 /* bytes from above will be in inWord (shifted correctly). If */ | 471 /* bytes from above will be in inWord (shifted correctly). If */ |
477 /* the input buffer is unaligned relative to the output buffer, */ | 472 /* the input buffer is unaligned relative to the output buffer, */ |
478 /* shifting has to be done. */ | 473 /* shifting has to be done. */ |
479 /*****************************************************************/ | 474 /*****************************************************************/ |
480 » if (inOffset) { | 475 » if (bufShift) { |
wtc
2013/05/07 18:00:50
With the new values of bufShift and invBufShift ab
| |
481 » » for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { | 476 » » /* preloadedByteCount is the number of input bytes pre-loaded |
477 » » * in inWord. | |
478 » » */ | |
479 » » unsigned int preloadedByteCount = bufShift/8; | |
480 » » for (; inputLen >= preloadedByteCount + WORDSIZE; | |
481 » » inputLen -= WORDSIZE) { | |
wtc
2013/05/07 18:00:50
How to understand this change:
1. At the beginnin
| |
482 nextInWord = *pInWord++; | 482 nextInWord = *pInWord++; |
483 inWord |= nextInWord RSH bufShift; | 483 inWord |= nextInWord RSH bufShift; |
484 nextInWord = nextInWord LSH invBufShift; | 484 nextInWord = nextInWord LSH invBufShift; |
485 ARCFOUR_NEXT_WORD(); | 485 ARCFOUR_NEXT_WORD(); |
486 *pOutWord++ = inWord ^ streamWord; | 486 *pOutWord++ = inWord ^ streamWord; |
487 inWord = nextInWord; | 487 inWord = nextInWord; |
488 } | 488 } |
489 if (inputLen == 0) { | 489 if (inputLen == 0) { |
490 /* Nothing left to do. */ | 490 /* Nothing left to do. */ |
491 cx->i = tmpi; | 491 cx->i = tmpi; |
492 cx->j = tmpj; | 492 cx->j = tmpj; |
493 return SECSuccess; | 493 return SECSuccess; |
494 } | 494 } |
495 » » finalIn = (const unsigned char *)pInWord - WORDSIZE + inOffset; | 495 » » finalIn = (const unsigned char *)pInWord - preloadedByteCount; |
496 } else { | 496 } else { |
497 for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { | 497 for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) { |
498 inWord = *pInWord++; | 498 inWord = *pInWord++; |
499 ARCFOUR_NEXT_WORD(); | 499 ARCFOUR_NEXT_WORD(); |
500 *pOutWord++ = inWord ^ streamWord; | 500 *pOutWord++ = inWord ^ streamWord; |
501 } | 501 } |
502 if (inputLen == 0) { | 502 if (inputLen == 0) { |
503 /* Nothing left to do. */ | 503 /* Nothing left to do. */ |
504 cx->i = tmpi; | 504 cx->i = tmpi; |
505 cx->j = tmpj; | 505 cx->j = tmpj; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 /* Convert the byte-stream to a word-stream */ | 564 /* Convert the byte-stream to a word-stream */ |
565 return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen ); | 565 return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen ); |
566 #else | 566 #else |
567 /* Operate on bytes, but unroll the main loop */ | 567 /* Operate on bytes, but unroll the main loop */ |
568 return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen ); | 568 return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen ); |
569 #endif | 569 #endif |
570 } | 570 } |
571 | 571 |
572 #undef CONVERT_TO_WORDS | 572 #undef CONVERT_TO_WORDS |
573 #undef USE_WORD | 573 #undef USE_WORD |
OLD | NEW |