diff options
-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) |