1 | /* |
2 | * Copyright 2010-2019 The OpenSSL Project Authors. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at |
7 | * https://www.openssl.org/source/license.html |
8 | */ |
9 | |
10 | /* TODO(3.0) Move this header into provider when dependencies are removed */ |
11 | #include <openssl/modes.h> |
12 | |
13 | #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) |
14 | typedef __int64 i64; |
15 | typedef unsigned __int64 u64; |
16 | # define U64(C) C##UI64 |
17 | #elif defined(__arch64__) |
18 | typedef long i64; |
19 | typedef unsigned long u64; |
20 | # define U64(C) C##UL |
21 | #else |
22 | typedef long long i64; |
23 | typedef unsigned long long u64; |
24 | # define U64(C) C##ULL |
25 | #endif |
26 | |
27 | typedef unsigned int u32; |
28 | typedef unsigned char u8; |
29 | |
30 | #define STRICT_ALIGNMENT 1 |
31 | #ifndef PEDANTIC |
32 | # if defined(__i386) || defined(__i386__) || \ |
33 | defined(__x86_64) || defined(__x86_64__) || \ |
34 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ |
35 | defined(__aarch64__) || \ |
36 | defined(__s390__) || defined(__s390x__) |
37 | # undef STRICT_ALIGNMENT |
38 | # endif |
39 | #endif |
40 | |
41 | #if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) |
42 | # if defined(__GNUC__) && __GNUC__>=2 |
43 | # if defined(__x86_64) || defined(__x86_64__) |
44 | # define BSWAP8(x) ({ u64 ret_=(x); \ |
45 | asm ("bswapq %0" \ |
46 | : "+r"(ret_)); ret_; }) |
47 | # define BSWAP4(x) ({ u32 ret_=(x); \ |
48 | asm ("bswapl %0" \ |
49 | : "+r"(ret_)); ret_; }) |
50 | # elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) |
51 | # define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ |
52 | asm ("bswapl %0; bswapl %1" \ |
53 | : "+r"(hi_),"+r"(lo_)); \ |
54 | (u64)hi_<<32|lo_; }) |
55 | # define BSWAP4(x) ({ u32 ret_=(x); \ |
56 | asm ("bswapl %0" \ |
57 | : "+r"(ret_)); ret_; }) |
58 | # elif defined(__aarch64__) |
59 | # define BSWAP8(x) ({ u64 ret_; \ |
60 | asm ("rev %0,%1" \ |
61 | : "=r"(ret_) : "r"(x)); ret_; }) |
62 | # define BSWAP4(x) ({ u32 ret_; \ |
63 | asm ("rev %w0,%w1" \ |
64 | : "=r"(ret_) : "r"(x)); ret_; }) |
65 | # elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) |
66 | # define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ |
67 | asm ("rev %0,%0; rev %1,%1" \ |
68 | : "+r"(hi_),"+r"(lo_)); \ |
69 | (u64)hi_<<32|lo_; }) |
70 | # define BSWAP4(x) ({ u32 ret_; \ |
71 | asm ("rev %0,%1" \ |
72 | : "=r"(ret_) : "r"((u32)(x))); \ |
73 | ret_; }) |
74 | # endif |
75 | # elif defined(_MSC_VER) |
76 | # if _MSC_VER>=1300 |
77 | # include <stdlib.h> |
78 | # pragma intrinsic(_byteswap_uint64,_byteswap_ulong) |
79 | # define BSWAP8(x) _byteswap_uint64((u64)(x)) |
80 | # define BSWAP4(x) _byteswap_ulong((u32)(x)) |
81 | # elif defined(_M_IX86) |
82 | __inline u32 _bswap4(u32 val) |
83 | { |
84 | _asm mov eax, val _asm bswap eax} |
85 | # define BSWAP4(x) _bswap4(x) |
86 | # endif |
87 | # endif |
88 | #endif |
89 | #if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) |
90 | # define GETU32(p) BSWAP4(*(const u32 *)(p)) |
91 | # define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) |
92 | #else |
93 | # define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) |
94 | # define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) |
95 | #endif |
96 | /*- GCM definitions */ typedef struct { |
97 | u64 hi, lo; |
98 | } u128; |
99 | |
100 | #ifdef TABLE_BITS |
101 | # undef TABLE_BITS |
102 | #endif |
103 | /* |
104 | * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should |
105 | * never be set to 8 [or 1]. For further information see gcm128.c. |
106 | */ |
107 | #define TABLE_BITS 4 |
108 | |
109 | struct gcm128_context { |
110 | /* Following 6 names follow names in GCM specification */ |
111 | union { |
112 | u64 u[2]; |
113 | u32 d[4]; |
114 | u8 c[16]; |
115 | size_t t[16 / sizeof(size_t)]; |
116 | } Yi, EKi, EK0, len, Xi, H; |
117 | /* |
118 | * Relative position of Xi, H and pre-computed Htable is used in some |
119 | * assembler modules, i.e. don't change the order! |
120 | */ |
121 | #if TABLE_BITS==8 |
122 | u128 Htable[256]; |
123 | #else |
124 | u128 Htable[16]; |
125 | void (*gmult) (u64 Xi[2], const u128 Htable[16]); |
126 | void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, |
127 | size_t len); |
128 | #endif |
129 | unsigned int mres, ares; |
130 | block128_f block; |
131 | void *key; |
132 | #if !defined(OPENSSL_SMALL_FOOTPRINT) |
133 | unsigned char Xn[48]; |
134 | #endif |
135 | }; |
136 | |
137 | /* |
138 | * The maximum permitted number of cipher blocks per data unit in XTS mode. |
139 | * Reference IEEE Std 1619-2018. |
140 | */ |
141 | #define XTS_MAX_BLOCKS_PER_DATA_UNIT (1<<20) |
142 | |
143 | struct xts128_context { |
144 | void *key1, *key2; |
145 | block128_f block1, block2; |
146 | }; |
147 | |
148 | struct ccm128_context { |
149 | union { |
150 | u64 u[2]; |
151 | u8 c[16]; |
152 | } nonce, cmac; |
153 | u64 blocks; |
154 | block128_f block; |
155 | void *key; |
156 | }; |
157 | |
158 | #ifndef OPENSSL_NO_OCB |
159 | |
160 | typedef union { |
161 | u64 a[2]; |
162 | unsigned char c[16]; |
163 | } OCB_BLOCK; |
164 | # define ocb_block16_xor(in1,in2,out) \ |
165 | ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \ |
166 | (out)->a[1]=(in1)->a[1]^(in2)->a[1] ) |
167 | # if STRICT_ALIGNMENT |
168 | # define ocb_block16_xor_misaligned(in1,in2,out) \ |
169 | ocb_block_xor((in1)->c,(in2)->c,16,(out)->c) |
170 | # else |
171 | # define ocb_block16_xor_misaligned ocb_block16_xor |
172 | # endif |
173 | |
174 | struct ocb128_context { |
175 | /* Need both encrypt and decrypt key schedules for decryption */ |
176 | block128_f encrypt; |
177 | block128_f decrypt; |
178 | void *keyenc; |
179 | void *keydec; |
180 | ocb128_f stream; /* direction dependent */ |
181 | /* Key dependent variables. Can be reused if key remains the same */ |
182 | size_t l_index; |
183 | size_t max_l_index; |
184 | OCB_BLOCK l_star; |
185 | OCB_BLOCK l_dollar; |
186 | OCB_BLOCK *l; |
187 | /* Must be reset for each session */ |
188 | struct { |
189 | u64 blocks_hashed; |
190 | u64 blocks_processed; |
191 | OCB_BLOCK offset_aad; |
192 | OCB_BLOCK sum; |
193 | OCB_BLOCK offset; |
194 | OCB_BLOCK checksum; |
195 | } sess; |
196 | }; |
197 | #endif /* OPENSSL_NO_OCB */ |
198 | |
199 | #ifndef OPENSSL_NO_SIV |
200 | |
201 | #define SIV_LEN 16 |
202 | |
203 | typedef union siv_block_u { |
204 | uint64_t word[SIV_LEN/sizeof(uint64_t)]; |
205 | unsigned char byte[SIV_LEN]; |
206 | } SIV_BLOCK; |
207 | |
208 | struct siv128_context { |
209 | /* d stores intermediate results of S2V; it corresponds to D from the |
210 | pseudocode in section 2.4 of RFC 5297. */ |
211 | SIV_BLOCK d; |
212 | SIV_BLOCK tag; |
213 | EVP_CIPHER_CTX *cipher_ctx; |
214 | EVP_MAC *mac; |
215 | EVP_MAC_CTX *mac_ctx_init; |
216 | int final_ret; |
217 | int crypto_ok; |
218 | }; |
219 | |
220 | #endif /* OPENSSL_NO_SIV */ |
221 | |