1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <string.h>
11e1051a39Sopenharmony_ci#include <openssl/crypto.h>
12e1051a39Sopenharmony_ci#include <openssl/err.h>
13e1051a39Sopenharmony_ci#include "crypto/modes.h"
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_OCB
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci/*
18e1051a39Sopenharmony_ci * Calculate the number of binary trailing zero's in any given number
19e1051a39Sopenharmony_ci */
20e1051a39Sopenharmony_cistatic u32 ocb_ntz(u64 n)
21e1051a39Sopenharmony_ci{
22e1051a39Sopenharmony_ci    u32 cnt = 0;
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci    /*
25e1051a39Sopenharmony_ci     * We do a right-to-left simple sequential search. This is surprisingly
26e1051a39Sopenharmony_ci     * efficient as the distribution of trailing zeros is not uniform,
27e1051a39Sopenharmony_ci     * e.g. the number of possible inputs with no trailing zeros is equal to
28e1051a39Sopenharmony_ci     * the number with 1 or more; the number with exactly 1 is equal to the
29e1051a39Sopenharmony_ci     * number with 2 or more, etc. Checking the last two bits covers 75% of
30e1051a39Sopenharmony_ci     * all numbers. Checking the last three covers 87.5%
31e1051a39Sopenharmony_ci     */
32e1051a39Sopenharmony_ci    while (!(n & 1)) {
33e1051a39Sopenharmony_ci        n >>= 1;
34e1051a39Sopenharmony_ci        cnt++;
35e1051a39Sopenharmony_ci    }
36e1051a39Sopenharmony_ci    return cnt;
37e1051a39Sopenharmony_ci}
38e1051a39Sopenharmony_ci
39e1051a39Sopenharmony_ci/*
40e1051a39Sopenharmony_ci * Shift a block of 16 bytes left by shift bits
41e1051a39Sopenharmony_ci */
42e1051a39Sopenharmony_cistatic void ocb_block_lshift(const unsigned char *in, size_t shift,
43e1051a39Sopenharmony_ci                             unsigned char *out)
44e1051a39Sopenharmony_ci{
45e1051a39Sopenharmony_ci    int i;
46e1051a39Sopenharmony_ci    unsigned char carry = 0, carry_next;
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_ci    for (i = 15; i >= 0; i--) {
49e1051a39Sopenharmony_ci        carry_next = in[i] >> (8 - shift);
50e1051a39Sopenharmony_ci        out[i] = (in[i] << shift) | carry;
51e1051a39Sopenharmony_ci        carry = carry_next;
52e1051a39Sopenharmony_ci    }
53e1051a39Sopenharmony_ci}
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_ci/*
56e1051a39Sopenharmony_ci * Perform a "double" operation as per OCB spec
57e1051a39Sopenharmony_ci */
58e1051a39Sopenharmony_cistatic void ocb_double(OCB_BLOCK *in, OCB_BLOCK *out)
59e1051a39Sopenharmony_ci{
60e1051a39Sopenharmony_ci    unsigned char mask;
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci    /*
63e1051a39Sopenharmony_ci     * Calculate the mask based on the most significant bit. There are more
64e1051a39Sopenharmony_ci     * efficient ways to do this - but this way is constant time
65e1051a39Sopenharmony_ci     */
66e1051a39Sopenharmony_ci    mask = in->c[0] & 0x80;
67e1051a39Sopenharmony_ci    mask >>= 7;
68e1051a39Sopenharmony_ci    mask = (0 - mask) & 0x87;
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    ocb_block_lshift(in->c, 1, out->c);
71e1051a39Sopenharmony_ci
72e1051a39Sopenharmony_ci    out->c[15] ^= mask;
73e1051a39Sopenharmony_ci}
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci/*
76e1051a39Sopenharmony_ci * Perform an xor on in1 and in2 - each of len bytes. Store result in out
77e1051a39Sopenharmony_ci */
78e1051a39Sopenharmony_cistatic void ocb_block_xor(const unsigned char *in1,
79e1051a39Sopenharmony_ci                          const unsigned char *in2, size_t len,
80e1051a39Sopenharmony_ci                          unsigned char *out)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    size_t i;
83e1051a39Sopenharmony_ci    for (i = 0; i < len; i++) {
84e1051a39Sopenharmony_ci        out[i] = in1[i] ^ in2[i];
85e1051a39Sopenharmony_ci    }
86e1051a39Sopenharmony_ci}
87e1051a39Sopenharmony_ci
88e1051a39Sopenharmony_ci/*
89e1051a39Sopenharmony_ci * Lookup L_index in our lookup table. If we haven't already got it we need to
90e1051a39Sopenharmony_ci * calculate it
91e1051a39Sopenharmony_ci */
92e1051a39Sopenharmony_cistatic OCB_BLOCK *ocb_lookup_l(OCB128_CONTEXT *ctx, size_t idx)
93e1051a39Sopenharmony_ci{
94e1051a39Sopenharmony_ci    size_t l_index = ctx->l_index;
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ci    if (idx <= l_index) {
97e1051a39Sopenharmony_ci        return ctx->l + idx;
98e1051a39Sopenharmony_ci    }
99e1051a39Sopenharmony_ci
100e1051a39Sopenharmony_ci    /* We don't have it - so calculate it */
101e1051a39Sopenharmony_ci    if (idx >= ctx->max_l_index) {
102e1051a39Sopenharmony_ci        void *tmp_ptr;
103e1051a39Sopenharmony_ci        /*
104e1051a39Sopenharmony_ci         * Each additional entry allows to process almost double as
105e1051a39Sopenharmony_ci         * much data, so that in linear world the table will need to
106e1051a39Sopenharmony_ci         * be expanded with smaller and smaller increments. Originally
107e1051a39Sopenharmony_ci         * it was doubling in size, which was a waste. Growing it
108e1051a39Sopenharmony_ci         * linearly is not formally optimal, but is simpler to implement.
109e1051a39Sopenharmony_ci         * We grow table by minimally required 4*n that would accommodate
110e1051a39Sopenharmony_ci         * the index.
111e1051a39Sopenharmony_ci         */
112e1051a39Sopenharmony_ci        ctx->max_l_index += (idx - ctx->max_l_index + 4) & ~3;
113e1051a39Sopenharmony_ci        tmp_ptr = OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK));
114e1051a39Sopenharmony_ci        if (tmp_ptr == NULL) /* prevent ctx->l from being clobbered */
115e1051a39Sopenharmony_ci            return NULL;
116e1051a39Sopenharmony_ci        ctx->l = tmp_ptr;
117e1051a39Sopenharmony_ci    }
118e1051a39Sopenharmony_ci    while (l_index < idx) {
119e1051a39Sopenharmony_ci        ocb_double(ctx->l + l_index, ctx->l + l_index + 1);
120e1051a39Sopenharmony_ci        l_index++;
121e1051a39Sopenharmony_ci    }
122e1051a39Sopenharmony_ci    ctx->l_index = l_index;
123e1051a39Sopenharmony_ci
124e1051a39Sopenharmony_ci    return ctx->l + idx;
125e1051a39Sopenharmony_ci}
126e1051a39Sopenharmony_ci
127e1051a39Sopenharmony_ci/*
128e1051a39Sopenharmony_ci * Create a new OCB128_CONTEXT
129e1051a39Sopenharmony_ci */
130e1051a39Sopenharmony_ciOCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec,
131e1051a39Sopenharmony_ci                                  block128_f encrypt, block128_f decrypt,
132e1051a39Sopenharmony_ci                                  ocb128_f stream)
133e1051a39Sopenharmony_ci{
134e1051a39Sopenharmony_ci    OCB128_CONTEXT *octx;
135e1051a39Sopenharmony_ci    int ret;
136e1051a39Sopenharmony_ci
137e1051a39Sopenharmony_ci    if ((octx = OPENSSL_malloc(sizeof(*octx))) != NULL) {
138e1051a39Sopenharmony_ci        ret = CRYPTO_ocb128_init(octx, keyenc, keydec, encrypt, decrypt,
139e1051a39Sopenharmony_ci                                 stream);
140e1051a39Sopenharmony_ci        if (ret)
141e1051a39Sopenharmony_ci            return octx;
142e1051a39Sopenharmony_ci        OPENSSL_free(octx);
143e1051a39Sopenharmony_ci    }
144e1051a39Sopenharmony_ci
145e1051a39Sopenharmony_ci    return NULL;
146e1051a39Sopenharmony_ci}
147e1051a39Sopenharmony_ci
148e1051a39Sopenharmony_ci/*
149e1051a39Sopenharmony_ci * Initialise an existing OCB128_CONTEXT
150e1051a39Sopenharmony_ci */
151e1051a39Sopenharmony_ciint CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec,
152e1051a39Sopenharmony_ci                       block128_f encrypt, block128_f decrypt,
153e1051a39Sopenharmony_ci                       ocb128_f stream)
154e1051a39Sopenharmony_ci{
155e1051a39Sopenharmony_ci    memset(ctx, 0, sizeof(*ctx));
156e1051a39Sopenharmony_ci    ctx->l_index = 0;
157e1051a39Sopenharmony_ci    ctx->max_l_index = 5;
158e1051a39Sopenharmony_ci    if ((ctx->l = OPENSSL_malloc(ctx->max_l_index * 16)) == NULL) {
159e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
160e1051a39Sopenharmony_ci        return 0;
161e1051a39Sopenharmony_ci    }
162e1051a39Sopenharmony_ci
163e1051a39Sopenharmony_ci    /*
164e1051a39Sopenharmony_ci     * We set both the encryption and decryption key schedules - decryption
165e1051a39Sopenharmony_ci     * needs both. Don't really need decryption schedule if only doing
166e1051a39Sopenharmony_ci     * encryption - but it simplifies things to take it anyway
167e1051a39Sopenharmony_ci     */
168e1051a39Sopenharmony_ci    ctx->encrypt = encrypt;
169e1051a39Sopenharmony_ci    ctx->decrypt = decrypt;
170e1051a39Sopenharmony_ci    ctx->stream = stream;
171e1051a39Sopenharmony_ci    ctx->keyenc = keyenc;
172e1051a39Sopenharmony_ci    ctx->keydec = keydec;
173e1051a39Sopenharmony_ci
174e1051a39Sopenharmony_ci    /* L_* = ENCIPHER(K, zeros(128)) */
175e1051a39Sopenharmony_ci    ctx->encrypt(ctx->l_star.c, ctx->l_star.c, ctx->keyenc);
176e1051a39Sopenharmony_ci
177e1051a39Sopenharmony_ci    /* L_$ = double(L_*) */
178e1051a39Sopenharmony_ci    ocb_double(&ctx->l_star, &ctx->l_dollar);
179e1051a39Sopenharmony_ci
180e1051a39Sopenharmony_ci    /* L_0 = double(L_$) */
181e1051a39Sopenharmony_ci    ocb_double(&ctx->l_dollar, ctx->l);
182e1051a39Sopenharmony_ci
183e1051a39Sopenharmony_ci    /* L_{i} = double(L_{i-1}) */
184e1051a39Sopenharmony_ci    ocb_double(ctx->l, ctx->l+1);
185e1051a39Sopenharmony_ci    ocb_double(ctx->l+1, ctx->l+2);
186e1051a39Sopenharmony_ci    ocb_double(ctx->l+2, ctx->l+3);
187e1051a39Sopenharmony_ci    ocb_double(ctx->l+3, ctx->l+4);
188e1051a39Sopenharmony_ci    ctx->l_index = 4;   /* enough to process up to 496 bytes */
189e1051a39Sopenharmony_ci
190e1051a39Sopenharmony_ci    return 1;
191e1051a39Sopenharmony_ci}
192e1051a39Sopenharmony_ci
193e1051a39Sopenharmony_ci/*
194e1051a39Sopenharmony_ci * Copy an OCB128_CONTEXT object
195e1051a39Sopenharmony_ci */
196e1051a39Sopenharmony_ciint CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src,
197e1051a39Sopenharmony_ci                           void *keyenc, void *keydec)
198e1051a39Sopenharmony_ci{
199e1051a39Sopenharmony_ci    memcpy(dest, src, sizeof(OCB128_CONTEXT));
200e1051a39Sopenharmony_ci    if (keyenc)
201e1051a39Sopenharmony_ci        dest->keyenc = keyenc;
202e1051a39Sopenharmony_ci    if (keydec)
203e1051a39Sopenharmony_ci        dest->keydec = keydec;
204e1051a39Sopenharmony_ci    if (src->l) {
205e1051a39Sopenharmony_ci        if ((dest->l = OPENSSL_malloc(src->max_l_index * 16)) == NULL) {
206e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
207e1051a39Sopenharmony_ci            return 0;
208e1051a39Sopenharmony_ci        }
209e1051a39Sopenharmony_ci        memcpy(dest->l, src->l, (src->l_index + 1) * 16);
210e1051a39Sopenharmony_ci    }
211e1051a39Sopenharmony_ci    return 1;
212e1051a39Sopenharmony_ci}
213e1051a39Sopenharmony_ci
214e1051a39Sopenharmony_ci/*
215e1051a39Sopenharmony_ci * Set the IV to be used for this operation. Must be 1 - 15 bytes.
216e1051a39Sopenharmony_ci */
217e1051a39Sopenharmony_ciint CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv,
218e1051a39Sopenharmony_ci                        size_t len, size_t taglen)
219e1051a39Sopenharmony_ci{
220e1051a39Sopenharmony_ci    unsigned char ktop[16], tmp[16], mask;
221e1051a39Sopenharmony_ci    unsigned char stretch[24], nonce[16];
222e1051a39Sopenharmony_ci    size_t bottom, shift;
223e1051a39Sopenharmony_ci
224e1051a39Sopenharmony_ci    /*
225e1051a39Sopenharmony_ci     * Spec says IV is 120 bits or fewer - it allows non byte aligned lengths.
226e1051a39Sopenharmony_ci     * We don't support this at this stage
227e1051a39Sopenharmony_ci     */
228e1051a39Sopenharmony_ci    if ((len > 15) || (len < 1) || (taglen > 16) || (taglen < 1)) {
229e1051a39Sopenharmony_ci        return -1;
230e1051a39Sopenharmony_ci    }
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ci    /* Reset nonce-dependent variables */
233e1051a39Sopenharmony_ci    memset(&ctx->sess, 0, sizeof(ctx->sess));
234e1051a39Sopenharmony_ci
235e1051a39Sopenharmony_ci    /* Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N */
236e1051a39Sopenharmony_ci    nonce[0] = ((taglen * 8) % 128) << 1;
237e1051a39Sopenharmony_ci    memset(nonce + 1, 0, 15);
238e1051a39Sopenharmony_ci    memcpy(nonce + 16 - len, iv, len);
239e1051a39Sopenharmony_ci    nonce[15 - len] |= 1;
240e1051a39Sopenharmony_ci
241e1051a39Sopenharmony_ci    /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
242e1051a39Sopenharmony_ci    memcpy(tmp, nonce, 16);
243e1051a39Sopenharmony_ci    tmp[15] &= 0xc0;
244e1051a39Sopenharmony_ci    ctx->encrypt(tmp, ktop, ctx->keyenc);
245e1051a39Sopenharmony_ci
246e1051a39Sopenharmony_ci    /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
247e1051a39Sopenharmony_ci    memcpy(stretch, ktop, 16);
248e1051a39Sopenharmony_ci    ocb_block_xor(ktop, ktop + 1, 8, stretch + 16);
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ci    /* bottom = str2num(Nonce[123..128]) */
251e1051a39Sopenharmony_ci    bottom = nonce[15] & 0x3f;
252e1051a39Sopenharmony_ci
253e1051a39Sopenharmony_ci    /* Offset_0 = Stretch[1+bottom..128+bottom] */
254e1051a39Sopenharmony_ci    shift = bottom % 8;
255e1051a39Sopenharmony_ci    ocb_block_lshift(stretch + (bottom / 8), shift, ctx->sess.offset.c);
256e1051a39Sopenharmony_ci    mask = 0xff;
257e1051a39Sopenharmony_ci    mask <<= 8 - shift;
258e1051a39Sopenharmony_ci    ctx->sess.offset.c[15] |=
259e1051a39Sopenharmony_ci        (*(stretch + (bottom / 8) + 16) & mask) >> (8 - shift);
260e1051a39Sopenharmony_ci
261e1051a39Sopenharmony_ci    return 1;
262e1051a39Sopenharmony_ci}
263e1051a39Sopenharmony_ci
264e1051a39Sopenharmony_ci/*
265e1051a39Sopenharmony_ci * Provide any AAD. This can be called multiple times. Only the final time can
266e1051a39Sopenharmony_ci * have a partial block
267e1051a39Sopenharmony_ci */
268e1051a39Sopenharmony_ciint CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad,
269e1051a39Sopenharmony_ci                      size_t len)
270e1051a39Sopenharmony_ci{
271e1051a39Sopenharmony_ci    u64 i, all_num_blocks;
272e1051a39Sopenharmony_ci    size_t num_blocks, last_len;
273e1051a39Sopenharmony_ci    OCB_BLOCK tmp;
274e1051a39Sopenharmony_ci
275e1051a39Sopenharmony_ci    /* Calculate the number of blocks of AAD provided now, and so far */
276e1051a39Sopenharmony_ci    num_blocks = len / 16;
277e1051a39Sopenharmony_ci    all_num_blocks = num_blocks + ctx->sess.blocks_hashed;
278e1051a39Sopenharmony_ci
279e1051a39Sopenharmony_ci    /* Loop through all full blocks of AAD */
280e1051a39Sopenharmony_ci    for (i = ctx->sess.blocks_hashed + 1; i <= all_num_blocks; i++) {
281e1051a39Sopenharmony_ci        OCB_BLOCK *lookup;
282e1051a39Sopenharmony_ci
283e1051a39Sopenharmony_ci        /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
284e1051a39Sopenharmony_ci        lookup = ocb_lookup_l(ctx, ocb_ntz(i));
285e1051a39Sopenharmony_ci        if (lookup == NULL)
286e1051a39Sopenharmony_ci            return 0;
287e1051a39Sopenharmony_ci        ocb_block16_xor(&ctx->sess.offset_aad, lookup, &ctx->sess.offset_aad);
288e1051a39Sopenharmony_ci
289e1051a39Sopenharmony_ci        memcpy(tmp.c, aad, 16);
290e1051a39Sopenharmony_ci        aad += 16;
291e1051a39Sopenharmony_ci
292e1051a39Sopenharmony_ci        /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
293e1051a39Sopenharmony_ci        ocb_block16_xor(&ctx->sess.offset_aad, &tmp, &tmp);
294e1051a39Sopenharmony_ci        ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);
295e1051a39Sopenharmony_ci        ocb_block16_xor(&tmp, &ctx->sess.sum, &ctx->sess.sum);
296e1051a39Sopenharmony_ci    }
297e1051a39Sopenharmony_ci
298e1051a39Sopenharmony_ci    /*
299e1051a39Sopenharmony_ci     * Check if we have any partial blocks left over. This is only valid in the
300e1051a39Sopenharmony_ci     * last call to this function
301e1051a39Sopenharmony_ci     */
302e1051a39Sopenharmony_ci    last_len = len % 16;
303e1051a39Sopenharmony_ci
304e1051a39Sopenharmony_ci    if (last_len > 0) {
305e1051a39Sopenharmony_ci        /* Offset_* = Offset_m xor L_* */
306e1051a39Sopenharmony_ci        ocb_block16_xor(&ctx->sess.offset_aad, &ctx->l_star,
307e1051a39Sopenharmony_ci                        &ctx->sess.offset_aad);
308e1051a39Sopenharmony_ci
309e1051a39Sopenharmony_ci        /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
310e1051a39Sopenharmony_ci        memset(tmp.c, 0, 16);
311e1051a39Sopenharmony_ci        memcpy(tmp.c, aad, last_len);
312e1051a39Sopenharmony_ci        tmp.c[last_len] = 0x80;
313e1051a39Sopenharmony_ci        ocb_block16_xor(&ctx->sess.offset_aad, &tmp, &tmp);
314e1051a39Sopenharmony_ci
315e1051a39Sopenharmony_ci        /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
316e1051a39Sopenharmony_ci        ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);
317e1051a39Sopenharmony_ci        ocb_block16_xor(&tmp, &ctx->sess.sum, &ctx->sess.sum);
318e1051a39Sopenharmony_ci    }
319e1051a39Sopenharmony_ci
320e1051a39Sopenharmony_ci    ctx->sess.blocks_hashed = all_num_blocks;
321e1051a39Sopenharmony_ci
322e1051a39Sopenharmony_ci    return 1;
323e1051a39Sopenharmony_ci}
324e1051a39Sopenharmony_ci
325e1051a39Sopenharmony_ci/*
326e1051a39Sopenharmony_ci * Provide any data to be encrypted. This can be called multiple times. Only
327e1051a39Sopenharmony_ci * the final time can have a partial block
328e1051a39Sopenharmony_ci */
329e1051a39Sopenharmony_ciint CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
330e1051a39Sopenharmony_ci                          const unsigned char *in, unsigned char *out,
331e1051a39Sopenharmony_ci                          size_t len)
332e1051a39Sopenharmony_ci{
333e1051a39Sopenharmony_ci    u64 i, all_num_blocks;
334e1051a39Sopenharmony_ci    size_t num_blocks, last_len;
335e1051a39Sopenharmony_ci
336e1051a39Sopenharmony_ci    /*
337e1051a39Sopenharmony_ci     * Calculate the number of blocks of data to be encrypted provided now, and
338e1051a39Sopenharmony_ci     * so far
339e1051a39Sopenharmony_ci     */
340e1051a39Sopenharmony_ci    num_blocks = len / 16;
341e1051a39Sopenharmony_ci    all_num_blocks = num_blocks + ctx->sess.blocks_processed;
342e1051a39Sopenharmony_ci
343e1051a39Sopenharmony_ci    if (num_blocks && all_num_blocks == (size_t)all_num_blocks
344e1051a39Sopenharmony_ci        && ctx->stream != NULL) {
345e1051a39Sopenharmony_ci        size_t max_idx = 0, top = (size_t)all_num_blocks;
346e1051a39Sopenharmony_ci
347e1051a39Sopenharmony_ci        /*
348e1051a39Sopenharmony_ci         * See how many L_{i} entries we need to process data at hand
349e1051a39Sopenharmony_ci         * and pre-compute missing entries in the table [if any]...
350e1051a39Sopenharmony_ci         */
351e1051a39Sopenharmony_ci        while (top >>= 1)
352e1051a39Sopenharmony_ci            max_idx++;
353e1051a39Sopenharmony_ci        if (ocb_lookup_l(ctx, max_idx) == NULL)
354e1051a39Sopenharmony_ci            return 0;
355e1051a39Sopenharmony_ci
356e1051a39Sopenharmony_ci        ctx->stream(in, out, num_blocks, ctx->keyenc,
357e1051a39Sopenharmony_ci                    (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,
358e1051a39Sopenharmony_ci                    (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);
359e1051a39Sopenharmony_ci    } else {
360e1051a39Sopenharmony_ci        /* Loop through all full blocks to be encrypted */
361e1051a39Sopenharmony_ci        for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) {
362e1051a39Sopenharmony_ci            OCB_BLOCK *lookup;
363e1051a39Sopenharmony_ci            OCB_BLOCK tmp;
364e1051a39Sopenharmony_ci
365e1051a39Sopenharmony_ci            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
366e1051a39Sopenharmony_ci            lookup = ocb_lookup_l(ctx, ocb_ntz(i));
367e1051a39Sopenharmony_ci            if (lookup == NULL)
368e1051a39Sopenharmony_ci                return 0;
369e1051a39Sopenharmony_ci            ocb_block16_xor(&ctx->sess.offset, lookup, &ctx->sess.offset);
370e1051a39Sopenharmony_ci
371e1051a39Sopenharmony_ci            memcpy(tmp.c, in, 16);
372e1051a39Sopenharmony_ci            in += 16;
373e1051a39Sopenharmony_ci
374e1051a39Sopenharmony_ci            /* Checksum_i = Checksum_{i-1} xor P_i */
375e1051a39Sopenharmony_ci            ocb_block16_xor(&tmp, &ctx->sess.checksum, &ctx->sess.checksum);
376e1051a39Sopenharmony_ci
377e1051a39Sopenharmony_ci            /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
378e1051a39Sopenharmony_ci            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);
379e1051a39Sopenharmony_ci            ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);
380e1051a39Sopenharmony_ci            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);
381e1051a39Sopenharmony_ci
382e1051a39Sopenharmony_ci            memcpy(out, tmp.c, 16);
383e1051a39Sopenharmony_ci            out += 16;
384e1051a39Sopenharmony_ci        }
385e1051a39Sopenharmony_ci    }
386e1051a39Sopenharmony_ci
387e1051a39Sopenharmony_ci    /*
388e1051a39Sopenharmony_ci     * Check if we have any partial blocks left over. This is only valid in the
389e1051a39Sopenharmony_ci     * last call to this function
390e1051a39Sopenharmony_ci     */
391e1051a39Sopenharmony_ci    last_len = len % 16;
392e1051a39Sopenharmony_ci
393e1051a39Sopenharmony_ci    if (last_len > 0) {
394e1051a39Sopenharmony_ci        OCB_BLOCK pad;
395e1051a39Sopenharmony_ci
396e1051a39Sopenharmony_ci        /* Offset_* = Offset_m xor L_* */
397e1051a39Sopenharmony_ci        ocb_block16_xor(&ctx->sess.offset, &ctx->l_star, &ctx->sess.offset);
398e1051a39Sopenharmony_ci
399e1051a39Sopenharmony_ci        /* Pad = ENCIPHER(K, Offset_*) */
400e1051a39Sopenharmony_ci        ctx->encrypt(ctx->sess.offset.c, pad.c, ctx->keyenc);
401e1051a39Sopenharmony_ci
402e1051a39Sopenharmony_ci        /* C_* = P_* xor Pad[1..bitlen(P_*)] */
403e1051a39Sopenharmony_ci        ocb_block_xor(in, pad.c, last_len, out);
404e1051a39Sopenharmony_ci
405e1051a39Sopenharmony_ci        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
406e1051a39Sopenharmony_ci        memset(pad.c, 0, 16);           /* borrow pad */
407e1051a39Sopenharmony_ci        memcpy(pad.c, in, last_len);
408e1051a39Sopenharmony_ci        pad.c[last_len] = 0x80;
409e1051a39Sopenharmony_ci        ocb_block16_xor(&pad, &ctx->sess.checksum, &ctx->sess.checksum);
410e1051a39Sopenharmony_ci    }
411e1051a39Sopenharmony_ci
412e1051a39Sopenharmony_ci    ctx->sess.blocks_processed = all_num_blocks;
413e1051a39Sopenharmony_ci
414e1051a39Sopenharmony_ci    return 1;
415e1051a39Sopenharmony_ci}
416e1051a39Sopenharmony_ci
417e1051a39Sopenharmony_ci/*
418e1051a39Sopenharmony_ci * Provide any data to be decrypted. This can be called multiple times. Only
419e1051a39Sopenharmony_ci * the final time can have a partial block
420e1051a39Sopenharmony_ci */
421e1051a39Sopenharmony_ciint CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
422e1051a39Sopenharmony_ci                          const unsigned char *in, unsigned char *out,
423e1051a39Sopenharmony_ci                          size_t len)
424e1051a39Sopenharmony_ci{
425e1051a39Sopenharmony_ci    u64 i, all_num_blocks;
426e1051a39Sopenharmony_ci    size_t num_blocks, last_len;
427e1051a39Sopenharmony_ci
428e1051a39Sopenharmony_ci    /*
429e1051a39Sopenharmony_ci     * Calculate the number of blocks of data to be decrypted provided now, and
430e1051a39Sopenharmony_ci     * so far
431e1051a39Sopenharmony_ci     */
432e1051a39Sopenharmony_ci    num_blocks = len / 16;
433e1051a39Sopenharmony_ci    all_num_blocks = num_blocks + ctx->sess.blocks_processed;
434e1051a39Sopenharmony_ci
435e1051a39Sopenharmony_ci    if (num_blocks && all_num_blocks == (size_t)all_num_blocks
436e1051a39Sopenharmony_ci        && ctx->stream != NULL) {
437e1051a39Sopenharmony_ci        size_t max_idx = 0, top = (size_t)all_num_blocks;
438e1051a39Sopenharmony_ci
439e1051a39Sopenharmony_ci        /*
440e1051a39Sopenharmony_ci         * See how many L_{i} entries we need to process data at hand
441e1051a39Sopenharmony_ci         * and pre-compute missing entries in the table [if any]...
442e1051a39Sopenharmony_ci         */
443e1051a39Sopenharmony_ci        while (top >>= 1)
444e1051a39Sopenharmony_ci            max_idx++;
445e1051a39Sopenharmony_ci        if (ocb_lookup_l(ctx, max_idx) == NULL)
446e1051a39Sopenharmony_ci            return 0;
447e1051a39Sopenharmony_ci
448e1051a39Sopenharmony_ci        ctx->stream(in, out, num_blocks, ctx->keydec,
449e1051a39Sopenharmony_ci                    (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,
450e1051a39Sopenharmony_ci                    (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);
451e1051a39Sopenharmony_ci    } else {
452e1051a39Sopenharmony_ci        OCB_BLOCK tmp;
453e1051a39Sopenharmony_ci
454e1051a39Sopenharmony_ci        /* Loop through all full blocks to be decrypted */
455e1051a39Sopenharmony_ci        for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) {
456e1051a39Sopenharmony_ci
457e1051a39Sopenharmony_ci            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
458e1051a39Sopenharmony_ci            OCB_BLOCK *lookup = ocb_lookup_l(ctx, ocb_ntz(i));
459e1051a39Sopenharmony_ci            if (lookup == NULL)
460e1051a39Sopenharmony_ci                return 0;
461e1051a39Sopenharmony_ci            ocb_block16_xor(&ctx->sess.offset, lookup, &ctx->sess.offset);
462e1051a39Sopenharmony_ci
463e1051a39Sopenharmony_ci            memcpy(tmp.c, in, 16);
464e1051a39Sopenharmony_ci            in += 16;
465e1051a39Sopenharmony_ci
466e1051a39Sopenharmony_ci            /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
467e1051a39Sopenharmony_ci            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);
468e1051a39Sopenharmony_ci            ctx->decrypt(tmp.c, tmp.c, ctx->keydec);
469e1051a39Sopenharmony_ci            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);
470e1051a39Sopenharmony_ci
471e1051a39Sopenharmony_ci            /* Checksum_i = Checksum_{i-1} xor P_i */
472e1051a39Sopenharmony_ci            ocb_block16_xor(&tmp, &ctx->sess.checksum, &ctx->sess.checksum);
473e1051a39Sopenharmony_ci
474e1051a39Sopenharmony_ci            memcpy(out, tmp.c, 16);
475e1051a39Sopenharmony_ci            out += 16;
476e1051a39Sopenharmony_ci        }
477e1051a39Sopenharmony_ci    }
478e1051a39Sopenharmony_ci
479e1051a39Sopenharmony_ci    /*
480e1051a39Sopenharmony_ci     * Check if we have any partial blocks left over. This is only valid in the
481e1051a39Sopenharmony_ci     * last call to this function
482e1051a39Sopenharmony_ci     */
483e1051a39Sopenharmony_ci    last_len = len % 16;
484e1051a39Sopenharmony_ci
485e1051a39Sopenharmony_ci    if (last_len > 0) {
486e1051a39Sopenharmony_ci        OCB_BLOCK pad;
487e1051a39Sopenharmony_ci
488e1051a39Sopenharmony_ci        /* Offset_* = Offset_m xor L_* */
489e1051a39Sopenharmony_ci        ocb_block16_xor(&ctx->sess.offset, &ctx->l_star, &ctx->sess.offset);
490e1051a39Sopenharmony_ci
491e1051a39Sopenharmony_ci        /* Pad = ENCIPHER(K, Offset_*) */
492e1051a39Sopenharmony_ci        ctx->encrypt(ctx->sess.offset.c, pad.c, ctx->keyenc);
493e1051a39Sopenharmony_ci
494e1051a39Sopenharmony_ci        /* P_* = C_* xor Pad[1..bitlen(C_*)] */
495e1051a39Sopenharmony_ci        ocb_block_xor(in, pad.c, last_len, out);
496e1051a39Sopenharmony_ci
497e1051a39Sopenharmony_ci        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
498e1051a39Sopenharmony_ci        memset(pad.c, 0, 16);           /* borrow pad */
499e1051a39Sopenharmony_ci        memcpy(pad.c, out, last_len);
500e1051a39Sopenharmony_ci        pad.c[last_len] = 0x80;
501e1051a39Sopenharmony_ci        ocb_block16_xor(&pad, &ctx->sess.checksum, &ctx->sess.checksum);
502e1051a39Sopenharmony_ci    }
503e1051a39Sopenharmony_ci
504e1051a39Sopenharmony_ci    ctx->sess.blocks_processed = all_num_blocks;
505e1051a39Sopenharmony_ci
506e1051a39Sopenharmony_ci    return 1;
507e1051a39Sopenharmony_ci}
508e1051a39Sopenharmony_ci
509e1051a39Sopenharmony_cistatic int ocb_finish(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len,
510e1051a39Sopenharmony_ci                      int write)
511e1051a39Sopenharmony_ci{
512e1051a39Sopenharmony_ci    OCB_BLOCK tmp;
513e1051a39Sopenharmony_ci
514e1051a39Sopenharmony_ci    if (len > 16 || len < 1) {
515e1051a39Sopenharmony_ci        return -1;
516e1051a39Sopenharmony_ci    }
517e1051a39Sopenharmony_ci
518e1051a39Sopenharmony_ci    /*
519e1051a39Sopenharmony_ci     * Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)
520e1051a39Sopenharmony_ci     */
521e1051a39Sopenharmony_ci    ocb_block16_xor(&ctx->sess.checksum, &ctx->sess.offset, &tmp);
522e1051a39Sopenharmony_ci    ocb_block16_xor(&ctx->l_dollar, &tmp, &tmp);
523e1051a39Sopenharmony_ci    ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);
524e1051a39Sopenharmony_ci    ocb_block16_xor(&tmp, &ctx->sess.sum, &tmp);
525e1051a39Sopenharmony_ci
526e1051a39Sopenharmony_ci    if (write) {
527e1051a39Sopenharmony_ci        memcpy(tag, &tmp, len);
528e1051a39Sopenharmony_ci        return 1;
529e1051a39Sopenharmony_ci    } else {
530e1051a39Sopenharmony_ci        return CRYPTO_memcmp(&tmp, tag, len);
531e1051a39Sopenharmony_ci    }
532e1051a39Sopenharmony_ci}
533e1051a39Sopenharmony_ci
534e1051a39Sopenharmony_ci/*
535e1051a39Sopenharmony_ci * Calculate the tag and verify it against the supplied tag
536e1051a39Sopenharmony_ci */
537e1051a39Sopenharmony_ciint CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag,
538e1051a39Sopenharmony_ci                         size_t len)
539e1051a39Sopenharmony_ci{
540e1051a39Sopenharmony_ci    return ocb_finish(ctx, (unsigned char*)tag, len, 0);
541e1051a39Sopenharmony_ci}
542e1051a39Sopenharmony_ci
543e1051a39Sopenharmony_ci/*
544e1051a39Sopenharmony_ci * Retrieve the calculated tag
545e1051a39Sopenharmony_ci */
546e1051a39Sopenharmony_ciint CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len)
547e1051a39Sopenharmony_ci{
548e1051a39Sopenharmony_ci    return ocb_finish(ctx, tag, len, 1);
549e1051a39Sopenharmony_ci}
550e1051a39Sopenharmony_ci
551e1051a39Sopenharmony_ci/*
552e1051a39Sopenharmony_ci * Release all resources
553e1051a39Sopenharmony_ci */
554e1051a39Sopenharmony_civoid CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx)
555e1051a39Sopenharmony_ci{
556e1051a39Sopenharmony_ci    if (ctx) {
557e1051a39Sopenharmony_ci        OPENSSL_clear_free(ctx->l, ctx->max_l_index * 16);
558e1051a39Sopenharmony_ci        OPENSSL_cleanse(ctx, sizeof(*ctx));
559e1051a39Sopenharmony_ci    }
560e1051a39Sopenharmony_ci}
561e1051a39Sopenharmony_ci
562e1051a39Sopenharmony_ci#endif                          /* OPENSSL_NO_OCB */
563