aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/tls_aesgcm.c63
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
36static void RIGHTSHIFTX(byte* x) 36static 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
51static void GMULT(byte* X, byte* Y) 100static void GMULT(byte* X, byte* Y)