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