23 #ifndef LW_INTERNAL_OCB_H
24 #define LW_INTERNAL_OCB_H
26 #include "internal-util.h"
42 #if defined(OCB_ENCRYPT_BLOCK)
58 #define OCB_CONCAT_INNER(name,suffix) name##suffix
59 #define OCB_CONCAT(name,suffix) OCB_CONCAT_INNER(name,suffix)
61 #if !defined(OCB_DOUBLE_L)
63 #define OCB_DOUBLE_L OCB_CONCAT(OCB_ALG_NAME,_double_l)
65 #if OCB_BLOCK_SIZE == 16
68 static void OCB_DOUBLE_L(
unsigned char out[16],
const unsigned char in[16])
71 unsigned char mask = (
unsigned char)(((
signed char)in[0]) >> 7);
72 for (index = 0; index < 15; ++index)
73 out[index] = (in[index] << 1) | (in[index + 1] >> 7);
74 out[15] = (in[15] << 1) ^ (mask & 0x87);
77 #elif OCB_BLOCK_SIZE == 12
80 static void OCB_DOUBLE_L
81 (
unsigned char out[12],
const unsigned char in[12])
84 unsigned char mask = (
unsigned char)(((
signed char)in[0]) >> 7);
85 for (index = 0; index < 11; ++index)
86 out[index] = (in[index] << 1) | (in[index + 1] >> 7);
87 out[11] = (in[11] << 1) ^ (mask & 0x41);
88 out[10] ^= (mask & 0x06);
92 #error "Unknown block size for OCB"
98 #define OCB_STATE OCB_CONCAT(OCB_ALG_NAME,_state_t)
102 unsigned char Lstar[OCB_BLOCK_SIZE];
103 unsigned char Ldollar[OCB_BLOCK_SIZE];
104 unsigned char L0[OCB_BLOCK_SIZE];
105 unsigned char L1[OCB_BLOCK_SIZE];
110 static void OCB_CONCAT(OCB_ALG_NAME,_init)
111 (OCB_STATE *state,
const unsigned char *k,
const unsigned char *nonce,
112 unsigned char offset[OCB_BLOCK_SIZE])
117 OCB_SETUP_KEY(&(state->ks), k);
120 memset(state->Lstar, 0,
sizeof(state->Lstar));
121 OCB_ENCRYPT_BLOCK(&(state->ks), state->Lstar, state->Lstar);
122 OCB_DOUBLE_L(state->Ldollar, state->Lstar);
123 OCB_DOUBLE_L(state->L0, state->Ldollar);
124 OCB_DOUBLE_L(state->L1, state->L0);
127 memset(offset, 0, OCB_BLOCK_SIZE);
128 memcpy(offset + OCB_BLOCK_SIZE - OCB_NONCE_SIZE, nonce, OCB_NONCE_SIZE);
129 offset[0] = ((OCB_TAG_SIZE * 8) & 0x7F) << 1;
130 offset[OCB_BLOCK_SIZE - OCB_NONCE_SIZE - 1] |= 0x01;
131 bottom = offset[OCB_BLOCK_SIZE - 1] & 0x3F;
132 offset[OCB_BLOCK_SIZE - 1] &= 0xC0;
135 unsigned byte_posn = bottom / 8;
136 #if OCB_BLOCK_SIZE == 16
138 unsigned char stretch[24];
139 OCB_ENCRYPT_BLOCK(&(state->ks), stretch, offset);
140 memcpy(stretch + 16, stretch + 1, 8);
141 lw_xor_block(stretch + 16, stretch, 8);
142 #elif OCB_BLOCK_SIZE == 12
144 unsigned char stretch[20];
145 OCB_ENCRYPT_BLOCK(&(state->ks), stretch, offset);
146 for (index = 0; index < 8; ++index) {
147 stretch[index + 12] =
148 (stretch[index + 1] << 1) | (stretch[index + 2] >> 7);
150 lw_xor_block(stretch + 12, stretch, 8);
152 unsigned char stretch[OCB_BLOCK_SIZE + 8] = {0};
153 #error "unsupported block size for OCB mode"
157 for (index = 0; index < OCB_BLOCK_SIZE; ++index) {
159 (stretch[index + byte_posn] << bottom) |
160 (stretch[index + byte_posn + 1] >> (8 - bottom));
163 memcpy(offset, stretch + byte_posn, OCB_BLOCK_SIZE);
169 static void OCB_CONCAT(OCB_ALG_NAME,_calculate_L)
170 (OCB_STATE *state,
unsigned char L[OCB_BLOCK_SIZE],
unsigned long long i)
172 OCB_DOUBLE_L(L, state->L1);
174 while ((i & 1) == 0) {
181 static void OCB_CONCAT(OCB_ALG_NAME,_process_ad)
182 (OCB_STATE *state,
unsigned char tag[OCB_BLOCK_SIZE],
183 const unsigned char *ad,
unsigned long long adlen)
185 unsigned char offset[OCB_BLOCK_SIZE];
186 unsigned char block[OCB_BLOCK_SIZE];
187 unsigned long long block_number;
190 memset(offset, 0,
sizeof(offset));
192 while (adlen >= OCB_BLOCK_SIZE) {
193 if (block_number & 1) {
194 lw_xor_block(offset, state->L0, OCB_BLOCK_SIZE);
195 }
else if ((block_number & 3) == 2) {
196 lw_xor_block(offset, state->L1, OCB_BLOCK_SIZE);
198 OCB_CONCAT(OCB_ALG_NAME,_calculate_L)(state, block, block_number);
199 lw_xor_block(offset, block, OCB_BLOCK_SIZE);
201 lw_xor_block_2_src(block, offset, ad, OCB_BLOCK_SIZE);
202 OCB_ENCRYPT_BLOCK(&(state->ks), block, block);
203 lw_xor_block(tag, block, OCB_BLOCK_SIZE);
204 ad += OCB_BLOCK_SIZE;
205 adlen -= OCB_BLOCK_SIZE;
211 unsigned temp = (unsigned)adlen;
212 lw_xor_block(offset, state->Lstar, OCB_BLOCK_SIZE);
213 lw_xor_block(offset, ad, temp);
214 offset[temp] ^= 0x80;
215 OCB_ENCRYPT_BLOCK(&(state->ks), block, offset);
216 lw_xor_block(tag, block, OCB_BLOCK_SIZE);
220 int OCB_CONCAT(OCB_ALG_NAME,_aead_encrypt)
221 (
unsigned char *c,
unsigned long long *clen,
222 const unsigned char *m,
unsigned long long mlen,
223 const unsigned char *ad,
unsigned long long adlen,
224 const unsigned char *nsec,
225 const unsigned char *npub,
226 const unsigned char *k)
229 unsigned char offset[OCB_BLOCK_SIZE];
230 unsigned char sum[OCB_BLOCK_SIZE];
231 unsigned char block[OCB_BLOCK_SIZE];
232 unsigned long long block_number;
236 *clen = mlen + OCB_TAG_SIZE;
239 OCB_CONCAT(OCB_ALG_NAME,_init)(&state, k, npub, offset);
242 memset(sum, 0,
sizeof(sum));
244 while (mlen >= OCB_BLOCK_SIZE) {
245 if (block_number & 1) {
246 lw_xor_block(offset, state.L0, OCB_BLOCK_SIZE);
247 }
else if ((block_number & 3) == 2) {
248 lw_xor_block(offset, state.L1, OCB_BLOCK_SIZE);
250 OCB_CONCAT(OCB_ALG_NAME,_calculate_L)(&state, block, block_number);
251 lw_xor_block(offset, block, OCB_BLOCK_SIZE);
253 lw_xor_block(sum, m, OCB_BLOCK_SIZE);
254 lw_xor_block_2_src(block, offset, m, OCB_BLOCK_SIZE);
255 OCB_ENCRYPT_BLOCK(&(state.ks), block, block);
256 lw_xor_block_2_src(c, block, offset, OCB_BLOCK_SIZE);
259 mlen -= OCB_BLOCK_SIZE;
265 unsigned temp = (unsigned)mlen;
266 lw_xor_block(sum, m, temp);
268 lw_xor_block(offset, state.Lstar, OCB_BLOCK_SIZE);
269 OCB_ENCRYPT_BLOCK(&(state.ks), block, offset);
270 lw_xor_block_2_src(c, block, m, temp);
275 lw_xor_block(sum, offset, OCB_BLOCK_SIZE);
276 lw_xor_block(sum, state.Ldollar, OCB_BLOCK_SIZE);
277 OCB_ENCRYPT_BLOCK(&(state.ks), sum, sum);
280 OCB_CONCAT(OCB_ALG_NAME,_process_ad)(&state, sum, ad, adlen);
281 memcpy(c, sum, OCB_TAG_SIZE);
285 int OCB_CONCAT(OCB_ALG_NAME,_aead_decrypt)
286 (
unsigned char *m,
unsigned long long *mlen,
288 const unsigned char *c,
unsigned long long clen,
289 const unsigned char *ad,
unsigned long long adlen,
290 const unsigned char *npub,
291 const unsigned char *k)
294 unsigned char *mtemp = m;
295 unsigned char offset[OCB_BLOCK_SIZE];
296 unsigned char sum[OCB_BLOCK_SIZE];
297 unsigned char block[OCB_BLOCK_SIZE];
298 unsigned long long block_number;
302 if (clen < OCB_TAG_SIZE)
304 *mlen = clen - OCB_TAG_SIZE;
307 OCB_CONCAT(OCB_ALG_NAME,_init)(&state, k, npub, offset);
310 memset(sum, 0,
sizeof(sum));
312 clen -= OCB_TAG_SIZE;
313 while (clen >= OCB_BLOCK_SIZE) {
314 if (block_number & 1) {
315 lw_xor_block(offset, state.L0, OCB_BLOCK_SIZE);
316 }
else if ((block_number & 3) == 2) {
317 lw_xor_block(offset, state.L1, OCB_BLOCK_SIZE);
319 OCB_CONCAT(OCB_ALG_NAME,_calculate_L)(&state, block, block_number);
320 lw_xor_block(offset, block, OCB_BLOCK_SIZE);
322 lw_xor_block_2_src(block, offset, c, OCB_BLOCK_SIZE);
323 OCB_DECRYPT_BLOCK(&(state.ks), block, block);
324 lw_xor_block_2_src(m, block, offset, OCB_BLOCK_SIZE);
325 lw_xor_block(sum, m, OCB_BLOCK_SIZE);
328 clen -= OCB_BLOCK_SIZE;
334 unsigned temp = (unsigned)clen;
335 lw_xor_block(offset, state.Lstar, OCB_BLOCK_SIZE);
336 OCB_ENCRYPT_BLOCK(&(state.ks), block, offset);
337 lw_xor_block_2_src(m, block, c, temp);
338 lw_xor_block(sum, m, temp);
344 lw_xor_block(sum, offset, OCB_BLOCK_SIZE);
345 lw_xor_block(sum, state.Ldollar, OCB_BLOCK_SIZE);
346 OCB_ENCRYPT_BLOCK(&(state.ks), sum, sum);
349 OCB_CONCAT(OCB_ALG_NAME,_process_ad)(&state, sum, ad, adlen);
int aead_check_tag(unsigned char *plaintext, unsigned long long plaintext_len, const unsigned char *tag1, const unsigned char *tag2, unsigned tag_len)
Check an authentication tag in constant time.
Definition: aead-common.c:26