diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-08 13:34:43 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-08 13:34:43 +0100 |
| commit | 9f00a0fdb159432f1d7232253e2180d85e5eca32 (patch) | |
| tree | 0b5e157a0bb052f71cc575c3ba93f14e88e91abd | |
| parent | f522dd94207275ac4a2706c4927a12c37707ff5a (diff) | |
| download | busybox-w32-9f00a0fdb159432f1d7232253e2180d85e5eca32.tar.gz busybox-w32-9f00a0fdb159432f1d7232253e2180d85e5eca32.tar.bz2 busybox-w32-9f00a0fdb159432f1d7232253e2180d85e5eca32.zip | |
tls: make RIGHTSHIFTX() in AES-GCM faster
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/tls_aesgcm.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/networking/tls_aesgcm.c b/networking/tls_aesgcm.c index 688df85fb..008dc9b5d 100644 --- a/networking/tls_aesgcm.c +++ b/networking/tls_aesgcm.c | |||
| @@ -35,17 +35,66 @@ static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz) | |||
| 35 | 35 | ||
| 36 | static void RIGHTSHIFTX(byte* x) | 36 | static void RIGHTSHIFTX(byte* x) |
| 37 | { | 37 | { |
| 38 | int i; | 38 | #define l ((unsigned long*)x) |
| 39 | int carryOut = 0; | 39 | #if 0 |
| 40 | int carryIn = 0; | ||
| 41 | int borrow = x[15] & 0x01; | ||
| 42 | 40 | ||
| 41 | // Generic byte-at-a-time algorithm | ||
| 42 | int i; | ||
| 43 | byte carryIn = (x[15] & 0x01) ? 0xE1 : 0; | ||
| 43 | for (i = 0; i < AES_BLOCK_SIZE; i++) { | 44 | for (i = 0; i < AES_BLOCK_SIZE; i++) { |
| 44 | carryOut = x[i] & 0x01; | 45 | byte carryOut = (x[i] << 7); // zero, or 0x80 |
| 45 | x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0); | 46 | x[i] = (x[i] >> 1) ^ carryIn; |
| 47 | carryIn = carryOut; | ||
| 48 | } | ||
| 49 | |||
| 50 | #elif BB_BIG_ENDIAN | ||
| 51 | |||
| 52 | // Big-endian can shift-right in larger than byte chunks | ||
| 53 | // (we use the fact that 'x' is long-aligned) | ||
| 54 | unsigned long carryIn = (x[15] & 0x01) | ||
| 55 | ? ((unsigned long)0xE1 << (LONG_BIT-8)) | ||
| 56 | : 0; | ||
| 57 | # if ULONG_MAX <= 0xffffffff | ||
| 58 | int i; | ||
| 59 | for (i = 0; i < AES_BLOCK_SIZE/sizeof(long); i++) { | ||
| 60 | unsigned long carryOut = l[i] << (LONG_BIT-1); // zero, or 0x800..00 | ||
| 61 | l[i] = (l[i] >> 1) ^ carryIn; | ||
| 62 | carryIn = carryOut; | ||
| 63 | } | ||
| 64 | # else | ||
| 65 | // 64-bit code: need to process only 2 words | ||
| 66 | unsigned long carryOut = l[0] << (LONG_BIT-1); // zero, or 0x800..00 | ||
| 67 | l[0] = (l[0] >> 1) ^ carryIn; | ||
| 68 | l[1] = (l[1] >> 1) ^ carryOut; | ||
| 69 | # endif | ||
| 70 | |||
| 71 | #else /* LITTLE_ENDIAN */ | ||
| 72 | |||
| 73 | // In order to use word-sized ops, little-endian needs to byteswap. | ||
| 74 | // On x86, code size increase is ~10 bytes compared to byte-by-byte. | ||
| 75 | unsigned long carryIn = (x[15] & 0x01) | ||
| 76 | ? ((unsigned long)0xE1 << (LONG_BIT-8)) | ||
| 77 | : 0; | ||
| 78 | # if ULONG_MAX <= 0xffffffff | ||
| 79 | int i; | ||
| 80 | for (i = 0; i < AES_BLOCK_SIZE/sizeof(long); i++) { | ||
| 81 | unsigned long ti = SWAP_BE32(l[i]); | ||
| 82 | unsigned long carryOut = ti << (LONG_BIT-1); // zero, or 0x800..00 | ||
| 83 | ti = (ti >> 1) ^ carryIn; | ||
| 84 | l[i] = SWAP_BE32(ti); | ||
| 46 | carryIn = carryOut; | 85 | carryIn = carryOut; |
| 47 | } | 86 | } |
| 48 | if (borrow) x[0] ^= 0xE1; | 87 | # else |
| 88 | // 64-bit code: need to process only 2 words | ||
| 89 | unsigned long tt = SWAP_BE64(l[0]); | ||
| 90 | unsigned long carryOut = tt << (LONG_BIT-1); // zero, or 0x800..00 | ||
| 91 | tt = (tt >> 1) ^ carryIn; l[0] = SWAP_BE64(tt); | ||
| 92 | tt = SWAP_BE64(l[1]); | ||
| 93 | tt = (tt >> 1) ^ carryOut; l[1] = SWAP_BE64(tt); | ||
| 94 | # endif | ||
| 95 | |||
| 96 | #endif /* LITTLE_ENDIAN */ | ||
| 97 | #undef l | ||
| 49 | } | 98 | } |
| 50 | 99 | ||
| 51 | static void GMULT(byte* X, byte* Y) | 100 | static void GMULT(byte* X, byte* Y) |
