]>
Commit | Line | Data |
---|---|---|
f472ec8c AP |
1 | /* ==================================================================== |
2 | * Copyright (c) 2010 The OpenSSL Project. All rights reserved. | |
3 | * | |
4 | * Redistribution and use is governed by OpenSSL license. | |
5 | * ==================================================================== | |
6 | */ | |
7 | ||
8 | #include <openssl/modes.h> | |
9 | ||
f472ec8c AP |
10 | #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) |
11 | typedef __int64 i64; | |
12 | typedef unsigned __int64 u64; | |
0f113f3e | 13 | # define U64(C) C##UI64 |
f472ec8c AP |
14 | #elif defined(__arch64__) |
15 | typedef long i64; | |
16 | typedef unsigned long u64; | |
0f113f3e | 17 | # define U64(C) C##UL |
f472ec8c AP |
18 | #else |
19 | typedef long long i64; | |
20 | typedef unsigned long long u64; | |
0f113f3e | 21 | # define U64(C) C##ULL |
f472ec8c AP |
22 | #endif |
23 | ||
24 | typedef unsigned int u32; | |
25 | typedef unsigned char u8; | |
26 | ||
27 | #define STRICT_ALIGNMENT 1 | |
021e5043 | 28 | #ifndef PEDANTIC |
0f113f3e MC |
29 | # if defined(__i386) || defined(__i386__) || \ |
30 | defined(__x86_64) || defined(__x86_64__) || \ | |
31 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ | |
32 | defined(__aarch64__) || \ | |
33 | defined(__s390__) || defined(__s390x__) | |
1e8f69c6 AP |
34 | # undef STRICT_ALIGNMENT |
35 | # endif | |
021e5043 | 36 | #endif |
f472ec8c | 37 | |
0ecedec8 | 38 | #if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) |
1e8f69c6 AP |
39 | # if defined(__GNUC__) && __GNUC__>=2 |
40 | # if defined(__x86_64) || defined(__x86_64__) | |
2da2a434 | 41 | # define BSWAP8(x) ({ u64 ret_=(x); \ |
0f113f3e | 42 | asm ("bswapq %0" \ |
2da2a434 RL |
43 | : "+r"(ret_)); ret_; }) |
44 | # define BSWAP4(x) ({ u32 ret_=(x); \ | |
0f113f3e | 45 | asm ("bswapl %0" \ |
2da2a434 | 46 | : "+r"(ret_)); ret_; }) |
1e8f69c6 | 47 | # elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) |
2da2a434 | 48 | # define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ |
0f113f3e | 49 | asm ("bswapl %0; bswapl %1" \ |
2da2a434 RL |
50 | : "+r"(hi_),"+r"(lo_)); \ |
51 | (u64)hi_<<32|lo_; }) | |
52 | # define BSWAP4(x) ({ u32 ret_=(x); \ | |
0f113f3e | 53 | asm ("bswapl %0" \ |
2da2a434 | 54 | : "+r"(ret_)); ret_; }) |
1e8f69c6 | 55 | # elif defined(__aarch64__) |
2da2a434 | 56 | # define BSWAP8(x) ({ u64 ret_; \ |
0f113f3e | 57 | asm ("rev %0,%1" \ |
2da2a434 RL |
58 | : "=r"(ret_) : "r"(x)); ret_; }) |
59 | # define BSWAP4(x) ({ u32 ret_; \ | |
0f113f3e | 60 | asm ("rev %w0,%w1" \ |
2da2a434 | 61 | : "=r"(ret_) : "r"(x)); ret_; }) |
1e8f69c6 | 62 | # elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) |
2da2a434 | 63 | # define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ |
0f113f3e | 64 | asm ("rev %0,%0; rev %1,%1" \ |
2da2a434 RL |
65 | : "+r"(hi_),"+r"(lo_)); \ |
66 | (u64)hi_<<32|lo_; }) | |
67 | # define BSWAP4(x) ({ u32 ret_; \ | |
0f113f3e | 68 | asm ("rev %0,%1" \ |
2da2a434 RL |
69 | : "=r"(ret_) : "r"((u32)(x))); \ |
70 | ret_; }) | |
1e8f69c6 AP |
71 | # endif |
72 | # elif defined(_MSC_VER) | |
73 | # if _MSC_VER>=1300 | |
74 | # pragma intrinsic(_byteswap_uint64,_byteswap_ulong) | |
0f113f3e MC |
75 | # define BSWAP8(x) _byteswap_uint64((u64)(x)) |
76 | # define BSWAP4(x) _byteswap_ulong((u32)(x)) | |
1e8f69c6 | 77 | # elif defined(_M_IX86) |
0f113f3e MC |
78 | __inline u32 _bswap4(u32 val) |
79 | { | |
80 | _asm mov eax, val _asm bswap eax} | |
81 | # define BSWAP4(x) _bswap4(x) | |
1e8f69c6 | 82 | # endif |
f472ec8c AP |
83 | # endif |
84 | #endif | |
f472ec8c | 85 | #if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) |
0f113f3e MC |
86 | # define GETU32(p) BSWAP4(*(const u32 *)(p)) |
87 | # define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) | |
f472ec8c | 88 | #else |
0f113f3e MC |
89 | # define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) |
90 | # define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) | |
f472ec8c | 91 | #endif |
0f113f3e MC |
92 | /*- GCM definitions */ typedef struct { |
93 | u64 hi, lo; | |
94 | } u128; | |
ab8a4e54 | 95 | |
0f113f3e MC |
96 | #ifdef TABLE_BITS |
97 | # undef TABLE_BITS | |
ab8a4e54 DSH |
98 | #endif |
99 | /* | |
100 | * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should | |
d8d95832 | 101 | * never be set to 8 [or 1]. For further information see gcm128.c. |
ab8a4e54 | 102 | */ |
0f113f3e | 103 | #define TABLE_BITS 4 |
ab8a4e54 DSH |
104 | |
105 | struct gcm128_context { | |
0f113f3e MC |
106 | /* Following 6 names follow names in GCM specification */ |
107 | union { | |
108 | u64 u[2]; | |
109 | u32 d[4]; | |
110 | u8 c[16]; | |
111 | size_t t[16 / sizeof(size_t)]; | |
112 | } Yi, EKi, EK0, len, Xi, H; | |
113 | /* | |
114 | * Relative position of Xi, H and pre-computed Htable is used in some | |
115 | * assembler modules, i.e. don't change the order! | |
116 | */ | |
ab8a4e54 | 117 | #if TABLE_BITS==8 |
0f113f3e | 118 | u128 Htable[256]; |
ab8a4e54 | 119 | #else |
0f113f3e MC |
120 | u128 Htable[16]; |
121 | void (*gmult) (u64 Xi[2], const u128 Htable[16]); | |
122 | void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, | |
123 | size_t len); | |
ab8a4e54 | 124 | #endif |
0f113f3e MC |
125 | unsigned int mres, ares; |
126 | block128_f block; | |
127 | void *key; | |
ab8a4e54 | 128 | }; |
32a2d8dd DSH |
129 | |
130 | struct xts128_context { | |
0f113f3e MC |
131 | void *key1, *key2; |
132 | block128_f block1, block2; | |
32a2d8dd DSH |
133 | }; |
134 | ||
6386b1b3 | 135 | struct ccm128_context { |
0f113f3e MC |
136 | union { |
137 | u64 u[2]; | |
138 | u8 c[16]; | |
139 | } nonce, cmac; | |
140 | u64 blocks; | |
141 | block128_f block; | |
142 | void *key; | |
6386b1b3 DSH |
143 | }; |
144 | ||
3feb6305 MC |
145 | #ifndef OPENSSL_NO_OCB |
146 | ||
81f3d632 AP |
147 | typedef union { |
148 | u64 a[2]; | |
149 | unsigned char c[16]; | |
c857a80c | 150 | } OCB_BLOCK; |
81f3d632 AP |
151 | # define ocb_block16_xor(in1,in2,out) \ |
152 | ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \ | |
153 | (out)->a[1]=(in1)->a[1]^(in2)->a[1] ) | |
154 | # if STRICT_ALIGNMENT | |
155 | # define ocb_block16_xor_misaligned(in1,in2,out) \ | |
156 | ocb_block_xor((in1)->c,(in2)->c,16,(out)->c) | |
157 | # else | |
158 | # define ocb_block16_xor_misaligned ocb_block16_xor | |
159 | # endif | |
c857a80c MC |
160 | |
161 | struct ocb128_context { | |
0f113f3e MC |
162 | /* Need both encrypt and decrypt key schedules for decryption */ |
163 | block128_f encrypt; | |
164 | block128_f decrypt; | |
165 | void *keyenc; | |
166 | void *keydec; | |
bd30091c | 167 | ocb128_f stream; /* direction dependent */ |
0f113f3e MC |
168 | /* Key dependent variables. Can be reused if key remains the same */ |
169 | size_t l_index; | |
170 | size_t max_l_index; | |
171 | OCB_BLOCK l_star; | |
172 | OCB_BLOCK l_dollar; | |
173 | OCB_BLOCK *l; | |
174 | /* Must be reset for each session */ | |
175 | u64 blocks_hashed; | |
176 | u64 blocks_processed; | |
177 | OCB_BLOCK tag; | |
178 | OCB_BLOCK offset_aad; | |
179 | OCB_BLOCK sum; | |
180 | OCB_BLOCK offset; | |
181 | OCB_BLOCK checksum; | |
c857a80c | 182 | }; |
0f113f3e | 183 | #endif /* OPENSSL_NO_OCB */ |